0

如果我正在迁移到 Angular 2 并且我想使用工厂模式来创建一个瞬态依赖项(一种在注入它的组件之间不共享状态的依赖项),那么在 Angular 中注册服务的最佳方法是什么1.5.8 计划迁移到 ng2 的注册服务方式

我知道在 Angular 2 中,组件可以通过将服务传递给 providers 数组来重新实例化服务,但是该选项在 Angular 1 中不存在,而且似乎.factory在 Angular 2 中几乎已被弃用,因为文档并没有给它太多的爱

一个示例是 TabulationService,它管理用户在仪表板上查看的选项卡的状态,这显然不会在组件之间共享状态。我想在它注入的每个组件中重新实例化服务。.factory但如果 Angular 2 最佳实践似乎回避使用它,我也想避免使用它。

这是我使用的“hack”,但我不喜欢它,因为即使它让我为我的服务提供类型提示和无状态,我也不能在创建的对象中使用依赖注入,我必须管理我的服务在被注入时的状态以及当它被注入的组件被销毁时(通过手动清除服务的状态):

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)来初始化该服务

4

1 回答 1

0

没有什么可以责怪 Angular 2 文档的。Angular 1factory服务在 Angular 2 DI 中作为useFactoryprovider实现。

factory如果是或service在这种情况下,这并不重要。两者都服务于相同的目的并共享相同的行为——它们在 Angular 1 中是单例。同样,在 Angular 2 中useFactoryuseClass提供者是同一个注入器中的单例。

为了在两个框架中统一实现所需的行为,应该在注入后实例化依赖项。使用工厂函数还是构造函数来完成并不重要——它们应该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();
  }
}
于 2016-12-09T21:16:55.807 回答