Как обновить значение, предоставленное поставщиком в Angular? - PullRequest
0 голосов
/ 06 августа 2020

У меня есть провайдер в AppModule, который предоставляет класс.

Есть ли способ обновить предоставленное значение во время выполнения?

{provide: MatDatepickerIntl, useClass: SomeClass}

Как можно заменить SomeClass на AnotherClass во время выполнения ( например: при реакции на событие в компоненте).

Я использую Angular 9.

EDIT

Я знаю, что могу использовать useFactory для генерации предоставленного значения на основе некоторого logi c. Проблема с этим подходом заключается в том, что фабричная функция по-прежнему запускается только один раз, когда компонент создается.

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

EDIT2:

Итак, app.module делает это:

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

Вышеупомянутая служба считывает текущий языковой стандарт и соответственно возвращает экземпляр подкласса MatDatepickerIntl , поэтому создается правильный класс.

Наконец, у меня есть событие в компоненте приложения ngOnInit:

onLangChange.subscribe(() => {
          
        })

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

Material Date Picker ожидает, что токен MatDatepickerIntl вернет требуемый подкласс. Вот как он загружает локализованные тексты.

Надеюсь, это проясняет ситуацию немного лучше.

Заранее спасибо!

1 Ответ

0 голосов
/ 07 августа 2020

Вы должны создать родительский сервис, который будет перенаправлять на ожидаемый сервис:

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