Skip to content

Commit

Permalink
fix(module:list): re-enter the Angular zone when the `NgZone.onStable…
Browse files Browse the repository at this point in the history
…` emits (#7314)

The `NgZone.onStable` always emits outside of the Angular zone, but the zone has not been
re-entered. This leads to change detection being called outside of the Angular zone.
  • Loading branch information
arturovt committed Mar 21, 2022
1 parent 2d77bc2 commit 425f8df
Showing 1 changed file with 19 additions and 16 deletions.
35 changes: 19 additions & 16 deletions components/list/list-item-cell.ts
Expand Up @@ -11,14 +11,15 @@ import {
Input,
NgZone,
OnChanges,
OnDestroy,
QueryList,
TemplateRef,
ViewChild
} from '@angular/core';
import { defer, merge, Observable, of, Subject } from 'rxjs';
import { defer, merge, MonoTypeOperatorFunction, Observable, of, Subject } from 'rxjs';
import { switchMap, take, takeUntil } from 'rxjs/operators';

import { NzDestroyService } from 'ng-zorro-antd/core/services';

@Component({
selector: 'nz-list-item-extra, [nz-list-item-extra]',
exportAs: 'nzListItemExtra',
Expand All @@ -28,9 +29,7 @@ import { switchMap, take, takeUntil } from 'rxjs/operators';
class: 'ant-list-item-extra'
}
})
export class NzListItemExtraComponent {
constructor() {}
}
export class NzListItemExtraComponent {}

@Component({
selector: 'nz-list-item-action',
Expand All @@ -40,7 +39,6 @@ export class NzListItemExtraComponent {
})
export class NzListItemActionComponent {
@ViewChild(TemplateRef) templateRef?: TemplateRef<void>;
constructor() {}
}

@Component({
Expand All @@ -55,44 +53,49 @@ export class NzListItemActionComponent {
`,
host: {
class: 'ant-list-item-action'
}
},
providers: [NzDestroyService]
})
export class NzListItemActionsComponent implements OnChanges, OnDestroy {
export class NzListItemActionsComponent implements OnChanges {
@Input() nzActions: Array<TemplateRef<void>> = [];
@ContentChildren(NzListItemActionComponent) nzListItemActions!: QueryList<NzListItemActionComponent>;

actions: Array<TemplateRef<void>> = [];
private destroy$ = new Subject();
private inputActionChanges$ = new Subject<null>();
private contentChildrenChanges$: Observable<null> = defer(() => {
if (this.nzListItemActions) {
return of(null);
}
return this.ngZone.onStable.asObservable().pipe(
return this.ngZone.onStable.pipe(
take(1),
this.enterZone(),
switchMap(() => this.contentChildrenChanges$)
);
});

constructor(private ngZone: NgZone, private cdr: ChangeDetectorRef) {
constructor(private ngZone: NgZone, cdr: ChangeDetectorRef, destroy$: NzDestroyService) {
merge(this.contentChildrenChanges$, this.inputActionChanges$)
.pipe(takeUntil(this.destroy$))
.pipe(takeUntil(destroy$))
.subscribe(() => {
if (this.nzActions.length) {
this.actions = this.nzActions;
} else {
this.actions = this.nzListItemActions.map(action => action.templateRef!);
}
this.cdr.detectChanges();
cdr.detectChanges();
});
}

ngOnChanges(): void {
this.inputActionChanges$.next(null);
}

ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
private enterZone<T>(): MonoTypeOperatorFunction<T> {
return (source: Observable<T>) =>
new Observable<T>(observer =>
source.subscribe({
next: value => this.ngZone.run(() => observer.next(value))
})
);
}
}

0 comments on commit 425f8df

Please sign in to comment.