Обнаружение изменений внутри службы в другой службе (Angular 7)

О оптимизации компилятора: http://www.gotw.ca/gotw/081.htm

1
задан Codehan25 4 March 2019 в 12:22
поделиться

1 ответ

Поскольку activeBusinessCase устанавливается асинхронно, и вы хотите получать уведомления об изменениях значений в другой части вашего приложения, это должно быть Subject. Используйте BehaviorSubject, чтобы сразу получить текущее значение при подписке.

// ----- UserAuthService -----

public activeBusinessCase$ = new BehaviorSubject<string>(null);

setActiveBusinessCase(bcase: string) {
  this.activeBusinessCase.next(bcase);
  this.setTitle(bcase);
}

Прослушайте изменения значений activeBusinessCase$ в вашем ConfigurationService и отобразите входящие значения на язык, который вы хотите вернуть.

// ----- ConfigurationService -----

// will emit a new language every time activeBusinessCase changes,
// this behavior could be changed depending on your specific needs
getAutoConfiguredBCLanguage$(): Observable<string> {
  return this.authService.activeBusinessCase$
    .pipe(
      // use 'distinctUntilChanged' to only emit values that are different from the previous,
      distinctUntilChanged(),
      map(abc => this.getAutoConfiguredBCLanguage(abc))
    );     
}

private getAutoConfiguredBCLanguage(activeBusinessCase: string): string {
  // no changes here apart from the input parameter - I omitted the code for brevity
  // use the parameter activeBusinessCase instead of this.activeBusinessCase here
}

Подпишитесь на getAutoConfiguredBCLanguage$, где вам нужен язык.

// ----- AppComponent -----

initLanguage() {
  this.configService.getAutoConfiguredBCLanguage$()
    .pipe(takeUntil(this.destroy$)) // unsubscribe when the component gets destroyed
    .subscribe(lang => {
      // use the language here
    });
}

private destroy$ = new Subject<void>();

onDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}

A BehaviorSubject имеет функцию getValue, которая возвращает последнее значение, выданное BehaviorSubject. Вы можете использовать эту функцию, чтобы получить текущее значение activeBusinessCase, но делать это только в том случае, если вы знаете, что делаете, т.е. если вы действительно хотите получить текущее значение в определенное время , которое вы вызываете getValue. Помните, что вы имеете дело с асинхронными действиями в вашем приложении. Если вы хотите быть уверены, что получите значение activeBusinessCase$ после его установки, вызвав this.authService.setActiveBusinessCase, вы должны подписаться на BehaviorSubject. Если вас не волнует, было ли уже установлено activeBusinessCase$, и вы просто хотите использовать текущее значение activeBusinessCase$, вы можете использовать getValue (который затем может вернуть null, который был установлен в качестве начального значения activeBusinessCase$ ).

Мое предложение:

// ---- HomeComponent ----

ngOnInit() {
  // To navigate to a route once the activeBusinessCase has a non null value
  // subscribe but only take the first non null element and no further values afterwards
  this.authService.activeBusinessCase$
    .pipe(first(Boolean))
    .subscribe(bc => this.router.navigate([Constants.routing.explorer + bc.toLowerCase()]));
}

// ---- SmagHttpService & UserAuthService ----

// Don't subscribe to activeBusinessCase$ in here!! Instead use
this.authService.activeBusinessCase$.getValue()
// when you need the current value (which might not have been set yet, 
// but you already have null checks here and if this part of your app worked before 
// there will be no differences)

// Example:
const businessCase = this.authService.activeBusinessCase$.getValue();
if (businessCase) {
  this.router.navigate([Constants.routing.explorer + businessCase.toLowerCase()]);
}

businessCase ? businessCase : environment.default_business_case
0
ответ дан fridoo 4 March 2019 в 12:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: