Angular 2+ 将 Component 扩展为另外两个组件

Angular 2+ extend Component by two other components

假设我们有一个包含很多列表的应用程序,因此有一些基本组件

export class SimpleListComponent { ... }

export class ExtendedListComponent extends SimpleListComponent { ... }

...我们可以轻松扩展。它们具有我们列表的所有基本功能(例如切换页面、计算结果……)。我们将这两个基本组件用于两个不同的英雄列表:

export class HeroSimpleListComponent extends SimpleListComponent { ... }

export class HeroExtendedListComponent extends ExtendedListComponent { ... }

不幸的是,我们仍然需要重复很多代码,因为 HeroSlimListComponentHeroExtendedListComponent 共享它们的很多功能(例如加载英雄、英雄路线等)。

我的第一个尝试是通过我们需要扩展的 class

export class ExtendedListComponent<T = SimpleListComponent> extends T { ... }

但这不起作用。此外,我发现 this post 指出,在 typescript 中多重继承是不可能的。我仍然觉得我在这里缺少一些基本的 angular 组件连接解决方​​案。

在此先感谢您的帮助!

你是对的,多重继承是不可用的(不幸的是,因为它会非常酷)。

可能性 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>>

需要记住的是,您扩展的 class 中的每一段代码都会作为每个扩展组件中的重复代码再次添加到您的最终构建中(查看产品构建的输出,有点像有趣)。