我有这个问题,一个带有数据绑定标签的按钮,如:
<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
实时更改其值?
您可以实现一个将作为公共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>
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;
}
}