1

I'm implementing an angular directive that is responsible for expanding and collapsing a set of blocks on the page. This directive expects as a parameter a set of "expandable items", all of which should have property isExpanded.

<expand-collapse-all expandable-items="expandableItems"></expand-collapse-all>

The blocks that should expand and collapse look like this:

<ul>
    <li ng-repeat="group in groups">
        <block items="group.items" library="group.library"></block>
    </li>
</ul>

expandableItems array is formed like this:

_.forEach(groups, group => {
     expandableItems.push(group.library);
});

The problem is that my expandableItems should be "computed" array, because isExpanded is a property of library, not a group, and groups can be added or deleted, and I don't want to manually update expandableItems array each time some group is added or removed.

I see that my problem can be solved by making group object expandable (adding isExpanded property to it) and passing entire group to block directive instead of passing items and library separately. But I'm still curious how it can be solved when it is like it is now.

I'm more aquainted with knockoutjs, and I know that in knockoutjs it could be easily achieved by defining expandableItems as ko.computed. I cannot figure out though how I can do similar thing in angularjs. Can I pass a function somehow to expand-collapse-all, that will be recalculating the expandableItems array?

I've tried doing this:

<expand-collapse-all expandable-items="getExpandableItems(groups)"></expand-collapse-all>

, defining getExpandableItems(groups) in the constructor of page's controller, but I get error "Error: 10 $digest() iterations reached. Aborting!"

1

1 Answer 1

1

You need to cache the computed array. You cannot return a new array instance each time, since Angular is checking reference equality and a failed check results in a new digest loop.

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

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.