2012-05-06 16 views
19

Un'etichetta Uso Ember.js ids campo di testo per un tag

<label for="id_of_text_field"> 
<input type="text" name="example" id="id_of_text_field" /> 

Dove il tag for dell'etichetta e la id tag del campo di testo devono corrispondere. Ho avuto due idee per fare questo lavoro nel mio modello Ember.js:

Idea # 1: Ho provato a fare uno speciale legame di nome field_id da utilizzare sia nel label e TextField. Ho eseguito in questo modo:

<label {{bindAttr for="content.field_id"}}> {{content.label}}</label> 
{{view Ember.TextField valueBinding="content.data" id="content.field_id"}} 

Purtroppo solo il label's id rende correttamente. L'ID TextField's non esegue il rendering non correttamente e risulta essere "metemorph ... something-or-other".

Idea # 2: di evocare in qualche modo id del TextField e l'uso che per il tag label, ma ho paura ad un certo punto id del TextField non sarà pronto quando il tag etichetta viene reso. Anche se questo non fosse un problema, non so come trovare l'ID TextField's da JS.

Questo è in un modello quindi avrò più di una di queste coppie label/TextField.

Come posso ottenere il tag for dell'etichetta per abbinarlo al tag id del TextField con Ember.js?

Grazie!

UPDATE

Utilizzando il consiglio di Peter Wagenet e leggera modifica, ho fatto la seguente:

<label {{bindAttr for="textField.elementId"}}> {{content.label}}</label> 
{{view Ember.TextField valueBinding="content.value" viewName="textField"}} 

Utilizzando questa tecnica gli utenti possono ora fare clic per selezionare le etichette TextFields, caselle di controllo, e di selezionare.

+1

Per l'ultima versione di Ember (1.4.0-beta.6) è necessario utilizzare 'for =" view.textField.elementId "". – jevon

risposta

21

Prima di tutto, il tag Metamorph è per il valore dell'etichetta. Non è correlato all'ID del campo. Tuttavia, questo codice non funzionerà ancora perché le proprietà standard non fanno nulla di speciale con i percorsi delle proprietà. In questo caso, il valore di id è letteralmente content.field_id. Questo non è certamente quello che volevi. In circostanze normali, è possibile utilizzare elementIdBinding (id è solo un alias per elementId), tuttavia non è possibile modificare gli ID degli elementi per le viste di ambra dopo la creazione, in modo che l'approccio non funzioni qui.

Una possibile soluzione utilizza la proprietà viewName. La proprietà viewName fornisce un riferimento con nome alla vista sullo parentView.Si potrebbe quindi, effettuare le seguenti operazioni:

<label {{bindAttr for="view.textField.field_id"}}> {{content.label}}</label> 
{{view Ember.TextField valueBinding="content.data" viewName="textField"}} 
+1

Penso che http://jsfiddle.net/GtsKK/2/ sia una dimostrazione completa di ciò che sta succedendo. Si desidera associare "for" a textField.elementId, non field_id, poiché la vista TextField non avrà quell'attributo. Inoltre, non puoi semplicemente utilizzare la classe TextField da sola poiché l'attributo name non associa nulla e, affinché sia ​​un modulo valido, devi fornire un nome per ciascun input, quindi ho creato una sottoclasse TextField e aggiunto il bind dell'attributo del nome mancante. –

+0

Siamo spiacenti per le modifiche ... quindi ho impostato il modello su: {{visualizza Ember.TextField valueBinding = "content.data "viewName =" textField "}} e il gioco è fatto. I tag ** for ** e ** id ** ora si stanno abbinando. Non è richiesto JS. Molto bella! Ho cambiato il tuo 'field_id' in 'elementId'. Sembra troppo facile. – shs

+0

Solo per curiosità, come faccio a ottenere "parentView" dall'interno del valore calcolato content.field_id? Da dentro field_id: function() {} Ho provato una varietà di get | getPath() con 'view', 'this.view', 'parentView', 'this.parentView', e sono tornati tutti nulli o indefiniti. – shs

1

Qui è stata la mia soluzione a questo problema da un po 'indietro:

App.Widget.TextField = Em.ContainerView.extend({ 
    tagName: '', 
    type: 'text', 
    label: null, 
    value: null, 
    valueSize: '30px', 

    childViews: ['labelView', 'inputView'], 

    labelView: Em.View.extend({ 
     tagName: 'label', 
     attributeBindings: ['for'], 

     forBinding: 'parentView.inputView.elementId', 

     init: function() { 
      this.set('defaultTemplate', Em.Handlebars.compile(this.getPath('parentView.label'))); 
      this._super(); 
     } 
    }), 

    inputView: Em.TextField.extend({ 
     typeBinding: 'parentView.type', 
     sizeBinding: 'parentView.valueSize', 
     valueBinding: 'parentView.value' 
    }) 
}); 

Poi all'interno di un modello di manubrio:

{{view App.Widget.TextField label="Some Label"}} 
5

Questo won risolvo sempre il tuo problema, ma volevo solo aggiungere che semplicemente l'annidamento dell'input all'interno dell'etichetta è spesso una soluzione conveniente, dal momento che ti consente di eliminare del tutto l'attributo for (reference).

+0

Interessante. Stavo progettando di disporre i controlli in una tabella con etichette in una colonna e controlli nell'altra. – shs

+0

Sai qual è il supporto del browser per questo? Con una versione di prova rapida sembra funzionare bene in Firefox e Chrome. Non ho IE a portata di mano ... –

+0

Non lo so. Tuttavia, sembra essere un modello comune, quindi presumo che sia ampiamente supportato. –

Problemi correlati