2011-12-16 15 views
7

Provo a collegare il valore dall'ingresso select all'attributo "selectedValue" nel controller.Come associare l'input del modulo valore selezionare all'attributo nel controller

Questo è app.js

Food = Ember.Application.create(); 

Food.appsController = Ember.Object.create({ 
    selectedValue: "" 
}); 

Food.Todo = Ember.Object.extend({ 
    title: null, 
    value: null 
}); 

Food.FoodController = Ember.ArrayProxy.create({ 
    content: [] 
}); 

Food.FoodController.pushObject(Food.Todo.create({title:"a", value:"1"})); 
Food.FoodController.pushObject(Food.Todo.create({title:"b", value:"2"})); 
Food.FoodController.pushObject(Food.Todo.create({title:"c", value:"3"})); 

Questo è index.html sguardo

{{#collection 
    contentBinding="Todos.todosController" 
    tagName="select" 
    itemClassBinding="content.isDone"}} 
    {{content.title}} 
{{/collection}} 

output come questo

<select id="ember180" class="ember-view"> 
    <option id="ember192" class="ember-view"> 
    <script id="metamorph-0-start" type="text/x-placeholder"></script> 
    a 
    <script id="metamorph-0-end" type="text/x-placeholder"></script> 
    </option> 
    <option id="ember196" class="ember-view"> 
    <script id="metamorph-1-start" type="text/x-placeholder"></script> 
    b 
    <script id="metamorph-1-end" type="text/x-placeholder"></script> 
    </option> 
    <option id="ember200" class="ember-view"> 
    <script id="metamorph-2-start" type="text/x-placeholder"></script> 
    c 
    <script id="metamorph-2-end" type="text/x-placeholder"></script> 
    </option> 
</select> 

non ho idea di come aggiungere valore alle opzioni e come legare il valore selezionato al controller. È possibile farlo in Emberjs?

risposta

7

Ember dispone ora di una vista di selezione interna.

Puoi trovarlo nell'ultima versione di Ember.js costruire qui: http://cloud.github.com/downloads/emberjs/ember.js/ember-latest.js

Ecco un esempio di utilizzo:

var App = Ember.Application.create(); 

App.Person = Ember.Object.extend({ 
    id: null, 
    firstName: null, 
    lastName: null, 

    fullName: function() { 
     return this.get('firstName') + " " + this.get('lastName'); 
    }.property('firstName', 'lastName').cacheable() 
}); 

App.selectedPersonController = Ember.Object.create({ 
    person: null 
}); 

App.peopleController = Ember.ArrayController.create({ 
    content: [ 
     App.Person.create({id: 1, firstName: 'Yehuda', lastName: 'Katz'}), 
     App.Person.create({id: 2, firstName: 'Tom', lastName: 'Dale'}), 
     App.Person.create({id: 3, firstName: 'Peter', lastName: 'Wagenet'}), 
     App.Person.create({id: 4, firstName: 'Erik', lastName: 'Bryn'}) 
    ] 
}); 

Il modello sarà simile:

{{view Ember.Select 
     contentBinding="App.peopleController" 
     selectionBinding="App.selectedPersonController.person" 
     optionLabelPath="content.fullName" 
     optionValuePath="content.id"}} 

Ancora una volta, ecco un esempio jsFiddle: http://jsfiddle.net/ebryn/zgLCr/

+0

dovrebbe aggiungere questa vista al core di Ember :-) – Bank

+1

Ho una versione migliorata che sarà presto inclusa con Ember: https://github.com/emberjs/ember.js/pull/424 – ebryn

+0

btw, questo è il [Ember.Select api] (http://emberjs.com/api/classes/Ember.Select.html) –

4

Utilizzando un personalizzato Ember.View funziona per me, ma penso che ci sia una soluzione migliore ...

Si veda l'esempio di lavoro è questo violino http://jsfiddle.net/pangratz/hcxrJ/

Manubrio:

{{#view Food.SelectView contentBinding="Food.foodController" 
    valueBinding="Food.appsController.selectedValue"}} 
    <select> 
     {{#each content}} 
      <option {{bindAttr value="value"}} >{{title}}</option> 
     {{/each}} 
    </select> 
{{/view}} 

app js:

Food = Ember.Application.create(); 

Food.SelectView = Ember.View.extend({ 
    value: null, 

    valueChanged: function(){ 
     this.$('select').val(this.get('value')); 
    }.observes('value'), 

    didInsertElement: function(){ 
     var self = this; 
     this.$('select').change(function(){ 
      var val = $('select option:selected').val(); 
      self.set('value', val); 
     }); 
    } 
}); 

Food.appsController = Ember.Object.create({ 
    selectedValue: "" 
}); 

Food.Todo = Ember.Object.extend({ 
    title: null, 
    value: null 
}); 

Food.foodController = Ember.ArrayProxy.create({ 
    content: [] 
}); 

Food.foodController.pushObject(Food.Todo.create({title:"a", value:"1"})); 
Food.foodController.pushObject(Food.Todo.create({title:"b", value:"2"})); 
Food.foodController.pushObject(Food.Todo.create({title:"c", value:"3"})); 
+0

Questa soluzione funziona bene per me per diversi motivi: a) La vista Ember.Seleziona restituisce l'intero oggetto nella serie di contenuti come valore selezionato, mentre io sono o nly interessato a recuperare il valore di selezione effettivo. b) Per quello che sto lavorando a questa implementazione è molto più veloce: non ho bisogno di binding sulle etichette e sui valori, non cambiano (ho rimosso il metodo valueChanged nell'estensione della classe vista sopra dato che non l'ho fatto necessario) Commento finale: il metodo select change handler contiene un piccolo errore (quando si hanno più selettori): $ ('selezionare le opzioni ... dovrebbe essere self. $ (' selezionare opzioni ... – Visionscaper

5

Saltando fuori dalla soluzione per @pangrantz, questo FIDD le esempio (http://jsfiddle.net/bsyjr/) illustra alcuni miglioramenti: il codice Handlebars è più pulito attraverso l'uso di tagName. Quando tagName è impostato su "select", le viste child diventano automaticamente elementi "option". Vedi il Ember.CollectionView.CONTAINER_MAP in https://github.com/emberjs/ember.js/blob/master/packages/ember-views/lib/views/collection_view.js per capire perché. Sul lato Javascript, specificando un itemViewClass, possiamo aggiungere l'attributo value all'elemento option.

<script type="text/x-handlebars" > 
    {{#collection Food.SelectView tagName="select" contentBinding="Food.foodController" 
     valueBinding="Food.appsController.selectedValue"}} 
     {{content.title}} 
    {{/collection}} 

    selected: {{view Ember.TextField valueBinding="Food.appsController.selectedValue"}}{{Food.appsController.selectedValue}} 
</script> 

Food = Ember.Application.create(); 

Food.SelectView = Ember.CollectionView.extend({ 
    value: null, 
    itemViewClass: SC.View.extend({ 
     attributeBindings:['value'], 
     valueBinding: 'content.value' 
    }), 

    valueChanged: function(){ 
     this.$().val(this.get('value')); 
    }.observes('value'), 

    didInsertElement: function(){ 
     var self = this; 
     this.$().change(function(){ 
      var val = $('select option:selected').val(); 
      self.set('value', val); 
     }); 
    } 
}); 

Food.appsController = Ember.Object.create({ 
    selectedValue: "" 
}); 

Food.Todo = Ember.Object.extend({ 
    title: null, 
    value: null 
}); 

Food.foodController = Ember.ArrayProxy.create({ 
    content: [] 
}); 

Food.foodController.pushObject(Food.Todo.create({title:"a", value:"1"})); 
Food.foodController.pushObject(Food.Todo.create({title:"b", value:"2"})); 
Food.foodController.pushObject(Food.Todo.create({title:"c", value:"3"})); 

C'è ancora spazio per migliorare la gestione, che non utilizza quadro evento di Ember evento, e sarebbe fare un sacco di senso utilizzare un SelectView scritto personalizzato che non leva manubrio, dal IMO, è dubbio quanto valore manubri aggiunga in questo caso.

+3

Vale la pena notare che l'helper '{{#collection}}' è deprecato in quanto gli stessi risultati possono essere ottenuti con maggiore chiarezza usando '{{#each}}' come ha fatto @pangratz. –

+0

Per fornire ulteriori chiarimenti, ci sono ancora alcuni posti in cui '{{ {#collection}} 'è utile.Tuttavia, proverei ad usare' {{#each}} 'prima e se non sei in grado di ottenere i risultati che vuoi allora considera' {{#collection}} 'abbiamo in programma per apportare ulteriori miglioramenti a '{{#each}}' che coprirà più c AS. –

1

Non sono sicuro se questo è utile per gli altri, ma ho fatto qualcosa di simile in base alle risposte qui, e ho fatto questo SelectView che dovrebbe funzionare anche in questo contesto. Si lega a "cambiare", elabora la vista attualmente selezionata e quindi fa qualcosa con il suo contenuto.

Food.SelectView = Ember.CollectionView.extend({ 
    change: function(e) { 
    var selected = this.$().find(":selected").index(); 
    var content = this.get('childViews')[selected].content; 
    // Do something with the result 
    Food.appsController.set('selectedValue', content.title); 
    } 
}); 

In questo modo è possibile passare attorno a un oggetto anziché all'indice della selezione.

Problemi correlati