我正在尝试构建一个应用程序,其中某些部分是从动态模板派生的,并且我希望允许该组件进行路由。
// Object received from API
class ComponentModel {
public name: string;
public template: string;
public styles: string [];
public path: string;
public outlet: string;
}
// Classes to store information about component
class ComponentInfo {
public model: ComponentModel;
public component: any;
public isRoute: boolean;
public isHome: boolean;
public componentReference: ComponentRef<any>;
public factory: ComponentFactory<any>;
}
// A map for all components created (to be used as a cache)
ComponentMap: Map<string, ComponentInfo> = new Map<string, ComponentInfo>();
// The container to show dynamic component
@ViewChild('dynamicContainer', { read: ViewContainerRef }) public dynamicContainer: ViewContainerRef;
// Create a component and all of his dependencies
public createComponentAndDependencies(model: ComponentModel, mainPage: boolean = false): any[] {
let ret = [];
var nComponent = Component({ template: model.template, styles: model.styles, selector: model.name, mainPage: mainPage })( class {} );
ret[ret.length] = nComponent;
this.ComponentMap.set(model.name, { model: model, component: nComponent } as ComponentInfo);
model.componentDependecies.forEach(dependency => { ret = ret.concat(this.createComponentAndDependencies(dependency)); });
return ret;
}
// main method, called after receive a component from API
public createComponentAndCompile(component: ComponentModel) {
try {
this.dynamicItemView.clear();
this.ComponentMap.clear();
const newComponents = this.createComponentAndDependencies(component, true);
const module = NgModule({
imports: [RouterModule],
declarations: newComponents,
entryComponents: newComponents,
})(class { });
let cp = this.compiler.compileModuleAndAllComponentsAsync(module);
cp.then((factories) => {
factories.componentFactories.forEach(componentFactory => {
let cpName = componentFactory.selector.toString();
let cpInfo = this.ComponentMap.get(cpName);
cpInfo.factory = componentFactory;
cpInfo.componentReference = componentFactory.create(this.injector, [], null, this.moduleRef);
cpInfo.componentReference.instance.name = cpName;
this.activatedRoute.routeConfig.children.push({
path: cpInfo.model.path,
component: cpInfo.componentReference.instance,
outlet: cpInfo.model.outlet
} as Route);
if (cpInfo.mainPage)
this.dynamicItemView.insert(cpInfo.componentReference.hostView);
});
this.router.events.subscribe(async re => {
console.log(re.toString());
});
});
} catch (error) {
this.notificationService.showError(error.message);
}
}
我动态地添加了路线
this.activatedRoute.routeConfig.children.push({
path: cpInfo.model.path,
component: cpInfo.componentReference.instance,
outlet: cpInfo.model.outlet
} as Route);
运行代码时,将正确创建并显示该组件,但是当我使用模板导航(即:<a [routerLink] = "['something', {outlets: {home: 'component1'}} }] "> Component 1 </a>
)时,将显示以下错误:"NavigationError(id: 2, url: 'something(home:component1)', error: Error: No component factory found for component1. Did you add it to @NgModule.entryComponents?)"
我在ngModule上插入了entryComponents,但仍然无法正常工作。
const module = NgModule({
imports: [RouterModule],
declarations: newComponents,
entryComponents: newComponents,
})(class { });
怎么了?