@@ -19,14 +19,15 @@ END - original License
1919
2020import {
2121 AfterContentInit ,
22- AfterViewInit ,
2322 ChangeDetectionStrategy ,
2423 Component ,
2524 ContentChild ,
25+ Directive ,
2626 DoCheck ,
2727 ElementRef ,
2828 EmbeddedViewRef ,
2929 EventEmitter ,
30+ Host ,
3031 Inject ,
3132 Input ,
3233 IterableDiffer ,
@@ -40,32 +41,12 @@ import {
4041} from "@angular/core" ;
4142import { ObservableArray } from "tns-core-modules/data/observable-array" ;
4243import { profile } from "tns-core-modules/profiling" ;
43- import { messageType , write } from "tns-core-modules/trace" ;
44- import {
45- KeyedTemplate ,
46- View ,
47- } from "tns-core-modules/ui/core/view" ;
44+ import { KeyedTemplate , View } from "tns-core-modules/ui/core/view" ;
4845import { LayoutBase } from "tns-core-modules/ui/layouts/layout-base" ;
49- import {
50- GridItemEventData ,
51- GridView ,
52- } from "../grid-view" ;
53-
54- import {
55- getSingleViewRecursive ,
56- isKnownView ,
57- registerElement ,
58- } from "nativescript-angular/element-registry" ;
59-
60- export const gridViewTraceCategory = "ns-grid-view" ;
46+ import { GridItemEventData , GridView } from "../grid-view" ;
47+ import { gridViewError , gridViewLog } from "./trace" ;
6148
62- export function gridViewLog ( message : string ) : void {
63- write ( message , gridViewTraceCategory ) ;
64- }
65-
66- export function listViewError ( message : string ) : void {
67- write ( message , gridViewTraceCategory , messageType . error ) ;
68- }
49+ import { getSingleViewRecursive , isKnownView , registerElement } from "nativescript-angular/element-registry" ;
6950
7051const NG_VIEW = "_ngViewRef" ;
7152
@@ -80,7 +61,7 @@ export class GridItemContext {
8061 }
8162}
8263
83- export interface SetupGridViewArgs {
64+ export interface SetupItemViewArgs {
8465 view : EmbeddedViewRef < any > ;
8566 data : any ;
8667 index : number ;
@@ -95,22 +76,19 @@ export interface SetupGridViewArgs {
9576 </DetachedContainer>` ,
9677 changeDetection : ChangeDetectionStrategy . OnPush
9778} )
98- export class GridViewComponent implements DoCheck , OnDestroy , AfterContentInit , AfterViewInit {
79+ export class GridViewComponent implements DoCheck , OnDestroy , AfterContentInit {
9980 public get nativeElement ( ) : GridView {
10081 return this . gridView ;
10182 }
10283
10384 @ViewChild ( "loader" , { read : ViewContainerRef } ) public loader : ViewContainerRef ;
104-
105- @Output ( ) public setupGridView = new EventEmitter < SetupGridViewArgs > ( ) ;
106-
85+ @Output ( ) public setupItemView = new EventEmitter < SetupItemViewArgs > ( ) ;
10786 @ContentChild ( TemplateRef ) public itemTemplateQuery : TemplateRef < GridItemContext > ;
10887
10988 @Input ( )
11089 public get items ( ) {
11190 return this . _items ;
11291 }
113-
11492 public set items ( value : any ) {
11593 this . _items = value ;
11694 let needDiffer = true ;
@@ -129,9 +107,12 @@ export class GridViewComponent implements DoCheck, OnDestroy, AfterContentInit,
129107 private _items : any ;
130108 private _differ : IterableDiffer < KeyedTemplate > ;
131109 private itemTemplate : TemplateRef < GridItemContext > ;
110+ private _templateMap : Map < string , KeyedTemplate > ;
132111
133- constructor ( @Inject ( ElementRef ) _elementRef : ElementRef ,
134- @Inject ( IterableDiffers ) private _iterableDiffers : IterableDiffers ) {
112+ constructor (
113+ @Inject ( ElementRef ) _elementRef : ElementRef ,
114+ @Inject ( IterableDiffers ) private _iterableDiffers : IterableDiffers ,
115+ ) {
135116 this . gridView = _elementRef . nativeElement ;
136117
137118 this . gridView . on ( GridView . itemLoadingEvent , this . onItemLoading , this ) ;
@@ -142,10 +123,6 @@ export class GridViewComponent implements DoCheck, OnDestroy, AfterContentInit,
142123 this . setItemTemplates ( ) ;
143124 }
144125
145- public ngAfterViewInit ( ) {
146- gridViewLog ( "GridView.ngAfterViewInit()" ) ;
147- }
148-
149126 public ngOnDestroy ( ) {
150127 this . gridView . off ( GridView . itemLoadingEvent , this . onItemLoading , this ) ;
151128 }
@@ -162,6 +139,20 @@ export class GridViewComponent implements DoCheck, OnDestroy, AfterContentInit,
162139 }
163140 }
164141
142+ public registerTemplate ( key : string , template : TemplateRef < GridItemContext > ) {
143+ gridViewLog ( "registerTemplate for key: " + key ) ;
144+ if ( ! this . _templateMap ) {
145+ this . _templateMap = new Map < string , KeyedTemplate > ( ) ;
146+ }
147+
148+ const keyedTemplate = {
149+ key,
150+ createView : this . createNativeViewFactoryFromTemplate ( template ) ,
151+ } ;
152+
153+ this . _templateMap . set ( key , keyedTemplate ) ;
154+ }
155+
165156 @profile
166157 public onItemLoading ( args : GridItemEventData ) {
167158 if ( ! args . view && ! this . itemTemplate ) {
@@ -183,14 +174,14 @@ export class GridViewComponent implements DoCheck, OnDestroy, AfterContentInit,
183174 }
184175
185176 if ( ! viewRef ) {
186- listViewError ( "ViewReference not found for item " + index + ". View recycling is not working" ) ;
177+ gridViewError ( "ViewReference not found for item " + index + ". View recycling is not working" ) ;
187178 }
188179 }
189180
190181 if ( ! viewRef ) {
191182 gridViewLog ( "onItemLoading: " + index + " - Creating view from template" ) ;
192183 viewRef = this . loader . createEmbeddedView ( this . itemTemplate , new GridItemContext ( ) , 0 ) ;
193- args . view = getGridItemRoot ( viewRef ) ;
184+ args . view = getItemViewRoot ( viewRef ) ;
194185 args . view [ NG_VIEW ] = viewRef ;
195186 }
196187
@@ -207,26 +198,41 @@ export class GridViewComponent implements DoCheck, OnDestroy, AfterContentInit,
207198 context . even = ( index % 2 === 0 ) ;
208199 context . odd = ! context . even ;
209200
210- this . setupGridView . next ( {
201+ this . setupItemView . next ( {
211202 context,
212203 data,
213204 index,
214205 view,
215206 } ) ;
216207 }
217208
209+ private createNativeViewFactoryFromTemplate ( template : TemplateRef < GridItemContext > ) {
210+ return ( ) => {
211+ const viewRef = this . loader . createEmbeddedView ( template , new GridItemContext ( ) , 0 ) ;
212+ const resultView = getItemViewRoot ( viewRef ) ;
213+ resultView [ NG_VIEW ] = viewRef ;
214+
215+ return resultView ;
216+ } ;
217+ }
218+
218219 private setItemTemplates ( ) {
219220 // The itemTemplateQuery may be changed after list items are added that contain <template> inside,
220221 // so cache and use only the original template to avoid errors.
221222 this . itemTemplate = this . itemTemplateQuery ;
222223
223- this . gridView . itemTemplate = ( ) => {
224- const viewRef = this . loader . createEmbeddedView ( this . itemTemplate , new GridItemContext ( ) , 0 ) ;
225- const resultView = getGridItemRoot ( viewRef ) ;
226- resultView [ NG_VIEW ] = viewRef ;
224+ if ( this . _templateMap ) {
225+ gridViewLog ( "Setting templates" ) ;
227226
228- return resultView ;
229- } ;
227+ const templates : KeyedTemplate [ ] = [ ] ;
228+ this . _templateMap . forEach ( ( value ) => {
229+ templates . push ( value ) ;
230+ } ) ;
231+ this . gridView . itemTemplates = templates ;
232+ }
233+ else { // If the map was not initialized this means that there are no named templates, so we register the default one.
234+ this . gridView . itemTemplate = this . createNativeViewFactoryFromTemplate ( this . itemTemplate ) ;
235+ }
230236 }
231237
232238 @profile
@@ -250,11 +256,28 @@ export interface ComponentView {
250256
251257export type RootLocator = ( nodes : any [ ] , nestLevel : number ) => View ;
252258
253- export function getGridItemRoot ( viewRef : ComponentView , rootLocator : RootLocator = getSingleViewRecursive ) : View {
259+ export function getItemViewRoot ( viewRef : ComponentView , rootLocator : RootLocator = getSingleViewRecursive ) : View {
254260 const rootView = rootLocator ( viewRef . rootNodes , 0 ) ;
255261 return rootView ;
256262}
257263
264+ @Directive ( { selector : "[gvTemplateKey]" } )
265+ export class TemplateKeyDirective {
266+ constructor (
267+ private templateRef : TemplateRef < any > ,
268+ @Host ( ) private grid : GridViewComponent ,
269+ ) {
270+ }
271+
272+ @Input ( )
273+ set gvTemplateKey ( value : any ) {
274+ gridViewLog ( "gvTemplateKey: " + value ) ;
275+ if ( this . grid && this . templateRef ) {
276+ this . grid . registerTemplate ( value , this . templateRef ) ;
277+ }
278+ }
279+ }
280+
258281if ( ! isKnownView ( "GridView" ) ) {
259282 registerElement ( "GridView" , ( ) => GridView ) ;
260283}
0 commit comments