Nat
Nat

Reputation: 487

Computed array in Angularjs

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

Upvotes: 1

Views: 251

Answers (1)

user1620220
user1620220

Reputation: 1315

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.

Upvotes: 1

Related Questions