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

问题描述 投票:0回答:2

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

<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变量(在mainComponent中)根据服务中的label实时更改其值?

angular components
2个回答
1
投票

您可以实现一个将作为公共Observable公开的私有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
投票
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;
      }

    }
© www.soinside.com 2019 - 2024. All rights reserved.