I don't really understand how track by
works and what it does.
My main goal is to use it with ng-repeat
to add some precision.
相关问题
- Is there a limit to how many levels you can nest i
- How to toggle on Order in ReactJS
- void before promise syntax
- Keeping track of variable instances
- Can php detect if javascript is on or not?
Using
track by
to track strings & duplicate valuesNormally
ng-repeat
tracks each item by the item itself. For the given arrayobjs = [ 'one', 'one', 2, 'five', 'string', 'foo']
,ng-repeat
attempts to track changes by eachobj
in theng-repeat="obj in objs"
. The problem is that we have duplicate values and angular will throw an error. One way to solve that is to have angular track the objects by other means. For strings,track by $index
is a good solution as you really haven't other means to track a string.track by
& triggering a digest & input focusesYou allude to the fact you're somewhat new to angular. A digest cycle occurs when angular performs an exhaustive check of each watched property in order to reflect any change to the correspodant view; often during a digest cycle it happens that your code modify other watched properties so the procedure needs to be performed again until angular detects no more changes.
For example: You click a button to update a model via
ng-click
, then you do somethings (i mean, the things you wrote in the callback to perform when an user makes a click), then angular trigger digest cycle in order to refresh the view. I'm not too articulate in explaining that so you should investigate further if that didn't clarify things.So back to
track by
. Let's use an example:ng-repeat
UIHow you track this object will determine how the UI reflects the change.
One of the most annoying UXs I've experienced is this. Say you have a table of objects, each cell has an input where you want to in-line edit those objects' properties. I want to change the value, then
on-blur
, save that object while moving to the next cell to edit while you might be waiting on the response. So this is an autosave type thing. Depending on how you setup yourtrack by
statement, you may lose current focus (e.g. the field you're currently editing) when the response gets written back into your array of objects.When you add
track by
you basically tell angular to generate a single DOM element per data object in the given collection.You can
track by $index
if your data source has duplicate identifiers.If you do need to repeat duplicate items, you can substitute the default tracking behavior with your own using the track by expression.
Example:
Try to use the duplicate values in
ng-repeat
, you will get an error such as:To avoid this kind of problems you should use
track by $index
. For example:Here is how you would get
$index
in nestedng-repeat
:Here are some resources that may help you:
track by $index
documentationngRepeat
documentationng-repeat
performance andtrack by
You should use
track by
only if you need to go against the default behaviour ofng-repeat
which is to remove duplicate items.You can track the items using the scope property
$index
or specifying a custom function.For instance:
Display all values of the array (42 is displayed twice).
For reference: https://docs.angularjs.org/api/ng/directive/ngRepeat