Как реализовать динамические компоненты с маршрутами в Angular 5? - PullRequest
1 голос
/ 10 мая 2019

Я пытаюсь создать приложение, в котором некоторые части получены из динамических шаблонов, и я хочу разрешить маршруты для этих компонентов.

// 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 { });

Что не так?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...