1
1
import {
2
2
Component ,
3
+ Directive ,
4
+ Input ,
3
5
DoCheck ,
4
6
OnDestroy ,
7
+ AfterContentInit ,
5
8
ElementRef ,
6
9
ViewContainerRef ,
7
10
TemplateRef ,
@@ -13,14 +16,16 @@ import {
13
16
EventEmitter ,
14
17
ViewChild ,
15
18
Output ,
16
- ChangeDetectionStrategy } from '@angular/core' ;
17
- import { isBlank } from "../lang-facade" ;
18
- import { isListLikeIterable } from "../collection-facade" ;
19
- import { ListView } from 'ui/list-view' ;
20
- import { View } from 'ui/core/view' ;
21
- import { ObservableArray } from 'data/observable-array' ;
22
- import { LayoutBase } from 'ui/layouts/layout-base' ;
23
- import { listViewLog } from "../trace" ;
19
+ Host ,
20
+ ChangeDetectionStrategy
21
+ } from '@angular/core' ;
22
+ import { isBlank } from "../lang-facade" ;
23
+ import { isListLikeIterable } from "../collection-facade" ;
24
+ import { ListView } from 'ui/list-view' ;
25
+ import { View , KeyedTemplate } from 'ui/core/view' ;
26
+ import { ObservableArray } from 'data/observable-array' ;
27
+ import { LayoutBase } from 'ui/layouts/layout-base' ;
28
+ import { listViewLog } from "../trace" ;
24
29
25
30
const NG_VIEW = "_ngViewRef" ;
26
31
@@ -51,14 +56,15 @@ export interface SetupItemViewArgs {
51
56
inputs : [ 'items' ] ,
52
57
changeDetection : ChangeDetectionStrategy . OnPush
53
58
} )
54
- export class ListViewComponent implements DoCheck , OnDestroy {
59
+ export class ListViewComponent implements DoCheck , OnDestroy , AfterContentInit {
55
60
public get nativeElement ( ) : ListView {
56
61
return this . listView ;
57
62
}
58
63
59
64
private listView : ListView ;
60
65
private _items : any ;
61
66
private _differ : IterableDiffer ;
67
+ private _templateMap : Map < string , KeyedTemplate > ;
62
68
63
69
@ViewChild ( 'loader' , { read : ViewContainerRef } ) loader : ViewContainerRef ;
64
70
@@ -68,7 +74,7 @@ export class ListViewComponent implements DoCheck, OnDestroy {
68
74
69
75
set items ( value : any ) {
70
76
this . _items = value ;
71
- var needDiffer = true ;
77
+ let needDiffer = true ;
72
78
if ( value instanceof ObservableArray ) {
73
79
needDiffer = false ;
74
80
}
@@ -87,12 +93,51 @@ export class ListViewComponent implements DoCheck, OnDestroy {
87
93
this . listView . on ( "itemLoading" , this . onItemLoading , this ) ;
88
94
}
89
95
96
+ ngAfterContentInit ( ) {
97
+ listViewLog ( "ListView.ngAfterContentInit()" ) ;
98
+ this . setItemTemplates ( ) ;
99
+ }
100
+
90
101
ngOnDestroy ( ) {
91
102
this . listView . off ( "itemLoading" , this . onItemLoading , this ) ;
92
103
}
93
104
105
+ private setItemTemplates ( ) {
106
+ if ( this . _templateMap ) {
107
+ listViewLog ( "Setting templates" ) ;
108
+
109
+ const templates : KeyedTemplate [ ] = [ ] ;
110
+ this . _templateMap . forEach ( value => {
111
+ templates . push ( value ) ;
112
+ } ) ;
113
+ this . listView . itemTemplates = templates ;
114
+ }
115
+ }
116
+
117
+ public registerTemplate ( key : string , template : TemplateRef < ListItemContext > ) {
118
+ listViewLog ( "registerTemplate for key: " + key ) ;
119
+ if ( ! this . _templateMap ) {
120
+ this . _templateMap = new Map < string , KeyedTemplate > ( ) ;
121
+ }
122
+
123
+ const keyedTemplate = {
124
+ key,
125
+ createView : ( ) => {
126
+ listViewLog ( "registerTemplate for key: " + key ) ;
127
+
128
+ const viewRef = this . loader . createEmbeddedView ( template , new ListItemContext ( ) , 0 ) ;
129
+ const resultView = getSingleViewFromViewRef ( viewRef ) ;
130
+ resultView [ NG_VIEW ] = viewRef ;
131
+
132
+ return resultView ;
133
+ }
134
+ } ;
135
+
136
+ this . _templateMap . set ( key , keyedTemplate ) ;
137
+ }
138
+
94
139
public onItemLoading ( args ) {
95
- if ( ! this . itemTemplate ) {
140
+ if ( ! args . view && ! this . itemTemplate ) {
96
141
return ;
97
142
}
98
143
@@ -115,6 +160,7 @@ export class ListViewComponent implements DoCheck, OnDestroy {
115
160
args . view = getSingleViewFromViewRef ( viewRef ) ;
116
161
args . view [ NG_VIEW ] = viewRef ;
117
162
}
163
+
118
164
this . setupViewRef ( viewRef , currentItem , index ) ;
119
165
120
166
this . detectChangesOnChild ( viewRef , index ) ;
@@ -128,7 +174,7 @@ export class ListViewComponent implements DoCheck, OnDestroy {
128
174
context . $implicit = data ;
129
175
context . item = data ;
130
176
context . index = index ;
131
- context . even = ( index % 2 == 0 ) ;
177
+ context . even = ( index % 2 === 0 ) ;
132
178
context . odd = ! context . even ;
133
179
134
180
this . setupItemView . next ( { view : viewRef , data : data , index : index , context : context } ) ;
@@ -139,24 +185,23 @@ export class ListViewComponent implements DoCheck, OnDestroy {
139
185
// TODO: Is there a better way of getting viewRef's change detector
140
186
const childChangeDetector = < ChangeDetectorRef > ( < any > viewRef ) ;
141
187
142
- listViewLog ( "Manually detect changes in child: " + index )
188
+ listViewLog ( "Manually detect changes in child: " + index ) ;
143
189
childChangeDetector . markForCheck ( ) ;
144
190
childChangeDetector . detectChanges ( ) ;
145
191
}
146
192
147
193
ngDoCheck ( ) {
148
194
if ( this . _differ ) {
149
- listViewLog ( "ngDoCheck() - execute differ" )
195
+ listViewLog ( "ngDoCheck() - execute differ" ) ;
150
196
const changes = this . _differ . diff ( this . _items ) ;
151
197
if ( changes ) {
152
- listViewLog ( "ngDoCheck() - refresh" )
198
+ listViewLog ( "ngDoCheck() - refresh" ) ;
153
199
this . listView . refresh ( ) ;
154
200
}
155
201
}
156
202
}
157
203
}
158
204
159
-
160
205
function getSingleViewRecursive ( nodes : Array < any > , nestLevel : number ) {
161
206
const actualNodes = nodes . filter ( ( n ) => ! ! n && n . nodeName !== "#text" ) ;
162
207
@@ -175,7 +220,7 @@ function getSingleViewRecursive(nodes: Array<any>, nestLevel: number) {
175
220
return actualNodes [ 0 ] ;
176
221
}
177
222
else {
178
- return getSingleViewRecursive ( actualNodes [ 0 ] . children , nestLevel + 1 )
223
+ return getSingleViewRecursive ( actualNodes [ 0 ] . children , nestLevel + 1 ) ;
179
224
}
180
225
}
181
226
}
@@ -184,8 +229,24 @@ function getSingleViewFromViewRef(viewRef: EmbeddedViewRef<any>): View {
184
229
return getSingleViewRecursive ( viewRef . rootNodes , 0 ) ;
185
230
}
186
231
187
- const changeDetectorMode = [ "CheckOnce" , "Checked" , "CheckAlways" , "Detached" , "OnPush" , "Default" ] ;
188
- const changeDetectorStates = [ "Never" , "CheckedBefore" , "Error" ] ;
189
- function getChangeDetectorState ( cdr : any ) {
190
- return "Mode: " + changeDetectorMode [ parseInt ( cdr . cdMode ) ] + " State: " + changeDetectorStates [ parseInt ( cdr . cdState ) ] ;
232
+ @Directive ( { selector : "[nsTemplateKey]" } )
233
+ export class TemplateKeyDirective {
234
+ constructor (
235
+ private templateRef : TemplateRef < any > ,
236
+ @Host ( ) private list : ListViewComponent ) {
237
+ }
238
+
239
+ @Input ( )
240
+ set nsTemplateKey ( value : any ) {
241
+ if ( this . list && this . templateRef ) {
242
+ this . list . registerTemplate ( value , this . templateRef ) ;
243
+ }
244
+ }
191
245
}
246
+
247
+ // Debug helpers:
248
+ // const changeDetectorMode = ["CheckOnce", "Checked", "CheckAlways", "Detached", "OnPush", "Default"];
249
+ // const changeDetectorStates = ["Never", "CheckedBefore", "Error"];
250
+ // function getChangeDetectorState(cdr: any) {
251
+ // return "Mode: " + changeDetectorMode[parseInt(cdr.cdMode)] + " State: " + changeDetectorStates[parseInt(cdr.cdState)];
252
+ // }
0 commit comments