同一项目的角度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@H_301_76@ 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相关文章