简体   繁体   English

Angular Reactive Forms:仅对某些特定的表单控件进行反跳

[英]Angular Reactive Forms: Debounce only some specific Form Control

I have a simple Search Component which contains a Reactive Form with 2 elements:我有一个简单的搜索组件,其中包含一个带有 2 个元素的反应式表单:

  • Text Input (to search for arbitrary matching text)文本输入(搜索任意匹配文本)
  • Checkbox (to include / exclude deleted results)复选框(包括/排除已删除的结果)

So far I use myFormGroup.valueChanges.subscribe(...) to execute my search method.到目前为止,我使用myFormGroup.valueChanges.subscribe(...)来执行我的搜索方法。

Now the problem is, that I want to debounce the text input.现在的问题是,我想去抖动文本输入。 And at the same time not debounce the checkbox, so the search method is getting executed instantly when clicking the checkbox.并且同时不去抖动复选框,因此当单击复选框时搜索方法会立即执行。

Using valueChanges.debounceTime(500) will of course debounce the whole form.使用valueChanges.debounceTime(500)当然会消除整个表单的抖动。 That's not what I want.那不是我想要的。

This is a stripped down example.这是一个精简的例子。 The real form has some more inputs.真实的形式有更多的输入。 Some should be debounced and some shouldn't.有些应该去抖,有些不应该。

Is there any easy way to get this done?有什么简单的方法可以完成这项工作吗? Or do I have to subscribe to every form control separately?还是我必须分别订阅每个表单控件?

Would be nice to see how you did solve this.很高兴看到你是如何解决这个问题的。

Thanks in advance.提前致谢。


EDIT: Code编辑:代码

export class SearchComponent {

  myFormGroup: FormGroup;

  constructor(fb: FormBuilder) {
    this.myFormGroup = fb.group({
      textInput: '',
      checkbox: false
    });
  }

  ngOnInit() {
    this.myFormGroup.valueChanges.subscribe(val => {
      // debounce only the textInput,
      // and then execute search
    });
  }

}

Create each individual FormControl before adding them to the form group and then you can control the valueChanges observable per FormControl在将它们添加到表单组之前创建每个单独的 FormControl,然后您可以控制每个 FormControl 可观察到的 valueChanges

this.textInput.valueChanges
      .pipe(
        debounceTime(400),
        distinctUntilChanged()
      )
      .subscribe(res=> {
        console.log(`debounced text input value ${res}`);
      });

the distinctUntilChanged will make sure only when the value is diffrent to emit something. distinctUntilChanged 将确保只有当值不同时才会发出某些东西。

Debounce the text control's valueChanges observable, then use combineLatest() to combine it with the checkbox control's valueChanges observable.去除文本控件的valueChanges可观察值,然后使用combineLatest()将其与复选框控件的valueChanges可观察值结合起来。

Simple example 简单例子

Debounce for a single control in a form group can be done by表单组中单个控件的去抖可以通过

   this.form.get('textInput')
  .valueChanges
  .pipe(debounceTime(500))
  .subscribe(dataValue => {
    console.log("dataValue", dataValue);
  });

Right now I had that problem, I solved it as follows!现在我遇到了那个问题,我按如下方式解决了!

// Reactive control
fieldOne = this.formBuilder.control('');

// Reactive form
formGroup = this.formBuilder.group({
  fieldOne: [],
  fieldTwo: [],
  fieldX: [],
});

this.fieldOne.valueChanges
  .pipe(debounceTime(300))
  .subscribe(value => {
    this.formGroup.get('fieldOne').setValue(value);
  });

you have response speed in the controls within the form group and a delay in the events emitted from the individual control, hopefully in the future that the valueChanges emitted by the formGroup will present the control that triggered the event and be able to use filter in the observable您在表单组内的控件中具有响应速度,并且从单个控件发出的事件有延迟,希望将来 formGroup 发出的 valueChanges 将呈现触发事件的控件并能够在可观察的

Regards!问候!

There's an issue on GitHub, which may(?:) solve this in the future: GitHub 上有一个问题,将来可能(?:)解决这个问题:

https://github.com/angular/angular/issues/19705 https://github.com/angular/angular/issues/19705

Then it should be possible (like in AngularJS) to debounce single input fields.然后应该可以(就像在 AngularJS 中一样)去抖动单个输入字段。

I faced the same issue and in my case creating a new Input component and providing debounce value in html solved issue without any custom code我遇到了同样的问题,在我的例子中,创建了一个新的 Input 组件并在 html 中提供了 debounce 值解决了没有任何自定义代码的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM