问题描述
使用Angular 4.1,我试图在呈现模块之前动态更改模块类型的模板.这可能吗?
Using Angular 4.1, I'm trying to dynamically change a module type's template before the module rendered. Is this possible?
我们正在引导页面上未知数量的组件(从已知的组件类型列表中引导),并且页面可能包含相同类型的多个组件.我找到了一种为这些组件中的每个组件提供不同选择器的方法,以便可以分别呈现它们(即使它们的类型相同),但是我还需要为每个组件提供不同的模板. 模板应为所选元素的内部HTML.
We are bootstrapping an unknown number of components on the page (from a known list of component types), and the page may contain multiple components of the same type. I've found out a way to give each of these components a different selector so they can be rendered separately (even if they're of the same type), but I also need to give each one a different template. The template should be the inner HTML of the selected element.
代码如下:
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;
不起作用.我也尝试过修改类型的元数据,但这也不起作用.
As noted near the end of the above code, (<any>factory).factory.template = node.innerHTML;
doesn't work. I've also tried modifying the metadata for the type, but that doesn't work, either.
我正在尝试通过其他方式实现的目标吗?如果不是,是否值得将其作为功能请求提交?
Is what I'm trying to achieve possible by another means? If not, is this worth submitting as a feature request?
(注意:以上代码部分基于其他代码,位于 https://github.com/angular/angular/issues/7136 .)
(Note: the above code is based in part on the code of others at https://github.com/angular/angular/issues/7136.)
我想知道在将来的Angular更新中是否可以通过将模板设置为<ng-content></ng-content>
以包含所选元素的innerHTML来实现相同的结果.目前无法使用自举组件,但基于Git上的 issue ,我希望很快.
I'm wondering if in a future update of Angular I'll be able to achieve the same result by setting the template to <ng-content></ng-content>
to include the innerHTML of the selected element. This isn't possible now with bootstrapped components, but based on this issue on Git, I'm hopeful it will be soon.
推荐答案
创建组件工厂后,无法为它设置模板. Angular编译器在生成工厂时会解析模板,并为每个组件创建一个视图类.创建组件工厂及其视图类之后,您将无法对其进行修改.在您的示例中,您使用的是ComponentFactoryResolver
You cannot set a template for a component factory after it was created. Angular compiler parses templates when generating a factory and creates a view class for each component. After the component factory and its view class are created you cannot modify it. In your example you're using ComponentFactoryResolver
const factory = this.resolver.resolveComponentFactory(componentDef.type);
返回已创建的工厂.
唯一的选择是在编译器生成工厂之前更改模板.但是我认为这是不可能的.您可能必须看一下组件的动态生成.
The only option is to change the template before the compiler generates factories. But I don't think it's possible. You will probably have to take a look at the dynamic generation of components.
阅读此处您需要了解Angular中的动态组件以获取更多信息.
这篇关于动态更改Angular 4组件的模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!