Search code examples
javascriptarraysbindingember.jsobservers

How to update content of one ArrayController from the selected value of another ArrayController in Ember.js


I have the following problem in ember.js. A child controller depends on a selected value in a parent controller in order to determine its content. In the database a child has a parent_id reference.

App.parentsController = Em.ArrayController.create({
    content: [],
    selected: null
});

App.sonsController = Em.ArrayController.create({
    // the value of content depends on the id of
    // the selected item in the parentsController
    content: [], 
    selected: null
});

App.daughtersController = Em.ArrayController.create({
    // the value of content depends on the id of
    // the selected item in the parentsController
    content: [], 
    selected: null
});

I would prefer to solve this without the parentsController having to know anything about the other controllers. This should be possible with observers, bindings or even through calculations but I have no clue where to start. Any help would be well appreciated.


Solution

  • You can use the binding system. The sonsController needs to observe the parentsController.selected property, and then update its content.

    Here is an example of how you can do that :

    App.parentsController = Em.ArrayController.create({
        content: [],
        selected: null
    });
    
    App.sonsController = Em.ArrayController.create({
        parentControllerBinding: 'App.parentsController',
        content: [], 
    
        updateContent: function() {
            var selected = this.getPath('parentController.selected');
            var newContent = Ember.A();
            newContent.pushObject(selected);
            this.set('content', newContent);
        }.observes('parentController.selected')
    });
    

    And here is the jsfiddle associated.

    N.B. : you could also directly bind the selected property :

    App.sonsController = Em.ArrayController.create({
        parentSelectedBinding: 'App.parentsController.selected',
          ...
    
        updateContent: function() {
           ...
        }.observes('parentSelected')
    })