@@ -24,7 +24,11 @@ export class ViewNode {
24
24
25
25
public nativeView : View ;
26
26
private _parentView : View ;
27
+
27
28
private _attachedToView : boolean = false ;
29
+ private _nativeViewCreated : boolean = false ;
30
+ private _nativeViewAttached : boolean = false ;
31
+
28
32
private attributes : Map < string , any > = new Map < string , any > ( ) ;
29
33
private cssClasses : Map < string , boolean > = new Map < string , boolean > ( ) ;
30
34
private static whiteSpaceSplitter = / \s + / ;
@@ -83,7 +87,8 @@ export class ViewNode {
83
87
84
88
this . _attachedToView = true ;
85
89
86
- this . createUI ( atIndex ) ;
90
+ this . createUI ( ) ;
91
+ this . attachToNativeParent ( atIndex ) ;
87
92
this . attachUIEvents ( ) ;
88
93
89
94
this . children . forEach ( child => {
@@ -93,24 +98,51 @@ export class ViewNode {
93
98
this . postAttachUI ( ) ;
94
99
}
95
100
96
- private createUI ( attachAtIndex : number ) : boolean {
97
- if ( ! isKnownView ( this . viewName ) )
101
+ private createUI ( ) {
102
+ if ( this . _nativeViewCreated ) {
103
+ console . log ( "Reattaching old view: " + this . viewName ) ;
98
104
return ;
105
+ }
106
+
107
+ if ( ! isKnownView ( this . viewName ) ) {
108
+ return ;
109
+ }
99
110
100
111
console . log ( 'createUI: ' + this . viewName +
101
- ', attachAt: ' + attachAtIndex +
102
112
', parent: ' + this . parentNode . viewName +
103
113
', parent UI ' + ( < any > this . parentNativeView . constructor ) . name ) ;
104
114
105
115
let viewClass = getViewClass ( this . viewName ) ;
116
+ this . nativeView = new viewClass ( ) ;
117
+ this . configureUI ( ) ;
118
+
119
+ this . _nativeViewCreated = true ;
120
+ }
121
+
122
+ private attachToNativeParent ( attachAtIndex : number ) {
106
123
if ( ! this . nativeView ) {
107
- this . nativeView = new viewClass ( ) ;
108
- } else {
109
- console . log ( 'Reattaching old view: ' + this . viewName ) ;
124
+ return ;
110
125
}
111
126
112
- this . configureUI ( ) ;
127
+ if ( this . _nativeViewAttached ) {
128
+ console . log ( "View already attached to native: " + this . viewName ) ;
129
+ return ;
130
+ }
131
+
132
+ if ( this . parentNode . isComplexProperty ) {
133
+ // complex property - we will deal with this in postAttachUI()
134
+ console . log ( 'attachToNativeParent SKIP attach becaus parent is complex property: ' + this . viewName +
135
+ ', attachAt: ' + attachAtIndex +
136
+ ', parent: ' + this . parentNode . viewName ) ;
137
+ return ;
138
+ }
113
139
140
+ console . log ( 'attachToNativeParent: ' + this . viewName +
141
+ ', attachAt: ' + attachAtIndex +
142
+ ', parent: ' + this . parentNode . viewName +
143
+ ', parent UI ' + ( < any > this . parentNativeView . constructor ) . name ) ;
144
+
145
+ this . _nativeViewAttached = true ;
114
146
if ( this . parentNativeView instanceof LayoutBase ) {
115
147
let parentLayout = < LayoutBase > this . parentNativeView ;
116
148
if ( attachAtIndex != - 1 ) {
@@ -127,8 +159,6 @@ export class ViewNode {
127
159
( < ContentView > this . parentNativeView ) . content = this . nativeView ;
128
160
} else if ( ( < any > this . parentNativeView ) . _addChildFromBuilder ) {
129
161
( < any > this . parentNativeView ) . _addChildFromBuilder ( this . viewName , this . nativeView ) ;
130
- } else if ( this . parentNode . isComplexProperty ) {
131
- // complex property - we will deal with this in postAttachUI()
132
162
}
133
163
else {
134
164
console . log ( 'parentNativeView: ' + this . parentNativeView ) ;
@@ -137,9 +167,9 @@ export class ViewNode {
137
167
}
138
168
139
169
private postAttachUI ( ) {
140
- if ( this . isComplexProperty ) {
170
+ if ( this . isComplexProperty || ! this . _nativeViewAttached ) {
141
171
let nativeParent = < any > this . parentNativeView ;
142
- if ( ! nativeParent ) {
172
+ if ( ! this . parentNode || ! nativeParent ) {
143
173
return ;
144
174
}
145
175
@@ -157,6 +187,8 @@ export class ViewNode {
157
187
else {
158
188
this . parentNode . setAttribute ( propertyName , realChildren [ 0 ] ) ;
159
189
}
190
+
191
+ this . _nativeViewAttached = true ;
160
192
}
161
193
}
162
194
}
@@ -261,7 +293,7 @@ export class ViewNode {
261
293
return ;
262
294
}
263
295
264
- console . log ( 'ViewNode.attachUIEvents: ' + this . viewName + ' ' + this . eventListeners . size ) ;
296
+ // console.log('ViewNode.attachUIEvents: ' + this.viewName + ' ' + this.eventListeners.size);
265
297
this . eventListeners . forEach ( ( callback , eventName ) => {
266
298
this . attachNativeEvent ( eventName , callback ) ;
267
299
} ) ;
@@ -272,7 +304,7 @@ export class ViewNode {
272
304
return ;
273
305
}
274
306
275
- console . log ( 'ViewNode.detachUIEvents: ' + this . viewName + ' ' + this . eventListeners . size ) ;
307
+ // console.log('ViewNode.detachUIEvents: ' + this.viewName + ' ' + this.eventListeners.size);
276
308
this . eventListeners . forEach ( ( callback , eventName ) => {
277
309
this . detachNativeEvent ( eventName , callback ) ;
278
310
} ) ;
@@ -297,13 +329,13 @@ export class ViewNode {
297
329
}
298
330
299
331
private attachNativeEvent ( eventName , callback ) {
300
- console . log ( 'attachNativeEvent ' + eventName ) ;
332
+ console . log ( 'attachNativeEvent view: ' + this . viewName + ' event: ' + eventName ) ;
301
333
let resolvedEvent = this . resolveNativeEvent ( eventName ) ;
302
334
this . nativeView . addEventListener ( resolvedEvent , callback ) ;
303
335
}
304
336
305
337
private detachNativeEvent ( eventName , callback ) {
306
- console . log ( 'detachNativeEvent ' + eventName ) ;
338
+ console . log ( 'detachNativeEvent view: ' + this . viewName + ' event: ' + eventName ) ;
307
339
let resolvedEvent = this . resolveNativeEvent ( eventName ) ;
308
340
this . nativeView . removeEventListener ( resolvedEvent , callback ) ;
309
341
}
@@ -330,11 +362,11 @@ export class ViewNode {
330
362
childNode . detachFromView ( ) ;
331
363
}
332
364
333
- public detachFromView ( ) : void {
365
+ private detachFromView ( detachFromNative : boolean = true ) : void {
334
366
this . _attachedToView = false ;
335
367
336
368
this . detachUIEvents ( ) ;
337
- if ( this . nativeView ) {
369
+ if ( detachFromNative && this . nativeView && this . _nativeViewAttached ) {
338
370
let nativeParent = this . nativeView . parent ;
339
371
if ( nativeParent ) {
340
372
if ( nativeParent instanceof LayoutBase ) {
@@ -345,11 +377,15 @@ export class ViewNode {
345
377
else {
346
378
nativeParent . _removeView ( this . nativeView ) ;
347
379
}
380
+
381
+ // Detach only the first native element
382
+ detachFromNative = false ;
383
+ this . _nativeViewAttached = false ;
348
384
}
349
385
}
350
386
351
387
this . children . forEach ( ( childNode ) => {
352
- childNode . detachFromView ( ) ;
388
+ childNode . detachFromView ( detachFromNative ) ;
353
389
} ) ;
354
390
}
355
391
0 commit comments