Skip to content

Commit

Permalink
fix(list-view): fix crash when used with ngFor (#2121)
Browse files Browse the repository at this point in the history
  • Loading branch information
edusperoni committed Sep 4, 2020
1 parent 548e074 commit 302afb3
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 22 deletions.
34 changes: 19 additions & 15 deletions nativescript-angular/directives/dialogs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ComponentFactoryResolver, ComponentRef, Injectable, Injector, NgModuleRef, Type, ViewContainerRef } from '@angular/core';
import { ComponentFactoryResolver, ComponentRef, Injectable, Injector, NgModuleRef, NgZone, Type, ViewContainerRef } from '@angular/core';
import { Frame, View, ViewBase, ProxyViewContainer, ShowModalOptions } from '@nativescript/core';

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

@Injectable()
export class ModalDialogService {
constructor(private location: NSLocationStrategy) {}
constructor(private location: NSLocationStrategy, private zone: NgZone) {}

public showModal(type: Type<any>, options: ModalDialogOptions): Promise<any> {
if (!options.viewContainerRef) {
Expand Down Expand Up @@ -98,8 +98,10 @@ export class ModalDialogService {
if (componentView) {
componentView.closeModal();
this.location._closeModalNavigation();
detachedLoaderRef.instance.detectChanges();
detachedLoaderRef.destroy();
this.zone.run(() => {
detachedLoaderRef.instance.detectChanges();
detachedLoaderRef.destroy();
});
}
});

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

if (detachedProxy.getChildrenCount() > 1) {
throw new Error('Modal content has more than one root view.');
}
componentView = detachedProxy.getChildAt(0);
if (detachedProxy.getChildrenCount() > 1) {
throw new Error('Modal content has more than one root view.');
}
componentView = detachedProxy.getChildAt(0);

if (componentView.parent) {
(<any>componentView.parent)._ngDialogRoot = componentView;
(<any>componentView.parent).removeChild(componentView);
}
if (componentView.parent) {
(<any>componentView.parent)._ngDialogRoot = componentView;
(<any>componentView.parent).removeChild(componentView);
}

options.parentView.showModal(componentView, { ...options, closeCallback });
options.parentView.showModal(componentView, { ...options, closeCallback });
});
});
}
}
6 changes: 3 additions & 3 deletions nativescript-angular/directives/list-view-comp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, ElementRef, IterableDiffers, forwardRef } from '@angular/core';
import { ChangeDetectionStrategy, Component, ElementRef, IterableDiffers, forwardRef, NgZone } from '@angular/core';
import { ListView } from '@nativescript/core';
import { TEMPLATED_ITEMS_COMPONENT, TemplatedItemsComponent } from './templated-items-comp';

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

protected templatedItemsView: ListView;

constructor(_elementRef: ElementRef, _iterableDiffers: IterableDiffers) {
super(_elementRef, _iterableDiffers);
constructor(_elementRef: ElementRef, _iterableDiffers: IterableDiffers, zone: NgZone) {
super(_elementRef, _iterableDiffers, zone);
}
}
10 changes: 6 additions & 4 deletions nativescript-angular/directives/templated-items-comp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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';
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';
import { ObservableArray, View, KeyedTemplate, LayoutBase, ItemEventData, TemplatedItemsView, profile } from '@nativescript/core';

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

constructor(_elementRef: ElementRef, private _iterableDiffers: IterableDiffers) {
constructor(_elementRef: ElementRef, private _iterableDiffers: IterableDiffers, private zone: NgZone) {
this.templatedItemsView = _elementRef.nativeElement;

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

viewRef.markForCheck();
viewRef.detectChanges();
this.zone.run(() => {
viewRef.markForCheck();
viewRef.detectChanges();
});
}

ngDoCheck() {
Expand Down

0 comments on commit 302afb3

Please sign in to comment.