angular - 动态更改 Angular 4 组件的模板

标签 angular angular2-template angular2-components

使用 Angular 4.1,我试图在模块呈现之前动态更改模块类型的模板。这可能吗?

我们正在页面上引导未知数量的组件(来自已知的组件类型列表),并且该页面可能包含多个相同类型的组件。我找到了一种方法,可以为这些组件中的每一个提供不同的选择器,以便它们可以单独呈现(即使它们属于同一类型),但我还需要为每个组件提供不同的模板。 模板应该是所选元素的内部 HTML。

代码如下:

import { Component, NgModule, Inject, ApplicationRef, ComponentFactoryResolver, OpaqueToken, Type } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MyNavComponent } from './MyNav.component';
import { MyRotatorComponent } from './MyRotator.component';
import { MySignUpComponent } from './MySignUp.component';

export const BOOTSTRAP_COMPONENTS_TOKEN = new OpaqueToken('bootstrap_components');

@NgModule({
    imports: [BrowserModule],
    declarations: [
        MyNavComponent,
        MyRotatorComponent,
        MySignUpComponent
    ],
    entryComponents: [
        MyNavComponent,
        MyRotatorComponent,
        MySignUpComponent
    ],
    providers: [
        {
            provide: BOOTSTRAP_COMPONENTS_TOKEN,
            useValue: [
                { type: MyNavComponent },
                { type: MyRotatorComponent },
                { type: MySignUpComponent }
            ]
        },
    ]
})
export class AppModule {
    constructor(
        private resolver: ComponentFactoryResolver,
        @Inject(BOOTSTRAP_COMPONENTS_TOKEN) private components: [Component],
    ) { }
    ngDoBootstrap(appRef: ApplicationRef) {
        console.log(this.components);
        this.components.forEach((componentDef: { type: Type<any>, selector: string }) => {
            const factory = this.resolver.resolveComponentFactory(componentDef.type);
            let selector = factory.selector;
            let nodes = document.querySelectorAll(selector);
            for (let i = 0; i < nodes.length; i++) {
                let node = nodes[i];
                (<any>factory).factory.selector = node;

                //The next line doesn't work... how can I dynamically set the template?
                (<any>factory).factory.template = node.innerHTML;

                appRef.bootstrap(factory);
            }
        });
    }
}

如上述代码末尾所述,(<any>factory).factory.template = node.innerHTML;不起作用。我也试过修改类型的元数据,但这也不起作用。

是否可以通过其他方式实现我正在努力实现的目标?如果不是,是否值得作为功能请求提交?

(注:以上代码部分引用了https://github.com/angular/angular/issues/7136的其他人的代码。)

更新:

我想知道在 Angular 的 future 更新中,我是否能够通过将模板设置为 <ng-content></ng-content> 来获得相同的结果。包含所选元素的 innerHTML。这对于自举组件现在是不可能的,但基于此 issue on Git ,我希望它会很快。

最佳答案

组件工厂创建后不能设置模板。 Angular 编译器在生成工厂时解析模板,并为每个组件创建一个 View 类。创建组件工厂及其 View 类后,您将无法修改它。在您的示例中,您使用的是 ComponentFactoryResolver

const factory = this.resolver.resolveComponentFactory(componentDef.type);

返回已经创建的工厂。

唯一的选择是在编译器生成工厂之前更改模板。但我认为这是不可能的。您可能需要看一下组件的动态生成。

阅读Here is what you need to know about dynamic components in Angular获取更多信息。

关于angular - 动态更改 Angular 4 组件的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44272519/

相关文章:

c# - RedirectToAction 不适用于 asp.net core 中的 angular2

angular - 将类添加到 Angular 2 中的某一特定行

css - 动态创建组件的 Angular 2 位置

angular - nx dep-graph 未显示任何关系

angular - ngx-datatable - 带有操作按钮的自定义列

Angular2/4 搜索建议

javascript - Angular 2 表达式解析器和 ng-init 指令

Angular2 - 表单中的自定义指令不当行为

angular - ionic2 rc0 中找不到组件工厂错误

angular - 应用程序在 Chrome 91 中无休止地重启,并在 'issues' 中出现 cookie 错误