我有一个小的共享Angular服务,如下所示:
import {Injectable} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs/Rx';
@Injectable()
export class SidebarService {
private _isOpen: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor() {
this._isOpen.subscribe(val => {
console.log(`isOpen: ${val}`);
});
}
public get isOpen() {
return this._isOpen.asObservable();
}
toggle() {
this._isOpen.next(!this._isOpen.getValue());
}
}
我想将.isOpen
属性绑定到视图中的元素。我目前正在使用以下代码段在视图中尝试绑定:
<p>Sidebar State: {{sidebarService?.isOpen | async}}</p>
该属性最初是绑定的,但不响应连续的更改。在SidebarService中调用侧边栏toggle()方法时,我想要的是侧边栏状态:更新。
有什么想法吗?
答案 0 :(得分:4)
问题是由于SidebarService的多个实例正在运行。
我通过将@Component装饰器中的提供程序的声明从共享SidebarService的两个组件移动到 app.module.ts 来修复此问题,如下所示:
@NgModule({
declarations: [
// ...
SidebarComponent,
// ...
],
imports: [ /* ... */ ])
],
// Line below was duplicated in two components,
// causing multiple instances...
providers: [SidebarService], // <--
bootstrap: [AppComponent]
})
这意味着我的绑定一起观察Observable的整个不同实例的变化。
我还发现.asObservable()调用完全没必要,因此生成的SidebarService现在看起来如下:
import {Injectable} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs/Rx';
@Injectable()
export class SidebarService {
private _isOpen: BehaviorSubject<boolean>;
constructor() {
this._isOpen = new BehaviorSubject(true);
}
public get isOpen() {
return this._isOpen;
}
toggle() {
this._isOpen.next(!this._isOpen.getValue());
}
}