2013-10-27 4 views
5

У меня есть следующие две модели:ember.js hasMany в список флажков

App.Child = DS.Model.extend({ 
    name: DS.attr('string') 
}); 

И:

App.Activity = DS.Model.extend({ 
    children: DS.hasMany('child',{async:true}), 
    name: DS.attr('string') 
}); 

Я хочу использовать флажки, чтобы выбрать между существующими детьми, для hasMany отношение.

К примеру, у меня есть эти трое детей:

App.Child.FIXTURES = [ 
    { id: 1, name: 'Brian' }, 
    { id: 2, name: 'Michael' }, 
    { id: 3, name: 'James' } 
]; 

Пользователь должен иметь возможность использовать флажков, при создании или редактировании активности, для выбора которых дети, чтобы добавить к hasMany отношения.

Я создал JSFiddle, чтобы проиллюстрировать мой вопрос: http://jsfiddle.net/Dd6Wh/. Нажмите «Создать новую активность», чтобы увидеть, что я пытаюсь сделать.

В основном это то же самое, что и Ember.Select [...] multiple = "true", но для флажков.

Каков правильный подход для чего-то подобного с Ember.js?

ответ

14

Вы можете использовать itemController в своем вспомогательном приложении вида each для управления выбором. В коде ниже я создал один называется ChildController:

App.ChildController = Ember.ObjectController.extend({  
    selected: function() { 
     var activity = this.get('content'); 
     var children = this.get('parentController.children'); 
     return children.contains(activity); 
    }.property(), 
    selectedChanged: function() { 
     var activity = this.get('content'); 
     var children = this.get('parentController.children'); 
     if (this.get('selected')) {          
      children.pushObject(activity);    
     } else {          
      children.removeObject(activity);              
     }   
    }.observes('selected') 
}); 

С в itemController вы можете раскрыть некоторые свойства и логик, без добавления его directlly к моделям. В этом случае вычисленное значение selected и наблюдатель selectedChanged.

В вашем шаблоне вы можете связать выбор, используя checkedBinding="selected". Поскольку прокси itemController каждая модель, будет использоваться selected свойство itemcontroller и связывание {{name}}, будет искать имя свойства модели:

<script type="text/x-handlebars" data-template-name="activities/new"> 
    <h1>Create a new activity</h1> 

    {{#each childList itemController="child"}} 
     <label> 
      {{view Ember.Checkbox checkedBinding="selected"}} 
      {{name}} 
     </label><br /> 
    {{/each}} 
    {{view Ember.TextField valueBinding="name"}} 
    <button {{action create}}>Create</button> 
</script> 

То же Подход в шаблоне редактирования:

<script type="text/x-handlebars" data-template-name="activities/edit"> 
    <h1>Edit an activity</h1> 

    {{#each childList itemController="child"}} 
     <label> 
      {{view Ember.Checkbox checkedBinding="selected"}} 
      {{name}} 
     </label><br /> 
    {{/each}} 
    {{view Ember.TextField valueBinding="name"}} 
    <button {{action update}}>Update</button> 
</script> 

Это скрипка с этой рабочей версией http://jsfiddle.net/marciojunior/8EjRk/

компонента

Шаблон

<script type="text/x-handlebars" data-template-name="components/checkbox-select"> 
    {{#each elements itemController="checkboxItem"}} 
     <label>    
      {{view Ember.Checkbox checkedBinding="selected"}} 
      {{label}} 
     </label><br /> 
    {{/each}}  
</script> 

Javascript

App.CheckboxSelectComponent = Ember.Component.extend({ 
    /* The property to be used as label */ 
    labelPath: null, 
    /* The model */ 
    model: null, 
    /* The has many property from the model */ 
    propertyPath: null, 
    /* All possible elements, to be selected */ 
    elements: null, 
    elementsOfProperty: function() { 
     return this.get('model.' + this.get('propertyPath')); 
    }.property() 
}); 

App.CheckboxItemController = Ember.ObjectController.extend({  
    selected: function() {   
     var activity = this.get('content'); 
     var children = this.get('parentController.elementsOfProperty');   
     return children.contains(activity); 
    }.property(), 
    label: function() {  
     return this.get('model.' + this.get('parentController.labelPath')); 
    }.property(), 
    selectedChanged: function() { 
     var activity = this.get('content'); 
     var children = this.get('parentController.elementsOfProperty'); 
     if (this.get('selected')) {          
      children.pushObject(activity);    
     } else {          
      children.removeObject(activity);              
     }   
    }.observes('selected') 
}); 

Обновлено скрипку http://jsfiddle.net/mgLr8/14/

Я надеюсь, что это помогает

+0

Спасибо за ваш ответ. Он отлично работает! Можно ли было бы создать это как компонент или вид многократного использования?Моя модель имеет несколько «hasMany» отношений, поэтому было бы здорово, если бы мне не пришлось копировать код несколько раз. – Martin

+1

Я извлек элемент из ember с некоторыми настраиваемыми свойствами. Пожалуйста, посмотрите http://jsfiddle.net/marciojunior/mgLr8/. –

+0

отличный ответ, я исправил скрипку для работы http://jsfiddle.net/mgLr8/13/ –

Смежные вопросы