2012-05-06 11 views
19

etykieta ma postać:Korzystanie ember.js identyfikatory pole tekstowe dla <label> tag tag

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

Jeżeli for tag etykiety i id tag w polu tekstowym muszą się zgadzać. Miałem dwa pomysły do ​​tej pracy w moim szablonu ember.js:

Idea # 1: Próbowałem zrobić specjalny wiązaniami nazwie field_id używać zarówno w label i TextField. Wykonałem to w następujący sposób:

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

Niestety tylko identyfikator label's jest renderowany poprawnie. Identyfikator TextField's nie jest poprawnie renderowany i okazuje się być "metemorficzny ... coś" lub "inny".

Idea # 2: jakoś wyczarować identyfikator pola tekstowego i użyć jej dla tagu etykiety, ale obawiam się, że w pewnym momencie id pola tekstowego nie będą gotowe, gdy tag etykieta jest renderowana. Nawet jeśli to nie był problem, nie wiem, jak znaleźć identyfikator z JS TextField's.

Jest to szablon, więc będę mieć więcej niż jedną z tych par etykiety/TextField.

W jaki sposób mogę uzyskać znacznik for etykiety, aby dopasować go do tagu TextField o wartości id za pomocą Ember.js?

Dziękujemy!

UPDATE

Korzystanie porady Petera Wagenet i lekkiej modyfikacji, zrobiłem co następuje:

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

Stosując to, że użytkownicy mogą teraz technika kliknij etykiety pól tekstowych, aby zaznaczyć pola wyboru i wybiera.

+1

Do najnowszej wersji Ember (1.4.0-beta.6) należy użyć 'for =" view.textField.elementId "'. – jevon

Odpowiedz

21

Po pierwsze, znacznik Metamorph służy do określenia wartości etykiety. Nie ma związku z identyfikatorem pola. Jednak ten kod nadal nie będzie działał, ponieważ właściwości standardowe nie powodują nic specjalnego ze ścieżkami właściwości. W tym przypadku wartość id, jest dosłownie content.field_id. To na pewno nie jest to, czego chciałeś. W normalnych okolicznościach można użyć elementIdBinding (id to tylko alias dla elementId), jednak element id dla widoku Ember nie może być zmieniony po utworzeniu, więc podejście nie będzie tutaj działało.

Jedno z możliwych rozwiązań wykorzystuje właściwość viewName. Właściwość viewName zapewnia nazwane odwołanie do widoku na parentView.Można wtedy wykonać następujące czynności:

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

Myślę, że http://jsfiddle.net/GtsKK/2/ to pełna demonstracja tego, co robi shs. Chcesz powiązać "dla" z textField.elementId, a nie field_id, ponieważ widok TextField nie będzie miał tego atrybutu. Ponadto, nie możesz po prostu użyć samej klasy TextField, ponieważ jej atrybut name nie wiąże niczego, a aby była to poprawna forma, musisz podać nazwę dla każdego ze swoich danych wejściowych, więc podklasowałem TextField i dodano brakujące powiązanie z atrybutem nazwy. –

+0

Przepraszamy za zmiany ... więc ustawiłem szablon na: {{view Ember.TextField valueBinding = "content.data "viewName =" textField "}} i to wszystko. Tagi ** ** i ** id ** są teraz zgodne. Nie wymaga JS. Bardzo dobrze! Zmieniłem twój "field_id" na "elementId". Wydaje się zbyt łatwe. – shs

+0

Po prostu z ciekawości, w jaki sposób uzyskałabym "parentView" z wewnątrz obliczonej wartości content.field_id? From inside field_id: function() {} Próbowałem różnych get | getPath() z 'view', 'this.view', 'parentView', 'this.parentView', i wszystkie one wróciły null lub undefined. – shs

1

Tu było moje rozwiązanie tego problemu od jakiś czas temu:

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' 
    }) 
}); 

Następnie od wewnątrz szablonu kierownicy:

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

to won Zawsze rozwiązuje twój problem, ale chciałem tylko dodać, że proste zagnieżdżanie danych wejściowych wewnątrz etykiety jest często wygodnym rozwiązaniem, ponieważ pozwala całkowicie zrzucić atrybut for (reference).

+0

Interesujące. Planowałem układanie kontroli w tabeli z etykietami w jednej kolumnie i kontrolami w drugiej. – shs

+0

Czy wiesz, co obsługuje przeglądarka? Dzięki szybkiej próbie wygląda na to, że działa dobrze w przeglądarkach Firefox i Chrome. Nie mam IE pod ręką ... –

+0

Nie wiem. Wydaje się, że jest to powszechny wzorzec, więc zakładam, że jest szeroko obsługiwany. –