Skip to content

Commit 24bb1bc

Browse files
authored
fix(module:autocomplete): remove NgZone dependency (#8462)
This commit eliminates the `NgZone` dependency from the autocomplete component. Since zone.js is becoming optional, `onStable` won't emit any value when `provideZonelessChangeDetection` is used in the application config. Instead, we now use the alternative approach provided by `afterNextRender`. Most of the code that was using `onStable` should be replaced with `afterNextRender`.
1 parent 025df9c commit 24bb1bc

File tree

6 files changed

+69
-20
lines changed

6 files changed

+69
-20
lines changed

components/auto-complete/autocomplete.component.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
EventEmitter,
1818
Host,
1919
Input,
20-
NgZone,
2120
OnChanges,
2221
OnDestroy,
2322
OnInit,
@@ -28,13 +27,15 @@ import {
2827
TemplateRef,
2928
ViewChild,
3029
ViewChildren,
31-
ViewEncapsulation
30+
ViewEncapsulation,
31+
inject
3232
} from '@angular/core';
3333
import { defer, merge, Observable, Subject, Subscription } from 'rxjs';
34-
import { filter, switchMap, take, takeUntil } from 'rxjs/operators';
34+
import { filter, switchMap, takeUntil } from 'rxjs/operators';
3535

3636
import { slideMotion } from 'ng-zorro-antd/core/animation';
3737
import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation';
38+
import { NZ_AFTER_NEXT_RENDER$ } from 'ng-zorro-antd/core/render';
3839
import { BooleanInput, CompareWith, NzSafeAny } from 'ng-zorro-antd/core/types';
3940
import { InputBoolean } from 'ng-zorro-antd/core/util';
4041

@@ -149,29 +150,28 @@ export class NzAutocompleteComponent implements AfterContentInit, AfterViewInit,
149150
private selectionChangeSubscription: Subscription | null = Subscription.EMPTY;
150151
private optionMouseEnterSubscription: Subscription | null = Subscription.EMPTY;
151152
private dataSourceChangeSubscription: Subscription | null = Subscription.EMPTY;
153+
152154
/** Options changes listener */
153-
readonly optionSelectionChanges: Observable<NzOptionSelectionChange> = defer(() => {
155+
private readonly optionSelectionChanges: Observable<NzOptionSelectionChange> = defer(() => {
154156
if (this.options) {
155157
return merge<NzOptionSelectionChange[]>(...this.options.map(option => option.selectionChange));
156158
}
157-
return this.ngZone.onStable.asObservable().pipe(
158-
take(1),
159-
switchMap(() => this.optionSelectionChanges)
160-
);
159+
160+
return this.afterNextRender$.pipe(switchMap(() => this.optionSelectionChanges));
161161
});
162-
readonly optionMouseEnter: Observable<NzAutocompleteOptionComponent> = defer(() => {
162+
163+
private readonly optionMouseEnter: Observable<NzAutocompleteOptionComponent> = defer(() => {
163164
if (this.options) {
164165
return merge<NzAutocompleteOptionComponent[]>(...this.options.map(option => option.mouseEntered));
165166
}
166-
return this.ngZone.onStable.asObservable().pipe(
167-
take(1),
168-
switchMap(() => this.optionMouseEnter)
169-
);
167+
168+
return this.afterNextRender$.pipe(switchMap(() => this.optionMouseEnter));
170169
});
171170

171+
private afterNextRender$ = inject(NZ_AFTER_NEXT_RENDER$);
172+
172173
constructor(
173174
private changeDetectorRef: ChangeDetectorRef,
174-
private ngZone: NgZone,
175175
@Optional() private directionality: Directionality,
176176
@Host() @Optional() public noAnimation?: NzNoAnimationDirective
177177
) {}

components/auto-complete/autocomplete.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -630,9 +630,9 @@ describe('auto-complete', () => {
630630

631631
let options = overlayContainerElement.querySelectorAll('nz-auto-option') as NodeListOf<HTMLElement>;
632632
options[0].click();
633-
fixture.detectChanges();
634-
zone.simulateZoneExit();
635-
fixture.detectChanges();
633+
634+
// `tick()` will handle over after next render hooks.
635+
TestBed.inject(ApplicationRef).tick();
636636

637637
const componentOptions = fixture.componentInstance.optionComponents.toArray();
638638
expect(componentOptions[0].selected).toBe(true);
@@ -655,9 +655,9 @@ describe('auto-complete', () => {
655655

656656
let options = overlayContainerElement.querySelectorAll('nz-auto-option') as NodeListOf<HTMLElement>;
657657
options[0].click();
658-
fixture.detectChanges();
659-
zone.simulateZoneExit();
660-
fixture.detectChanges();
658+
659+
// `tick()` will handle over after next render hooks.
660+
TestBed.inject(ApplicationRef).tick();
661661

662662
const componentOptions = fixture.componentInstance.optionComponents.toArray();
663663
expect(componentOptions[0].selected).toBe(true);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Use of this source code is governed by an MIT-style license that can be
3+
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
4+
*/
5+
6+
import { InjectionToken, Injector, afterNextRender, inject } from '@angular/core';
7+
import { Observable } from 'rxjs';
8+
9+
/**
10+
* An injection token representing `afterNextRender` as an observable rather
11+
* than a callback-based API has been added. This might be necessary in code
12+
* where streams of data are already being used and we need to wait until
13+
* the change detection ends before performing any tasks.
14+
*/
15+
export const NZ_AFTER_NEXT_RENDER$ = new InjectionToken<Observable<void>>('nz-after-next-render', {
16+
providedIn: 'root',
17+
factory: () => {
18+
const injector = inject(Injector);
19+
20+
return new Observable<void>(subscriber => {
21+
const ref = afterNextRender(
22+
() => {
23+
subscriber.next();
24+
subscriber.complete();
25+
},
26+
{ injector }
27+
);
28+
29+
return () => ref.destroy();
30+
});
31+
}
32+
});

components/core/render/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Use of this source code is governed by an MIT-style license that can be
3+
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
4+
*/
5+
6+
export * from './public-api';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"lib": {
3+
"entryFile": "public-api.ts"
4+
}
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Use of this source code is governed by an MIT-style license that can be
3+
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
4+
*/
5+
6+
export * from './after-next-render';

0 commit comments

Comments
 (0)