FormControl.detectchanges - why use distinctUntilChanged?

谁都会走 提交于 2019-12-01 18:01:07

Using debounceTime(1000) means we only send a request when the user stopped typing for 1 second, during that second the user can write 3 characters then erase them, so the input value didn't change since last request but you are sending the same request, to avoid that you can use .distinctUntilChanged()

  this.myFormControl.valueChanges
      .debounceTime(1000)
      .distinctUntilChanged()
      .subscribe(newValue => {
        console.log('debounced: ', newValue)
      });

distinctUntilChanged when applied to the valueChanges observable...

...is completely and utterly futile!

It only works as expected on an individual value (as you said). So you'll get a new value even if nothing has changed.

To track changes for the whole form you need to write a custom comparer, the simplest of which uses JSON.stringify to output a value that can be compared. The valueChanges observable emits an object and distinctUntilChanges isn't smart enough to do anything beyond a reference compare (that's a link to the RxJS source code) unless you provide a comparer function.

this.form.valueChanges.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === 
                                                           JSON.stringify(b)))

                      .subscribe(changes => { console.log('The form changed!'); });

distinctUntilChanged works fine for an individual value with a primitive type because === is sufficient to detect changes.

How do I solve infinite loops?

If you're trying to add distinctUntilChanges into your pipe (for the whole form) to avoid an infinite loop when you programmatically update the form value - you probably want this instead:

    this.form.patchValue(address || {}, { emitEvent: false });
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!