假设我们有一个包含很多列表的应用程序,因此有一些基本组件
export class SimpleListComponent { ... }
export class ExtendedListComponent extends SimpleListComponent { ... }
...我们可以轻松扩展。它们具有列表的所有基本功能(例如切换页面,计数结果等)。我们将这两个基本组件用于两个不同的英雄列表:
export class HeroSimpleListComponent extends SimpleListComponent { ... }
export class HeroExtendedListComponent extends ExtendedListComponent { ... }
不幸的是,我们仍然必须重复很多代码,因为HeroSlimListComponent
和HeroExtendedListComponent
共享了许多功能(例如加载英雄,通往英雄的路线等)。
我的第一个尝试是传递我们需要扩展的类
export class ExtendedListComponent<T = SimpleListComponent> extends T { ... }
但这不起作用。另外,我发现this post指出在打字稿中不可能多重继承。仍然有一种感觉,我在这里缺少一些基本的角度分量连接解决方案。
预先感谢您的帮助!
答案 0 :(得分:1)
您是正确的,多重继承是不可用的(不幸的是,因为它太酷了)。
可能性1 似乎您的常用操作可以存在于简单列表组件内部,并且可以在构造函数中提供扩展组件所需的属性(例如路径)。调用super()时,可以向下传递配置选项。
export class SimpleListComponent {
constructor(
routePath: string,
) {}
}
// extending component
export class HeroSlimListComponent extends SimpleListComponent {
constructor() {
super('<my-route-path>');
}
}
可能性2 值得一试mixins!我还没有玩过这些游戏,所以也许有一些经验的人可以参与其中?他们似乎并不能完全解决问题,因为您仍然必须实现接口,但是对于父组件来说,这可能是一组很好的通用功能。
可能性3 (可能是我个人的最爱) 将通用列表和扩展列表组件保留为接受输入并提供输出但不扩展它们的组件。而是在html中使用它们。例如,可以传递导航路径,并可以在父级组件处提供数据服务,并将其注入树中的子组件中。要配置列表项,您可以传入模板引用(请参见material tables examples)。这只是一个粗糙的示例,需要进行优化,但是在这里:
// simple list component
// selector = simple-list
constructor(simpleListService: SimpleListService) {}
// hero simple list component
@Component({
....
providers: [
{ provide: SimpleListService, useClass: HeroSimpleListService },
],
})
// html
<simple-list [navPath]='heroNavPath' <...other templates / props>>
需要记住的一点是,您扩展的类中的每一段代码都作为每个扩展组件中的重复代码再次添加到了最终版本中(请查看prod版本的输出,这很有趣)。