从 PrimeNG 组件库迁移到 Material 库后,我们不得不手动重新实现每个组件实例,我们遇到了完全相同的挑战。展望未来,我们希望尽可能地将库组件与应用程序分离,以便在我们决定再次更改库时,替换它会更容易。
一般的想法是创建一个应用程序组件,该组件将充当库组件的传递组件,并且所有公开的功能都将在组件实现的接口中定义。
下面是一个(相当)通用且简单的示例:
|-- Components
|-- button
|-- button.component.css
|-- button.component.html
|-- button.component.ts
|-- button.model.ts
|-- button.module.ts
组件文件是使用 CLI 生成的标准文件。 .model.ts 文件包含组件的接口,.module.ts 文件包含同样使用 CLI 生成的 Angular 模块。
button.component.html
<button (click)="clicked()"><i [ngClass]="icon"></i>{{text}}</button>
button.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { IButton } from './button.model';
@Component({
selector: 'app-button',
templateUrl: './button.component.html',
styleUrls: ['./button.component.css']
})
export class ButtonComponent implements OnInit, IButton {
@Input() text: string;
@Input() icon: string;
@Output() clickEvent: EventEmitter<void> = new EventEmitter<void>();
constructor() { }
ngOnInit() {
}
clicked(): void {
this.clickEvent.emit();
}
}
将所有输入和输出(尽可能通用)定义为组件(以及任何未来实现)需要实现的接口。这将确保组件的功能始终保持不变。
button.model.ts
import { EventEmitter } from '@angular/core';
export interface IButton {
text: string;
icon: string;
clickEvent: EventEmitter<void>;
}
在模块中声明并导出组件。
button.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ButtonComponent } from './button.component';
@NgModule({
declarations: [
ButtonComponent
],
imports: [
CommonModule,
// component module imports here
],
exports: [
ButtonComponent
]
})
export class ButtonModule { }
遵循上述方法意味着您只需导入模块即可在您的应用中引用该组件 - 您永远不会直接引用库组件。
<app-button [text]="'export'" [icon]="'fas fa-file-export'" (clickEvent)="doSomething()"></app-button>
如果您需要替换或扩展组件,请对模块(例如导入库组件模块)、模板进行必要的更改,并确保组件仍然实现接口。