polymer 1.0 force array re-sorting/re-filtering - polymer-1.0

By default, dom-repeat arrays only re-filter and re-sort when the array itself is mutated, or the item itself changes property that correspond to its observer: https://www.polymer-project.org/1.0/docs/devguide/templates.html#filtering-and-sorting-lists.
Is there anyway to trigger sorting function when the sorting function itself change? For example, when you want to change from increasing order to decreasing order, a.k.a changing sorting function.

Try calling render on the dom-repeat.
From the source code documentation:
In order to re-run the filter or sort functions based on changes to sub-fields
of items, the observe property may be set as a space-separated list of
item sub-fields that should cause a re-filter/sort when modified. If
the filter or sort function depends on properties not contained in items,
the user should observe changes to those properties and call render to update
the view based on the dependency change.

Related

How to iterate over a collection of objects already filtered by ng-repeat filters

I have a collection of objects that AngularJS filters by a text search within a title property on each object.
After this filter has run, I am left with a set of items that matches this filter.
I would like to iterate over this subset of the list, after clicking a button, and change a property on the items that match this filter.
Is there an easy way to do this in AngularJS, or am I going to be doing this outside Angular and then updating the state manually in the controller?
When the user clicks the button you can get this values and make some change. But I think you need do it inside your controller.
It appears that within an ng-repeat you can do the following
item in items | filter:x as results will store the fragment of the repeated items as results, but only after the items have been processed through the filter.

Which element of array changed in AngularJS?

I'm using $watch to get a callback when an array changes. Sending true for the third param will detect when any part of any element changes. But I need to know when and which item has been added or removed. Is there a better way of decoding added/removed element than just doing a manual comparison?
I would like to know whether an item was added or deleted and easily get a reference to the item.

Does ng-repeat retain DOM elements or create all new ones when the collection changes?

I've seen a lot of questions about the order in which ng-repeat finishes compared to other directives or things going on in Angular land, but I haven't been able to find an answer to how exactly it accomplishes this.
I have two ideas of how it could work.
First Way:
When ng-repeat's watcher triggers, it removes all elements it created from the DOM then creates all new elements in their place, even if many of those elements are the same (e.g. in the case of 1 item added to the backing array).
Second way: Since ng-repeat already keeps track of which elements go with which items in its backing collection, it simply removes the items that no longer exist in the collection and creates new elements for items that are new to the collection.
Which is it and why?
It's the second way: Angular tries to be smart about creating/removing DOM elements:
The ngRepeat directive provides a way to render a collection of items given a template. To do this, AngularJS compiles the given template and then clones it for each unique item in the collection. As the collection is mutated by the Controller, AngularJS adds, removes, and updates the relevant DOM elements as needed.
But, how does AngularJS know which actions to perform when? If you start to test the rendering, you'll discover that AngularJS doesn't brute force DOM creation; that is, it doesn't recreate the DOM for every rendering. Instead, it only creates a new DOM element when a completely new item has been introduced to the collection. If an existing item has been updated, AngularJS merely updates the relevant DOM properties rather than creating a new DOM node.
This can still impact performance unnecessarily, i.e. when passing elements by-value in a collection (there's an excellent example of this in the blog post linked above). That's why Angular supports "track by" for ngRepeat since version 1.2: It's a way to help Angular decide when DOM creation is necessary:
With this association in place, AngularJS will not $destroy and re-create DOM nodes unnecessarily. This can have a huge performance and user experience benefit.
The official documentation states:
You can also provide an optional tracking function which can be used to associate the objects in the collection with the DOM elements. If no tracking function is specified the ng-repeat associates elements by identity in the collection.
For example: item in items track by item.id is a typical pattern when the items come from the database. In this case the object identity does not matter. Two objects are considered equivalent as long as their id property is same.

ng-repeat's element not updated on array modification when in a partial

I have a similar issue to what is stated in the 2 posts below - I have 3 ng repeats in a partial, when I update the source arrays the changes are not reflected in the view.
ng-repeat's element not updated on array modification
AngularJS not refreshing ngRepeat when updating array
The ng repeats are within 3 ul's with each listing out input checkboxes with ng click on each, if I check an input from the the first list then my js code runs through the other 2 arrays, finds matching inputs and sets a property called IsSelected to true which is bound to ng checked of each input. e.g regions in the first list - if I check europe, then it checks all the European countries in the second list, and all the related cities in the 3rd list when I click on an apply button. $scope.$apply() after the js code for setting IsSelected doesnt work, but if I set the arrays to null then the view appears empty for that particular list. I then tried to use track with a property that constantly changes when I update the array elements like a guid but that also doesnt work. If it was a scope issue then why would setting the array to null then update the view as suspected?

Updating indices of models in a collection

I have a list of songs (each one in the form of an album cover) that are sortable via jQuery UI's sortable library (http://jqueryui.com/demos/sortable/). All of the songs are models that reside in a single collection. When a "sorted" event is fired, I want to recalculate the order of the songs and update their respective indices. I know how to get the index of a model within a collection, but is it possible to update/set a model's index? I realize that I can just set an "order" attribute on the model and update that, but it seems like updating the indices would be much cleaner.
Sounds like you will want to define a comparator on the collection, then call sort on it when the widget's sorted event is fired.

Resources