AOT无法解决[...]的所有参数

use*_*063 4 dependency-injection aot angular2-aot angular

首先,我必须说我的应用程序在"使用"JIT时工作正常.我甚至可以捆绑prod(没有AOT,只是JIT),它工作正常.

但是当我尝试编译它(AOT)时,ngc我收到一个错误,其中说:

Can't resolve all parameters for MyComponentView in /path/my-component/my-component.view.ts:
([object Object], [object Object], [object Object], [object Object], ?)
Run Code Online (Sandbox Code Playgroud)

这是以下构造函数MyComponent:

constructor( headerService:HeaderService, sidebarService:SidebarService, @Inject( AuthService.Token ) authService:AuthService.Class, router:Router, carbon:Carbon ) {
    …
    this.carbon = carbon;
    …
}
Run Code Online (Sandbox Code Playgroud)

AppModule中提供了最后一个依赖项(Carbon),如下所示:

@NgModule( {
    imports: [
        …
    ],
    declarations: [
        …
    ],
    providers: [
        …
        CARBON_PROVIDERS,   //<---- HERE IS BEING PROVIDED
        CARBON_SERVICES_PROVIDERS,
        …
    ],
    bootstrap: [ AppComponent ],
} )
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

CARBON_PROVIDERS正在使用的进口angular2-carbonldp这是出口他们喜欢这个项目:

export const CARBON_PROVIDERS:any[] = [
{
        provide: Carbon,
        useFactory(): Context {
            return carbon;
        },
    },
    {
        provide: ContextToken,
        useFactory(): Context {
            return activeContextFn();
        },
    },
    {
        provide: App.Context,
        useFactory(): App.Context {
            if( ! activeContextFn.isAppContext() ) throw new Errors.IllegalStateError( "The activeContext is not an App Context" );
            return <any>activeContextFn();
        },
    },
];
Run Code Online (Sandbox Code Playgroud)

但我最终得到了同样的错误,我不明白为什么!你们碰巧知道它为什么会那样起作用吗?

Alu*_*dad 7

因为AOT编译器仅支持一小部分JavaScript.这个事实记录很少,根本没有记录,也没有广泛宣传.

它无法解析Angular 2框架装饰器中的许多JavaScript表达式.这包括他们合法的函数调用.

以下代码导致失败

useFactory(): Context {
  return activeContextFn();
}
Run Code Online (Sandbox Code Playgroud)

原因是AOT下的angular2装饰器根本不是装饰器.

Angular 2 AOT编译器维护一个已知的装饰器列表,它在运行时不会持久存在,而是将它们视为注释*.这意味着它们只能包含常量表达式,对导出名称的引用,几种形式的数组文字语法和由常量表达式组成的对象文字语法,以及其他一些内容.

如果您想知道,是的,这意味着您不再编写TypeScript代码,因此不再编写JavaScript代码.顺便说一下,这也意味着你不能相信你的大多数工具,因为他们会为无效代码提供绿灯,因为他们不了解这种语言.

它是一种具有不同语义的不同语言,而不仅仅是一个子集,因为它执行的装饰器转换违反了ECMAScript中该特征的规范.Typescript不会添加或修改ECMAScript的任何运行时行为.

*作为参考,这里使用术语注释,因为它与@Script语言中现已死亡有关.这是Angular团队发明用于编写框架的语言,并在他们转移到TypeScript之前通过专用的转换器开始大量使用.

在这个特定情况下,我认为您需要重写您的工厂,如下所示:

useFactory: contextFactory

....

export function contextFactory() {
    return activeContextFn();
}
Run Code Online (Sandbox Code Playgroud)

这可能不是您需要做的全部,语言无疑会随着时间而改变.它将获得IDE支持.

这是一个相当有用的"沙盒" https://github.com/rangle/angular-2-aot-sandbox

请注意,上面链接的存储库不是官方文档源,它根据其功能定义自己的子集.谨慎使用.