我仍然在RxJS周围缠着我的头,这种模式我一直在努力,我希望找到一种更优雅的写作方式。
实现Model-View-Intent模式组件的模型部分,我有一个函数,它将操作作为输入,返回单个state$
Observable作为输出。
function model(actions) {
const firstProperty$ =
const anotherProperty$ = …
// Better way to write this?
const state$ = Rx.Observable.combineLatest(
firstProperty$, anotherProperty$,
(firstProperty, anotherProperty) => ({
firstProperty, anotherProperty
})
);
return state$;
}
所以我的model
方法计算了一堆observable,每个observable都会发出代表我的应用程序状态一部分的项。没关系。
但是如何将它们干净地组合成一个发出状态的单个observable,每个状态都是一个对象,其键是最初的可观察名称?
答案 0 :(得分:1)
我从https://github.com/cyclejs/todomvc-cycle借用了这种模式:
function model(initialState$, actions){
const mod$ = modifications(actions)
return initialState$
.concat(mod$)
.scan( (state, mod) => mod(state))
.share()
}
function modifications(actions){
const firstMod$ = actions.anAction$.map(anAction => (
state => ({ ...state,
firstProperty: anAction.something
})
const secondMod$ = actions.otherAction$.map(otherAction => (
state => ({ ...state,
firstProperty: otherAction.something,
secondProperty: aComputation(otherAction)
})
return Rx.Observable.merge([firstMod$, secondMod$ ]).share()
}
在主要功能中:
const initialState$ = Rx.Observable.from({})
const actions = intent(DOM)
const state$ = model(initialState$, actions).share()
答案 1 :(得分:1)
使用CHadrien的帮助,这是一个有效的解决方案。
const prop1$ = Rx.Observable.of('foo');
const prop2$ = Rx.Observable.of('bar');
const prop3$ = Rx.Observable.of('baz');
const prop4$ = Rx.Observable.of('foobar');
function combineObservables(objectOfObservables) {
const keys = Object.keys(objectOfObservables);
const observables = keys.map(key => objectOfObservables[key]);
const combined$ = Rx.Observable.combineLatest(
observables, (...values) => {
var obj = {};
for (let i = 0 ; i < keys.length ; i++) {
obj[keys[i]] = values[i];
}
return obj;
}
);
return combined$;
}
combineObservables({prop1$, prop2$, prop3$, prop4$}).subscribe(x => console.log(x));
结果:
[object Object] {
prop1$: "foo",
prop2$: "bar",
prop3$: "baz",
prop4$: "foobar"
}