Skip to content

Commit 425f8df

Browse files
authored
fix(module:list): re-enter the Angular zone when the NgZone.onStable 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.
1 parent 2d77bc2 commit 425f8df

1 file changed

Lines changed: 19 additions & 16 deletions

File tree

components/list/list-item-cell.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ import {
1111
Input,
1212
NgZone,
1313
OnChanges,
14-
OnDestroy,
1514
QueryList,
1615
TemplateRef,
1716
ViewChild
1817
} from '@angular/core';
19-
import { defer, merge, Observable, of, Subject } from 'rxjs';
18+
import { defer, merge, MonoTypeOperatorFunction, Observable, of, Subject } from 'rxjs';
2019
import { switchMap, take, takeUntil } from 'rxjs/operators';
2120

21+
import { NzDestroyService } from 'ng-zorro-antd/core/services';
22+
2223
@Component({
2324
selector: 'nz-list-item-extra, [nz-list-item-extra]',
2425
exportAs: 'nzListItemExtra',
@@ -28,9 +29,7 @@ import { switchMap, take, takeUntil } from 'rxjs/operators';
2829
class: 'ant-list-item-extra'
2930
}
3031
})
31-
export class NzListItemExtraComponent {
32-
constructor() {}
33-
}
32+
export class NzListItemExtraComponent {}
3433

3534
@Component({
3635
selector: 'nz-list-item-action',
@@ -40,7 +39,6 @@ export class NzListItemExtraComponent {
4039
})
4140
export class NzListItemActionComponent {
4241
@ViewChild(TemplateRef) templateRef?: TemplateRef<void>;
43-
constructor() {}
4442
}
4543

4644
@Component({
@@ -55,44 +53,49 @@ export class NzListItemActionComponent {
5553
`,
5654
host: {
5755
class: 'ant-list-item-action'
58-
}
56+
},
57+
providers: [NzDestroyService]
5958
})
60-
export class NzListItemActionsComponent implements OnChanges, OnDestroy {
59+
export class NzListItemActionsComponent implements OnChanges {
6160
@Input() nzActions: Array<TemplateRef<void>> = [];
6261
@ContentChildren(NzListItemActionComponent) nzListItemActions!: QueryList<NzListItemActionComponent>;
6362

6463
actions: Array<TemplateRef<void>> = [];
65-
private destroy$ = new Subject();
6664
private inputActionChanges$ = new Subject<null>();
6765
private contentChildrenChanges$: Observable<null> = defer(() => {
6866
if (this.nzListItemActions) {
6967
return of(null);
7068
}
71-
return this.ngZone.onStable.asObservable().pipe(
69+
return this.ngZone.onStable.pipe(
7270
take(1),
71+
this.enterZone(),
7372
switchMap(() => this.contentChildrenChanges$)
7473
);
7574
});
7675

77-
constructor(private ngZone: NgZone, private cdr: ChangeDetectorRef) {
76+
constructor(private ngZone: NgZone, cdr: ChangeDetectorRef, destroy$: NzDestroyService) {
7877
merge(this.contentChildrenChanges$, this.inputActionChanges$)
79-
.pipe(takeUntil(this.destroy$))
78+
.pipe(takeUntil(destroy$))
8079
.subscribe(() => {
8180
if (this.nzActions.length) {
8281
this.actions = this.nzActions;
8382
} else {
8483
this.actions = this.nzListItemActions.map(action => action.templateRef!);
8584
}
86-
this.cdr.detectChanges();
85+
cdr.detectChanges();
8786
});
8887
}
8988

9089
ngOnChanges(): void {
9190
this.inputActionChanges$.next(null);
9291
}
9392

94-
ngOnDestroy(): void {
95-
this.destroy$.next();
96-
this.destroy$.complete();
93+
private enterZone<T>(): MonoTypeOperatorFunction<T> {
94+
return (source: Observable<T>) =>
95+
new Observable<T>(observer =>
96+
source.subscribe({
97+
next: value => this.ngZone.run(() => observer.next(value))
98+
})
99+
);
97100
}
98101
}

0 commit comments

Comments
 (0)