Bry*_*son 41 javascript angular
我知道如何将服务注入组件(通过@Component),但是如何使用DI来传递组件之外的服务?
换句话说,我不想这样做:
export class MyFirstSvc {
}
export class MySecondSvc {
    constructor() {
        this.helpfulService = new MyFirstSvc();
    }
}
export class MyThirdSvc {
    constructor() {
        this.helpfulService = new MyFirstSvc();
    }
}
Thi*_*ier 48
是的,首先要@Injectable在每个要注入的服务上添加装饰器.事实上,这个Injectable名字有点阴险.这并不意味着该类将是"可注入的",但它将进行装饰,因此可以注入构造函数参数.有关更多详细信息,请参阅此github问题:https://github.com/angular/angular/issues/4404.
以下是我对注射机制的理解.在@Injectable为类设置装饰器时,Angular将尝试为当前执行链的注入器中的相应类型创建或获取实例.实际上,Angular2应用程序不仅有一个注入器,而且还有一个注入器树.它们与整个应用程序和组件隐式关联.此级别的一个关键特性是它们以分层方式链接在一起.这个注入器树映射组件树.没有为"服务"定义注入器.
我们来试试吧.我有以下应用程序:
组件AppComponent:在bootstrap函数中创建Angular2应用程序时提供的应用程序的主要组件
@Component({
  selector: 'my-app', 
    template: `
      <child></child>
    `,
    (...)
    directives: [ ChildComponent ]
})
export class AppComponent {
}
组件ChildComponent:将在AppComponent组件中使用的子组件
@Component({
    selector: 'child', 
    template: `
      {{data | json}}<br/>
      <a href="#" (click)="getData()">Get data</a>
    `,
    (...)
})
export class ChildComponent {
  constructor(service1:Service1) {
    this.service1 = service1;
  }
  getData() {
    this.data = this.service1.getData();
      return false; 
  }
}
两个服务,Service1和Service2:Service1由ChildComponent和Service2使用Service1
@Injectable()
export class Service1 {
  constructor(service2:Service2) {
    this.service2 = service2;
  }
  getData() {
    return this.service2.getData();
  }
}
@Injectable()
export class Service2 {
  getData() {
    return [
      { message: 'message1' },
      { message: 'message2' }
    ];
  }
}
以下是所有这些元素及其关系的概述:
Application
     |
AppComponent
     |
ChildComponent
  getData()     --- Service1 --- Service2
在这种应用中,我们有三个注射器:
bootstrap函数的第二个参数配置的应用程序注入器AppComponent可以使用providers此组件的属性配置的注入器.它可以"看到"应用程序注入器中定义的元素.这意味着如果在此提供程序中找不到提供程序,它将自动查找此父注入程序.如果在后者中找不到,则会抛出"找不到提供者"错误.ChildComponent将遵循比相同的规则喷油器AppComponent之一.要注入为组件执行的注入链中涉及的元素,将首先在此注入器中查找提供者,然后在AppComponent一个注册器中查找提供者,最后在应用程序中查找提供者.这意味着当尝试将注入Service1到ChildComponent构造函数中时,Angular2将查看注入ChildComponent器,然后进入注册器,AppComponent最后进入应用程序.
由于Service2需要注入Service1,因此将执行相同的分辨率处理:ChildComponent注入器,AppComponent一个和应用程序.
这意味着,Service1和Service2根据使用您的需要可以在每个级别中指定providers为组件属性和的第二参数bootstrap为应用注射器功能.
这允许共享一组元素的依赖项实例:
因此它非常强大,您可以根据自己的需要和需求自由组织.
以下是相应的plunkr所以你可以用它玩:https://plnkr.co/edit/PsySVcX6OKtD3A9TuAEw?p=preview.
Angular2文档中的这个链接可以帮助您:https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html .
希望它可以帮助你(对不起,答案很长),蒂埃里
bootstrap()如果每个服务只有一个实例(单例),您可以将它们放在应用程序的根目录中.@Injectable()在任何依赖于另一个的服务上使用装饰器.boot.ts
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';
import {MyFirstSvc} from '../services/MyFirstSvc';
import {MySecondSvc} from '../services/MySecondSvc';
bootstrap(AppComponent, [MyFirstSvc, MySecondSvc]);
MySecondSvc.ts
import {Injectable} from 'angular2/core';
import {MyFirstSvc} from '../services/MyFirstSvc';
@Injectable()
export class MySecondSvc {
  constructor(private _firstSvc:MyFirstSvc) {}
  getValue() {
    return this._firstSvc.value;
  }
}
请参阅Plunker其他文件.
服务DI有点奇怪的是它依赖于组件.例如,   MySecondSvc在组件请求它时创建,并且取决于MyFirstSvc组件树中"提供"的位置,这可能会影响MyFirstSvc注入哪个实例MySecondSvc.这里将对此进行更多讨论:您是否只能通过引导程序将服务注入服务?
| 归档时间: | 
 | 
| 查看次数: | 36463 次 | 
| 最近记录: |