Browse Source

Refactor to use Angular's new output() event API

Replaces all usages of EventEmitter and @Output with the new output() API across multiple components and directives. This modernizes event handling to align with Angular's latest best practices and improves code consistency.
pull/24766/head
Fahri Gedik 8 months ago
parent
commit
956773d7c3
  1. 11
      npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts
  2. 4
      npm/ng-packs/packages/core/src/lib/directives/caps-lock.directive.ts
  3. 4
      npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts
  4. 19
      npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts
  5. 4
      npm/ng-packs/packages/core/src/lib/directives/init.directive.ts
  6. 4
      npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts
  7. 4
      npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts
  8. 5
      npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts
  9. 21
      npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts
  10. 10
      npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts
  11. 10
      npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts
  12. 4
      npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.ts

11
npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts

@ -5,20 +5,19 @@ import {
Component, Component,
computed, computed,
ContentChild, ContentChild,
EventEmitter,
inject, inject,
Injector, Injector,
Input, Input,
LOCALE_ID, LOCALE_ID,
OnChanges, OnChanges,
OnDestroy, OnDestroy,
Output,
PLATFORM_ID, PLATFORM_ID,
signal, signal,
SimpleChanges, SimpleChanges,
TemplateRef, TemplateRef,
TrackByFunction, TrackByFunction,
ViewChild, ViewChild,
output
} from '@angular/core'; } from '@angular/core';
import { AsyncPipe, isPlatformBrowser, NgComponentOutlet, NgTemplateOutlet } from '@angular/common'; import { AsyncPipe, isPlatformBrowser, NgComponentOutlet, NgTemplateOutlet } from '@angular/common';
@ -118,7 +117,7 @@ export class ExtensibleTableComponent<R = any> implements OnChanges, AfterViewIn
@Input() actionsTemplate?: TemplateRef<any>; @Input() actionsTemplate?: TemplateRef<any>;
@Output() tableActivate = new EventEmitter(); readonly tableActivate = output();
@Input() selectable = false; @Input() selectable = false;
@ -128,18 +127,18 @@ export class ExtensibleTableComponent<R = any> implements OnChanges, AfterViewIn
_selectionType: SelectionType = SelectionType.multiClick; _selectionType: SelectionType = SelectionType.multiClick;
@Input() selected: any[] = []; @Input() selected: any[] = [];
@Output() selectionChange = new EventEmitter<any[]>(); readonly selectionChange = output<any[]>();
// Infinite scroll configuration // Infinite scroll configuration
@Input() infiniteScroll = false; @Input() infiniteScroll = false;
@Input() isLoading = false; @Input() isLoading = false;
@Input() scrollThreshold = 10; @Input() scrollThreshold = 10;
@Output() loadMore = new EventEmitter<void>(); readonly loadMore = output<void>();
@Input() tableHeight: number; @Input() tableHeight: number;
@Input() rowDetailTemplate?: TemplateRef<RowDetailContext<R>>; @Input() rowDetailTemplate?: TemplateRef<RowDetailContext<R>>;
@Input() rowDetailHeight: string | number = '100%'; @Input() rowDetailHeight: string | number = '100%';
@Output() rowDetailToggle = new EventEmitter<R>(); readonly rowDetailToggle = output<R>();
@ContentChild(ExtensibleTableRowDetailComponent) @ContentChild(ExtensibleTableRowDetailComponent)
rowDetailComponent?: ExtensibleTableRowDetailComponent<R>; rowDetailComponent?: ExtensibleTableRowDetailComponent<R>;

4
npm/ng-packs/packages/core/src/lib/directives/caps-lock.directive.ts

@ -1,10 +1,10 @@
import { Directive, EventEmitter, HostListener, Output } from '@angular/core'; import { Directive, HostListener, output } from '@angular/core';
@Directive({ @Directive({
selector: '[abpCapsLock]', selector: '[abpCapsLock]',
}) })
export class TrackCapsLockDirective { export class TrackCapsLockDirective {
@Output('abpCapsLock') capsLock = new EventEmitter<boolean>(); readonly capsLock = output<boolean>({ alias: 'abpCapsLock' });
@HostListener('window:keydown', ['$event']) @HostListener('window:keydown', ['$event'])
onKeyDown(event: KeyboardEvent): void { onKeyDown(event: KeyboardEvent): void {

4
npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts

@ -1,4 +1,4 @@
import { Directive, ElementRef, EventEmitter, Input, OnInit, Output, inject } from '@angular/core'; import { Directive, ElementRef, Input, OnInit, inject, output } from '@angular/core';
import { fromEvent } from 'rxjs'; import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators'; import { debounceTime } from 'rxjs/operators';
import { SubscriptionService } from '../services/subscription.service'; import { SubscriptionService } from '../services/subscription.service';
@ -13,7 +13,7 @@ export class InputEventDebounceDirective implements OnInit {
@Input() debounce = 300; @Input() debounce = 300;
@Output('input.debounce') readonly debounceEvent = new EventEmitter<Event>(); readonly debounceEvent = output<Event>({ alias: 'input.debounce' });
ngOnInit(): void { ngOnInit(): void {
const input$ = fromEvent<InputEvent>(this.el.nativeElement, 'input').pipe( const input$ = fromEvent<InputEvent>(this.el.nativeElement, 'input').pipe(

19
npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts

@ -1,12 +1,11 @@
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Directive, Directive,
ElementRef, ElementRef,
EventEmitter, Input,
Input, OnInit,
OnInit, inject,
Output, output
inject
} from '@angular/core'; } from '@angular/core';
import { FormGroupDirective, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { FormGroupDirective, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { fromEvent } from 'rxjs'; import { fromEvent } from 'rxjs';
@ -37,7 +36,7 @@ export class FormSubmitDirective implements OnInit {
@Input() @Input()
markAsDirtyWhenSubmit = true; markAsDirtyWhenSubmit = true;
@Output() readonly ngSubmit = new EventEmitter(); readonly ngSubmit = output();
executedNgSubmit = false; executedNgSubmit = false;

4
npm/ng-packs/packages/core/src/lib/directives/init.directive.ts

@ -1,4 +1,4 @@
import { Directive, Output, EventEmitter, ElementRef, AfterViewInit, inject } from '@angular/core'; import { Directive, ElementRef, AfterViewInit, inject, output } from '@angular/core';
@Directive({ @Directive({
selector: '[abpInit]', selector: '[abpInit]',
@ -6,7 +6,7 @@ import { Directive, Output, EventEmitter, ElementRef, AfterViewInit, inject } fr
export class InitDirective implements AfterViewInit { export class InitDirective implements AfterViewInit {
private elRef = inject(ElementRef); private elRef = inject(ElementRef);
@Output('abpInit') readonly init = new EventEmitter<ElementRef<any>>(); readonly init = output<ElementRef<any>>({ alias: 'abpInit' });
ngAfterViewInit() { ngAfterViewInit() {
this.init.emit(this.elRef); this.init.emit(this.elRef);

4
npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts

@ -1,4 +1,4 @@
import { Directive, ElementRef, EventEmitter, OnInit, Output, inject } from '@angular/core'; import { Directive, ElementRef, OnInit, inject, output } from '@angular/core';
import { fromEvent } from 'rxjs'; import { fromEvent } from 'rxjs';
import { SubscriptionService } from '../services/subscription.service'; import { SubscriptionService } from '../services/subscription.service';
@ -10,7 +10,7 @@ export class StopPropagationDirective implements OnInit {
private el = inject(ElementRef); private el = inject(ElementRef);
private subscription = inject(SubscriptionService); private subscription = inject(SubscriptionService);
@Output('click.stop') readonly stopPropEvent = new EventEmitter<MouseEvent>(); readonly stopPropEvent = output<MouseEvent>({ alias: 'click.stop' });
ngOnInit(): void { ngOnInit(): void {
this.subscription.addOne(fromEvent<MouseEvent>(this.el.nativeElement, 'click'), event => { this.subscription.addOne(fromEvent<MouseEvent>(this.el.nativeElement, 'click'), event => {

4
npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts

@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, Output, inject, DOCUMENT } from '@angular/core'; import { Component, Input, inject, DOCUMENT, output } from '@angular/core';
import { NgTemplateOutlet } from '@angular/common'; import { NgTemplateOutlet } from '@angular/common';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { ConfigStateService, LocalizationPipe, TrackByService } from '@abp/ng.core'; import { ConfigStateService, LocalizationPipe, TrackByService } from '@abp/ng.core';
@ -103,7 +103,7 @@ export class FeatureManagementComponent
} }
} }
@Output() readonly visibleChange = new EventEmitter<boolean>(); readonly visibleChange = output<boolean>();
modalBusy = false; modalBusy = false;

5
npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts

@ -19,14 +19,13 @@ import {
computed, computed,
DOCUMENT, DOCUMENT,
ElementRef, ElementRef,
EventEmitter,
inject, inject,
Input, Input,
Output,
QueryList, QueryList,
signal, signal,
TrackByFunction, TrackByFunction,
ViewChildren, ViewChildren,
output
} from '@angular/core'; } from '@angular/core';
import { concat, of } from 'rxjs'; import { concat, of } from 'rxjs';
import { finalize, switchMap, take, tap } from 'rxjs/operators'; import { finalize, switchMap, take, tap } from 'rxjs/operators';
@ -160,7 +159,7 @@ export class PermissionManagementComponent
} }
} }
@Output() readonly visibleChange = new EventEmitter<boolean>(); readonly visibleChange = output<boolean>();
@ViewChildren('selectAllInThisTabsRef') @ViewChildren('selectAllInThisTabsRef')
selectAllInThisTabsRef!: QueryList<ElementRef<HTMLInputElement>>; selectAllInThisTabsRef!: QueryList<ElementRef<HTMLInputElement>>;

21
npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts

@ -2,13 +2,12 @@
import { import {
Component, Component,
ElementRef, ElementRef,
EventEmitter,
Input, Input,
OnInit, OnInit,
Output,
Renderer2, Renderer2,
ViewChild, ViewChild,
inject, inject,
output
} from '@angular/core'; } from '@angular/core';
import { ABP, StopPropagationDirective } from '@abp/ng.core'; import { ABP, StopPropagationDirective } from '@abp/ng.core';
@ -22,9 +21,9 @@ import { ABP, StopPropagationDirective } from '@abp/ng.core';
[attr.form]="formName" [attr.form]="formName"
[class]="buttonClass" [class]="buttonClass"
[disabled]="loading || disabled" [disabled]="loading || disabled"
(click.stop)="click.next($event); abpClick.next($event)" (click.stop)="click.emit($event); abpClick.emit($event)"
(focus)="focus.next($event); abpFocus.next($event)" (focus)="focus.emit($event); abpFocus.emit($event)"
(blur)="blur.next($event); abpBlur.next($event)" (blur)="blur.emit($event); abpBlur.emit($event)"
> >
<i [class]="icon" class="me-1" aria-hidden="true"></i><ng-content></ng-content> <i [class]="icon" class="me-1" aria-hidden="true"></i><ng-content></ng-content>
</button> </button>
@ -58,17 +57,17 @@ export class ButtonComponent implements OnInit {
@Input() @Input()
attributes?: ABP.Dictionary<string>; attributes?: ABP.Dictionary<string>;
@Output() readonly click = new EventEmitter<MouseEvent>(); readonly click = output<MouseEvent>();
@Output() readonly focus = new EventEmitter<FocusEvent>(); readonly focus = output<FocusEvent>();
@Output() readonly blur = new EventEmitter<FocusEvent>(); readonly blur = output<FocusEvent>();
@Output() readonly abpClick = new EventEmitter<MouseEvent>(); readonly abpClick = output<MouseEvent>();
@Output() readonly abpFocus = new EventEmitter<FocusEvent>(); readonly abpFocus = output<FocusEvent>();
@Output() readonly abpBlur = new EventEmitter<FocusEvent>(); readonly abpBlur = output<FocusEvent>();
@ViewChild('button', { static: true }) @ViewChild('button', { static: true })
buttonRef!: ElementRef<HTMLButtonElement>; buttonRef!: ElementRef<HTMLButtonElement>;

10
npm/ng-packs/packages/theme-shared/src/lib/components/checkbox/checkbox.component.ts

@ -1,4 +1,4 @@
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core'; import { Component, forwardRef, Input, output } from '@angular/core';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core'; import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
@ -13,8 +13,8 @@ import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
[readonly]="checkboxReadonly" [readonly]="checkboxReadonly"
[class]="checkboxClass" [class]="checkboxClass"
[style]="checkboxStyle" [style]="checkboxStyle"
(blur)="checkboxBlur.next()" (blur)="checkboxBlur.emit()"
(focus)="checkboxFocus.next()" (focus)="checkboxFocus.emit()"
/> />
@if (label) { @if (label) {
<label [class]="labelClass" [for]="checkboxId"> <label [class]="labelClass" [for]="checkboxId">
@ -44,6 +44,6 @@ export class FormCheckboxComponent extends AbstractNgModelComponent {
| undefined; | undefined;
@Input() checkboxClass = 'form-check-input'; @Input() checkboxClass = 'form-check-input';
@Input() checkboxReadonly = false; @Input() checkboxReadonly = false;
@Output() checkboxBlur = new EventEmitter<void>(); readonly checkboxBlur = output<void>();
@Output() checkboxFocus = new EventEmitter<void>(); readonly checkboxFocus = output<void>();
} }

10
npm/ng-packs/packages/theme-shared/src/lib/components/form-input/form-input.component.ts

@ -1,4 +1,4 @@
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core'; import { Component, forwardRef, Input, output } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'; import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core'; import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
@ -18,8 +18,8 @@ import { AbstractNgModelComponent, LocalizationPipe } from '@abp/ng.core';
[readonly]="inputReadonly" [readonly]="inputReadonly"
[class]="inputClass" [class]="inputClass"
[style]="inputStyle" [style]="inputStyle"
(blur)="formBlur.next()" (blur)="formBlur.emit()"
(focus)="formFocus.next()" (focus)="formFocus.emit()"
[(ngModel)]="value" [(ngModel)]="value"
/> />
</div> </div>
@ -46,6 +46,6 @@ export class FormInputComponent extends AbstractNgModelComponent {
| null | null
| undefined; | undefined;
@Input() inputClass = 'form-control'; @Input() inputClass = 'form-control';
@Output() formBlur = new EventEmitter<void>(); readonly formBlur = output<void>();
@Output() formFocus = new EventEmitter<void>(); readonly formFocus = output<void>();
} }

4
npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.ts

@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, Input, OnInit, output } from '@angular/core';
import { Toaster } from '../../models/toaster'; import { Toaster } from '../../models/toaster';
import { LocalizationPipe } from '@abp/ng.core'; import { LocalizationPipe } from '@abp/ng.core';
@ -12,7 +12,7 @@ export class ToastComponent implements OnInit {
@Input() @Input()
toast!: Toaster.Toast; toast!: Toaster.Toast;
@Output() remove = new EventEmitter<number>(); readonly remove = output<number>();
get severityClass(): string { get severityClass(): string {
if (!this.toast || !this.toast.severity) return ''; if (!this.toast || !this.toast.severity) return '';

Loading…
Cancel
Save