Как использовать фабричный шаблон, если я перехожу с Angular 1.5.8 на Angular 2?

Если я перехожу на Angular 2 и хочу использовать шаблон фабрики для создания временной зависимости (зависимость, которая не разделяет состояние между компонентами, в которые она внедряется), каков наилучший способ регистрации службы в angular 1.5.8 с планами перехода на ng2 способ регистрации сервисов

Я знаю, что в Angular 2 компоненты могут восстанавливать сервисы, передавая их в массив провайдеров, но эта опция не существует в Angular 1, и кажется, что .factory в Angular 2 почти устарела, так как документы не дают ему много любви

Примером может служить TabulationService, который управляет состоянием вкладки, которую пользователь просматривает на панели мониторинга, которая, очевидно, не будет делить состояние между компонентами. Я хотел бы повторно создать сервис в каждом компоненте, в который он внедряется. Но я также хочу избежать использования .factory если Angular 2 лучшие практики, кажется, уклоняются от его использования.

Вот "хак", к которому я прибегал, но мне он не нравится, потому что, хотя он и дает мне подсказку типа и отсутствие состояния для моего сервиса, я не могу использовать внедрение зависимостей в объект, который создается, и мне приходится управлять состоянием моего сервиса, когда он внедряется и когда компонент, в который он внедряется, уничтожается (путем ручной очистки состояния сервиса):

tab-manager.service.ts:

import { TabManager } from './tab-manager.class';

export class TabService {
  manager;

  public initialize(tabs: string[], defaultTab: string) {
    this.manager = new TabManager(tabs, defaultTab);
  }
}

tab-manager.class.ts:

import { includes } from 'lodash';

const mandatory = (param) => { throw new Error(`${ param } is a required field in Tab Manager!`) };
export class TabManager {
  tab: string;

  constructor(public tabs: string[] = mandatory(`tabs`), public defaultTab: string = mandatory('defaultTab')) { 
    this.checkTab(defaultTab);
    this.tab = defaultTab;
  }

  public switchTab(tab) {
    const self = this;

    self.checkTab(tab);
    self.tab = tab;
  }

  private checkTab(tab: string) {
    const self = this;
    if (!includes(self.tabs, tab)) {
      throw new Error(`{ tab } is not a valid tab. Available tabs are ${ self.tabs.join(',') }`);
    }
  }
}

Затем служба инициализируется путем импорта службы TabManager из tab-manager.service.ts и вызов `angular.service('TabService', TabManagerService)

1 ответ

В документации Angular 2 винить нечего. Угловой 1 factory сервис реализован в Angular 2 DI как useFactory провайдер.

Это не имеет значения, если это factory или же service в этом случае. Оба служат одной и той же цели и имеют одинаковое поведение - они являются синглетонами в Angular 1. Аналогично, useFactory а также useClass провайдеры - это синглтоны внутри одного инжектора в Angular 2.

Для достижения желаемого поведения равномерно в обеих структурах должна быть создана зависимость после внедрения. Неважно, если это делается с помощью функции фабрики или конструктора - они должны быть определены как value обслуживание в Angular 1 или useValue провайдер в Angular 2.

Для Angular 1 это будет:

export class TabulationService { ... }
export type TTabulationService = typeof TabulationService;
...

app.value('TabulationService', TabulationService);

app.component('some', {
  controller: class {
    tabulationService: TabulationService;

    static $inject = ['TabulationService'];

    constructor (TabulationService: TTabulationService) {
      this.tabulationService = new TabulationService();
    }
  }
});

А для Angular 2:

providers: [{ provide: TabulationService, useValue: TabulationService }]
...

@Component(...)
export class SomeComponent {
  tabulationService: TabulationService;

  constructor (@Inject(TabulationService) TabulationService: TTabulationService) {
    this.tabulationService = new TabulationService();
  }
}
Другие вопросы по тегам