【问题标题】:angular reactive form valuechanges with pipe. IS THIS A BUG ???角度反应形式值随管道变化。这是一个错误???
【发布时间】:2018-08-02 10:07:21
【问题描述】:

似乎管道不适用于反应式表单控件 valueChanges。我已经准备好了这个https://stackblitz.com/edit/angular-vdeqrz,以便您可以重现该问题。

在文本字段中输入一些内容。然后输入“boom”(不带引号)。错误捕获后,控件不再工作。 之后您可以验证在其上输入新内容。它不会检测到任何其他输入。

如果您刷新页面,它会再次运行。

我在这里错过了什么吗?

【问题讨论】:

  • 为什么要抛出错误。你可以返回 of(false/null) 对吧?
  • 其实这是一个愚蠢的问题,应该从SO中删除。创建它的时候我失眠了。

标签: angular rxjs reactive-programming angular-reactive-forms reactive


【解决方案1】:

这不是错误。每个 Rx 流可以发出零个或多个 next 通知和一个 errorcomplete 通知,但不能同时发出两者。

因此,如果您使用throwError,则链将自行处理,因为您永远不会让同一个链发出两个或更多error 通知,这是您所期望的。

显然有很多方法可以避免这种情况。例如,您可以使用不同于 throwError 的东西,并用一些对象包装输入值。但是你将无法在观察者的error 处理程序中处理它。

您也可以使用retrytap来处理错误:

this.query.valueChanges
  .pipe(
    switchMap(d => (d === 'boom') ? throwError(new Error("boom")) :  of(d)),
    tap({ error: err => console.log(err) }),
    retry(),
  )
  .subscribe({
    next: d => console.log(d),
    complete: () => console.log("complete")
  })

你必须在这里使用tap,因为错误永远不会到达观察者。

您更新的演示:https://stackblitz.com/edit/angular-1qfn2z?file=src/app/app.component.ts

【讨论】:

    【解决方案2】:

    rxjs throw error 操作符将阻止 observable 再次发射,就像您取消订阅 valueChanges observable 一样 尝试像这样使用 throwError 运算符只是 throw new Error object

    this.query.valueChanges
      .pipe(map(d => (d === 'boom') ? new Error("boom") :  d))
      .subscribe(
        d => console.log(d),
        err => console.log(err),
        () => console.log("complete")
      )
    

    【讨论】:

      【解决方案3】:

      是的,你肯定错过了一些东西。

      打开你的控制台(浏览器,而不是闪电战),看看你实际上有一个错误:

      Error: boom
          at SwitchMapSubscriber.eval [as project] (app.component.ts:43)
          at SwitchMapSubscriber._next (switchMap.ts:100)
          at SwitchMapSubscriber.Subscriber.next (Subscriber.ts:102)
          at SafeSubscriber.schedulerFn [as _next] (event_emitter.ts:88)
          at SafeSubscriber.__tryOrUnsub (Subscriber.ts:270)
          at SafeSubscriber.next (Subscriber.ts:212)
          at Subscriber._next (Subscriber.ts:142)
          at Subscriber.next (Subscriber.ts:102)
          at EventEmitter.Subject.next (Subject.ts:62)
          at EventEmitter.emit (event_emitter.ts:78)
      

      这就是你的应用程序的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-02
        • 2018-12-06
        • 1970-01-01
        • 2018-07-30
        • 2021-05-05
        • 2020-11-23
        • 2022-01-03
        • 2018-11-17
        相关资源
        最近更新 更多