Aktualisiert: Die "MakeNode" Widget-Erweiterung

12. September 2011 um 15.18 Uhr von Satyam | In Entwicklung , YUI 3 Galerie | 8 Kommentare

Anmerkung der Redaktion: Dieser Artikel wurde ursprünglich Anfang dieses Jahres veröffentlicht . Seitdem hat das hat MakeNode Modul mit dem YUI Galerie veröffentlicht worden und erhielt einige Verbesserungen. Der heutige Artikel spiegelt die neuesten Änderungen zu MakeNode.

In meinem vorherigen Artikel, Ein Rezept für ein YUI 3 Anwendung , zeigte ich einen Weg zu benutzen Y.substitute als eine sehr grundlegende Vorlage Prozessor. Die Idee nahm das Leben von dort aus, mit Anregungen von den Leuten im IRC-Channel # yui, und ich machte es ein Widget-Erweiterung, die auf dem YUI Gallery ist, genannt MakeNode . MakeNode ist keine generische Template-Prozessor und es ist nicht so gemeint ist. Auf der anderen Seite, wird es eng mit dem YUI integriert Widget Foundation Class, einschließlich className-und Event-Helfer und Internationalisierung. In diesem Artikel werde ich die Spinner Beispiel und ändern Sie es, die Richtlinien aus meinem vorherigen Artikel zu folgen und MakeNode verwenden. MakeNode ist als Galerie-Komponente als auch die modifizierten verfügbaren Spinner -Komponente und der beispielsweise die in diesem Artikel verwendet werden soll .

Erweitern Sie Ihre Komponente

Um MakeNode laden Sie das Modul in Ihrem gehören müssen YUI().use() -Anweisung mit dem Namen 'gallery-makenode' oder, wenn ein Modul definiert über YUI.add() , listen ihn als requires Array. Dann, um Ihr Widget erweitern, listen Sie diese in das dritte Argument zu Y.Base.create() , wie folgt aus:

  Y.Spinner Y.Base.create = (
      'Spinner',
      Y.Widget,
      [Y.MakeNode],
      {
         / / Instanz-Mitglieder ...
      },
      {
          / / Statische Member
      }
 ); 

Sie können MakeNode entlang einer beliebigen Anzahl von geeigneten Erweiterungen für Widget, wie WidgetParent, WidgetChild, WidgetStdMode hinzufügen, fügt usw. MakeNode zwei geschützte Methoden, um durch den Entwickler, verwendet werden _makeNode und _locateNodes, und es wird von mehreren statischen Eigenschaften zu lesen, wenn gefunden .

Alle Mitglieder dieser Erweiterung sind entweder protected oder private, da sie dazu bestimmt sind, von der Komponenten-Entwickler und nicht das von der Implementierung über die Komponenten, die nicht mit ihnen belästigt werden sollte verwendet werden. Denken Sie daran, den "Show Protected"-Option überprüfen, bei der Anzeige der API-Dokumentation .

Definieren Sie die Vorlage

Das erste, was Sie normalerweise tun wird ist, um die Vorlage für Ihre Komponente zu definieren. Für die Spinner, wird unsere Vorlage sein:

  _template: [
     '<input Type="text" title="{s input}" class="{c input}">',
     '<button Type="button" title="{s up}" class="{c up}"> </ button>',
     '<button Type="button" title="{s down}" class="{c down}"> </ button>'
 ]. Join ('\ n'), 

Das Standard-Template wird in der Regel genannt werden _TEMPLATE und erklärte, an den anderen statischen Eigenschaften der Klasse, wie ATTRS . MakeNode wird diese Vorlage benutzen, wenn nichts anderes ausdrücklich vorgesehen ist. Die Vorlage wird von einfachem HTML sowie eine Reihe von Platzhalter in geschweiften Klammern, jeder von einem einzelnen Zeichen (die Verarbeitung Code) gemacht, gefolgt von einem oder mehreren Argumenten gemacht. Die Platzhalter und was sie produzieren, sind:

  • {@ attributeName} Konfiguration Attributwert

  • {p propertyName} Instanzeigenschaft Wert

  • {m methodName arg1 arg2 ….} Rückgabewert der Methode gegeben. Die Verarbeitung Code wird durch den Namen der Methode und einer beliebigen Anzahl von Argumenten getrennt durch ein Leerzeichen gefolgt.

  • {c classNameKey} CSS className aus der erzeugten _CLASS_NAMES statische Eigenschaft (siehe Die _CLASS_NAMES Eigentum weiter unten)

  • {s key} -String aus dem strings -Attribut, mit key , als der Sub-Attribut.

  • {? condition valueIfTrue valueIfFalse } ähnlich wie die ?: Betreiber von JavaScript, wertet auf valueIfTrue wenn Bedingung truish, valueIfFalse anders.

  • {1 condition valueIfOne valueIfMore } verwendet werden, um Singular / Plural Worte über den Wert der Bedingung basieren.

  • {} jeder andere Wert wird genau wie behandelt werden Y.substitute tut.

Zum Beispiel, {@ value} wird zu übersetzen this.get('value') , während {p value} übersetzt, um this['value'] .

Als Platzhalter Argumente haben, wie {m} , {?} und {1} , müssen Zeichenketten in doppelte Anführungszeichen eingeschlossen werden. Zahlen, boolesche Werte und null (alle ohne Anführungszeichen) wird zu ihrer richtigen Datentypen analysiert werden. Platzhalter können verschachtelt werden. Die {?} und {1} Platzhalter enthält üblicherweise eine verschachtelte Platzhalter für den Zustand und möglicherweise für ihre Werte, zum Beispiel:

  Menge {p} {1} {p qty "Einheit" "Einheiten"} 

Wenn die Eigenschaft qty 1 ist, wird es zu bewerten, "1 unit" , für 2 oder mehr wird es wieder "2 units" und so weiter. Eine etwas ausführlichere Version Umgang mit Null wäre:

  {?  {P} Menge "Menge {p} {1} {p qty" Einheit "" Einheiten "}" "none"} 

Beachten Sie, dass das Ergebnis der Verarbeitung der inneren Platzhalter, wenn ein String ist, muss in seinen eigenen Satz von Anführungszeichen gesetzt werden.

Um ein Anführungszeichen in einem String in Anführungszeichen enthalten, verwenden Sie \\" . MakeNode nicht verwenden;, die doppelten Backslash erforderlich ist, weil JavaScript in ein einziges interpretieren wird und verwirft es, bevor es zu MakeNode bekommt nur doppelte Anführungszeichen dürfen eval() so Der Parser ist begrenzt, aber sicher. Alles andere als Zahlen, null , booleans und Zeichenketten in doppelten Anführungszeichen werden ignoriert.

Der {?} Platzhalter ist auch praktisch, um mit Checkboxen und Radio-Buttons verwenden. Es kann benutzt werden, um die Zeichenkette sein "checked" in Abhängigkeit von der Wahrheitswert der Verarbeitungsanweisung Code, der folgt. So <input type="checkbox" {? {m getLength} "checked" ""}/> <input type="checkbox" {? {m getLength} "checked" ""}/> wird eine deutliche Checkbox zu produzieren, wenn die getLength Methode gibt alles andere als Null.

Für die {c} Platzhalter, müssen wir haben ein _CLASS_NAMES Eigenschaft definiert.

Weitere Platzhalter können hinzugefügt werden, indem man sie in die MakeNode werden _templateHandlers Hash.

Die _CLASS_NAMES Eigentum

Zusammen mit dem ATTRS und _TEMPLATE statische Eigenschaften können wir definieren eine _CLASS_NAMES statische Eigenschaft, die zu einem Array von Zeichenfolgen verweist. Jede dieser Zeichenfolgen wird verwendet, um eine className zu erzeugen. So _CLASS_NAMES: ['input'] die className produzieren wird "yui3-spinner-input" . Diese Klassennamen werden in einer Instanz-Eigenschaft gespeichert this._classNames . Die {c input} Platzhalter in der Vorlage oben wird ersetzt durch "yui3-spinner-input" . Ich nenne die Saiten in aufgelistet _CLASS_NAMES , wie zum Beispiel 'input' , den "className Tasten", da sie als Schlüssel, um auf die tatsächliche className oder die Elemente enthält, diese beziehen sich Klassennamen verwendet werden können, wie wir später sehen werden.

Sie können die _CLASS_NAMES -Eigenschaft auf eine beliebige Anzahl von Klassennamen zu generieren, ob man sie in der Vorlage verwenden oder nicht. Sie können immer noch erreichen diese zusätzlichen Klassennamen von innerhalb this._classNames . Der className wird unter Verwendung des yui3 Präfix durch den Wert des gefolgt NAME statische Eigenschaft wandte Kleinbuchstaben, und dann die Zeichenfolge im gegebenen _CLASS_NAMES (das letzte wird nicht gedreht werden klein geschrieben), die alle durch Bindestriche getrennt sind. Die _classNames Hash enthält auch die Klassennamen für die boundingBox und der contentBox , die erste unter der "boundingBox" -Taste und die zweite unter dem "content" -Taste. Widget tritt dem boundingBox die Klassennamen von den Werten der abgeleiteten NAME Eigentum der jede der Klassen in der Vererbung Kette, beginnend mit yui3-widget . MakeNode Läden in this._classNames nur das oberste className für die boundingBox .

Wenn die WidgetStdMod Modul geladen wird, wird MakeNode erzeugen auch Einträge für seine HEADER , BODY und FOOTER Abschnitte mit denselben Tasten, die auch die Konstanten in demselben Modul definiert.

Wenn eine Komponente mehreren Ebenen weg von Widget, wie SuperSpecialSpinner Erben von SuperSpinner die aus erbt Spinner , die aus erbt Widget, und wenn einer oder alle von ihnen haben _CLASS_NAMES Eigenschaften definiert, MakeNode Klassennamen wird für alle von ihnen produzieren und speichern sie in this._classNames . Sie müssen nicht auf jeder Ebene die Namen bereits in den vorangegangenen Stufen erklärt gehören. In der Tat ist es besser, dass Sie nicht da die Klassennamen auf jeder Ebene produziert wird den Wert des benutzen NAME Eigentum von diesem Niveau. So wird in SuperSpecialSpinner , {c input} wird immer noch dazu führen, "yui3-spinner-input" und nicht "yui3-superspecialspinner-input" und so wird es halten Sie Ihre CSS-Datei immer noch gültig.

Der Platzhalter {s}

Widget hat eine strings -Konfiguration Attribut definiert, obwohl es nicht mit einem beliebigen Wert initialisiert. Dieses Attribut soll Strings, die sichtbar (oder mittels Screenreader, um zu lesen) den Anwender liegen auf Halten. Es ist wichtig, dass Sie nie gehören sichtbaren Strings direkt in der Vorlage. Dies ist keine Forderung der MakeNode - es war noch nie so eine gute Idee überhaupt. Alle Strings, die durch angesehen oder gelesen werden, um den Benutzer sind, sollte immer in der platziert werden strings -Attribut. Die strings Attribut enthält einen Hash, wo jeder einzelne Text durch seinen Schlüssel befindet. Die Spinner-Komponente hat, die folgende Zeichenfolgen, die Sie in der Vorlage verwendet werden oben zu sehen.

  Streicher: {
     Wert: {
         Eingang: "Drücken Sie die Pfeil hoch / runter-Tasten für kleinere Schritten, page up / down für die großen Schritten."
         bis: "Increment",
         unten: "Dekrement"
     }
 }, 

Der beste Teil der dabei ist, dass Ihre Komponente in andere Sprachen können sehr leicht lokalisiert werden, indem Entwickler, die mit Ihrer Komponente. Beim Erstellen einer Instanz der Spinner, könnten Sie tun:

  var = new mySpinner Spinner ({Saiten: Y.Intl.get ('Spinner')}); 

Einstellen der Konfiguration Attribut strings auf diese Weise ersetzt die Standard- strings -Werte mit denen aus der Sprache Ressource Datei mit Hilfe des zuvor definierten Sprache. Die {s} Platzhalter greift die Saiten in der gespeicherten strings Attribut, entweder die Standard-oder diejenigen die übersetzten diejenigen, falls eingestellt. Die {s xxxx} Platzhalter ist fast wie mit {@ strings.xxxx} außer, dass die lokalisierten Ersatz-Strings können Platzhalter, die weiterverarbeitet werden müssen. Dies ist wichtig für Übersetzungen seit syntaktische Reihenfolge variiert von Sprache zu Sprache und dies ermöglicht den Text umzuformulieren, einschließlich seiner Platzhalter jede beliebige Sprache anpassen. Strings kann auch über sein {@ strings.xxxx.yyyy.zzzz} , die den Zugriff auf Saiten tiefer verschachtelt werden können und wird weitere Substitutionen zu verhindern. Geschweiften Klammern können in einem Text mit aufgenommen werden {LBRACE} und {RBRACE} als Platzhalter.

Mit _makeNode in renderUI

Wir verwenden die Vorlage, um das Markup für unsere Komponente zu erstellen. Dazu rufen wir die MakeNode _makeNode Methode, wie folgt aus:

  renderUI: function () {
     . this.get ('Contentbox') append (this._makeNode ());
 }, 

Dies wird in der füllen contentBox unserer Widget mit dem Markup aus der Verarbeitung der Vorlage. Die _makeNode Methode gibt eine Instanz von Y.Node , die angehängt oder eingefügt werden können oder einfach nur überall statt für die spätere Verwendung. Es gibt nicht einen String, produziert sie einen Node Instanz. (Wenn Sie einen String und einen Knoten nicht tun, können Sie mit dem _substitute Verfahren, was bedeutet, dass Sie in einer Vorlage passieren muss.)

Die _makeNode Methode hat zwei optionale Argumente: ein Verweis auf eine Vorlage und ein Objekt in Platzhalter füllen, als Y.substitute tut. In diesem einfachen Spinner Beispiel gibt es eine einzige Schablone für die ganze abrufen kann aber auch andere Widgets Bruchstücke von mehreren Vorlagen zu verlangen. In diesem Fall würden Sie in der Regel rufen _makeNode ohne Argumente für den Hauptteil und rufen Sie es erneut mit verschiedenen Vorlagen, um in den zusätzlichen Teile zu füllen. Das Beispiel enthält diese renderUI Methode:

  renderUI: function () {
     var fieldset = this._makeNode ();
     this.each (function (item) {
         fieldset.appendChild (this._makeNode (MultipleTemplates.RADIO_TEMPLATE, item));
     }, This);
     this.get ('Contentbox') append (fieldset).;
 } 

Der erste Aufruf von _makeNode gibt einen Node -Instanz in der Variable gespeichert fieldset . Die Probe Komponente ist auch mit erweitert Y.ArrayList so dass die RADIO_TEMPLATE mit Werten aus den Elementen in dem Array Liste gespeichert, und die resultierenden Knoten angehängt dem aufgenommenen gefüllt wird fieldset bevor es schließlich auf die beigefügte contentBox . Die spezielle Platzhalter wie {@} oder {p} wird immer noch um die Attribute oder Eigenschaften in der Haupt-Objekt verweisen. Die verschachtelten Elemente verarbeitet werden ebenso Y.substitute würde.

Die Methode _locateNodes

MakeNode stellt weiterhin ein _locateNodes Methode, die versuchen, alle Elemente mit den Klassennamen in lokalisieren erklärt wird _CLASS_NAMES . Um bestimmte Elemente, die Sie beliebig viele className Schlüssel übergeben können finden, sonst _locateNodes versucht sie alle. Für jedes Element eines jeden className gefunden, _locateNodes erzeugt eine private Instanz-Eigenschaft mit dem Unterstrich-Präfix, indem der Name des Schlüssels und dem gefolgt "Node" -Suffix. So wird in unserem Beispiel Spinner, _locateNodes generiert die Eigenschaften _inputNode , _upNode und _downNode . Wenn mehrere Elemente die gleiche className haben, _locateNodes eine Bezugnahme auf die erste von ihnen zurück. Wenn ein Element nicht gefunden wird, wird keine Variable angelegt werden.

In der Spinner-Komponente verwenden wir _locateNodes nach dem Erstellen des Markups:

  renderUI: function () {
     . this.get (CBX) append (this._makeNode ());
     this._locateNodes ();
 }, 

Die _events statische Eigenschaft

Eine weitere Eigenschaft kann nach dem Vorbild der definiert werden _TEMPLATE und _CLASS_NAMES und das ist _EVENTS . _EVENTS wird eine Hash-up von Klassennamen Tasten, die jeweils eine Hash des Event-Typen und Methoden, um sie zu behandeln, zu enthalten. Es ist besser mit einem Beispiel erklären:

  _events: {
     Eingang: "Veränderung", / / ​​ruft this._afterInputChange
     boundingBox: [
         {
             Typ: "Schlüssel",
             fn: '_onDirectionKey', / / ​​ruft this._onDirectionKey
             args: ((Y.UA.opera) "down"!? "Presse:") + "38, 40, 33, 34"
         },
         'MouseDown' / / ruft this._afterBoundingBoxMousedown
     ],
     Dokument: 'mouseUp', / / ​​ruft this._afterDocumentMouseup,
     Y: 'broadcastingObject: someEvent' / / ruft diese ["_afterYBroadcastingObject: someEvent"]
 }, 

_EVENTS ist ein Objekt (ein Hash) mit beliebig vielen Einträgen. Die Namen der Eigenschaften, das heißt, die Schlüssel des Hash, identifizieren die Knoten, deren Ereignisse werden wir zuhören. Es sind die gleichen className Schlüssel in definierten _CLASS_NAMES . Es gibt mehrere zusätzliche Sondertasten:

  • "boundingBox" wird zum Begrenzungsrahmen selbst beziehen.

  • "document" bezieht sich auf das Dokument mit diesem Widget.

  • "THIS" bezieht sich auf den Widget selbst

  • "Y" bezieht sich auf die Y -Instanz.

Wenn das Widget hat mit WidgetStdMod als auch erweitert worden, die Tasten HEADER , BODY und FOOTER wird für die betroffenen Teile beziehen, da sie die Verfügbarkeit in der _classNames Hash. JavaScript muss nicht die Schlüssel zum zitiert werden, wenn sie gültige Bezeichner so keine der oben in Anführungszeichen gesetzt werden müssen, sind.

Die _EVENTS Gegenständen verarbeitet wird, nachdem die renderUI , bindUI und syncUI Methoden aufgerufen wurden, so das Widget wird erwartet, dass bereits innerhalb des Dokuments Körper eingeführt werden, da sonst das "document" Kennung wird scheitern.

Für jedes dieser Elemente gibt es ein Ereignis-ID oder ein Array von Ereignis-IDs. Ein Ereignis kann durch die Art des Ereignisses zu hören oder ein Objekt mit weiteren Einzelheiten identifiziert werden. Standardmäßig wird MakeNode als Zuhörer eine Methode namens mit dem verwenden "_after" Präfix durch das Element Kennung mit dem ersten Zeichen, gefolgt von der Event-Typ mit seinem ersten Charakter groß gefolgt aktiviert. Der Codeblock oben zeigt die Methoden für jedes Ereignis aufgerufen.

Ein Ereignis-ID kann auch ein Objekt mit Eigenschaften, sein type , fn und args . Der type ist obligatorisch und zeigt die Art der Veranstaltung gehört zu werden. Die fn -Eigenschaft gibt den Namen der Methode, die auf das Ereignis wodurch die automatische Benennung hören wird. Seit _EVENTS ist eine statische Eigenschaft, es hat keinen Zugriff auf this , damit es nicht bei der Aufnahme eines tatsächlichen Verweis auf eine Methode, nur seinen Namen. Der args -Argument kann verwendet werden, um weitere Argumente für den Anrufer wie mit dem Pass werden key Ereignis, das einen Schlüssel-Spezifikation erfordert.

MakeNode verwenden Node.delegate , um auf Ereignisse auf Elemente der zuhören boundingBox , während es benutzen will Node.after , um auf Ereignisse aus der zuhören boundingBox und dem Dokument Körper. Es wird verwendet this.after bis zu Veranstaltungen unter dem hören THIS Schlüssel und Y.after für Zuhörer unter dem genannten Y -Taste. Alle Veranstaltungen sind auf die Verwendung nach der Ereignis-Listener, da sie gemeint sind, um das Widget auf Ereignisse zu reagieren zugehört, nicht um das Verhalten des Objekts, das sie so in keinem Fall können diese Ereignisse verhindert oder gestoppt werden feuert filtern. (Hinweis: Hören auf das key -Ereignis auf jedem verschachtelten Element funktioniert nur mit Version 3.4.0pr1 und oben, da Delegation der key Veranstaltung nicht zur Verfügung stand, bevor alle anderen Funktionen arbeiten mit früheren Versionen als auch.).

Die _EVENTS Erklärungen sind kumulativ, wenn Komponenten voneinander erben. Jede Klasse in der Vererbung Kette wird eine eigene _EVENTS Erklärung separat verarbeitet.

Die _ATTRS_2_UI statische Eigenschaft

Veranstaltungen in beide Richtungen gehen, von der Benutzeroberfläche auf das Bauteil und von der Komponente bis zur UI. Die erste von der Handhabung _EVENTS Eigentum. Dann gibt es die Ereignisse, die von Attribut-Wert Änderungen, die in der Benutzeroberfläche widerspiegeln müssen gefeuert. Wie ich im vorherigen Artikel, wenn es irgendwelche Nebenwirkungen durch Ändern einer Konfiguration Attribut erwähnt, sollten sie nach Veränderung Ereignis-Listener verarbeitet werden, nicht durch den optionalen setter Methode des Attributs, der nur mit der Normalisierung der Wert sollte so eingestellt umzugehen. Die Benutzeroberfläche sollte widerspiegeln den Zustand der Konfiguration Attribute, zuerst in syncUI , wenn gerade initialisiert und danach bei jeder Attribut change-Ereignis. Für letztere müssen wir ein Ereignis-Listener zu befestigen, was wir normalerweise tun in bindUI . Widget bietet bereits einen Mechanismus, um diese einfache, den ich in den Kommentaren zum vorherigen Artikel beschrieben zu machen.

Widget verwendet die Instanzeigenschaft _UI_ATTRS , die ein Objekt mit zwei weiteren Eigenschaften, enthält SYNC und BIND . Jeder von ihnen ist ein Array mit den Namen der Konfiguration Attribute zunächst synchronisiert werden und dann hörte, um die UI spiegelt die aktuellen Werte zu halten. Widget erwartet jeder dieser Einträge, eine Methode zugeordnet ist, nach dem Attribut Name mit dem Präfix benannt haben _uiSet mit dem ersten Zeichen des Attributs Name in Großbuchstaben umgewandelt, um den Namen der Methode in der richtigen Kamel Fall haben. Wenn also "value" nach einem der aufgeführten wurde _UI_ATTRS Arrays (entweder SYNC oder BIND ), würde erwarten, dass ein Widget finden _uiSetValue Verfahren. Diese Methode erhält zwei Argumente, die value festgelegt, und src der Änderung. Dies ist der Code für unser Spinner _uiSetValue Methode:

  _uiSetValue: function (value, src) {
     if (src === UI) {
         zurück;
     }
     this._inputNode.set (Wert, this.get (Formatter) (Wert));
 }, 

Alle Groß-Kennungen sehen Sie in diesem Teil des Codes entsprechen Stringkonstanten erklärt an anderer Stelle, damit der YUI Compressor, um seine Arbeit besser zu machen. Die Methode, im Grunde, setzt den value HTML-Attribut in der <input> Box auf den neuen Wert gesetzt, nachdem sie formatiert. Der Verweis auf das Textfeld wurde, bereitgestellt durch _locateNodes . Das src Argument wird zunächst überprüft, ob der String-Wert gesetzt 'ui' . Wenn dies so ist, werden keine Maßnahmen ergriffen werden. Dies ist um Endlosschleifen zu vermeiden. Gibt der Benutzer etwas in das Eingabefeld ein, würde dessen Wert in die go value Konfiguration Attribut, das dann ein Feuer würde valueChange Ereignis, das würde gehen _uiSetValue genannt, die, wenn nicht aktiviert, dann gehen Sie und ändern Sie den Wert des Eingangs-Box, die würde den ganzen Prozess wieder auslösen. So wird in _uiSetValue , wenn wir wissen, die Veränderung kommt aus dem UI, tun wir nichts, und so brechen die Schleife. Dies erfordert jedoch anderen Teil des Codes an anderer Stelle. In der Listener für das DOM-Ereignis, wenn wir die Konfiguration Attribut festzulegen, verwenden wir die dritte optionale Argument zu setzen, etwa so:

  _afterValueChange: function (ev) {
     this.set (Wert, ev.newVal, {src: UI});
 } 

Es liegt an uns, um sicherzustellen, dass Änderungen aus dem UI gekennzeichnet sind und prüfen Sie dann damit, dass die gleiche Flagge, um Schleifen zu vermeiden. Haben die Kennung verwenden src beim Einstellen der Wert des Attributs, nicht source , die nicht erkannt werden.

Mit all das gesagt hatte, habe ich noch nicht über die statische Eigenschaft gesprochen _ATTRS_2_UI in der Überschrift dieses Abschnitts erwähnt. Da die Kommentare in meinem vorhergehenden Artikel zeigt (durch die Fehler ich in ihnen gemacht), um sicherzustellen, dass alle Attribute beeinflussen die Benutzeroberfläche ordnungsgemäß aufgelistet ist etwas unordentlich. Sie sollten sich nicht initialisieren _UI_ATTRS von Grund auf neu seit Widget listet bereits eine ganze Menge von Attributen und die verloren gehen würden. Sie müssen neue Attributnamen über die bisherigen, was etwas ist schwer zu merken, wie man es richtig machen zu verketten. Um es einfach, wird MakeNode aus der statischen Eigenschaft lesen _ATTRS_2_UI und zu tun, dass die Verkettung für Sie. Es wird alle diese Listen von jeder und jede Klasse in der Vererbungskette so verketten, auf jeder Ebene jeder Klasse kann eigene Attribute zu behandeln. In Spinner, haben wir:

  _ATTRS_2_UI: {
     BIND: Wert,
     SYNC: VALUE
 }, 

MakeNode akzeptiert sowohl ein Array von Namen oder ein einzelnes Attribut Name, wie im vorliegenden Fall.

Die Frage stellt sich natürlich, warum zwei Listen, eine für die Bindung des anderen für die Synchronisierung? SYNC wird beim ersten Mal eingesetzt, nachdem die renderUI und bindUI Methoden, wenn sie vorhanden sind, werden genannt und vor syncUI , während jene, die in BIND wird, gebunden zu sein die entsprechenden Attribute für spätere Änderungen. Ziemlich oft die SYNC -Array hat weniger Einträge als der BIND Liste und das ist, weil die Vorlage für die Komponente bereits haben könnten genau die gleiche Default-Wert wie die Konfiguration Attribut und gibt es keine Notwendigkeit, eine erste Synchronisierung zu tun. Also, wenn der Standardwert für den value Konfiguration Attribut ist eine leere Zeichenkette und die <input> Element in der Vorlage hat keinen value Attribut, dann gibt es keine Notwendigkeit, sie auf die Initialisierung zu synchronisieren.

Attribute im Abschnitt BIND werden ihre _uiSet Xxxx Verfahren in beliebiger Reihenfolge aufgerufen, als Attribute in beliebiger Reihenfolge eingestellt werden kann. Attribute in aufgelistet SYNC wird einmal in der Reihenfolge, in der sie mit denen der Vorfahren vor ihren Erben aufgeführt sind aufgerufen werden, so dass, wenn man von einer anderen abhängig ist (was sie nicht tun sollten), die Reihenfolge wichtig sein könnte.

MakeNode wird nach doppelten Einträgen in jedem dieser Arrays zu überprüfen. Wenn irgendein erscheinen, bedeutet dies, dass eine Klasse unserer Komponente von bereits behandelt dieses Attribut und jede neue Erklärung würde höchstwahrscheinlich überschreiten die erbt _uiSet Xxxx Handler für sie. Übrigens MakeNode überprüft auch nach doppelten Einträgen in _CLASS_NAMES , die auch zu Konflikten in einigen können, wenn auch nicht alle Umstände. MakeNode wird eine Nachricht in das Protokoll für solche Fehler zu schreiben.

Die _PUBLISH Eigentum

Schließlich wird die _PUBLISH werden statische Eigenschaft Liste jene Ereignisse, die veröffentlicht werden müssen. Es enthält einen Hash mit dem Namen der Veranstaltung wie die Tasten und einem Objekt-Literal von Konfigurations-Attribute wie seine Werte. Es wird veröffentlichen alle Ereignisse in einer solchen Immobilie in all der Vererbungskette aufgeführt. Das gleiche Ereignis Name kann in einer Klasse und in jeder Klasse erbt von ihm, das machen die Konfiguration Attribute der späteren überschreiben die, die in den älteren veröffentlicht werden. Zum Beispiel möchten Sie möglicherweise ein vorhandenes Ereignis sendet weltweit zu machen. Genau wie bei der _EVENTS Eigentum, da _PUBLISH ist eine statische Eigenschaft, ohne Zugriff auf this , bei der Angabe von Funktionen, ist es der Name der Methode als String, also gegeben werden muss.

Abschluss

MakeNode bietet eine sehr einfache Template-Prozessor, mit einer Funktionalität, die stark mit dem Widget Foundation Class integriert ist. Es bietet auch Hilfsmethoden zur Klassennamen zu schaffen, um in der Vorlage verwendet werden, und dass er diese Namen verwenden zu lokalisieren und beziehen sich auf den Knoten erstellt. Außerdem bietet die Möglichkeit, in die Ereignisse sowohl von der Benutzeroberfläche und der Komponente selbst erzeugt Haken und ordnen jeweils mit einem Verfahren. Er tut all diese Dinge, und gleichzeitig dafür Sorge um die Erbschaft-Kette gerade auf Widget und jeder Ebene der Klassen, die Sie definieren können zu respektieren.

Es steht nicht für absolut alle Möglichkeiten bieten, deckt aber eine gute Auswahl von ihnen. Trotzdem funktioniert es nicht aus, dass Sie aus das Hinzufügen zusätzlicher Funktionalität. Vielleicht haben selten einen schreiben bindUI oder syncUI Methode, wenn Sie den Kleber durch MakeNode zu verwenden, aber Sie können dies tun, da MakeNode nicht nutzt sie.

Als Bonus für diejenigen, die Geduld, so weit, ich habe auch modifizierte Anthony Pipkins Button-Set von Galerie Komponenten gelesen hatte und machte ein Akkordeon und TimeSpinner Komponenten, die alle in der Galerie .

Satyam Über den Autor: Daniel Barreiro (Screen Name Satyam) gibt es schon seit geraumer Zeit gewesen. Der ENIAC wurde Sie den Tag gedreht, bevor er geboren wurde, so dass er verpasste aber er hat nicht viel verpasst. Er hatte eine Chance, Lochkarten, Programm 6502 Chips (erinnere mich an den Apple II?), Eine eigene TRS-80 und sehen Sie einige fantastische Stücke von Betriebsmitteln in seinem Heimatland Argentinien, die in Museen anderswo gewesen sein könnte. Wenn Globalisierung öffnete die Türen zu der Welt, seine dann kaum brauchbare Englisch (plus ein Elektrotechnik-Studium) setzte ihn auf der Laufbahn, die in einem 5-Jahres-Job in der Bay Area zurück in den Tagen des NCSA Mosaic beendet. Völlig von den lustigen Kringeln ein Freund von ihm in seinem Text-Editor geschrieben, voll von <'s und>' s fasziniert, landete er lernen sehr viel über die Welt der Frontend-Engineering. Es war ein langer Weg seit COBOL und Fortran. Jetzt lebt er ganz glücklich semi-Ruhestand in der Mittelmeer-Küste nahe Barcelona, ​​Spanien.

Teilen und zu erweitern: Lesezeichen mit del.icio.us | Digg it! | reddit!

8 Kommentare »

RSS-Feed für Kommentare zu diesem Beitrag. TrackBack URI

  1. Äh, wow. Schließlich machte es durch diesen Artikel, und ich bin gespannt, versuchen Sie sich die Galerie-Modul. Es scheint so * viele * von Gerüsten, die ich bin mir nicht sicher toll für die Entwickler neue zu YUI, ohne in den Schützengräben erste ist, aber ich kann sicherlich sehen, wie es einige sehr wiederholenden Code zu verkürzen, vor allem für diejenigen von uns, die haben bereits gesetzt in unserer Zeit :-).

    Ich bin neugierig auf die folgende Erklärung ab: "Die _events Eigenschaft wird nach dem renderUI verarbeitet, bindUI syncUI und Methoden berufen worden sind, so das Widget wird erwartet, dass bereits innerhalb des Dokuments Körper eingeführt werden, da sonst das" Dokument "Kennung wird scheitern." Im Allgemeinen wird ein Widget gerendert bedeutet nicht zwangsläufig, dass es in der DOM ist, habe ich oft machen Sie ein Widget zu einem Knoten enthalten, die noch nicht eingesetzt worden ist, der gut arbeitet, so lange ich nicht versuchen zu erreichen, in das DOM .

    Also, ist das Thema in der Erklärung nur ein Problem zu wollen, wenn das "Dokument"-Kennung verwenden, oder wird es dazu führen, Verarbeitung im Allgemeinen zum Scheitern verurteilt? Ich frage mich, ob die Funktionalität _LOCATE_NODES sollte zuerst überprüft werden, fallen zurück auf DOM überprüft, wenn nötig?

    Vielen Dank für zwei große (wenn auch nicht lange) Artikel und der Galerie-Modul.

    B

    Kommentar von Brian J. Miller - 12. September 2011 #

  2. Brian

    Wenn Sie das "Dokument" Kennung in _events und verwenden Sie die Komponente nicht an das Dokument angehängt, wird es ignoriert. Darüber hinaus wird "Dokument" zu dem Dokument das Bauteil in entnehmen, ob der Hauptstraße einen oder der einen in einem Iframe.

    _locateNodes funktionieren wird, ob die Komponente auf dem Dokument angebracht ist oder nicht, weil es innerhalb der boundingBox sucht, sonst könnte es Elemente mit den gleichen Klassennamen in anderen Instanzen der Komponente zu pflücken.

    Kommentar von Satyam - 13. September 2011 #

  3. Vielen Dank Satyam. Große zeitsparende Verbesserungen Widget Schreiben.

    Ich habe durch ein wenig Mühe herauszufinden, die Modul-Abhängigkeiten zu gehen. Und die Version von August schien es nicht zu den _events Feuern haben. Aber das war einmal heraus und rechnete mit einer neueren Version Galerie, es funktioniert großartig.

    Ich habe zusammen ein einfacheres Beispiel setzen, nur um zu zeigen das grundlegendste Widget mit MakeNode mit bloßen Anforderungen Hexe könnte hilfreich sein:

    https://github.com/JohnICello/yui-samples

    Kommentar von John Iannicello - 16. September 2011 #

  4. Haben Sie sich überlegt Aufspaltung aus der fantastischen Vorlage Prozessor in eine separate Galerie-Modul?

    Kommentar von John Lindal - 22. September 2011 #

  5. John ,

    Es ist schon komisch, dass die Frage auftaucht, weil das ganze Projekt begann mit der Vorlage nur Ding. Deshalb heißt es MakeNode, nachdem, was es war seine einzige, dann öffentliche Methode, makeNode so als würde man fragen, wieder eine Stufe ist. Aber kann es sinnvoll sein, mal sehen die Zahlen:

    Die aktuelle Debug-Version ist 23.7K, mit der minimierte Version 4.68k, ein Fünftel (I platziert zu viele Kommentare für den API-Dokumentation). Bis 3.4.1 rauskommt, hat diese Version eine gepatchte Y.substitute enthalten. Sobald das aus ist, geht die minimierte bis 3.87k, in anderen Worten, die Patch 17%.

    Wenn ich alles nicht zu Templating verwandt, (und ich auch bedeuten, Fallenlassen _locateNodes) ausziehen geht es hinunter bis 2.13k. Das bedeutet, dass die Vorlage bereits nimmt 55% des Moduls. Ich frage mich, ob es sich lohnt Aufspaltung ist.

    Ich hätte gedacht, mich haben, dass die Template-Teil war vielleicht ein Drittel des Pakets so dass es Sinn gemacht hätte, um den Rest fallen. Macht es Sinn, dies zu tun mit diesen Zahlen?

    Fügen Sie _locateNodes, was ist so handlich, sobald Sie _makeNode verwendet, und der ganze Rest endet als nicht so sehr, nachdem alle.

    Kommentar von Satyam - 22. September 2011 #

  6. Ich scheine nicht in der Lage sein, damit dieses Modul ruhig.

    Ich fügte hinzu, zwei neue Funktionen:

    Wenn die Klasse mit MakeNode noch irgendeine von denen es erbt hat eine renderUI Methode, wird es automatisch für Sie erstellen, welche fügt das Ergebnis der Verarbeitung der _template dem Contentbox und dann eine _locateNodes tut.

    Ich habe auch die {n} Platzhalter, die eine Folge der Verarbeitung Codes und Argumente übernimmt und übernehmen den Wert des ersten ist ein Objekt, die es verwenden, um den zweiten Prozess wird hinzugefügt.

    So {np objRef @ attr} wird vom Haus aus zu lesen objRef , davon ausgehen, der Wert ist ein Objekt, und lesen Attribut attr von ihm. Es funktioniert nur mit den Codes, die Verarbeitung einfache Bezeichner als Argumente (nicht mit {f}) zu nehmen.

    Kommentar von Satyam - 29. September 2011 #

  7. Neuer Zusatz:

    Die _events Deskriptor hat eine neue Option auf seine Handler. Neben dem "Typ", "fn" und "Argumenten" Eigenschaften haben Sie nun 'wann'.

    Wenn nicht angegeben, wird standardmäßig "nach". Es kann auch sein, 'vor' und 'delegieren'. Er bestimmt, welche Methode es um das Ereignis zu befestigen, entweder Y.after (die Standardeinstellung), Y.on (für "vorher") oder Y.delegate (für "Delegierte") verwendet.

    Der Standardwert für die Benennung von Ereignis-Listener-Methoden Änderungen seit jetzt gibt es nicht nur ein '_nach' Präfix, kann nun mit Methoden '_before' oder '_delegate' beginnen.

    Kommentar von Satyam - 21. Oktober 2011 #

  8. Hallo zusammen,

    Treeble Datenquelle ist great.However es nicht in der Lage, JSON-Daten ohne eckige Klammern für z. B. zu analysieren:
    {"TreeNode":
    [{"Label": "ModelDate", "Modell1": null, "Model2": null},
    {"TreeNode": {"label": "Growth Rate", "Modell1": 14 ", Model2": 20},
    "Label": "Model Preis", "Modell1": "15", "Model2": "16"},
    {"TreeNode":
    {"TreeNode":
    {"TreeNode":
    [{"Label": "GRANT1", "Modell1": 1000, "Model2": 1000},
    {"Label": "grant2", "Modell1": 1000, "Model2": 800},
    {"Label": "grant3", "Modell1": 1000, "Model2": 900}],
    "Label": "eingekleidet", "Modell1": 3000, "Model2": 5700},
    "Label": "Optionen", "Modell1": 3000, "Model2": 5700},
    "Label": "Nettowert", "Modell1": 3500, "Model2": 5000}]} funktioniert nicht

    Allerdings, wenn ich manuell setzen eckigen Klammern scheint es funktioniert.

    Können Sie antworten. Es ist dringend notwendig

    Kommentar von Nanditha - 16. Januar 2012 #

Hinterlasse einen Kommentar

Hinweis: Kommentare sind für Erstbesucher moderiert. Spam gelöscht.

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Hosted by Yahoo!

Copyright © 2006-2012 Yahoo! Inc. Alle Rechte vorbehalten. Datenschutz - Allgemeine Geschäftsbedingungen

Präsentiert von WordPress auf Yahoo! Web Hosting .