docs(common): rewrite docs for NgForOf#ngForTrackBy (#42329)

Clarify the prupose of the tracking function and document how to create a good one.

Fixes #40461

PR Close #42329
This commit is contained in:
Igor Minar 2021-05-25 13:51:10 -07:00 committed by Zach Arend
parent 38b0e71cb2
commit 14abc68ccf
2 changed files with 55 additions and 16 deletions

View File

@ -141,21 +141,22 @@ export class NgForOf<T, U extends NgIterable<T> = NgIterable<T>> implements DoCh
this._ngForOfDirty = true;
}
/**
* A function that defines how to track changes for items in the iterable.
* Specifies a custom `TrackByFunction` to compute the identity of items in an iterable.
*
* When items are added, moved, or removed in the iterable,
* the directive must re-render the appropriate DOM nodes.
* To minimize churn in the DOM, only nodes that have changed
* are re-rendered.
* If a custom `TrackByFunction` is not provided, `NgForOf` will use the item's [object
* identity](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)
* as the key.
*
* By default, the change detector assumes that
* the object instance identifies the node in the iterable.
* When this function is supplied, the directive uses
* the result of calling this function to identify the item node,
* rather than the identity of the object itself.
* `NgForOf` uses the computed key to associate items in an iterable with DOM elements
* it produces for these items.
*
* The function receives two inputs,
* the iteration index and the associated node data.
* A custom `TrackByFunction` is useful to provide good user experience in cases when items in an
* iterable rendered using `NgForOf` have a natural identifier (for example, custom ID or a
* primary key), and this iterable could be updated with new object instances that still
* represent the same underlying entity (for example, when data is re-fetched from the server,
* and the iterable is recreated and re-rendered, but most of the data is still the same).
*
* @see `TrackByFunction`
*/
@Input()
set ngForTrackBy(fn: TrackByFunction<T>) {

View File

@ -113,14 +113,52 @@ export interface IterableChangeRecord<V> {
}
/**
* An optional function passed into the `NgForOf` directive that defines how to track
* changes for items in an iterable.
* The function takes the iteration index and item ID.
* When supplied, Angular tracks changes by the return value of the function.
* A function optionally passed into the `NgForOf` directive to customize how `NgForOf` uniquely
* identifies items in an iterable.
*
* `NgForOf` needs to uniquely identify items in the iterable to correctly perform DOM updates
* when items in the iterable are reordered, new items are added, or existing items are removed.
*
*
* In all of these scenarios it is usually desirable to only update the DOM elements associated
* with the items affected by the change. This behavior is important to:
*
* - preserve any DOM-specific UI state (like cursor position, focus, text selection) when the
* iterable is modified
* - enable animation of item addition, removal, and iterable reordering
*
* A common use for custom `trackBy` functions is when the model that `NgForOf` iterates over
* contains a property with a unique identifier. For example, given a model:
*
* ```ts
* class User {
* id: number;
* name: string;
* ...
* }
* ```
* a custom `trackBy` function could look like the following:
* ```ts
* function userTrackBy(index, user) {
* return user.id;
* }
* ```
*
* A custom `trackBy` function must have several properties:
*
* - be [idempotent](https://en.wikipedia.org/wiki/Idempotence) (be without side effects, and always
* return the same value for a given input)
* - return unique value for all unique inputs
* - be fast
*
* @see [`NgForOf#ngForTrackBy`](api/common/NgForOf#ngForTrackBy)
* @publicApi
*/
export interface TrackByFunction<T> {
/**
* @param index The index of the item within the iterable.
* @param item The item in the iterable.
*/
(index: number, item: T): any;
}