2013-03-01 4 views
6

Ich versuche, eine generische Ansicht zu schreiben, die benutzerdefinierte Felder in meiner App behandelt, aber ich habe eine harte Zeit, damit dies funktioniert. Hier ist das Szenario - ich habe ein fieldDef-Objekt, das die benutzerdefinierten Felder definiert, und eine valueObject, die ein Array hat, customFields, die die Werte hat. Was ich versuche zu tun, so etwas wie diese:Ember TextField valueBinding mit dynamischer Eigenschaft

{{view Ember.TextField valueBinding="valueObject.customFields.[fieldDef.name]"}} 

, dass offensichtlich nicht funktionieren, weil es fieldDef.name als Literal behandelt. Ich habe versucht, die TextField-Klasse zu überschreiben, aber es scheint nicht zu binden.

Irgendwelche Vorschläge, wie dies zu erreichen ist?

Danke, Scott

Antwort

6

Ember kann in einen Array-Index nicht binden, so dass man es umgehen muß. Eine Lösung besteht darin, sich auf eine unidirektionale Bindung zu beschränken, bei der Ihr Textfeld den Werte-Hash aktualisiert. Wenn Sie vorhaben, das Formular zu senden, nachdem der Benutzer auf eine Schaltfläche geklickt hat, sollte dies den Zweck erfüllen.

eine Reihe von Feld-IDs in Ihrem Controller definieren und einen Hash für ihre Werte in zu gehen.

App.ApplicationController = Ember.Controller.extend({ 
    fieldIds: ['name', 'email', 'whatever'], 
    fieldValues: {} // {name: 'user', email: '[email protected]', ...} 
}); 

Jetzt Ember.TextField erweitern, um Ihre Hash-Werten zu aktualisieren, wenn ein Textfeld ändert. Sie müssen jeder Instanz eine fieldId und einen Verweis auf die values Hash von Ihrem Controller übergeben.

App.TextField = Ember.TextField.extend({ 
    fieldId: null, 
    values: null, 

    valueChange: function() { 
     var fieldId = this.get('fieldId'); 
     var values = this.get('values'); 
     if (values && fieldId) values[fieldId] = this.get('value'); 
    }.observes('value') 
}); 

Die Vorlage ist einfach.

{{#each fieldId in fieldIds}} 
    <label>{{fieldId}}</label> 
    {{view App.TextField fieldIdBinding="fieldId" valuesBinding="fieldValues"}} 
    <br/> 
{{/each}} 

Here it is fleshed out in a jsfiddle.

+1

Dank - habe ich einen Ansatz sehr ähnlich. –

+0

Muss ich App.TextField = Ember.TextField.extend ({}) im Controller deklarieren, wenn ich nur ein normales Textfeld mit einem ValueBinding haben möchte? –

1

@ahmacleod große antwort mann. Nur für den Fall, dass jemand interessiert es große Werke zu wählen erstreckt:

import Ember from 'ember'; 

export default Ember.Select.extend({ 
    fieldId: null, 
    values: null, 

    valueChange: function() { 
    var fieldId = this.get('fieldId'); 
    var values = this.get('values'); 
    if (values && fieldId) values[fieldId] = this.get('value'); 
    }.observes('value') 
}); 

Nennen Sie es als eine normale Komponente (Komponenten/dynamic-select.js)

{{#each id in fieldIds}} 
    {{dynamic-select content=fieldIds fieldIdBinding="header"  
    valuesBinding="fields"}} 
{{/each}} 
Verwandte Themen