同一项目的角度AOT和JIT

前端之家收集整理的这篇文章主要介绍了同一项目的角度AOT和JIT前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在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,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);
    }
}

正如您所看到的,我可以使用自定义HTML作为模板调用addHtmlComponent方法在运行时编译新组件.

我的模板看起来像:

<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编译从输出编译的bundle中删除Angular的“编译器”部分.
我尝试了什么
– 我试图直接在我的代码上要求它但仍然不存在.
– 我试着检查像角度(或角度材料)的网站如何处理它.但是不符合我的情况.实际上,两者都已经在AOT版本中编译了所有示例的版本.动态部分是样本周围的“正义”内容.

如果要检查角度材料的作用:
每个组件的所有网站示例:https://github.com/angular/material2/tree/master/src/material-examples

然后他们有装载机:
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编译从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

试试这个:
import { Compiler,COMPILER_OPTIONS,CompilerFactory,NgModule } from '@angular/core';
    import { BrowserModule,} from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';

    import { AppComponent } from './app.component';
    import { HelloComponent } from './hello.component';


    import { JitCompilerFactory } from '@angular/platform-browser-dynamic';

    export function createCompiler(compilerFactory: CompilerFactory) {
      return compilerFactory.createCompiler();
    }


    @NgModule({
      providers: [
        { provide: COMPILER_OPTIONS,useValue: {},multi: true },{ provide: CompilerFactory,useClass: JitCompilerFactory,deps: [COMPILER_OPTIONS] },{ provide: Compiler,useFactory: createCompiler,deps: [CompilerFactory] }
      ],imports: [BrowserModule,FormsModule],declarations: [AppComponent,HelloComponent],bootstrap: [AppComponent]
    })
    export class AppModule { }

CODE EXAMPLE

But JitCompiler still not able to create Dependency Injection tree. I
suspect @Injectable to be remove from AOT part. But i can’t do your
trick.

在上面的代码示例中,没有NgModule和Component的装饰器.所以,这意味着没有@Injectable也无法注入提供者.那么为什么我们不为@NgModule和@Component @Injectable装饰器编写并只将其写入服务?
因为,他们有装饰器(@ NgModule / @ Components),服务没有.他们的装饰者足以让Angular知道他们是可注射的.

CODE EXAMPLE与DI.

更新:
创建自定义包装器CustomNgModule,CustomComponent和CustomInjectable装饰器:

export function CustomComponent(annotation: any) {
    return function (target: Function) {
        const component = new Component(annotation);
        Component(component)(target);

    };
}

export function CustomNgModule(annotation: any) {
    return function (target: Function) {
        const ngModule = new NgModule(annotation);
        NgModule(ngModule)(target);
    };
}


export function CustomInjectable() {
  return function (target: Function) {
      const injectable = new Injectable();
      Injectable()(target);
  };
}

When building with AOT flag,Angular-CLI looks like cleans bundle
from native decorators from parts of code which need to be compiled
dynamically.

And where you want dynamically compile modules with components
in AOT with DI functionality,replace native decorators
(NgModule/Injectable...) with custom one to preserve decorators in
AOT compilation mode:

lazy.module.ts:

@CustomComponent({
  selector: 'lazy-component',template: 'Lazy-loaded component. name:  {{name}}.Service 
           {{service.foo()}}!',//providers: [SampleService]
})
export class LazyComponent {
  name;
  constructor(public service: SampleService) {
    console.log(service);
    console.log(service.foo());
  }
}

@CustomNgModule({
  declarations: [LazyComponent],providers: [SampleService]
})
export class LazyModule {
}

app.component.ts:

...
 ngAfterViewInit() {

    this.compiler.compileModuleAndAllComponentsAsync(LazyModule)
      .then((factories) => {
        const f = factories.componentFactories[0];    
        const cmpRef = this.vc.createComponent(f);    
        cmpRef.instance.name = 'dynamic';
      });
  }
...

CODE EXAMPLE 3

猜你在找的Angularjs相关文章