Angular6中组件之间共享逻辑时如何使用组合而不是继承?
How to use composition instead of inheritance when sharing logic between components in Angular 6?
我在 Angular 中有一个结构如下的模块:
moduleName
componentA
componentB
现在 componentA
和 componentB
非常相似,因为它们共享一些属性和方法,例如:
protected available: boolean = true;
由于不想重复,我创建了一个基础 class,它存储了所有这些:
export abstract class BaseComponent {
protected available: boolean = true;
}
并且两个控制器都继承自 class:
import { BaseComponent } from '../base.component';
export class ComponentA extends BaseComponent implements OnInit {
constructor() {
super();
}
ngOnInit() {
console.log(this.available);
}
}
这很好用。然而,当我研究这个灵魂时,很多人都在说:
Don't use inheritance, use composition in this case.
好的,但是我怎样才能使用组合呢?与当前解决方案相比,收益真的那么大吗?
非常感谢您的宝贵时间。
要在 angular 中组合对象,您需要在 class 中引用该对象,它共享数据和功能。为此,您需要使用 Angular 服务,并将它们注入您的 class,并且每个组件应该有 1 个服务实例。
- 通过 运行 创建新服务
ng g s my-service
,从您的服务注释中删除 providedIn: 'root'
(我们希望为每个组件提供实例)
- 添加
public available: boolean = true;
到服务
provide
通过组件的服务,在组件的 @Component
配置中
- 在你的两个组件构造函数中注入服务,
constructor(private myService:MyService)
现在您有了一个保留数据和功能的组合
@Component({
selector: 'app',
templateUrl: './app.my-component.html',
styleUrls: ['./app.my-component.css'],
providers: [MyService]
})
export class MyComponent {
constructor(private myService: MyService) {
}
}
如果您使用大部分相同的逻辑创建相同的组件。您可以使用继承,例如 controlSelectComponent 和 controlInputComponent stackblitz example
对于组合,您需要创建服务并将其提供给两个组件。但是因为all service are singletone,你不保持服务中的组件状态。当一个组件改变状态时,另一个组件崩溃。
您也可以在提供者部分为每个组件提供服务
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [MyService]
})
export class AppComponent {
constructor(private myService: MyService) {
}
}
但是如果在服务中保存状态不是最好的解决方案
结论
使用服务和组合在组件之间共享辅助方法。
对具有相同逻辑和状态变化的组件使用抽象 class 和继承。
我还建议您阅读有关组合优于继承的内容。 Angular 使用的语法 (InversifyJs) 非常相似。请看这个blog
我在 Angular 中有一个结构如下的模块:
moduleName
componentA
componentB
现在 componentA
和 componentB
非常相似,因为它们共享一些属性和方法,例如:
protected available: boolean = true;
由于不想重复,我创建了一个基础 class,它存储了所有这些:
export abstract class BaseComponent {
protected available: boolean = true;
}
并且两个控制器都继承自 class:
import { BaseComponent } from '../base.component';
export class ComponentA extends BaseComponent implements OnInit {
constructor() {
super();
}
ngOnInit() {
console.log(this.available);
}
}
这很好用。然而,当我研究这个灵魂时,很多人都在说:
Don't use inheritance, use composition in this case.
好的,但是我怎样才能使用组合呢?与当前解决方案相比,收益真的那么大吗?
非常感谢您的宝贵时间。
要在 angular 中组合对象,您需要在 class 中引用该对象,它共享数据和功能。为此,您需要使用 Angular 服务,并将它们注入您的 class,并且每个组件应该有 1 个服务实例。
- 通过 运行 创建新服务
ng g s my-service
,从您的服务注释中删除providedIn: 'root'
(我们希望为每个组件提供实例) - 添加
public available: boolean = true;
到服务 provide
通过组件的服务,在组件的@Component
配置中- 在你的两个组件构造函数中注入服务,
constructor(private myService:MyService)
现在您有了一个保留数据和功能的组合
@Component({
selector: 'app',
templateUrl: './app.my-component.html',
styleUrls: ['./app.my-component.css'],
providers: [MyService]
})
export class MyComponent {
constructor(private myService: MyService) {
}
}
如果您使用大部分相同的逻辑创建相同的组件。您可以使用继承,例如 controlSelectComponent 和 controlInputComponent stackblitz example
对于组合,您需要创建服务并将其提供给两个组件。但是因为all service are singletone,你不保持服务中的组件状态。当一个组件改变状态时,另一个组件崩溃。
您也可以在提供者部分为每个组件提供服务
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [MyService]
})
export class AppComponent {
constructor(private myService: MyService) {
}
}
但是如果在服务中保存状态不是最好的解决方案
结论
使用服务和组合在组件之间共享辅助方法。
对具有相同逻辑和状态变化的组件使用抽象 class 和继承。
我还建议您阅读有关组合优于继承的内容。 Angular 使用的语法 (InversifyJs) 非常相似。请看这个blog