6

我有一个 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 个不同的过滤器呢?

我错过了满足我需求的任何方法吗?

提前致谢!

4

5 回答 5

4

要么使用像这里RxJS 建模这样的分区,否则使用 Observables 操作符控制结构

或者,如果前一个过滤条件为真,则使用映射和管道对象代替过滤器,否则为空。因此,您可以使用过滤器在链中的任何位置捕获 null。

最后一个选项在过滤器函数的 else 部分调用一些函数

于 2016-03-12T14:33:14.687 回答
4

我们有一个类似的案例并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();
于 2017-07-20T08:17:17.523 回答
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);
于 2016-03-12T10:51:09.127 回答
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.statusChangesObservable 来跟踪输入值。

于 2016-03-13T14:06:09.000 回答
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,此代码将返回一个空数组,但这只是一个示例,您可以改用任何验证和表达式。

于 2020-06-11T02:29:43.967 回答