Подтвердить что ты не робот

Angular2 "Услуги", как @включить одну услугу в другую (одноточие)

Как я мог бы вводить одну услугу в другую? Предположим, например, что у меня есть коллекция, для которой требуется другая коллекция (TeamCollection = > PlayerCollection). В настоящее время я просто создаю две отдельные коллекции и использую что-то вроде:

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

Но для этого требуется, чтобы я написал свой код singleton getInstance внутри Typescript для каждой службы, которую я хочу быть экземпляром singleton.

Каков правильный способ сделать это? Я хочу иметь как синглеты в моих Компонентах, так и иметь возможность вставлять одну службу в другую, используя синтаксис конструктора, без создания нового экземпляра синглтонов.

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

Ответ 1

Итак, перечитав этот отличный пост Паскалем Пречтом: http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html

И, увидев, что он комментирует: http://twofuckingdevelopers.com/2015/04/angular-2-singleton-service/

"Все введенное с использованием Angular 2s DI уже является Singleton. Нет необходимости в такой службе"

Я пошел на тестирование, и то, что я сейчас нашел, ответил на мой вопрос и еще больше смутил тему DI в angular2.

Смотрите следующий код:

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);
  });  
});

До тех пор, пока он был тем же Инжектором (var injector), который создал оба они имеют один и тот же uuID. Хотя, когда я использую второй инжектор (var injectorT), UUID различаются, что означает создание нового экземпляра 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

Ответ 2

Я обнаружил, что другой способ иметь однопользовательскую услугу - создать шаблон singleton с помощью метода getInstance(), который вызывает конструктор, тогда вы не вводите свою службу в конструктор компонента, а просто ссылаетесь на нее как на статическую класс. Здесь вы можете проверить пример кода:

Доступ к ключевым данным по всему приложению в Angular 2 и Ionic 2

Ищите мой ответ, я думаю, что он второй на странице. Если это сработает для вас, я был бы признателен, если бы вы смогли его проголосовать. Спасибо.

Ответ 3

Что вам нужно сделать, это следующее:

Вы можете вводить услугу только после того, как вы "предоставили" эту услугу. Когда это делается в @component, это легко, потому что у вас есть оператор [....].

Если вы хотите сделать это для службы, у вас нет провайдеров: [].... поэтому единственное место, где вы можете это сделать, - это время загрузки, когда вам нужно указать службу в

boostrap(app, [

PlayerCollection,
Other,
More Services...



]

Если вы копаете в документации, в нем говорится, что вам нужно сделать это таким образом.