假设我有一组映射到输入字段的验证消息。假设我们从服务器获取这些验证消息。
我还有一个映射到输入字段的更改事件流。
每当我得到某个特定字段的更改事件时,我想
答案 0 :(得分:1)
每次有验证消息时,您似乎都在重新开始处理更改事件。在这种情况下,您可以尝试类似:
filteredValidation$ = validation$.flatMapLatest(function ( aObjs ) {
return changeEvent$.scan(function ( acc, changeEvent ) {
return isIn(changeEvent, acc) ? removeChangeEvent(changeEvent, acc) : acc;
}, aObjs);
});
您必须根据isIn
的特定形状编写removeChangeEvent
和change_event
,但这很容易。
acc
函数中的累加器scan
表示的状态,该状态本身是最新的过滤验证对象。我没有测试过,但希望它有效。
顺便说一句:我喜欢你的图表,它是你想要实现的处理的完美例证。
答案 1 :(得分:1)
这是另一种采用不同技术的答案。这个想法是相似的(使用scan
来记住以前的值,但是我们从reduce函数中获取当前值,这取决于发出值的源。)
jsfiddle:http://jsfiddle.net/guc1tm4m/1
var ta_validation = document.getElementById('ta_validation');
var ta_change = document.getElementById('ta_change');
var ta_result = document.getElementById('ta_result');
function emits ( who, who_ ) {return function ( x ) {
who.innerHTML = [who.innerHTML, who_ + " emits " + JSON.stringify(x)].join("\n");
};}
function isIn (changeEvent, prev){
return !!prev[0][changeEvent];
}
function removeChangeEvent(changeEvent, prev) {
delete prev[0][changeEvent];
return prev;
}
var validation$ = Rx.Observable
.fromEvent(document.getElementById('validation'), 'click')
.map(function(_, index){
var values=[
[{a:'req', b:'req', c:'req'}],
[{d:'req', e:'req'}],
[{x:'req', y:'req', z:'req'}]
];
return values[index % values.length];
})
.do(emits(ta_validation, 'validation'))
.share();
var changeEvent$ = Rx.Observable
.fromEvent(document.getElementById('change'), 'click')
.map(function(_, index){
console.log('ssds', index)
var values=['x', 'a', 'b', 'z'];
return values[index % values.length];
})
.do(emits(ta_change, 'change'))
.share();
var filteredValidation$ = Rx.Observable
.merge(validation$.map(function (x) {return function ( ) {return x;}}),
changeEvent$.map(function ( changeEvent ) {
return function ( prev ) {
return isIn(changeEvent, prev) ? removeChangeEvent(changeEvent, prev) : prev;
};
}))
.scan(function ( prev, f ) {
return f(prev);
}, {})
.do(emits(ta_result, 'result'));
validation$.subscribe(function(){ });
changeEvent$.subscribe(function(){ });
filteredValidation$.subscribe(function(){ });
答案 2 :(得分:1)
我已经改编了上面的jsfiddle以显示我想出的解决方案。
jsfiddle:http://jsfiddle.net/hellosmithy/7kcoud2c/2/
基本上,此版本使用Rx.Observable.window
根据来自changeEvents$
流的新事件来整理validation$
流。
var filteredValidation$ = validation$
.merge(
changeEvent$
.window(validation$)
.flatMapLatest(changeWindow => {
return changeWindow.scan((acc, next) => acc.add(next), new Set());
)
.withLatestFrom(validation$, (filterSet, errs) => {
return errs.filter(err => !filterSet.has(err.key));
})
)
.distinctUntilChanged()