我有一个看起来像这样的服务:
DogService {
public getSelectedDog(): Observable<Uuid> {...}
public getDog(dogUuid: Uuid): Observable<Dog> {...}
}
我想创建一个始终包含我选择的狗的Observable,即Observable<Dog>
。
目前我正在做的是:
let selectedDog: Observable<Dog> = dogService.getSelectedDog().flatMap( selectedDog => {
return dogService.getDog( selectedDog );
});
然后您可以订阅所选狗的更改,如下所示:
selectedDog.subscribe( dog => console.log( 'dog: ", dog.name, dog.mood );
不幸的是,这似乎并没有像我预期的那样发挥作用。 selectedDog仅可观察 当狗本身发生变化时,当选定的狗改变时不会触发。
例如,假设我们执行以下操作:
const dog1: Dog = new Dog( '1', // uuid
'Shadow', // name
'happy' // mood
);
const dog2: Dog = new Dog( '2', // uuid
'Barky', // name
'Angry' // mood
);
// Fires the getDog observable
dogService.addDog( dog1 );
// Fires the getDog observable
dogService.addDog( dog2 );
// Fires the getSelectedDogObservable
dogService.selectDog( dog1.uuid )
// --- Now in console.log we will see: 'dog: Shadow happy'
不幸的是,如果我更新狗,控制台无法登录:
const updatedDog1: Dog = new Dog( '1', // uuid
'Shadow', // name
'SAD' // mood
);
// Fires the getDog observable
dogService.updateDog( updatedDog1 );
// --- the console.log doesn't get invoked. Crap.
问题:如果选择或选定的狗发生变化,我该如何创建Observable<Dog>
?
答案 0 :(得分:1)
您的代码应该有效,因此我怀疑您的服务存在问题。我有一些代码来证明它原则上应该可以工作。
您应该纠正的一个错误是您使用的是flatMap
,但应该使用switchMap
。问题是flatMap
会将每个流合并到您的流中,无论您何时选择新的狗,这意味着您将不断获得您不想要的以前选定的狗的更新。所以这是我正在谈论的代码:
var dogs = [
Rx.Observable.timer(0, 500).map(() => 'barky'),
Rx.Observable.timer(0, 1000).map(() => 'cuddles')
];
var selectedDog = 0;
var dogSelector = Rx.Observable
.timer(0, 5000)
.map(_ => {
selectedDog = (selectedDog ? 0 : 1);
return selectedDog;
})
.switchMap(i => dogs[i]);
dogSelector.subscribe(dog => console.log(`Doggy: ${dog}`))
http://jsbin.com/haqutehajo/1/edit?js,console
每隔5秒选择一只新狗,每只狗每隔1秒或半秒发送一次更新。同时尝试使用flatMap
代替switchMap
,您将看到我在说什么。