pgmr.cloud
9 February 2024
TypeScript的装饰器可以帮助您减少Angular应用程序的样板文件!
medium/custom-decorator at main · TimJ0212/medium
Contribute to TimJ0212/medium development by creating an account on GitHub.
装饰器是Angular开发人员已知的功能。对于像@NgModule或@Component Angular这样的已知装饰器,装饰器本身正在提升生产力。你也能做到!
你确定吗?
我想在对应用程序进行资源密集型或关键性操作之前,您几乎随时都会看到这个问题。
首先,您将实现一个方法,并在每次请求用户确认时调用它。这还不错,但通过定期调用方法,您可以在代码中的任何地方都得到方法调用。如果有一个注释,它会自动询问用户并处理响应,那不是很好吗?
(即使你在想,我也不需要这个,注释适合所有类型的重复工作,比如auth或其他东西。)
让我们开始吧
- 使用ng new创建新的角度工作空间
- 使用ng Add@Angular/Material添加角度材质
- 创建一个简单的对话框组件:ng g组件组件/简单对话框
- 创建一个名为confirmable.decorator.ts的文件(在我的例子中是在共享/decorator目录中)
装饰器
import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { SimpleDialogComponent } from '../../components/simple-dialog/simple-dialog.component'; import { AppModule } from '../../app.module'; import { Type } from '@angular/core'; export interface ConfirmableDecoratorOptions { title?: string; text?: string; } export function Confirmable() { return ( target: Object, propertyKey: string, descriptor: PropertyDescriptor ) => { const originalMethod = descriptor.value; const config: ConfirmableDecoratorOptions = { title: 'Confirmationen needed', text: 'Are you sure?', }; descriptor.value = async function (...args: any[]) { const dialog: MatDialog = AppModule.INJECTOR.get<MatDialog>( MatDialog as Type<MatDialog> ); const dialogRef: MatDialogRef<SimpleDialogComponent> = dialog.open( SimpleDialogComponent, { data: { title: config.title, text: config.text, }, } ); dialogRef.afterClosed().subscribe((result) => { if (result === true) { return originalMethod.apply(this, args); } }); }; return descriptor; }; }
简单的对话框
import { Component, Inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import { MatButtonModule } from '@angular/material/button'; export type DialogData = { title: string; text: string; }; @Component({ selector: 'app-simple-dialog', standalone: true, imports: [CommonModule, MatDialogModule, MatButtonModule], template: ` <h1 mat-dialog-title>{{ data.title }}</h1> <div mat-dialog-content> {{ data.text }} </div> <div mat-dialog-actions> <button [mat-dialog-close]="false" mat-button>Cancel</button> <button [mat-dialog-close]="true" mat-button>Ok</button> </div> `, }) export class SimpleDialogComponent { constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {} }
对应的模块(在我的情况下,两者都是AppModule)
import { Injector, NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatButtonModule } from '@angular/material/button'; import { MatDialogModule } from '@angular/material/dialog'; @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, BrowserAnimationsModule, MatButtonModule, MatDialogModule, ], providers: [], bootstrap: [AppComponent], }) export class AppModule { static INJECTOR: Injector; constructor(injector: Injector) { AppModule.INJECTOR = injector; } }
现在,您可以在任何您喜欢的方法上添加decorator
import { Component } from '@angular/core'; import { Confirmable } from './shared/decorators/confirmable.decorator'; @Component({ selector: 'app-root', template: `<button (click)="doSomething()" color="primary" mat-raised-button> Do Something </button> <div>{{ this.confirmed }}</div> `, }) export class AppComponent { public confirmed: boolean = false; @Confirmable() // <-- Here it is! public doSomething(): void { this.confirmed = true; } }
运行npm-Run-start,如果您在localhost:4200上打开浏览器,您的应用程序应该是这样的
如果你按下蓝色按钮,你会看到一个对话框,要求确认。如果取消,则不会调用该方法。但只要按下“确定”,应用程序流程就会继续。
- 登录 发表评论