我有两个可观察的:
- 表示复选框输入列表的可观察对象。
- 一个表示来自服务器的事件流的可观察对象。
我想使用第一个值过滤第二个 observable。
从服务器接收到的值包含一个tag
属性,该属性对应于复选框列表中的值。由上述两者组合产生的 observable 只会产生来自服务器的值,该服务器的tag
属性包含在选中的复选框中。
我有两个可观察的:
我想使用第一个值过滤第二个 observable。
从服务器接收到的值包含一个tag
属性,该属性对应于复选框列表中的值。由上述两者组合产生的 observable 只会产生来自服务器的值,该服务器的tag
属性包含在选中的复选框中。
您可以使用withLatestFrom
.
.
source.withLatestFrom(checkboxes, (data, checkbox) => ({data, checkbox}))
.filter(({data, checkbox}) => ...)
这里,checkboxes
是一个表示复选框输入列表的可观察对象。source
是一个表示来自服务器的事件流的可观察对象。在过滤器功能中,您可以检查数据是否与复选框设置相比有效并让它通过。
checkboxes
请注意,在流可以发出任何东西之前发出至少 1 个值是很重要的。
附言。关于其他答案,即使源是冷的,此解决方案也有效。
为了使用流 B 的值过滤流 A,您需要观察流 B 并使用最新的值来过滤流 A。
用于switch()
将 B observable 转换为 observable 从 A observable 产生值。
checkedInputValuesSource
.map(function (options) {
return dataSource
.filter(function (value) {
return options.indexOf(value) !== -1;
});
})
.switch()
.subscribe(function (x) {
console.log('out: ' + x);
});
使用switch()
假设这dataSource
是一个热门的 observable。
interval()
用于生成虚拟数据的示例:
var input,
checkedInputValuesSource,
dataSource;
input = document.querySelectorAll('input');
// Generate source describing the current filter.
checkedInputValuesSource = Rx.Observable
.fromEvent(input, 'change')
.map(function () {
var inputs = document.querySelectorAll('input'),
checkedInputValues = [];
[].forEach.call(inputs, function (e) {
if (e.checked) {
checkedInputValues.push(e.value);
}
});
return checkedInputValues;
})
.startWith([]);
// Generate random data source (hot).
dataSource = Rx.Observable
.interval(500)
.map(function () {
var options = ['a', 'b', 'c'];
return options[Math.floor(Math.floor(Math.random() * options.length))];
})
.do(function (x) {
console.log('in: ' + x);
})
.share();
checkedInputValuesSource
.map(function (options) {
return dataSource
.filter(function (value) {
return options.indexOf(value) !== -1;
});
})
.switch()
.subscribe(function (x) {
console.log('out: ' + x);
});
<script src='https://rawgit.com/Reactive-Extensions/RxJS/v.2.5.3/dist/rx.all.js'></script>
<input type='checkbox' value='a'>
<input type='checkbox' value='b'>
<input type='checkbox' value='c'>
此示例将产生类似于以下内容的输出:
in: c
in: a
out: a
in: b
in: c
out: a
in: b
in: a
其中in
反映了所有生成的输入和b
通过过滤器的数据。通过检查复选框输入来调整过滤器,这些输入反映值“a”、“b”和“c”。
显然,我需要的是select
,filter
和switchLatest
. 我写了一个小测试用例来证明这一点:https ://gist.github.com/igstan/d5b8db7b43f49dd87382#file-observable-filter-observable-js-L36-L45
扩展@Dorus的答案......在Kotlin中,您可以这样做:
val observable: Observable<Data> = ...
val filter: Observable<Checkbox> = ...
val filtered: Observable<Data> =
observable.filterWithLatestFrom(filter) { checkbox -> checkbox.isSelected }
使用扩展功能:
/**
* Return an [Observable] with type [T1] that is filtered using the last event emitted by the [other] observable.
*/
fun <T1 : Any, T2 : Any> Observable<T1>.filterWithLatestFrom(other: Observable<T2>, filterFunction: (T2) -> Boolean)
: Observable<T1> {
return this.withLatestFrom(other) { obs1, obs2 -> Pair(obs1, obs2) }
.filter { (_, obs2) -> filterFunction.invoke(obs2) }
.map { (obs1, _) -> obs1}
}