【问题标题】:Best way to subscribe to true value changes of FormControl in Angular2+?在 Angular 2 中订阅 FormControl 的真实值更改的最佳方式?
【发布时间】:2019-07-15 12:43:12
【问题描述】:

valueChanges 存在于 FormControl 对象上的 Observable 每次在 FormControl 对象上调用 setValue(value) 函数时都会发出值。

使用 RxJS 运算符 distinctUntilChanged 我们可以过滤掉不是新的值。但是如果 FormControl 有初始值,这不起作用。

const formGroup1 = new FormGroup({page: new FormControl(1)});
const formControl1 = formGroup1.get('page');
formControl1.valueChanges.pipe(distinctUntilChanged())
  .subscribe(v => console.log(`new formControl1 value: ${v}`));
formControl1.setValue(1);
formControl1.setValue(2);

这将记录

> new form1Control value: 1
> new form1Control value: 2

1 是 valueChanges Observable 发出的第一个值,因为 formControl1 值是在创建 valueChanges Observable 之前设置的。

distinctUntilChanged 从不过滤掉第一个发出的值

这是解决此问题的一种方法:

const formGroup2 = new FormGroup({page: new FormControl(1)});
const formControl2 = formGroup2.get('page');
formControl2.valueChanges.pipe(
    startWith(1),
    distinctUntilChanged(),
    skip(1)
).subscribe(v => console.log(`new formControl2 value: ${v}`));
formControl2.setValue(1);
formControl2.setValue(2);

在这里,我通过发出 FormControl 初始值然后跳过它来修改 valueChanges Observable。所以第一次调用distinctUntilChanged,也就是line:

formControl2.setValue(1)

它已经有previousValue(1)来比较新值,所以订阅里面的函数不会被执行。

但我不太喜欢这种解决方案。 Angular7 和 RxJS6 中是否有内置或推荐的方法来处理 FormControl 值的变化?

stackblitz:https://stackblitz.com/edit/angular-arevmw?file=app%2Ficon-overview-example.ts

【问题讨论】:

    标签: javascript angular rxjs angular-reactive-forms rxjs6


    【解决方案1】:

    如果我正确理解了这个问题,您是否希望您的 observable 仅触发除初始值之外的任何值更改?

    你有没有试过在创建表单控件的时候设置值

    new FormControl({ value: 1 });

    或者你可以指定在设置值时不想发出事件

    const formControl1 =new FormControl(1); formControl1.setValue(1, { emitEvent: false });

    根据文档可以在设置值时指定选项,包括:

    emitEvent:当 true 或未提供(默认值)时,statusChanges 和 valueChanges 可观察对象都会在控件值更新时发出具有最新状态和值的事件。如果为 false,则不会发出任何事件。

    我希望这会有所帮助!

    【讨论】:

    • 在我的示例中,表单控件的初始值为 1。我在创建控件后立即调用 setValue(1),valueChanges 可观察对象发出 1,我不希望这样,因为它不是新值,和最初的一样。
    • 我想我理解你。我不知道初始表单值和订阅其更改的内置或推荐方法。就我个人而言,当我必须实现这种方法时,我最终会使用 emitEvent: false 方法,但这主要是个人喜好。
    【解决方案2】:

    distinctUntilChanged 初始状态始终为空。但是当第一个值发出时 distinctuntilchanged 存储第一个值。在发出第二个值之后,它是比较新值和存储值。所以您的解决方案是正确的,或者您可以使用 skipWhile 进行第一个值比较。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-19
      • 2017-05-12
      • 2022-01-01
      • 2018-12-09
      • 1970-01-01
      • 2018-07-13
      • 2017-10-18
      • 1970-01-01
      相关资源
      最近更新 更多