Angular2 依赖注入 - 多层

Angular2 dependency injection - multiple layer

查看此问题的底部,了解我必须更改哪些内容才能使其正常工作。

我正在尝试弄清楚如何注入一个从另一个文件获取注入的对象。按照 angular.io 5 Min Quickstart and Pascal Precht's article about Dependency Injection 的示例,我成功地将我的 Person2 注入到主应用程序 class。

app.ts:

/// <reference path="typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap} from 'angular2/angular2';
import {Person2} from './person2';

@Component({
    selector: 'my-app'
})
@View({
    template: '<h1>Hello {{name}}</h1>'
})
class MyAppComponent {
    name: string;

    constructor(person: Person2) {
        this.name = person.name;
    }
}

bootstrap(MyAppComponent, [Person2]);

person2.ts:

export class Person2 {
    name: string;

    constructor() {
        this.name = 'Mee!';
    }
}

这很好用。现在我尝试注入 Person,它得到 Person2。

person.ts:

import {Inject} from 'angular2/angular2';

export class Person {
    name: string;

    constructor(@Inject('Person2') person2) {
        this.name = person2.name;
    }
}

一些关于 person.ts 的注释:

  1. 我不知道从哪里得到 'angular2/di'。似乎 'angular2/angular2' 有注入,因为打字稿编译器没有抱怨。
  2. Pascal Precht's article about Dependency Injection 说我可以注入 @Inject(Person2) Person2person: Person2,但其中 none 有效,因为打字稿编译器不知道从哪里获取 Person2。所以我尝试了 @Inject('Person2') person2 并且至少它得到了编译。
  3. person.ts 仅当我在 person.ts 中导入 Person2 时才可以用 person: Person2 编译。但是我应该能够将 Person2 注入到 Person 而无需在 Person 中导入它。如果我必须导入我正在注入的东西,那么依赖注入的意义何在,对吗?

已修订 app.ts:

/// <reference path="typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap} from 'angular2/angular2';
import {Person} from './person';
import {Person2} from './person2';

@Component({
    selector: 'my-app'
})
@View({
    template: '<h1>Hello {{name}}</h1>'
})
class MyAppComponent {
    name: string;

    constructor(person: Person) {
        this.name = person.name;
    }
}

bootstrap(MyAppComponent, [Person, Person2]);

当我 运行 修改后的应用程序时,我没有得到预期的结果,但浏览器控制台出现错误 Error during instantiation of Person! (MyAppComponent -> Person).

我做错了什么?

编辑 我尝试了@alexpods 的回答,但仍然没有成功。我做了一个Plunker with compiled js files。如果您将 app.js 行 #27 更改为 [person_1.Person],您将看到它不再起作用。

编辑 2:终于我成功了

正如@alexpods 所说,我更改了 app.ts 上的 bootstrap 行及其注入方式。

// you need to import Inject and bind
import {Component, View, bootstrap, Inject, bind} from 'angular2/angular2';
//...../.
// you need to inject using @Inject. person: Person will not work.
constructor(@Inject('Person') person) {
//......
// on top of declaring Person and Person2 as dependencies, you need to associate the string `Person` and `Person2` to actual class, so that @Inject can find them.
bootstrap(MyAppComponent, [Person, Person2, bind('Person').toClass(Person), bind('Person2').toClass(Person2)]);

这还不够:不像 angular.io 5 Min Quickstart 所说的那样,我不得不不包括 --emitDecoratorMetadata。我的 tsc 命令如下所示:

tsc --watch -m commonjs -t es5 app.ts person.ts person2.ts --experimentalDecorators

这里是another plunker that works.

我正在使用 tsc 版本 1.6.0-beta。

'Person2' 字符串的绑定添加到应用程序 bootstrap(或 MyApComponentbindings 属性):

import {Component, View, bootstrap, bind } from 'angular2/angular2';

// a lot of code ...

bootstrap(MyAppComponent, [Person, Person2, bind('Person2').toClass(Person2)]);