(Угловой) Сделать глобальные переменные всегда меняют свои значения в соответствии с сервисом - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть эта проблема, кнопка с меткой, связанной с данными, что-то вроде:

<button>{{label}}</button>

Мне нужно изменить ее значения в зависимостичто на экране.И это в основном просто, я просто изменяю значение label в моем component.ts.
Проблема в том, что после некоторых изменений в системе мне нужно, чтобы это происходило при использовании другого компонента.Эта кнопка всегда находится на экране, на MainComponent, но когда вы набираете FooComponent (нажимая на определенные вещи на экране), мне нужно изменить ее ярлык.
Для этого я создал Main.service.ts, где я создал переменную label и просто вызвал ее значение в mainComponent.
Это сервис:

@Injectable({
  providedIn: 'root'
})
export class MainService {

  constructor() { }

  label = "IntialFoo";

  foo01() {
    this.label = 'foo01';
  }

  foo02() {
    this.label= 'foo02';
  }

И компонент:

export class MainComponent extends BaseService<any> implements OnInit {

  constructor(
    private mainService: MainService,
    ...
  ) {
    super(...);
  }

  ...
  label = this.mainService.label;

Теперь, скажем, я импортирую свой сервис в свой fooComponent, я бы вызвал функции сервиса для изменениязначение label работает в сервисе.И это проблема, кнопка не меняет своих значений, и это потому, что переменная не перечисляется в сервисе, она просто получает свое значение один раз, а затем она не изменяется.
Итак, как мне сделать, чтобы моя переменная label (в mainComponent) в реальном времени меняла свое значение в соответствии с label в сервисе?

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Вы можете реализовать частный объект BehaviorSubject, который будет представлен как общедоступная наблюдаемая.Примерно так:

import { Injectable } from '@angular/service';
import { Observable, BehaviorSubject } from 'rxjs';

@Injectable({
    providedIn: 'root'
})
export class MainService {

    private label: BehaviorSubject<string> = new BehaviorSubject<string>('IntialFoo');
    label$: Observable<string> = this.label.asObservable();

    updateLabel(updatedLabel) {
        this.label.next(updatedLabel);
    }
}

Затем вы можете внедрить этот сервис в качестве зависимости в ваших Компонентах, а затем использовать метку $ с async в вашем шаблоне, чтобы избежать ручного вызова unsubscribe.Примерно так:

export class MainComponent extends BaseService < any > implements OnInit {

  constructor(private mainService: MainService,...) {
    ...
  }

  ...

  label$ = this.mainService.label$;

}

А в шаблоне:

<button>{{ label$ | async }}</button>
0 голосов
/ 13 февраля 2019
I would not extend the component with BaseService as the service should be a singleton.  I would have the service injected into any component that needs the label and the service to return as observable.  Please see code below...

    // Service
    @Injectable({
      providedIn: 'root'
    })
    export class MainService {

      constructor() { }                  
      getLabel(component:string): Observable<string> {
        return Observable.of(component);

      }
    }

    // Component:
    import { takeWhile, switchMap } from 'rxjs/operators';            
    import { OnInit, OnDestroy, Input } from '@angular/core'

    export class MainComponent implements OnInit, OnDestroy {

          constructor(
            private mainService: MainService,
            ...
          ) {

          }
      @Input() passedInLbl:string;
      private label: string;
      private isActive: boolean;
      ngOnInit():void {
          this.isActive = true;
          mainService.getLabel(passedInLabel).pipe(
              switchMap(resp => {
                  this.label = resp;
              }),
              takeWhile(() => this.isActive)
          );
      }
      ngOnDestory(): void {
          this.isActive = false;
      }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...