动态更改 Angular 4 个组件的模板
Dynamically changing the template for an Angular 4 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 的未来更新中,我是否能够通过将模板设置为 <ng-content></ng-content>
以包含 HTML 的内部来实现相同的结果所选元素。现在使用自举组件不可能做到这一点,但基于此 issue on Git,我希望它很快就会实现。
组件工厂创建后不能设置模板。 Angular 编译器在生成工厂时解析模板并为每个组件创建视图 class。创建组件工厂及其视图 class 后,您将无法修改它。在您的示例中,您使用的是 ComponentFactoryResolver
const factory = this.resolver.resolveComponentFactory(componentDef.type);
哪个returns已经创建了工厂。
唯一的选择是在编译器生成工厂之前更改模板。但我认为这是不可能的。你可能不得不看一下组件的动态生成。
阅读 Here is what you need to know about dynamic components in Angular 了解更多信息。
使用 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 的未来更新中,我是否能够通过将模板设置为 <ng-content></ng-content>
以包含 HTML 的内部来实现相同的结果所选元素。现在使用自举组件不可能做到这一点,但基于此 issue on Git,我希望它很快就会实现。
组件工厂创建后不能设置模板。 Angular 编译器在生成工厂时解析模板并为每个组件创建视图 class。创建组件工厂及其视图 class 后,您将无法修改它。在您的示例中,您使用的是 ComponentFactoryResolver
const factory = this.resolver.resolveComponentFactory(componentDef.type);
哪个returns已经创建了工厂。
唯一的选择是在编译器生成工厂之前更改模板。但我认为这是不可能的。你可能不得不看一下组件的动态生成。
阅读 Here is what you need to know about dynamic components in Angular 了解更多信息。