2011-12-16 16 views
7

Intento vincular el valor de la selección de entrada al atributo "selectedValue" en el controlador.Cómo vincular la entrada del formulario de valor de valor para el atributo en el controlador

Esta es 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"})); 

Esta es index.html mirada

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

salida como esta

<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> 

no tengo idea de cómo agregar valor a opción y cómo vincular el valor seleccionado de regreso al controlador. ¿Es esto posible de hacer en Emberjs?

Respuesta

7

Ember ahora tiene una vista de selección incorporada.

Lo puede encontrar en la última Ember.js construir aquí: http://cloud.github.com/downloads/emberjs/ember.js/ember-latest.js

He aquí un ejemplo de uso:

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

La plantilla se vería así:

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

De nuevo, aquí hay un ejemplo jsFiddle: http://jsfiddle.net/ebryn/zgLCr/

+0

debería agregar esta vista al núcleo Ember :-) – Bank

+1

Tengo una versión mejorada que se incluirá con Ember pronto: https://github.com/emberjs/ember.js/pull/424 – ebryn

+0

por cierto, este es el [Ember.Select api] (http://emberjs.com/api/classes/Ember.Select.html) –

4

Usando una costumbre Ember.View funciona para mí, pero creo que hay una solución mejor ...

Ver ejemplo de trabajo es este violín http://jsfiddle.net/pangratz/hcxrJ/

Manillar:

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

aplicación .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

Esta solución funciona bien para por varias razones: a) La vista Ember.Select devuelve todo el objeto en la matriz de contenido como valor seleccionado, mientras estoy o nly interesado en recuperar el valor de selección real. b) Para lo que estoy trabajando en esta implementación es mucho más rápido: no necesito enlaces en las etiquetas y los valores, no cambian (eliminé el método valueChanged en la extensión de clase de vista anterior ya que no lo hice) lo necesita) Comentario final: el método de selección del controlador de cambios contiene un pequeño error (cuando tiene múltiples selectores): $ ('seleccionar opciones ... debe ser uno mismo. $' (seleccionar opciones ... – Visionscaper

5

Saltando de la solución para @pangrantz, este Fidd El ejemplo (http://jsfiddle.net/bsyjr/) ilustra algunas mejoras: El código de manubrios está más limpio mediante el uso de tagName. Cuando tagName se establece en "seleccionar", las vistas secundarias se convierten automáticamente en elementos de "opción". Consulte Ember.CollectionView.CONTAINER_MAP en https://github.com/emberjs/ember.js/blob/master/packages/ember-views/lib/views/collection_view.js para comprender por qué. En el lado de Javascript, al especificar un itemViewClass, podemos agregar el atributo de valor al elemento de opción.

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

Todavía hay margen de mejora en el manejo, que no está utilizando el framework caso de Ember evento, y que tendría mucho sentido utilizar un SelectView escrito personalizado que no aprovecha manillares, ya que la OMI, es dudoso cuánto valor agrega Handlebars en este caso.

+3

Vale la pena señalar el helper '{{#collection}}' está en desuso ya que se pueden obtener los mismos resultados con mayor claridad usando '{{#each}}' como lo hizo @pangratz. –

+0

Para aclarar aún más, todavía hay algunos lugares donde '{ {#collection}} 'es útil. Sin embargo, trataría de usar' {{#each}} 'primero y si no puede obtener los resultados que desea, considere' {{#collection}} 'planeamos para hacer más mejoras en '{{#each}}' que cubrirá más c ases. –

1

No estoy seguro de si esto es útil para otros, pero he estado haciendo algo similar basado en las respuestas aquí, y he hecho este SelectView que también debería funcionar en este contexto. Se une a 'cambio', resuelve la vista que está seleccionada actualmente y luego hace algo con su contenido.

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

De esta manera puede pasar alrededor de un objeto en lugar del índice de la selección.

Cuestiones relacionadas