1

I (like so many others) have run into an issue with the infinite $digest loop. After reading many SO Q&As and spending plenty of time in AngularJS documentation I am still not certain how to build this component using best practices.

The origin of the issue appears to be due to nested filters. However, I am purposefully breaking up responsibility of functionality in a way that I think is correct.

Here's a plnkr: http://plnkr.co/edit/RnPcMOTzRfTv5ye1ixJ3?p=preview

As you'll see, there is a paging directive that accepts an items array that is filtered outside of its scope.

<app-pager items="items | filter:filter.value" items-per-page="5"> 

Within the custom directive all of the pagination functionality is handled:

<div class="pager"> <div ng-transclude ng-repeat="item in items | limitTo:itemsPerPage:(page * itemsPerPage)"></div> <uib-pagination total-items="items.length" items-per-page="itemsPerPage" ng-model="page"></uib-pagination> </div> 

This technically works, but it throws the 10 $digest() iterations reached error because of the mutated array. Oh, and sorry about the naming of variables, "items" being reused; its just a quick example and there is no conflict since the pager directive creates an isolated scope.

I don't want the filter to be part of the pagination and I don't want to have to repeat page functionality in multiple areas of my app.

What is the best approach to restructuring this to follow best practices?

Update: It looks like [email protected] doesn't support the second parameter of limitTo, but this doesn't change the root of the problem.

    1 Answer 1

    0

    Ok, the thing is about the attribute items on <app-paper> element. It looks like you should not use filter in data binding expression, because it will cause infinite $digest loop as it force it to execute each time items were filtered.

    What you can do is to pass filter value to the directive along with unfiltereditems. And then you create and use your custom filter inside of the directive.

    Here is my plunker example (I changed code in both html files and in js one). Note how I filter pages length (btw, you had a little mistake in logic of filtering pages offset).

    But! As you mentioned:

    [email protected] doesn't support the second parameter of limitTo

    So, I suppose, you should create your own filter to make it work correctly. Here is my another plunker example of how it works with [email protected]

    3
    • Thanks for the inspiration. I have updated the Plnkr to incorporate your idea but maintained the separation of responsibilities. However, this approach doesn't easily allow for multiple filters. Any thoughts? plnkr.co/edit/RnPcMOTzRfTv5ye1ixJ3?p=previewCommentedFeb 3, 2017 at 18:09
    • This approach also makes advanced filtering a bit more difficult. One of the other issues is that a search filter function which would need access to the search query has no context of the controller.CommentedFeb 3, 2017 at 19:15
    • I don't think that not having controller context in a filter function is bad or especially an issue. Rather the opposite. Because you can be sure it will not cause any side effect to your environment. It will only filter. As for difficulty, I don't think so too =) If filters are multiple and advanced it should be a little bit difficult. Here's updated plnk. Just added Math.abs() for odd filter and little changes in page.html to make pages amount work correctly.
      – GProst
      CommentedFeb 4, 2017 at 10:11

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.