Angular2依赖注入 - 多层

时间:2015-09-03 22:02:51

标签: dependency-injection typescript angular

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

我试图找出如何注入从另一个文件中获取注入的对象。根据{{​​3}}和angular.io 5 Min Quickstart的示例,我将Person2成功注入主应用类。

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. 我无法弄清楚在哪里得到&#39; angular2 / di&#39;。似乎&#39; angular2 / angular2&#39;因为打字稿编译器没有抱怨所以有Inject。
  2. Pascal Precht's article about Dependency Injection说我可以注入@Inject(Person2) Person2person: Person2,但由于打字稿编译器不知道从哪里获取Person2,所以它们都不起作用。所以我尝试了@Inject('Person2') person2,至少可以编译。
  3. 只有在person.ts中导入Person2时,
  4. person.ts才可以使用person: Person2进行编译。但我应该能够将Person2注入Person而不在Person中导入它。如果我必须导入我注入的内容,依赖注入的重点是什么,对吧?
  5. 修改后的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的答案,但仍然没有运气。我做了Pascal Precht's article about Dependency Injection。如果您将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)]);
    

    这仍然不够:与Plunker with compiled js files不同,我不得不包括--emitDecoratorMetadata。我的tsc命令如下所示:

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

    这是angular.io 5 Min Quickstart

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

1 个答案:

答案 0 :(得分:3)

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

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

// a lot of code ...

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