订阅Angular 2中FormControl的真值变化的最佳方法?

问题描述 投票:1回答:2

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

使用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发出的第一个值,因为在创建valueChanges Observable之前设置了formControl1值。

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第一次被调用,这是行:

formControl2.setValue(1)

它将已经有previousValue(1)来比较新值,因此subscribe中的函数将不会被执行。

但我真的不喜欢这个解决方案。是否有内置或推荐的方法来处理Angular7和RxJS6中的FormControl值更改?

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

javascript angular rxjs angular-reactive-forms rxjs6
2个回答
1
投票

如果我正确理解了这个问题,你希望你的observable只触发除初始值之外的任何值变化吗?

您是否尝试在创建表单控件时设置该值

new FormControl({ value: 1 });

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

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

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

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

我希望这有帮助!


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.