Я пытаюсь создать приложение, в котором некоторые части получены из динамических шаблонов, и я хочу разрешить маршруты для этих компонентов.
// 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?)"
Я вставил entryComponents в ngModule, но все еще не работает.
const module = NgModule({
imports: [RouterModule],
declarations: newComponents,
entryComponents: newComponents,
})(class { });
Что не так?