Angular2"服务"如何将一个服务注入另一个服务(单身人士)?

时间:2015-11-06 20:47:16

标签: angular

我如何将一项服务注入另一项服务?举个例子,我说我有一个需要另一个Collection的集合(TeamCollection => PlayerCollection)。目前我只创建两个单独的集合,并使用类似:

import {PlayerCollection} from "<<folder>>/player";

但是这需要我在Typescript中为我想要成为单例实例的每个服务编写自己的单例getInstance代码。

这样做的正确方法是什么?我希望在我的组件中拥有两个单例,并且能够使用构造函数语法将一个服务注入另一个服务,而无需创建新的单例实例。

class TeamCollection {    
    constructor(@Inject(PlayerCollection): PlayerCollection) {}
}

3 个答案:

答案 0 :(得分:16)

因此,重新阅读Pascal Precht的这篇优秀文章:http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html

看到他发表评论:http://twofuckingdevelopers.com/2015/04/angular-2-singleton-service/

&#34;使用Angular 2的DI注入的所有内容都已经是Singleton。不需要这样的服务&#34;

我进行了测试,我现在发现的内容都回答了我的问题,让我对angular2中的DI话题更加困惑。

请参阅以下代码:

team.ts

import {BaseCollection, BaseModel} from "./base";
import {PlayerCollection} from './player';
import {Injectable, Inject} from "angular2/angular2";

@Injectable()
export class TeamCollection extends BaseCollection {
    playerCollection: PlayerCollection;
    constructor(@Inject(PlayerCollection) playerCollection: PlayerCollection) {
        super();
        this.playerCollection = playerCollection;
    }

    create(data: Object): TeamModel {
        return new TeamModel(data);
    }
}

player.ts

import {BaseCollection, BaseModel} from "./base";
import {Injectable} from "angular2/angular2";

@Injectable()
export class PlayerCollection extends BaseCollection {
    create(data: Object): PlayerModel {
        return new PlayerModel(data);
    }
}

team.spec.ts

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

//VERY IMPORTANT TO ALWAYS LOAD THESE
import 'zone.js';
import 'reflect-metadata';
import 'es6-shim';

import {TeamModel, TeamCollection} from "../../app/model/team";
import {PlayerCollection} from "../../app/model/player";
import {Inject, Injector} from "angular2/angular2";

describe('TeamCollection', () => {
  var teamCollection: TeamCollection;
  var playerCollection: PlayerCollection; 
  beforeEach(() => {
      var injector = Injector.resolveAndCreate([
        TeamCollection,
        PlayerCollection
      ]);
      teamCollection = injector.get(TeamCollection);  

      var injectorT = Injector.resolveAndCreate([
        PlayerCollection
      ]);
      playerCollection = injector.get(PlayerCollection);
  });

  it('should have a singleton PlayerCollection shared between all classes within the application', () => {
    console.log(teamCollection.playerCollection.uuId);
    console.log(playerCollection.uuId);
  });  
});

只要创建两者的Injector(var injector)相同,它们共享相同的uuID虽然当我使用第二个注入器(var injectorT)时,UUID是不同的意味着创建了一个新实例of playerCollection。

现在我的问题是。如果我使用组件提供程序语法:

@Component({
  selector: 'app',
  providers: [TeamCollection]
}) 

@Component({
  selector: 'player-list',
  providers: [PlayerCollection]
})

两者会共享同一个玩家集合,还是会创建一个新实例?

编辑: 只要通过bootstrap(.., [ServiceA,ServiceB])方法创建

,它们就会执行

感谢pascal precht http://blog.thoughtram.io/angular/2015/09/17/resolve-service-dependencies-in-angular-2.html

答案 1 :(得分:1)

我发现使用单例服务的另一种方法是使用调用构造函数的getInstance()方法创建单例模式,然后不将服务注入组件构造函数,而只是将其作为静态引用类。您可以在此处查看示例代码:

Access key data across entire app in Angular 2 & Ionic 2

寻找我的答案,我认为它是页面中的第二个。如果它适合你,我将不胜感激,如果你可以投票。感谢。

答案 2 :(得分:1)

您需要确保以下内容:

只有在提供&#34;提供&#34;服务。在@component中执行此操作时很容易,因为您有provider [....]语句。

当您想要为服务执行此操作时,您没有提供者:[] ....因此,您可以执行此操作的唯一位置是在您需要在

中指定服务的引导时间内
boostrap(app, [

PlayerCollection,
Other,
More Services...



]

如果您仔细阅读文档,则明确说明您需要这样做。