Or Barmatz
Or Barmatz

Reputation: 307

Ember - binding nested arrays

I have an Ember component that takes in an array as it's content and for each item renders a checkbox if it's an object or a new nested instance if it's an array.

The component needs to be able to bind data both to the first set of items in the root array and all the nested items. I though of using computed properties and observers but as Ember states You cannot use nested forms like [email protected] or [email protected][email protected].

Any idea how this can be achieved?

Component:

<dl class="selection-list">
    {{#each content}}
        <dd>
            {{#isArray this}}
                {{selection-list content=this}}
            {{else}}
                <label class="checkbox">
                    {{input type="checkbox" checked=selected disabled=disabled}}
                    {{label}}
                </label>

                {{#isArray children}}
                    {{selection-list content=children}}
                {{/isArray}}
            {{/isArray}}
        </dd>
    {{/each}}
</dl>

Model:

App.ApplicationRoute = Ember.Route.extend({
  model: function () {
    return {
      items: [
        {
          label: '1'
        },
        {
          label: '2', 
          children: [
            {
              label: '2.1'
            }, 
            {
              label: '2.2',
              children: [
                {
                  label: '2.2.1'
                },
                {
                  label: '2.2.2'
                },
                {
                  label: '2.2.3'
                }
              ]
            }
          ]
        },
        {
          label: '3'
        },
        {
          label: '4'
        }
      ]
    };
  }
});

Use of binding:

App.ApplicationController = Ember.ObjectController.extend({
    selectionCount: function () {
       return this.get('items').filterBy('selected').length;
    }.property('[email protected]')
});

Example:
http://jsbin.com/yipuw/1/edit?html,js,output

Upvotes: 0

Views: 452

Answers (2)

pjfingers
pjfingers

Reputation: 51

I really don't feel like we've arrived at 'the' solution for the nested array binding issue as of yet. I've extended your bins with my own current working solution. The key to this is a pseudo-property whose only mission in life is to notify parents that something changed somewhere down the family tree.

http://jsbin.com/yivif/2/edit?html,js,output

Actually, here's a slightly tighter version

http://jsbin.com/yivif/10/edit?html,js,output

Upvotes: 0

givanse
givanse

Reputation: 14963

I solved this using views. The key points are:

  • Changed the component to a view. We want to keep the same context for N levels of nesting.
  • Used Ember.Checkbox and handled the change event in there so we can modify selectCount as clicks happen instead of iterating through the list of checkboxes every time one of them changes.

Check it out: http://jsbin.com/nuzex/1/edit?html,js,console,output

Upvotes: 1

Related Questions