【问题标题】:Class is not injectable if it is defined right after a component with meta annotation如果在带有元注释的组件之后立即定义类,则它是不可注入的
【发布时间】:2025-11-24 03:35:01
【问题描述】:

我刚开始使用 Angular2 快速启动项目。有一个简单的应用程序工作。我添加了DataService 类,这样代码就会有关注点分离。

最初我在应用程序的主要组件 MyAppComponent 之后添加了 DataService 类,如下所示。

import {Component, View} from 'angular2/core';
import {NgFor} from 'angular2/common';
import {bootstrap} from 'angular2/platform/browser';

@Component({
    'selector': 'my-app',
    template: `<div *ngFor="#item of items">{{item}}</div>`,
    directives: [NgFor],
    providers: [DataService] //taking service as injectable
})
export class MyAppComponent {
    items: Array<number>;
    constructor(service: DataService) {
        this.items = service.getItems(); //retrieving list to bind on the UI.
    }
}
//created service, but its after the component which has meta annotation
export class DataService {
    items: Array<number>;
    constructor() {
        this.items = [1, 2, 3, 4];
    }
    getItems() {
        return this.items; //return the items list
    }
}

bootstrap(MyAppComponent)

上面的代码编译正确,但在运行时会抛出下面的错误。

例外:无法解析所有参数 MyAppComponent(未定义)。确保它们都具有有效的类型或 注释。

在使用代码 2 小时后,我将 DataService 移到了 MyAppComponent 的上方,这已成功。我真的很高兴这个问题解决了。

但我很想知道,如果我在 class 之后放置 DataService 类并在其上放置 MetaAnnotation,为什么它不起作用?

编辑

我尝试了@Günter Zöchbauer 提供的解决方案,如下所示,

import {Component, View, Inject, forwardRef} from 'angular2/core';
import {NgFor} from 'angular2/common';
import {bootstrap} from 'angular2/platform/browser';

@Component({
    'selector': 'my-app',
    template: `<div *ngFor="#item of items">{{item}}</div>`,
    directives: [NgFor],
    providers: [DataService] //tried commenting this still throws error.
})
export class MyAppComponent {
    items: Array<number>;
    constructor(@Inject(forwardRef(() => DataService)) service: DataService) {
        this.items = service.getItems();
    }
}

但在控制台中仍然出现错误。看起来很奇怪

异常:类型错误:无法读取未定义的属性“toString”

【问题讨论】:

    标签: javascript dependency-injection ecmascript-6 angular


    【解决方案1】:

    JavaScript 不会提升类。要么使用forwardRef,将DataService 移到它自己的文件中,要么将DataService 类移到MyAppComponent 之上

    @Component({
        'selector': 'my-app',
        template: `<div *ngFor="#item of items">{{item}}</div>`,
        directives: [NgFor],
        providers: [forwardRef(() => DataService)] //taking service as injectable
    })
    export class MyAppComponent {
        items: Array<number>;
        constructor(@Inject(forwardRef(() => DataService)) service: DataService) {
            this.items = service.getItems(); //retrieving list to bind on the UI.
        }
    }
    

    另见
    - Angular 2 error:
    - http://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html

    【讨论】:

    • @Gunter 在这种情况下 forwardRef 必须进入 providers 属性
    • @GünterZöchbauer 这次编辑解决了我的问题..但我可以知道为什么我们需要这样做两次吗?
    • 我假设是因为在这两个地方你指的是一个未知的类,因为这两行都在类声明之前。
    最近更新 更多