从多个 FormControl 创建 Observable

Create Observable from multiple FormControl

我有一个 Observable<FormGroup> 有几个布尔值 FormControl

readonly someForm$ = model$.pipe(map((model: Model) => {
  return new FormGroup({
    foo: new FormControl(model.getFoo()),
    bar: new FormControl(model.getBar()),
  });
}));

我想创建一个 Observable,如果任何 FormControl 值是 true,它就会发出。我尝试了以下

readonly result$ = someForm$.pipe(switchMap(
  form => form.valueChanges.pipe(
    map(changes => changes.foo || changes.bar),
    startWith(() => form.value['foo'] || form.value['bar'])
  )
));

尽管 result$ 在测试期间总是解析为 true。创建本质上是 foo || bar 的可观察对象的正确方法是什么?

最小示例:https://stackblitz.com/edit/angular-material-bvy7bj

使用 filter 运算符过滤掉虚假值

const result$ = someForm$.pipe(
  switchMap((form) =>
    form.valueChanges.pipe(
      filter((changes) => changes.foo || changes.bar),
      map((changes) => changes.foo || changes.bar)
    )
  )
);

我已经创建了模拟表单和模拟用户事件

import { BehaviorSubject, of } from 'rxjs';
import { filter, map, startWith, switchMap } from 'rxjs/operators';
const someForm$ = of({ // custom Observable form
  valueChanges: new BehaviorSubject({
    foo: false,
    bar: false,
  }),
  value: {
    foo: false,
    bar: false,
  },
});

const result$ = someForm$.pipe(
  switchMap((form) =>
    form.valueChanges.pipe(
      filter((changes) => changes.foo || changes.bar), // filtering falsey values
      map((changes) => changes.foo || changes.bar) // map to true
    )
  )
);

result$.subscribe((data) => {
  console.log(data); 
});

someForm$.subscribe((data) => {
  data.valueChanges.next({ foo: false, bar: true }); // custom user event
  data.valueChanges.next({ foo: false, bar: false }); // custom user event
  data.valueChanges.next({ foo: true, bar: false }); // custom user event
});

演示:

https://stackblitz.com/edit/typescript-tfqjms?file=index.ts&devtoolsheight=100

有几个问题:

  • 您的组件中有 result$,您的模板中有 $result

  • startWith() 不接受函数,它需要是您的 use-case.

    中的一个值
  • 您对 someForm$ 进行了两次订阅,这会创建两个不相关的 FormGroup 实例。您需要在 someForm$.

    末尾使用 shareReplay(1)

您更新的演示:https://stackblitz.com/edit/angular-material-xpqmcs?file=app%2Fapp.component.ts