在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)
Possible reason : 我猜的主要原因是因为AOT编译从输出编译的bundle中删除了Angular的一部分"compiler" . What i have try - 我试图直接在我的代码上要求它但仍然不存在 . - 我试着检查像角度(或角度材料)的网站如何处理它 . 但是不符合我的情况 . 实际上,两者都已经在AOT版本中编译了所有示例的版本 . 动态部分是样本周围的"just"内容 .
如果您想检查角度材料的作用方式:每个组件的所有网站示例:https://github.com/angular/material2/tree/master/src/material-examples
可能是正确的方法,但我不知道如何适应它来管理,动态Tab内容 .
EDIT :我在这里添加样本:https://github.com/yanis-git/aot-jit-angular(分支大师)
正如您将看到的,AOT编译从bundle中删除了wall编译器,结果如下:
Module not found: Error: Can't resolve '@angular/compiler/src/config'
我试图在AppModule上强制compilater Factory,但仍然没有结果 .
我在同一个repo上有另一个示例,但在分支“lazy-jit”上,现在我将Compiler嵌入到输出的包中,但是新的错误出现在我面前:
ERROR Error: No NgModule metadata found for 'ArticleLiveModule'.
谁看起来与这个问题完全相同:https://github.com/angular/angular/issues/16033
2 回答
试试这个:
CODE EXAMPLE
在上面的代码示例中,NgModule和Component没有 decorators . 所以,这意味着没有 @Injectable 也无法注入
providers
. 那么为什么我们不为 @NgModule 和 @Component @Injectable decorator编写并只将其写入 Services ?因为,他们有装饰器(@ NgModule / @ Components),Services
没有 . 他们的装饰者足以让Angular知道他们是 injectable .CODE EXAMPLE与DI .
UPDATE: 创建自定义包装器
CustomNgModule
,CustomComponent
和CustomInjectable
装饰器:lazy.module.ts:
app.component.ts:
CODE EXAMPLE 3
我最近遇到了同样的问题,现在放弃了尝试解决的问题 .
Afaik这不能(现在)因为angular removes metadata on production build .
我们应该在8896关闭后再试一次 .