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

时间:2017-03-07 16:26:30

标签: angular dependency-injection angular2-aot aot

首先,我必须说我的应用程序正常运行"使用" JIT。 我甚至可以捆绑生产(没有AOT,只是JIT),它工作正常。

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

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

这是MyComponent

的构造函数
constructor( headerService:HeaderService, sidebarService:SidebarService, @Inject( AuthService.Token ) authService:AuthService.Class, router:Router, carbon:Carbon ) {
    …
    this.carbon = carbon;
    …
}

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

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

正在使用导出它们的angular2-carbonldp项目导入CARBON_PROVIDERS

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();
        },
    },
];

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

2 个答案:

答案 0 :(得分:6)

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

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

以下代码导致失败

useFactory(): Context {
  return activeContextFn();
}

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

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

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

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

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

在这种特殊情况下,我认为您需要按如下方式重写工厂:

useFactory: contextFactory

....

export function contextFactory() {
    return activeContextFn();
}

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

这是一个非常有用的沙盒&#34; https://github.com/rangle/angular-2-aot-sandbox

请注意,上面链接的存储库 是官方文档来源,并且定义了 拥有 基于其功能的子集。 请谨慎使用。

答案 1 :(得分:0)

对于搜索此特定错误文本的其他人:

在启用AOT的情况下构建父角度项目时遇到了此错误,该项目有一个子角度库项目,该项目已与ng-packagr打包在一起,该内部使用了桶。通过将库项目中的所有桶形引用都更改为显式引用,可以解决该问题。

之前

import { MyService } from './featureFolder';

之后

import { MyService } from './featureFolder/my.service';

问题链接 开发团队声称这是固定的,但在Angular 8中似乎以某种形式恢复了。 https://github.com/angular/angular/issues/23713