Skip to content

Commit ceea32d

Browse files
author
vakrilov
committed
Non-recursive detach form native
1 parent 72e7454 commit ceea32d

File tree

1 file changed

+55
-19
lines changed

1 file changed

+55
-19
lines changed

src/nativescript-angular/view_node.ts

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ export class ViewNode {
2424

2525
public nativeView: View;
2626
private _parentView: View;
27+
2728
private _attachedToView: boolean = false;
29+
private _nativeViewCreated: boolean = false;
30+
private _nativeViewAttached: boolean = false;
31+
2832
private attributes: Map<string, any> = new Map<string, any>();
2933
private cssClasses: Map<string, boolean> = new Map<string, boolean>();
3034
private static whiteSpaceSplitter = /\s+/;
@@ -83,7 +87,8 @@ export class ViewNode {
8387

8488
this._attachedToView = true;
8589

86-
this.createUI(atIndex);
90+
this.createUI();
91+
this.attachToNativeParent(atIndex);
8792
this.attachUIEvents();
8893

8994
this.children.forEach(child => {
@@ -93,24 +98,51 @@ export class ViewNode {
9398
this.postAttachUI();
9499
}
95100

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);
98104
return;
105+
}
106+
107+
if (!isKnownView(this.viewName)) {
108+
return;
109+
}
99110

100111
console.log('createUI: ' + this.viewName +
101-
', attachAt: ' + attachAtIndex +
102112
', parent: ' + this.parentNode.viewName +
103113
', parent UI ' + (<any>this.parentNativeView.constructor).name);
104114

105115
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) {
106123
if (!this.nativeView) {
107-
this.nativeView = new viewClass();
108-
} else {
109-
console.log('Reattaching old view: ' + this.viewName);
124+
return;
110125
}
111126

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+
}
113139

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;
114146
if (this.parentNativeView instanceof LayoutBase) {
115147
let parentLayout = <LayoutBase>this.parentNativeView;
116148
if (attachAtIndex != -1) {
@@ -127,8 +159,6 @@ export class ViewNode {
127159
(<ContentView>this.parentNativeView).content = this.nativeView;
128160
} else if ((<any>this.parentNativeView)._addChildFromBuilder) {
129161
(<any>this.parentNativeView)._addChildFromBuilder(this.viewName, this.nativeView);
130-
} else if (this.parentNode.isComplexProperty) {
131-
// complex property - we will deal with this in postAttachUI()
132162
}
133163
else {
134164
console.log('parentNativeView: ' + this.parentNativeView);
@@ -137,9 +167,9 @@ export class ViewNode {
137167
}
138168

139169
private postAttachUI() {
140-
if (this.isComplexProperty) {
170+
if (this.isComplexProperty || !this._nativeViewAttached) {
141171
let nativeParent = <any>this.parentNativeView;
142-
if (!nativeParent) {
172+
if (!this.parentNode || !nativeParent) {
143173
return;
144174
}
145175

@@ -157,6 +187,8 @@ export class ViewNode {
157187
else {
158188
this.parentNode.setAttribute(propertyName, realChildren[0]);
159189
}
190+
191+
this._nativeViewAttached = true;
160192
}
161193
}
162194
}
@@ -261,7 +293,7 @@ export class ViewNode {
261293
return;
262294
}
263295

264-
console.log('ViewNode.attachUIEvents: ' + this.viewName + ' ' + this.eventListeners.size);
296+
// console.log('ViewNode.attachUIEvents: ' + this.viewName + ' ' + this.eventListeners.size);
265297
this.eventListeners.forEach((callback, eventName) => {
266298
this.attachNativeEvent(eventName, callback);
267299
});
@@ -272,7 +304,7 @@ export class ViewNode {
272304
return;
273305
}
274306

275-
console.log('ViewNode.detachUIEvents: ' + this.viewName + ' ' + this.eventListeners.size);
307+
// console.log('ViewNode.detachUIEvents: ' + this.viewName + ' ' + this.eventListeners.size);
276308
this.eventListeners.forEach((callback, eventName) => {
277309
this.detachNativeEvent(eventName, callback);
278310
});
@@ -297,13 +329,13 @@ export class ViewNode {
297329
}
298330

299331
private attachNativeEvent(eventName, callback) {
300-
console.log('attachNativeEvent ' + eventName);
332+
console.log('attachNativeEvent view: ' + this.viewName + ' event: ' + eventName);
301333
let resolvedEvent = this.resolveNativeEvent(eventName);
302334
this.nativeView.addEventListener(resolvedEvent, callback);
303335
}
304336

305337
private detachNativeEvent(eventName, callback) {
306-
console.log('detachNativeEvent ' + eventName);
338+
console.log('detachNativeEvent view: ' + this.viewName + ' event: ' + eventName);
307339
let resolvedEvent = this.resolveNativeEvent(eventName);
308340
this.nativeView.removeEventListener(resolvedEvent, callback);
309341
}
@@ -330,11 +362,11 @@ export class ViewNode {
330362
childNode.detachFromView();
331363
}
332364

333-
public detachFromView(): void {
365+
private detachFromView(detachFromNative: boolean = true): void {
334366
this._attachedToView = false;
335367

336368
this.detachUIEvents();
337-
if (this.nativeView) {
369+
if (detachFromNative && this.nativeView && this._nativeViewAttached) {
338370
let nativeParent = this.nativeView.parent;
339371
if (nativeParent) {
340372
if (nativeParent instanceof LayoutBase) {
@@ -345,11 +377,15 @@ export class ViewNode {
345377
else {
346378
nativeParent._removeView(this.nativeView);
347379
}
380+
381+
// Detach only the first native element
382+
detachFromNative = false;
383+
this._nativeViewAttached = false;
348384
}
349385
}
350386

351387
this.children.forEach((childNode) => {
352-
childNode.detachFromView();
388+
childNode.detachFromView(detachFromNative);
353389
});
354390
}
355391

0 commit comments

Comments
 (0)