diff --git a/components/rate/rate.component.ts b/components/rate/rate.component.ts index 967f757136..0964b44864 100644 --- a/components/rate/rate.component.ts +++ b/components/rate/rate.component.ts @@ -13,8 +13,8 @@ import { EventEmitter, forwardRef, Input, + NgZone, OnChanges, - OnDestroy, OnInit, Optional, Output, @@ -25,10 +25,11 @@ import { ViewEncapsulation } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { Subject } from 'rxjs'; +import { fromEvent } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; +import { NzDestroyService } from 'ng-zorro-antd/core/services'; import { BooleanInput, NgClassType, NumberInput } from 'ng-zorro-antd/core/types'; import { InputBoolean, InputNumber } from 'ng-zorro-antd/core/util'; @@ -47,8 +48,6 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'rate'; [class.ant-rate-disabled]="nzDisabled" [class.ant-rate-rtl]="dir === 'rtl'" [ngClass]="classMap" - (blur)="onBlur($event)" - (focus)="onFocus($event)" (keydown)="onKeyDown($event); $event.preventDefault()" (mouseleave)="onRateLeave(); $event.stopPropagation()" [tabindex]="nzDisabled ? -1 : 1" @@ -72,6 +71,7 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'rate'; `, providers: [ + NzDestroyService, { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NzRateComponent), @@ -79,7 +79,7 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'rate'; } ] }) -export class NzRateComponent implements OnInit, OnDestroy, ControlValueAccessor, OnChanges { +export class NzRateComponent implements OnInit, ControlValueAccessor, OnChanges { readonly _nzModuleName: NzConfigKey = NZ_CONFIG_MODULE_NAME; static ngAcceptInputType_nzAllowClear: BooleanInput; @@ -88,7 +88,7 @@ export class NzRateComponent implements OnInit, OnDestroy, ControlValueAccessor, static ngAcceptInputType_nzAutoFocus: BooleanInput; static ngAcceptInputType_nzCount: NumberInput; - @ViewChild('ulElement', { static: false }) private ulElement?: ElementRef; + @ViewChild('ulElement', { static: true }) ulElement!: ElementRef; @Input() @WithConfig() @InputBoolean() nzAllowClear: boolean = true; @Input() @WithConfig() @InputBoolean() nzAllowHalf: boolean = false; @@ -107,7 +107,6 @@ export class NzRateComponent implements OnInit, OnDestroy, ControlValueAccessor, starStyleArray: NgClassType[] = []; dir: Direction = 'ltr'; - private readonly destroy$ = new Subject(); private hasHalf = false; private hoverValue = 0; private isFocused = false; @@ -129,16 +128,18 @@ export class NzRateComponent implements OnInit, OnDestroy, ControlValueAccessor, constructor( public nzConfigService: NzConfigService, + private ngZone: NgZone, private renderer: Renderer2, private cdr: ChangeDetectorRef, - @Optional() private directionality: Directionality + @Optional() private directionality: Directionality, + private destroy$: NzDestroyService ) {} ngOnChanges(changes: SimpleChanges): void { const { nzAutoFocus, nzCount, nzValue } = changes; if (nzAutoFocus && !nzAutoFocus.isFirstChange()) { - const el = this.ulElement!.nativeElement; + const el = this.ulElement.nativeElement; if (this.nzAutoFocus && !this.nzDisabled) { this.renderer.setAttribute(el, 'autofocus', 'autofocus'); } else { @@ -161,17 +162,32 @@ export class NzRateComponent implements OnInit, OnDestroy, ControlValueAccessor, .pipe(takeUntil(this.destroy$)) .subscribe(() => this.cdr.markForCheck()); - this.directionality.change?.pipe(takeUntil(this.destroy$)).subscribe((direction: Direction) => { + this.directionality.change.pipe(takeUntil(this.destroy$)).subscribe((direction: Direction) => { this.dir = direction; this.cdr.detectChanges(); }); this.dir = this.directionality.value; - } - ngOnDestroy(): void { - this.destroy$.next(); - this.destroy$.complete(); + this.ngZone.runOutsideAngular(() => { + fromEvent(this.ulElement.nativeElement, 'focus') + .pipe(takeUntil(this.destroy$)) + .subscribe(event => { + this.isFocused = true; + if (this.nzOnFocus.observers.length) { + this.ngZone.run(() => this.nzOnFocus.emit(event)); + } + }); + + fromEvent(this.ulElement.nativeElement, 'blur') + .pipe(takeUntil(this.destroy$)) + .subscribe(event => { + this.isFocused = false; + if (this.nzOnBlur.observers.length) { + this.ngZone.run(() => this.nzOnBlur.emit(event)); + } + }); + }); } onItemClick(index: number, isHalf: boolean): void { @@ -215,22 +231,12 @@ export class NzRateComponent implements OnInit, OnDestroy, ControlValueAccessor, this.updateStarStyle(); } - onFocus(e: FocusEvent): void { - this.isFocused = true; - this.nzOnFocus.emit(e); - } - - onBlur(e: FocusEvent): void { - this.isFocused = false; - this.nzOnBlur.emit(e); - } - focus(): void { - this.ulElement!.nativeElement.focus(); + this.ulElement.nativeElement.focus(); } blur(): void { - this.ulElement!.nativeElement.blur(); + this.ulElement.nativeElement.blur(); } onKeyDown(e: KeyboardEvent): void {