我有一个Observable,可以从文本框中听取一些用户输入。如果观察到的字符串长度为> = 3(filter
),则它会执行一些HTTP调用(switchMap
)。
现在我想以某种方式检测用户输入是否已被过滤。原因是:
如果HTTP调用已完成,则应显示结果。
如果用户输入已被过滤(==无效),则应清除结果。
以下是我想要的代码(请参阅:ifFiltered
):
this.userInput.valueChanges
.filter(val => val && val.length >= 3)
.ifFiltered(() => this.results = [])
.switchMap(val => getDataViaHTTP())
.subscribe(val => this.results = val);
我知道,我可以将这个逻辑放在filter
函数中,用于这个简单的例子。但是,如果我有10个不同的滤镜呢?
我是否错过任何满足我需求的方法?
提前致谢!
答案 0 :(得分:4)
使用像RxJS modeling if else control structures with Observables operators
这样的分区或者,如果前一个过滤条件为true,则使用map并管道对象,否则使用null。因此,您可以使用过滤器在链中的任何位置捕获null。
最后一个选项在过滤函数的else部分调用一些函数
答案 1 :(得分:3)
我建议有一个公共事件流,创建两个过滤流,并在订阅之前合并这两个:
var o = this.userInput.valueChanges;
var empty= o.filter(t=> t.length < 3)
.map(t=>[])
var nonempty = o.filter(t=> t.length >= 3)
.switchMap(t=> getDataViaHTTP());
empty.merge(nonempty).subscribe(val => this.results = val);
答案 2 :(得分:3)
如上所述,我们遇到了类似的情况,并使用partition
进行了尝试,但发现在这里使用throw
更加方便。所以对于你的代码
this.userInput.valueChanges
.do(val => {
if (!val || val.length < 3) {
throw new ValueTooShortError();
}
})
.switchMap(val => getDataViaHTTP())
.do(val => this.results = val)
.catch(() => this.results = [])
.subscribe();
答案 3 :(得分:2)
我使用Validators
为我的用例找到了另一个不错的解决方案:
(我知道这不是使用Observables解决问题的解决方案。而是使用Angular2功能很好地解决问题。)
this.userInput.validator = Validators.compose([
Validators.required,
Validators.minLength(3)
]);
this.userInput.valueChanges
.filter(val => this.userInput.valid)
.switchMap(val => getDataViaHTTP())
.subscribe(val => this.results = val);
现在我可以使用userInput.valid
属性和/或userInput.statusChanges
Observable来跟踪输入值。
答案 4 :(得分:0)
可能已经晚了,但想为仍在寻求更清洁方法来在.map中验证IF EMPTY的成员发帖:
of(fooBar).pipe(
map(
(val) =>
({
...val,
Foo: (val.Bar
? val.Foo.map((e) => ({
title: e.Title,
link: e.Link,
}))
: []) as fooModal[],
}));
如果缺少val.bar,此代码将返回一个空数组,但这只是一个示例,您可以改用任何验证和表达式。