Skip to content

Commit 302afb3

Browse files
authored
fix(list-view): fix crash when used with ngFor (#2121)
1 parent 548e074 commit 302afb3

File tree

3 files changed

+28
-22
lines changed

3 files changed

+28
-22
lines changed

Diff for: nativescript-angular/directives/dialogs.ts

+19-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ComponentFactoryResolver, ComponentRef, Injectable, Injector, NgModuleRef, Type, ViewContainerRef } from '@angular/core';
1+
import { ComponentFactoryResolver, ComponentRef, Injectable, Injector, NgModuleRef, NgZone, Type, ViewContainerRef } from '@angular/core';
22
import { Frame, View, ViewBase, ProxyViewContainer, ShowModalOptions } from '@nativescript/core';
33

44
import { NSLocationStrategy } from '../router/ns-location-strategy';
@@ -32,7 +32,7 @@ export class ModalDialogParams {
3232

3333
@Injectable()
3434
export class ModalDialogService {
35-
constructor(private location: NSLocationStrategy) {}
35+
constructor(private location: NSLocationStrategy, private zone: NgZone) {}
3636

3737
public showModal(type: Type<any>, options: ModalDialogOptions): Promise<any> {
3838
if (!options.viewContainerRef) {
@@ -98,8 +98,10 @@ export class ModalDialogService {
9898
if (componentView) {
9999
componentView.closeModal();
100100
this.location._closeModalNavigation();
101-
detachedLoaderRef.instance.detectChanges();
102-
detachedLoaderRef.destroy();
101+
this.zone.run(() => {
102+
detachedLoaderRef.instance.detectChanges();
103+
detachedLoaderRef.destroy();
104+
});
103105
}
104106
});
105107

@@ -111,20 +113,22 @@ export class ModalDialogService {
111113
});
112114
const detachedFactory = options.resolver.resolveComponentFactory(DetachedLoader);
113115
detachedLoaderRef = options.containerRef.createComponent(detachedFactory, 0, childInjector, null);
114-
detachedLoaderRef.instance.loadComponent(options.type).then((compRef) => {
115-
const detachedProxy = <ProxyViewContainer>compRef.location.nativeElement;
116+
this.zone.run(() => {
117+
detachedLoaderRef.instance.loadComponent(options.type).then((compRef) => {
118+
const detachedProxy = <ProxyViewContainer>compRef.location.nativeElement;
116119

117-
if (detachedProxy.getChildrenCount() > 1) {
118-
throw new Error('Modal content has more than one root view.');
119-
}
120-
componentView = detachedProxy.getChildAt(0);
120+
if (detachedProxy.getChildrenCount() > 1) {
121+
throw new Error('Modal content has more than one root view.');
122+
}
123+
componentView = detachedProxy.getChildAt(0);
121124

122-
if (componentView.parent) {
123-
(<any>componentView.parent)._ngDialogRoot = componentView;
124-
(<any>componentView.parent).removeChild(componentView);
125-
}
125+
if (componentView.parent) {
126+
(<any>componentView.parent)._ngDialogRoot = componentView;
127+
(<any>componentView.parent).removeChild(componentView);
128+
}
126129

127-
options.parentView.showModal(componentView, { ...options, closeCallback });
130+
options.parentView.showModal(componentView, { ...options, closeCallback });
131+
});
128132
});
129133
}
130134
}

Diff for: nativescript-angular/directives/list-view-comp.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ChangeDetectionStrategy, Component, ElementRef, IterableDiffers, forwardRef } from '@angular/core';
1+
import { ChangeDetectionStrategy, Component, ElementRef, IterableDiffers, forwardRef, NgZone } from '@angular/core';
22
import { ListView } from '@nativescript/core';
33
import { TEMPLATED_ITEMS_COMPONENT, TemplatedItemsComponent } from './templated-items-comp';
44

@@ -17,7 +17,7 @@ export class ListViewComponent extends TemplatedItemsComponent {
1717

1818
protected templatedItemsView: ListView;
1919

20-
constructor(_elementRef: ElementRef, _iterableDiffers: IterableDiffers) {
21-
super(_elementRef, _iterableDiffers);
20+
constructor(_elementRef: ElementRef, _iterableDiffers: IterableDiffers, zone: NgZone) {
21+
super(_elementRef, _iterableDiffers, zone);
2222
}
2323
}

Diff for: nativescript-angular/directives/templated-items-comp.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AfterContentInit, ContentChild, Directive, DoCheck, ElementRef, EmbeddedViewRef, EventEmitter, Host, Inject, InjectionToken, Input, IterableDiffer, IterableDiffers, OnDestroy, Output, TemplateRef, ViewChild, ViewContainerRef, ɵisListLikeIterable as isListLikeIterable, Injectable } from '@angular/core';
1+
import { AfterContentInit, ContentChild, Directive, DoCheck, ElementRef, EmbeddedViewRef, EventEmitter, Host, Inject, InjectionToken, Input, IterableDiffer, IterableDiffers, OnDestroy, Output, TemplateRef, ViewChild, ViewContainerRef, ɵisListLikeIterable as isListLikeIterable, Injectable, NgZone } from '@angular/core';
22
import { ObservableArray, View, KeyedTemplate, LayoutBase, ItemEventData, TemplatedItemsView, profile } from '@nativescript/core';
33

44
import { getSingleViewRecursive } from '../element-registry';
@@ -54,7 +54,7 @@ export abstract class TemplatedItemsComponent implements DoCheck, OnDestroy, Aft
5454
this.templatedItemsView.items = this._items;
5555
}
5656

57-
constructor(_elementRef: ElementRef, private _iterableDiffers: IterableDiffers) {
57+
constructor(_elementRef: ElementRef, private _iterableDiffers: IterableDiffers, private zone: NgZone) {
5858
this.templatedItemsView = _elementRef.nativeElement;
5959

6060
this.templatedItemsView.on('itemLoading', this.onItemLoading, this);
@@ -188,8 +188,10 @@ export abstract class TemplatedItemsComponent implements DoCheck, OnDestroy, Aft
188188
NativeScriptDebug.listViewLog(`Manually detect changes in child: ${index}`);
189189
}
190190

191-
viewRef.markForCheck();
192-
viewRef.detectChanges();
191+
this.zone.run(() => {
192+
viewRef.markForCheck();
193+
viewRef.detectChanges();
194+
});
193195
}
194196

195197
ngDoCheck() {

0 commit comments

Comments
 (0)