-
Notifications
You must be signed in to change notification settings - Fork 467
/
track-by-property.pipe.ts
98 lines (63 loc) · 2.74 KB
/
track-by-property.pipe.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Import the core angular services.
import { Pipe } from "@angular/core";
import { PipeTransform } from "@angular/core";
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
interface TrackByFunctionCache {
[ propertyName: string ]: <T>( index: number, item: T ) => any;
}
// Since the resultant TrackBy functions are based purely on a static property names, we
// can cache these Functions across the entire app. No need to generate more than one
// Function for the same property names.
var cache: TrackByFunctionCache = Object.create( null );
@Pipe({
name: "trackByProperty",
pure: true
})
export class TrackByPropertyPipe implements PipeTransform {
// I return a TrackBy function that plucks the given properties from the ngFor item.
public transform( propertyNames: "$index" ) : Function;
public transform( propertyNames: string ) : Function;
public transform( propertyNames: string[] ) : Function;
public transform( propertyNames: any ) : Function {
console.warn( `Getting track-by for [${ propertyNames.toString() }].` );
var cacheKey = propertyNames;
// If the given property names are defined as an Array, then we have to generate
// the item identity based on the composition of several item values (in which
// each key in the input maps to a property on the item).
if ( Array.isArray( propertyNames ) ) {
cacheKey = propertyNames.join( "->" );
// Ensure cached identity function.
if ( ! cache[ cacheKey ] ) {
cache[ cacheKey ] = function trackByProperty<T>( index: number, item: T ) : any {
var values = [];
// Collect the item values that will be aggregated in the resultant
// item identity
for ( var propertyName of propertyNames ) {
values.push( item[ propertyName ] );
}
return( values.join( "->" ) );
};
}
// If the property name is the special "$index" key, we'll create an identity
// function that simply uses the collection index. This assumes that the order of
// the collection is stable across change-detection cycles.
} else if ( propertyNames === "$index" ) {
// Ensure cached identity function.
if ( ! cache[ cacheKey ] ) {
cache[ cacheKey ] = function trackByProperty<T>( index: number, item: T ) : any {
return( index ); // <---- Using INDEX.
};
}
// By default, we'll use the provided item property value as the identity.
} else {
// Ensure cached identity function.
if ( ! cache[ cacheKey ] ) {
cache[ cacheKey ] = function trackByProperty<T>( index: number, item: T ) : any {
return( item[ propertyNames ] ); // <---- Using VALUE.
};
}
}
return( cache[ cacheKey ] );
}
}