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上打开浏览器,您的应用程序应该是这样的
如果你按下蓝色按钮,你会看到一个对话框,要求确认。如果取消,则不会调用该方法。但只要按下“确定”,应用程序流程就会继续。
- 登录 发表评论