(角度)使全局变量始终根据服务更改其值

时间:2019-02-13 11:27:27

标签: angular components

我有这个问题,一个带有数据绑定标签的按钮,类似于:

  

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

我需要它根据屏幕上的内容更改其值。这很容易,我只需在我的component.ts中更改label值。
问题是,在系统上进行了一些更改之后,当我使用其他组件时,我需要这样做。此按钮始终在屏幕上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使label变量(在mainComponent中)实时更改其值?

2 个答案:

答案 0 :(得分:1)

您可以实现一个私有的BehaviorSubject,将其作为公共Observable公开。像这样:

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管道中使用label $,以避免手动调用unsubscribe。像这样:

export class MainComponent extends BaseService < any > implements OnInit {

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

  ...

  label$ = this.mainService.label$;

}

在模板中:

<button>{{ label$ | async }}</button>

答案 1 :(得分:0)

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;
      }

    }