0

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

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks givanse. Based on your solution I have created my own which still keeps the component structure and doesn't require reopening the Checkbox view. jsbin.com/ruyosu/2/edit?html,js,output
@OrBarmatz if you have a solution, perhaps you can provide details as an answer here, you can even accept it as the 'best' answer. This will help others in the future who run into this same problem.
@technicolorenvy my solution covers a feature I was looking for but not relevant per say to the topic of my original question. There is yet to be, so it seems, a way to observe nested arrays. I have provided a link in my previous comment to my own implementation which involves notifications between nested components sharing a single model.
Its the same solution I provided, but you changed back views to components. Thats cool, have it your way.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.