angular 反应形式值随管道变化。这是一个错误吗???

angular reactive form valuechanges with pipe. IS THIS A BUG ???

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

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

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

我在这里遗漏了什么吗?

是的,您肯定漏掉了什么。

打开您的控制台(浏览器控制台,而不是 blitz 控制台)并查看您确实遇到错误:

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)

这就是您的应用程序出现问题的原因。

rxjs throw error operator 将阻止 observable 再次发射,就像您取消订阅 valueChanges observable 一样 像这样尝试使用 throwError 运算符只是抛出新的 Error 对象

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

这不是错误。每个 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