如果我从Angular 1.5.8迁移到Angular 2,我该如何使用工厂模式?

时间:2016-12-09 19:46:13

标签: angularjs angular typescript angular-services angular-factory

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

我知道在角度2中,组件可以通过将服务传递给providers数组来重新实现服务,但是角度1中不存在该选项,并且似乎.factory只是在角度2中被弃用,因为docs不会给它太多的爱

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

这是我所使用的“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(',') }`);
    }
  }
}

然后通过从tab-manager.service.ts导入TabManager服务并调用`angular.service('TabService',TabManagerService)来初始化服务

1 个答案:

答案 0 :(得分:0)

没有什么可以归咎于Angular 2文档。 Angular 1 factory服务在Angular 2 DI中实现为useFactory provider

如果在这种情况下factoryservice,这并不重要。两者都有相同的目的并且具有相同的行为 - 它们是Angular 1中的单例。同样,useFactoryuseClass提供者是Angular 2中同一个注入器中的单例。

为了在两个框架中统一地实现期望的行为,应该在注入之后实例化依赖性。如果使用工厂或构造函数完成这一点并不重要 - 它们应该在Angular 1中的value服务或Angular 2中的useValue提供程序中定义。

对于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();
  }
}