【发布时间】:2018-08-21 08:09:55
【问题描述】:
在 angular5 上,我尝试对我的大部分模块/组件进行同一个项目的 AOT 编译...但我有一部分需要 JIT 编译。
对于第二部分,HTML 来自 Ajax 请求并包含一些必须由 angular 编译的组件标记。为了管理这部分,我使用如下指令:
export class ArticleLiveDirective implements OnInit, OnChanges, OnDestroy {
// [...]
constructor(
private container: ViewContainerRef,
private compiler: Compiler
) { }
// [...]
private addHtmlComponent(template: string, properties: any = {}) {
this.container.clear();
//Force always rootDomElement.
const divTag = document.createElement('div');
divTag.setAttribute('id',this.currentId);
divTag.innerHTML = template;
template = divTag.outerHTML;
// We create dynamic component with injected template
@Component({ template })
class ArticleLIveComponent implements OnInit, OnChanges, OnDestroy {
constructor(
private articleService: ArticleService
) {}
ngOnInit() {}
ngOnChanges(changes: SimpleChanges) {}
ngOnDestroy() {}
goToPage($event: Event, pagination: string) {
this.articleService.askToChangeArticle(pagination);
//Stop propagation
$event.stopPropagation();
return false;
}
}
// we declare module with all dependencies
@NgModule({
declarations: [
ArticleLIveComponent
],
imports: [
BrowserModule,
MatTabsModule
],
providers: []
})
class ArticleLiveModule {}
// we compile it
const mod = this.compiler.compileModuleAndAllComponentsSync(ArticleLiveModule);
const factory = mod.componentFactories.find((comp) =>
comp.componentType === ArticleLIveComponent
);
// fetch instance of fresh crafted component
const component = this.container.createComponent(factory);
// we inject parameter.
Object.assign(component.instance, properties);
}
}
如您所见,我可以调用 addHtmlComponent 方法在运行时使用自定义 HTML 作为模板编译新组件。
我的模板看起来像:
<div>
<h2>Foo bar</h2>
<mat-tab-group>
<mat-tab label="Tab 1">Content 1</mat-tab>
<mat-tab label="Tab 2">Content 2</mat-tab>
</mat-tab-group>
<p>Other content</p>
一切正常,直到我切换到 AOT 编译(仅供参考:https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack)
可能的原因: 我猜的主要原因是因为 AOT 编译从输出编译包中删除了 Angular 的“编译器”部分。 我的尝试 - 我试图直接在我的代码上要求它,但仍然不存在。 - 我试图检查像角度(或角度材料)这样的网站如何处理它。但不适合我的情况。事实上,两者都已经编译了 AOT 版本中的所有示例。动态部分是“只是”样本周围的内容。
如果你想检查角度材料是如何做到的: 每个组件的所有网站示例:https://github.com/angular/material2/tree/master/src/material-examples
然后他们有 loader : https://github.com/angular/material.angular.io/blob/master/src/app/shared/doc-viewer/doc-viewer.ts#L85
这可能是正确的做法,但我不知道如何调整它来管理动态的 Tab 内容。
编辑:我在这里添加了示例:https://github.com/yanis-git/aot-jit-angular(分支大师)
正如你将看到的,AOT 编译从包中删除了墙编译器,这个结果:
Module not found: Error: Can't resolve '@angular/compiler/src/config'
我尝试在 AppModule 上强制编译器工厂,但仍然没有结果。
我在同一个 repo 上有另一个示例,但是在分支“lazy-jit”上,现在我在输出的包中嵌入了编译器,但新的错误出现在我身上:
ERROR Error: No NgModule metadata found for 'ArticleLiveModule'.
谁看起来和这个问题完全一样:https://github.com/angular/angular/issues/16033
【问题讨论】:
-
Angular 材质不会在运行时编译模板。他们使用 entryComponents github.com/angular/material2/blob/…
-
是的,这是我试图解释的。我不能使用相同的材料网站方式,因为它们使用预编译的组件示例。
-
感谢 yurzui 这个资源,我已经尝试过了,但不幸的是。没有 Angular 的编译器部分的结果编译。
-
你能创建简单的应用程序来重现它吗?
标签: angular angular5 jit aot angular-aot