2013-10-27 16 views
5

Mam następujące dwa modele:ember.js hasMany lista wyboru

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

I:

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

chcę użyć pola wyboru, aby wybrać pomiędzy istniejącymi dzieci, dla relacjach hasMany Relacja.

Na przykład, mam tych troje dzieci:

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

Użytkownik powinien mieć możliwość korzystania z pola wyboru, podczas tworzenia lub edytowania czynności, do wyboru których dzieci, aby dodać do hasMany relacji.

Stworzyłem JSFiddle, aby zilustrować moje pytanie: http://jsfiddle.net/Dd6Wh/. Kliknij "Utwórz nową aktywność", aby zobaczyć, co próbuję wykonać.

Zasadniczo jest taki sam jak Ember.Wybierz [...] multiple = "true", ale dla pól wyboru.

Jakie jest prawidłowe podejście do czegoś podobnego w Ember.js?

Odpowiedz

14

Możesz użyć itemController w swoim pomocniku widoku each, aby zarządzać zaznaczeniem. W kodzie poniżej stworzyłem jeden nazywa 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') 
}); 

z itemController można narazić niektóre właściwości i logiki, bez dodawania go directlly do swoich modeli. W tym przypadku obliczona właściwość selected i obserwator selectedChanged.

W swoim szablonie możesz powiązać wybór za pomocą checkedBinding="selected". Ponieważ pełnomocnika itemController każdego modelu, własność itemcontroller selected zostaną wykorzystane, a wiązanie {{name}} będzie odnośnika Właściwość Nazwa modelu:

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

To samo aproach w edycji szablonu:

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

jest to skrzypce z tym roboczej wersji http://jsfiddle.net/marciojunior/8EjRk/

Komponent

Szablon

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

Updated skrzypce http://jsfiddle.net/mgLr8/14/

Mam nadzieję, że to pomaga

+0

Dziękuję za odpowiedź. Działa doskonale! Czy możliwe byłoby zbudowanie tego jako elementu lub widoku wielokrotnego użytku?Mój model ma wiele relacji "ma wiele", więc byłoby świetnie, gdybym nie musiał wielokrotnie kopiować kodu. – Martin

+1

Wyodrębniono do komponentu embers, z pewnymi właściwościami, które można dostosowywać. Proszę spojrzeć na http://jsfiddle.net/marciojunior/mgLr8/. –

+0

świetna odpowiedź, naprawiłem skrzypce do pracy http://jsfiddle.net/mgLr8/13/ –