gpt4 book ai didi

angular - FormControl.detectchanges - 为什么使用 distinctUntilChanged?

转载 作者:太空狗 更新时间:2023-10-29 17:22:16 25 4
gpt4 key购买 nike

阅读 How to use RxJs distinctUntilChanged?this ,似乎 distinctUntilChanged 将输出流更改为仅提供不同的连续值

我的意思是,如果相同的值立即连续到达,那么您实际上是在过滤流,并且只得到该重复值的一次出现。

如果我这样写:

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

我看不出输出有什么不同:

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

我看到一些地方建议在订阅表单输入的 valueChanges 时使用 distinctUntilChanged — 但我不太明白为什么。

这是一个输入,所以如果用户正在输入,它总是在变化,对吧?这些值将始终不同,因此您只是无缘无故地添加了一个额外的操作来过滤输入。

还是我在这里遗漏了什么?

编辑

根据我的第一个代码示例,使用 distinctUntilChanged,我创建了一个值为 Mr Trump 的表单输入,并确保将其保存在模型中。

然后我在控件内部单击并粘贴了 Mr Trump。由于值是相同的,我希望看不到任何记录 — 控件具有与之前相同的值,所以 distinctUntilChanged 应该忽略它吗?

编辑 2

在进一步查看我的测试后,这种行为似乎是因为我使用了一个 AbstractControls 数组:

this.itemsControl = <FormArray>this.form.controls['items']; 
...
this.itemsControl.controls[index].valueChanges...

因此,尽管当输入值相同时它仍然会触发有点奇怪,但我猜我需要连接到此数组项(一个表单组)中实际输入的 valueChanges ),而不是数组项本身。

编辑 3

因此,将 EDIT 2 中的代码更改为以下内容后,将已存在的相同值粘贴到输入控件中不会触发 valueChanges(如预期)。在 EDIT 2 中,valueChanges Hook 到整个 formGroup,而不是单独的输入控件(在本例中称为 content):

let fg = this.itemsControl.controls[index]; // get the formGroup
fg['controls'].content.valueChanges
.debounceTime(1000)
.distinctUntilChanged()
.subscribe(newValue => {...});

最佳答案

distinctUntilChanged 当应用于 valueChanges 可观察...

...可能永远都行不通!

它仅在单个值上按预期工作(如您所说)。因此,即使没有任何更改,您也会获得一个新值。

要跟踪整个表单的更改,您需要编写自定义比较器,其中最简单的使用 JSON.stringify 来输出可以比较的值。 valueChanges observable 发出一个对象,而 distinctUntilChanges 不够智能,无法执行 reference compare 之外的任何事情。 (这是指向 RxJS 源代码的链接)除非您提供比较器函数。

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

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

distinctUntilChanged 适用于具有基本类型的单个值,因为 === 足以检测更改。

如何解决无限循环?

如果您尝试将 distinctUntilChanges 添加到您的管道(对于整个表单)以避免在以编程方式更新表单值时出现无限循环 - 您可能需要这样:

    this.form.patchValue(address || {}, { emitEvent: false });

关于angular - FormControl.detectchanges - 为什么使用 distinctUntilChanged?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46889851/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com