Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Your code will work but it is not optimal.</p> <p>I forked your jsFiddle code and added logging to demonstrate it:</p> <ul> <li>Open <a href="http://jsfiddle.net/jvandemo/tDhgv/1/" rel="nofollow">http://jsfiddle.net/jvandemo/tDhgv/1/</a></li> <li>Open the console in your browser</li> <li>Type something in the input fields and you will notice that the <code>filterItems</code> runs 9 times every time the <code>$scope.query</code> changes</li> </ul> <p>So why is this?</p> <p>Well, there are 2 reasons:</p> <ol> <li>Your function call is inside an ng-repeat so it gets called multiple times (as expected, no surprises here)</li> <li><p>There is an issue with your <code>filterItems</code> method.</p> <p>You have assigned the <code>filterItems</code> method to the inner <code>ng-repeat</code>. Therefore Angular will automatically watch the result of the function for you and 'refresh' when it changes.</p> <p>However, inside your <code>filterItems</code> code you make an immediate change to the data Angular is watching for you by performing <code>g.filteredItemCount = ret.length</code> causing Angular to perform another 'refresh' since it detects a new change.</p> <p>If you were to comment out that single ine of code, you would immediately see a drop in number of times the method would run.</p></li> </ol> <p>So what's a better way?</p> <p>In your case I would:</p> <ul> <li>Define a watcher for <code>$scope.query</code></li> <li>Filter the data in your watcher and store it separately (to leave the original data untouched)</li> <li>Loop through the filtered data with the <code>ng-repeat</code> tags</li> </ul> <p>Your code will be cleaner, faster and more efficient which is important if your data set would be much bigger.</p> <p>I created a jsFiddle for your convenience: <a href="http://jsfiddle.net/jvandemo/VeLEJ/1/" rel="nofollow">http://jsfiddle.net/jvandemo/VeLEJ/1/</a> </p> <p>If you open the console, you will see that the code only runs once when <code>$scope.query</code> changes instead of 9 times before.</p> <p>Visually the result is the same, but behind the scenes there is quite a difference...</p> <p>Hope that helps!</p> <hr> <p>UPDATE: </p> <p>An approach for better performance is to restructure the data (once after loading the data).</p> <p>I have created a jsFiddle with sample code to demonstrate it: <a href="http://jsfiddle.net/jvandemo/fTE5R/1/" rel="nofollow">http://jsfiddle.net/jvandemo/fTE5R/1/</a></p> <p>The data is restructured to avoid <code>forEach</code> cycles and to avoid as many loops as possible and to allow the <code>query</code> object to be applied directly to the items in the directive.</p> <p>This looks a lot like the original code but without the need for calling filtering functions inside the <code>scope</code>.</p> <p>If your application can deliver the data in the format of <code>$scope.items</code> the whole process would even be faster and the optimization step could be skipped.</p> <p>Hope that helps!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload