L'estensione Widget "MakeNode"

Luglio 8, 2011 at 14:11 da Satyam | In Development | 6 commenti

Nota del redattore: Dal momento che questo articolo è stato originariamente pubblicato, il modulo MakeNode è stato pubblicato alla Galleria YUI e ha ricevuto alcuni miglioramenti. Consultare l'articolo aggiornato, Aggiornamento: l'estensione "MakeNode" Widget .

Nel mio articolo precedente, una ricetta per una applicazione 3 YUI , ho mostrato un modo per utilizzare Y.substitute come un processore modello molto di base. L'idea ha preso vita da lì, con i suggerimenti delle persone nel canale IRC # yui, e ho fatto una estensione Widget che è disponibile sul mio sito, chiamato MakeNode . MakeNode non è un processore modello generico e non è intesa come uno. D'altra parte, è strettamente integrato con il YUI Widget classe base, compresi aiutanti className e l'evento e l'internazionalizzazione. In questo articolo, voglio prendere il Spinner esempio e modificarlo in modo da seguire le linee guida del mio precedente articolo e di utilizzare MakeNode. Il componente Spinner modificato ( JS , CSS , sprite ), nonché un esempio sono disponibili dal mio sito. Collegamenti a ulteriori risorse possono essere trovate alla fine di questo articolo.

Estendere il componente

Una volta MakeNode è caricato, è necessario includere il modulo nel vostro YUI().use() istruzione usando il nome 'makenode' . Quindi, per estendere la widget, si iscrive nel terzo argomento Y.Base.create() , in questo modo:

  Y.Spinner Y.Base.create = (
      'Spinner',
      Y.Widget,
      [Y.MakeNode],
      {
         / / Istanza membri ...
      },
      {
          / / Membri statici
      }
 ); 

È possibile aggiungere MakeNode lungo qualsiasi numero di estensioni adatte per Widget, come WidgetParent, WidgetChild, WidgetStdMode, ecc MakeNode aggiunge due metodi protette, _makeNode e _locateNodes, e sarà letto da diverse proprietà statiche, se trovato.

Tutti i membri di questa estensione sono sia protetto o privato dal momento che sono destinati ad essere utilizzati dallo sviluppatore componente e non il realizzatore l'utilizzo di tali componenti, che non deve essere disturbato con la loro.

Definizione del modello

La prima cosa che normalmente è quello di definire il modello per il componente. Per il Spinner, il nostro modello sarà:

  _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'), 

Il modello di default di solito è chiamato _TEMPLATE e dichiarato lungo le altre proprietà statiche della classe, ad esempio ATTRS . MakeNode utilizzerà questo modello se non altro è esplicitamente previsto. Il modello è realizzato in semplice HTML più una serie di segnaposto racchiusi tra parentesi graffe, ciascuno costituito da un singolo carattere (il codice di elaborazione) e seguita da uno o più argomenti. I segnaposto e ciò che producono sono i seguenti:

  • {@ attributeName} configurazione valore dell'attributo

  • {p propertyName} valore della proprietà di istanza

  • {m methodName arg1 arg2 ….} valore restituito dal metodo indicato. Il codice di elaborazione è seguita dal nome del metodo e qualsiasi numero di argomenti separati da spazi bianchi. Le stringhe devono essere racchiuse tra virgolette doppie. Numeri, booleani e null verranno convertiti da stringa a loro tipi di dati corretti

  • {c classNameKey} CSS className generato dal _CLASS_NAMES proprietà statica

  • {s key} stringa da strings di attributi, utilizzando key come il sub-attributo.

  • {? other placeholder } Produce la stringa checked quando il risultato della elaborazione del resto del segnaposto è vero.

  • {} qualsiasi altro valore verranno trattati esattamente come Y.substitute fa.

Ad esempio, {@ value} si tradurrà in this.get('value') , mentre {p value} si traduce in this['value'] .

Il {m} segnaposto è un po 'più complessa. Il primo argomento dopo la m codice di elaborazione è il nome del metodo e il resto degli argomenti, tutti separati da spazi, che saranno passati al metodo indicato. Questi argomenti possono essere numeri, null , true , false o stringhe racchiuse tra virgolette. MakeNode li analizza e li converte in loro tipo corretto, quindi {m myMethod 123.45 true “this is a string”} comporterà chiamando this.myMethod(123.45, true, “this is a string”) in modo che i primi due argomenti vengono convertiti i loro tipi di dati corretti e la stringa può contenere spazi. Per includere delle virgolette, utilizzare \\" , la barra rovesciata due volte il perché JavaScript interpreterà una sola e se ne disfa prima di arrivare a MakeNode. solo le doppie virgolette sono consentiti, MakeNode non usa eval() in modo che il parser si limita ma tutto sicuro. ma i numeri, null , booleani e stringhe tra doppi apici verrà ignorato.

Il {?} segnaposto è comodo da usare con caselle di controllo e pulsanti di opzione. Si produrrà la stringa “checked” a seconda del valore di verità del codice istruzione di elaborazione che segue. Così, <input type=”checkbox” {? m getLength}/> <input type=”checkbox” {? m getLength}/> produrrà una casella di controllo marcata se il getLength metodo restituisce niente, ma zero. {?} accetterà qualsiasi dei segnaposto altri, anche se ha senso solo con i primi tre.

Per la {c} segnaposto, abbiamo bisogno di avere un _CLASS_NAMES proprietà definita.

Ulteriori segnaposto può essere aggiunto a MakeNode aggiungendoli in _templateHandlers hash.

La proprietà _CLASS_NAMES

Insieme al ATTRS e _TEMPLATE attributi statici, si può definire un _CLASS_NAMES proprietà che punta ad un array di stringhe. Ciascuno di tali stringhe verrà utilizzato per generare un className. Così _CLASS_NAMES: ['input'] produrrà il className “yui3-spinner-input” . Queste NOMECLASSE vengono memorizzati in proprietà un esempio this._classNames . L' {c input} segnaposto nel modello di cui sopra saranno sostituiti da “yui3-spinner-input” .

È possibile utilizzare la _CLASS_NAMES proprietà di generare un numero illimitato di nomi di classi, se si utilizzano nel modello o meno. È ancora possibile raggiungere tali NOMECLASSE extra dall'interno this._classNames . Il className viene generato utilizzando il yui3 prefisso seguito dal valore del NAME proprietà statica trasformato in minuscolo, e poi la stringa indicata in _CLASS_NAMES (quest'ultimo non sarà trasformato in minuscolo), tutti separati da trattini. Il _classNames hash conterrà anche le NOMECLASSE per la boundingBox e la contentBox , il primo sotto il "." chiave e il secondo sotto il “content” il tasto. Widget assegna alla boundingBox i NOMECLASSE derivanti dai valori della NAME proprietà di ciascuna delle classi nella catena di ereditarietà, a partire yui3-widget . Negozi MakeNode in this._classNames solo il più in alto className per il boundingBox .

Se un componente è a diversi livelli di distanza da Widget, come SuperSpecialSpinner ereditando da SuperSpinner che eredita da Spinner che eredita da Widget, e se qualcuno o tutti loro hanno _CLASS_NAMES proprietà definite, MakeNode produrrà NOMECLASSE per tutti loro e memorizzarli in this._classNames . Non è necessario inserire ad ogni livello i nomi già dichiarato nei livelli precedenti. In realtà, è meglio che non in quanto le NOMECLASSE prodotte ad ogni livello verrà utilizzato il valore della NAME proprietà di quel livello. Così, in SuperSpecialSpinner , {c input} ancora causare “yui3-spinner-input” e non “yui3-superspecialspinner-input” e quindi manterrà il vostro file CSS ancora valido.

Il segnaposto {s}

Widget ha una strings di configurazione attributo definito, anche se non viene inizializzato con qualsiasi valore. Questo attributo è destinato a contenere le stringhe che sono visibili (o, tramite lettori di schermo, leggere) l'utente. E 'importante che non si comprendono le stringhe visibili direttamente nel modello. Questo non è un requisito di MakeNode - non è mai stata una buona idea a tutti. Tutte le stringhe che devono essere visualizzati da o leggere l'utente deve sempre essere messi in strings attributo. La strings attributo contiene un hash dove si trova ogni singolo testo per la sua chiave. Il componente Spinner ha le seguenti stringhe, che potete vedere utilizzati nel modello di cui sopra.

  stringhe: {
     valore: {
         Ingresso: "Premere la freccia su / giù per incrementi minori, pagina su / giù per incrementi maggiori."
         up: "Increment",
         verso il basso: "Decremento"
     }
 }, 

La parte migliore di questa operazione è che il componente può essere localizzato in altre lingue molto facilmente dagli sviluppatori che utilizzano il componente. Quando si crea un'istanza di Spinner, si potrebbe fare:

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

Impostando l'attributo di configurazione strings in questo modo, sostituisce i default strings valori con quelli del file di risorsa di lingua utilizzando il linguaggio precedentemente definito. Il {s} segnaposto accede alle stringhe memorizzate in strings attributo, sia quelli di default o quelli tradotti, se impostato. Il {s xxxx} segnaposto è, in realtà, nient'altro che un collegamento al {@ strings.xxxx} segnaposto. Tuttavia, il primo può accedere solo le stringhe al livello superiore mentre, ad esempio, {@ strings.xxxx.yyyy.zzzz} permetterebbe di accedere a una stringa più in profondità.

Utilizzando _makeNode in renderUI

Usiamo il modello per creare il markup per la nostra componente. Per fare ciò, possiamo chiamare MakeNode di _makeNode metodo, in questo modo:

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

Questo compilare il contentBox del nostro widget con il markup dalla trasformazione del modello. Il _makeNode metodo restituisce un'istanza di Y.Node che può essere aggiunto o inserito ovunque o semplicemente tenuto per un uso successivo. Non restituisce una stringa, produce un Node esempio.

Il _makeNode metodo accetta due argomenti opzionali: un riferimento a un modello e un oggetto da compilare segnaposto, come Y.substitute fa. Nel nostro esempio Spinner semplice c'è un modello unico per il widget di tutto, ma altri widget che potrebbero richiedere i pezzi realizzati in diversi modelli. In questo caso, si chiama di solito _makeNode senza argomenti per la parte principale e lo chiamano ancora una volta con diversi modelli per compilare le parti extra. L' esempio contiene questa renderUI metodo:

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

La prima chiamata a _makeNode restituisce un Node esempio memorizzato nella variabile fieldset . Il componente di esempio può essere prolungata anche Y.ArrayList in modo che il RADIO_TEMPLATE sarà riempito con i valori presi dalle voci memorizzate nella lista di array ei nodi risultanti allegata alla fieldset prima della sua definitiva allegato al contentBox . I segnaposto speciali come {@} o {p} continuerà a fare riferimento agli attributi o proprietà dell'oggetto principale. Gli elementi nidificati saranno trattati proprio come Y.substitute farebbe.

Il metodo _locateNodes

MakeNode prevede inoltre un _locateNodes metodo che cercherà di individuare tutti gli elementi con i NOMECLASSE dichiarati in _CLASS_NAMES . Per individuare gli elementi specifici che si possono passare un numero qualsiasi di chiavi className, altrimenti, _locateNodes tenta tutte. Per ogni elemento trovato di ogni className, _locateNodes produrrà una proprietà privata istanza utilizzando l'underscore prefisso seguito dal nome della chiave e il “Node” suffisso. Così, nel nostro esempio Spinner, _locateNodes genererà la proprietà _inputNode , _upNode e _downNode . Se diversi elementi hanno la stessa className, _locateNodes restituirà un riferimento al primo di essi. Se un elemento non viene trovato, non variabile verrà creato.

Nel componente Spinner usiamo _locateNodes dopo la creazione del markup:

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

La proprietà _EVENTI statica

Una proprietà ulteriore può essere definita lungo le linee di _TEMPLATE e _CLASS_NAMES e che è _EVENTS . _EVENTS conterrà un hash costituito da tasti nome della classe, ciascuno contenente un hash di tipi di eventi e metodi per gestirli. È meglio spiegato con un esempio:

  _EVENTI: {
     '.': {
         chiave: {
             fn: '_onDirectionKey',
             args: ((Y.UA.opera) "down":? "stampa:") + "38, 40, 33, 34"
         },
         mousedown: '_onMouseDown'
     },
     '..': {
         mouseup: '_onDocMouseUp'
     },
     Ingresso: {
         cambiamento: '_onInputChange'
     }
 }, 

_EVENTS è un oggetto (un hash) con qualsiasi numero di proprietà. I nomi delle proprietà, vale a dire, le chiavi di hash, identificare gli elementi di cui eventi che si ascolta. Sono gli stessi identificativi usati in _CLASS_NAMES . Ci sono due tasti supplementari speciali "." e ".." . Mentre i tasti className si riferiscono agli elementi nidificati nel contentBox , il "." chiave si riferisce al boundingBox stesso mentre ".." si riferisce al documento che contiene questo widget. Pensate a loro come fare una chdir comando quando si trova a boundingBox livello. Il _EVENTS proprietà viene elaborato dopo le renderUI , bindUI e syncUI metodi sono stati chiamati così il widget dovrebbe essere già inserito all'interno del corpo del documento, altrimenti il ".." avrà esito negativo.

Ciascuna delle voci in _EVENTS è un ulteriore scopo che utilizza il tipo di evento come chiave e il nome di un metodo di istanza gestirlo. _EVENTS , essendo una variabile statica, non ha accesso a this in modo che non può prendere riferimenti effettiva funzione, solo il nome del metodo listener evento. Alcuni tipi di eventi devono argomenti extra, come la key evento. In questo caso, invece di fornire il nome del gestore di eventi è possibile fornire un oggetto con le proprietà fn e args per contenere il nome della funzione e gli argomenti supplementari, quando richiesto.

MakeNode userà Node.delegate per ascoltare gli eventi degli elementi nidificati, mentre si userà Y.on per ascoltare gli eventi dal boundingBox e il corpo del documento. (Nota: ascoltare la key evento su qualsiasi elemento nidificato funziona solo con 3.4.0pr1 versione e soprattutto, in quanto delegazione della key .. evento non era disponibile prima di tutte le altre caratteristiche funzionano con le versioni precedenti, pure)

I _EVENTS dichiarazioni sono cumulabili quando i componenti ereditano gli uni dagli altri. Ogni classe nella catena di ereditarietà avrà un proprio _EVENTS dichiarazione elaborata separatamente.

La proprietà _ATTRS_2_UI statica

Eventi in entrambe le direzioni, dall'interfaccia utente al componente e dal componente per l'interfaccia utente. I primi sono gestiti dal _EVENTS proprietà. Poi ci sono gli eventi generati da variazioni del valore di attributi che devono essere riflessi nell'interfaccia utente. Come ho già detto nel precedente articolo, quando ci sono degli effetti secondari di modificare un attributo di configurazione, che dovrebbe essere gestita dal listener di eventi di cambiamento, non dal opzionale setter metodo dell'attributo, che dovrebbe trattare solo con la normalizzazione del valore che viene impostato. L'interfaccia utente dovrebbe riflettere lo stato degli attributi di configurazione, prima in syncUI , quando viene inizializzato e poi su ogni evento change attributo. Per questi ultimi, abbiamo bisogno di collegare un listener di eventi, che facciamo in bindUI . Widget fornisce già un meccanismo per fare quella semplice, che ho descritto nel commento al precedente articolo.

Widget utilizza l'istanza di proprietà _UI_ATTRS che contiene un oggetto con due ulteriori proprietà, SYNC e BIND . Ciascuno di questi è un array elenco dei nomi degli attributi di configurazione di essere inizialmente sincronizzati e poi ascoltato per mantenere l'interfaccia utente riflettente valori correnti. Widget attende che ciascuna di queste voci per avere un metodo associato ad esso, prende il nome dell'attributo prefisso _uiSet con il primo carattere del nome dell'attributo convertito in caratteri maiuscoli per avere il nome del metodo, in caso camel corretta. Quindi, se "value" è stata quotata in una qualsiasi delle _UI_ATTRS array (in entrambi i SYNC o BIND ), Widget si aspetterebbe di trovare un _uiSetValue metodo. Questo metodo riceve due argomenti, il value viene impostato e la src del cambiamento. Questo è il codice per la nostra Spinner _uiSetValue metodo:

  _uiSetValue: function (value, src) {
     if (src === UI) {
         ritorno;
     }
     this._inputNode.set (VALUE, this.get (formattatore) (valore));
 }, 

Tutti gli identificatori maiuscole che vedete in questo pezzo di codice corrispondono a costanti stringa dichiarata altrove, per consentire al compressore YUI per fare il suo lavoro migliore. Il metodo, in fondo, imposta il value attributo HTML nella <input> casella per il set di nuovo valore, dopo essere stato formattato. Il riferimento alla casella di testo è stato fornito da _locateNodes . La src argomento viene inizialmente controllato per vedere se impostato il valore di stringa 'ui' . Se è così, nessuna azione sarà presa. Questo per evitare cicli infiniti. Se l'utente inserisce qualcosa nella casella di input, il suo valore sarebbe andato nel value attributo di configurazione che poi avrebbe sparato un valueChange evento, che otterrebbe _uiSetValue chiamata che, se incontrollata, potrebbe poi andare a modificare il valore della casella di input, che farebbe scattare l'intero processo di nuovo. Così, in _uiSetValue , se conosciamo il cambiamento deriva dalla UI, non facciamo nulla e così interrompere il loop. Tuttavia, ciò richiede un altro pezzo di codice altrove. Nel listener per l'evento DOM, quando abbiamo impostato l'attributo di configurazione, si usa il terzo argomento opzionale per impostare, in questo modo:

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

Spetta a noi far sì che i cambiamenti provenienti dal UI sono contrassegnati così e quindi controllare che stessa bandiera per evitare loop.

Con tutto questo detto, non ho ancora menzionato la proprietà statica _ATTRS_2_UI menzionato nel titolo di questa sezione. Come i commenti nei miei spettacoli precedente articolo (attraverso gli errori che ho fatto in loro), facendo in modo che tutti gli attributi che riguardano l'interfaccia utente sono correttamente elencati è un po 'disordinato. Non si dovrebbe mai inizializzare _UI_ATTRS da zero dal momento che già Widget elenca tutta una serie di attributi e di quelli andrebbero perduti. Devi concatenare i nomi degli attributi nuovi su quelli già esistenti, che è un po 'difficile ricordare come farlo nel modo giusto. Per farla semplice, MakeNode leggerà dalla proprietà statica _ATTRS_2_UI e fare che la concatenazione per voi. Si concatenare tutte le liste di questo tipo dalla classe ogni nella catena di ereditarietà così a ogni livello ogni classe in grado di gestire i propri attributi. In Spinner, abbiamo:

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

MakeNode accetterà sia un array di nomi o un nome singolo attributo, come in questo caso.

La domanda sorge spontanea, perché due liste, una per legare l'altra per la sincronizzazione? Molto spesso il SYNC matrice ha meno voci BIND lista e questo perché il modello per il componente può già avere il valore molto stesso attributo di configurazione e non c'è bisogno di fare una sincronizzazione iniziale. Quindi, se il valore predefinito per il value attributo di configurazione è una stringa vuota e la <input> elemento nel modello non ha alcun value attributo, allora non c'è bisogno di sincronizzare il loro inizializzazione.

MakeNode verificherà le voci duplicate in una qualsiasi di queste matrici. Se qualcuno appare, significa che un nostro componente eredita dalla classe gestisce già questo attributo e ogni nuova dichiarazione avrebbe oltrepassato molto probabilmente il _uiSetXxxx gestore per esso. Per inciso, MakeNode verifica anche per le voci duplicate in _CLASS_NAMES , che possono anche causare conflitti in alcuni, anche se non tutte, le circostanze. MakeNode scriverà un messaggio nel registro per tali errori.

Conclusione

MakeNode offre un processore modello molto semplice, con funzionalità di semplice che è fortemente integrata con la classe base Widget. Esso fornisce anche metodi di supporto per creare NOMECLASSE da utilizzare nel modello e utilizzare tali nomi per individuare i nodi creati. Inoltre fornisce i mezzi per agganciare sugli eventi generati sia dalla UI e il componente stesso e associare ognuna con un metodo. Lo fa tutte queste cose, avendo cura di rispettare la catena di ereditarietà dritto fino a Widget e qualsiasi livello di classi che si possono definire.

Esso non prevede assolutamente tutte le possibilità, ma copre una vasta gamma di loro. Tuttavia, non vi preclude la possibilità di aggiungere funzionalità extra. Raramente si potrebbe avere a dare una bindUI o syncUI metodo se si utilizza la colla fornita da MakeNode, ma è possibile farlo, dal momento che MakeNode non li utilizza.

Come un bonus a chi ha avuto la pazienza di leggere insieme Button fino a questo punto, ho anche modificato Anthony Pipkin di componenti galleria:

La documentazione API può essere trovato qui .

Condividi ed estendere: Segnalibro con Del.icio.us | Digg it! | reddit!

6 commenti »

RSS feed dei commenti a questo post. TrackBack URI

  1. Questo è compatibile con la componente di visualizzazione di Ryan del nuovo MVC che si sviluppano nel 3.4.x? Potrebbe essere utilizzato per eseguire il rendering del markup in un modo compatibile con questo quadro?

    Commento di Andrew Wooldridge - 9 Luglio 2011 #

  2. Andrew ,

    Questa estensione è inteso come un aiuto per costruire i componenti, come il pulsante e gli esempi mostrano Spinner, di non costruire intere applicazioni, come il framework MVC fa. Questi componenti possono essere utilizzati ovunque qualsiasi altro componente derivata da Widget può. Nel framework MVC, sarebbe naturale di utilizzare tali componenti in classi che ereditano da Y.View per costruire l'interfaccia utente, lungo semplice HTML o qualsiasi altro componente derivata da Widget, se utilizza MakeNode o no.

    Commento di Satyam - 10 Luglio 2011 #

  3. Satyam,

    Questo è abbastanza grande! Ho sperimentato tutti i punti di dolore che si stanno affrontando con questa estensione Widget. Sembra che l'uso di questa estensione è possibile rimuovere un sacco di ripetitivo caldaia piastra di codice si finisce per scrivere durante la creazione di widget personalizzati, mentre la standardizzazione su come collegare il codice e la logica con il DOM e il rendering, che è emozionante vedere!

    Vuoi essere l'aggiunta di questa alla Galleria 3 YUI, rendendola più accessibile per le persone. Utilizzare ()?

    Come ha sottolineato Andrew, esistono alcune sovrapposizioni concettuali con Y.View per eventi e di rendering, anche se i due API sono diversi. Potrebbe valere la pena cercare di capire se esiste un terreno comune per le API due per essere più simili (in particolare con la roba DOM eventi).

    Dal punto di vista generale API che hai fatto tutto protetto / privato attraverso la '_' (underscore) prefix, io sono curioso di sentire i vostri pensieri su questo. Penso che le proprietà statiche come: `_CLASS_NAMES` e `_EVENTI`, ecc potrebbe anche essere solo: `CLASS_NAMES`, e `EVENTI` sans il carattere di sottolineatura-prefix. Essa può essere solo la mia preferenza, ma ci si sente eccessivamente protettivo :)

    Commento di Eric Ferraiuolo - 12 lug 2011 #

  4. Eric ,

    Grazie per il tuo commento. In effetti, questo nasce dalla ripetizione noiosa. Mi piace anche l'ordine del componente risultante è trattata come gran parte di essa in modi dichiarativi e il personale è ridotto e procedurale standardizzato, specialmente tutti i metodi _uiSetXxxx.

    Non voglio a che fare con GitHub e la Galleria YUI quindi non mi posta lì. Non mi importa se qualcuno lo fa, ma io non ho intenzione di farlo o mantenerla.

    La cosa DOM eventi è uscita Y.View, solo che io uso i tasti NOMECLASSE per identificare gli elementi, dal momento che tutta l'estensione fa, beh, un uso estensivo di loro. Si occupa anche di collegare gli eventi in tutta la gerarchia delle classi quindi non c'è bisogno di ripetere quelle Quando si eredita da altre classi.

    Per quanto riguarda i membri protetti / privato, ho sollevato questo con Jenny che ha chiesto la squadra e ho cambiato tutti gli ex membri pubblici a quelle protette sulla base di tale consiglio.

    Fondamentalmente ci sono due ruoli di sviluppo, il creatore dei componenti e l'utente del componente o 'implementor' come Jenny riferimento ad essi. E 'meglio se i membri della classe destinati allo sviluppatore di componenti non ingombrare la documentazione API per lo sviluppatore. In questo senso, molti membri di Widget come CONTENT_TEMPLATE, renderUI, HTML_PARSER o Base.ATTRS non dovrebbe mai essere pubblica come lo sviluppatore non dovrebbe nemmeno sapere su di loro.

    D'altra parte, i membri come _uiSetTabIndex o _uiSetDisabled sono molto adeguatamente protetto dichiarate. Così, nel componente in modalità sviluppatore, si dovrebbe sempre avere Mostra Protected il, mentre come un implementor non si dovrebbe. Ciò eviterebbe gli sviluppatori di componenti di re-implementare funzionalità che è già lì, come il componente Button originale nella Galleria che aveva il codice rifare ciò che questi due metodi già fare.

    Credo che da quando Jenny dovuto portarlo fino alla squadra non ci sono indicazioni in questo senso e quindi dovremo convivere con qualche incoerenza nei componenti esistenti.

    Commento di Satyam - 12 luglio 2011 #

  5. Un aggiornamento:

    Ho aggiunto un codice di elaborazione di più: "1". E 'utile nel trattare con singolare / plurale testo, per esempio: p {{1} qty p {} qty "unità" "unità"}. Questa stringa produrrà sia "1 unità" o "123 unità" a seconda del valore della qty proprietà.

    Come illustrato nell'esempio precedente, segnaposto può ora essere nidificati uno nell'altro. Così, un argomento per un segnaposto può essere il valore restituito da un altro segnaposto.

    Ho cambiato anche il segnaposto di agire più come il {?}:? Operatore. Invece di produrre un testo fisso, permette di restituire qualcosa di suoi argomenti dire, per esempio: {? {P} {p qty qty} "none"}.

    Per fare un esempio estremo, questo modello:

    {? P {} qty "{p qty} {1} {p qty" unità "" unità "}" "none"}

    produrrà la "none" testo ", 1 unità", "2 unità", "3 unità" e così via per i valori successivi della qty proprietà.

    Il metodo di elaborazione del modello è ora disponibile come _substitute metodo.

    Commento di Satyam - 13 Agosto 2011 #

  6. Ulteriori modifiche:

    Ora, la proprietà _EVENTI statica, gli ascoltatori hash che definiscono per ogni evento, prende un paio di extra selettori virtuali. La struttura di _EVENTI è:


    _EVENTS: {
    selector: {
    eventType: listener,
    ....
    }
    }

    dove i selettori sono le chiavi usate nella proprietà _CLASS_NAMES per creare le NOMECLASSE utilizzati nei modelli per gli elementi HTML, che aiutano a individuarli.

    C'erano due selettori speciali: '.' indica il boundingBox e '..' il documento il widget è dentro

    Ora ho aggiunto due altri selettori virtuali, questo, tutte maiuscole, si riferisce al widget stesso e Y all'istanza Y, ad esempio:


    _EVENTS: {
    THIS: {
    visibleChange: '_afterVisibleChange'
    },
    Y: {
    'broadcastingWidget:somethingChange':'_afterSomethingChange'
    }
    }

    Il tasto Y, se si vuole rappresentare l'istanza Y, sarà preso da JavaScript come la stringa "Y". Usare sempre Y come chiave virtuale, anche se è stato chiamato un qualcosa di YUI altro esempio, ricordo, è solo la stringa "Y", non l'istanza di Y reale.

    MakeNode sarà impostato solo dopo listener di eventi, mai prima (on) ascoltatori, che è il caso più frequente. Se avete bisogno di ascoltare un 'prima' evento, configurarlo come al solito.

    Commento di Satyam - 19 Agosto 2011 #

Lascia un commento

Nota: I commenti sono moderati per la prima volta. Spam eliminato.

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

Ospitato da Yahoo!

Copyright © 2006-2012 Yahoo! Inc. Tutti i diritti riservati. Privacy Policy - Termini di servizio

Powered by WordPress su Yahoo! Web Hosting .