如何更新Angular中提供者提供的值?

时间:2020-08-06 18:11:59

标签: angular dynamic angular-providers

我在AppModule中有一个提供程序,提供了一个类。

是否可以在运行时更新提供的值?

{provide: MatDatepickerIntl, useClass: SomeClass}

如何在运行时(即:对组件中的事件做出反应时)将SomeClass替换为AnotherClass。

我正在使用Angular 9。

编辑

我知道可以使用 useFactory 根据某些逻辑来生成提供的值。这种方法的问题在于,在创建组件时,工厂功能仍然只运行一次。

我想做的是每当发生某个事件时再次运行该功能。我该怎么办?

EDIT2:

因此app.module会这样做:

// this is in providers array...
     {
          provide: MatDatepickerIntl, deps: [DatePickerIntlService],
          useFactory: (datePickerIntl) => datePickerIntl.getLocale()
     }

上述服务读取当前语言环境,并相应地返回MatDatepickerIntl子类实例,因此它创建了正确的类。

最后,我在应用程序组件ngOnInit中有了该事件:

onLangChange.subscribe(() => {
          
        })

如何更改事件处理程序中提供的MatDatepickerIntl子类? 我可以致电服务,但无法用结果更新提供的值...

材料日期选择器希望MatDatepickerIntl令牌返回所需的子类。这就是它加载本地化文本的方式。

希望这可以使事情变得更好。

谢谢!

1 个答案:

答案 0 :(得分:0)

您必须创建一个父服务,它将重新路由到预期的服务:

@Injectable({
  providedIn: 'root'
})
export class MyParentService {
  childService: ChildEnService | ChildFrService | ChildEsService;
  private ngDestroy$: Subject<void> = new Subject();

  constructor(private childEnService: ChildEnService,
              private childFrService: ChildFrService,
              private childEsService: ChildEsService,
              private languageObsService: LanguageObsService) {
    this.languageObsService.getCurrentLanguage().pipe(
                                                 takeUntil(this.ngDestroy$)
                                               ).subscribe(
                                                 newLanguage => this.updateChild(newLanguage);
                                               );
  }

  public getMyPreciousData() {
    return this.childService?.getMyPreciousData();
  }

  private updateChild(newLanguage: LanguageEnum) {
    swtich(newLanguage) {
      case LanguageEnum.en:
        this.childService = this.childEnService;
        break;
      case LanguageEnum.fr:
        this.childService = this.childFrService;
        break;
      case LanguageEnum.es:
        this.childService = this.childEsService;
        break;
    }
  }

  private ngOnDestroy() {
    // unsubscribe the languageObsService
    this.ngDestroy$.next();
    this.ngDestroy$.complete();
  }
}


@Injectable({
  providedIn: 'root'
})
export class LanguageObsService{
  currentLanguage$: BehaviorSubject<LanguageEnum> = new BehaviorSubject(LanguageEnum.en);

  constructor() {}

  public getCurrentLanguage(): Observable<LanguageEnum> {
    return this.currentLanguage$.asObservable();
  }

  public setCurrentLanguage(newLanguage: LanguageEnum): void {
    this.currentLanguage$.next(newLanguage);
  }
}