我正在做一个大型的基于angular的项目,有很多(比方说,>惰性加载模块。每个模块都有相同的UI,因此每个模块都可以由相同的组件表示。模块之间的区别在于它们提供不同的动态实例化子组件。因此,我真正想要实现的是在每个模块中具有相同的UI,但根据路由提供不同的可用子组件集-您可以想象,例如将被馈送到组件出口的Type<MySubComponent>
实例。
每个模块都有单独的路由,也就是说,路由决定了我们在哪个模块。
我如何在Angular中定义这个?
- 据我所知,Angular中的路由总是指向一个组件(该组件将在导航到该路由时显示)。不是对提供数据的底层服务或其他类,而是对UI本身。 因此,一种直接的OOP方法是将我的一个模块ui组件定义为基类,然后在每个模块中派生一个特定于模块的组件,该组件"填充一些空白"。(即实现一些提供数据的抽象方法)。
问题是:显然,即使我的子类本身没有指定
@Component
装饰符,它也不会被继承。因此,我必须为每个200多个模块复制完全相同的@Component
装饰器,使用相同的模板和样式url,我认为这严重违反了DRY原则,因此是糟糕的设计。如果不这样做,我得到错误NG6001,可以通过以下代码复制:@Component({
template: '<div></div>'
})
abstract class BaseComponent {
abstract get moduleSpecificStuff(): string;
}
export class ConcreteComponent extends BaseComponent {
get moduleSpecificStuff(): string {
return 'This is the concrete module!';
}
}
因此,我怎么能路由到相同的UI无处不在,而没有大量重复的代码和得到一些不同的数据/内容在每个路由下提供?
作为进一步的警告,不能有任何包含所有路由的全局列表。我有一个特殊模块的列表,每个模块都知道到它的子模块的路由,并根据需要惰性加载它们。也就是说,对于每一个路由,必须注册相同的组件,但必须提供不同的数据。
编辑:实际上没有回答这个问题,做了一些测试,想出了这个
你可以试着通过名字(字符串)来加载组件。如果你能设法获得BasePageComponent的组件名称列表(通过api、本地存储、路由参数等),你应该能够获得组件的类型,然后加载它们。
已使用此线程
test.component.ts
@ComponentLookup('TestComponent') // Add this decorator to components
两个输出:
export const ComponentLookupRegistry: Map<string, any> = new Map();
export const ComponentLookup = (key: string): any => {
return (cls: any) => {
ComponentLookupRegistry.set(key, cls);
};
};
通过字符串加载组件的代码:
// This will get the TestComponent class
const classRef = ComponentLookupRegistry.get('TestComponent');
// Not important stuff
const viewContainerRef = this.adHost.viewContainerRef;
const componentRef = viewContainerRef.createComponent(classRef);
似乎Route.data
属性是存储这类数据的正确位置。这里可以提供任意特定于路由的数据。
组件(即使它在许多路由中都是相同的组件)可以注入ActivatedRoute
并从data
中作为一个可观察对象检索数据,或者一次检索数据,例如在初始化时,通过snapshot
属性。