【问题标题】:How to use debounceTime in an angular component?如何在角度组件中使用 debounceTime?
【发布时间】:2018-06-07 10:42:52
【问题描述】:

我的要求是执行响应式表单字段验证,以便仅在用户停止输入后才显示错误消息。

我如何使用响应式表单和 Rxjs debounceTime 来实现这一点?

我正在寻找一种适用于响应式表单的解决方案

【问题讨论】:

标签: angular rxjs debounce


【解决方案1】:

实现此功能的(或至少一种)方法是动态删除和添加验证器。

在您的输入中,使用 keydown 绑定,当用户开始键入时,将剥离验证器,并使用 keyup 绑定,它将通过 debounceTime 管道运行,然后重新应用验证器(但仅在指定的去抖时间已过)。

代码在这里:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

@Component({
    selector: 'form-component',
    template: `
        <form [formGroup]="formGroup">
          <input type="text" formControlName="name" (keyup)="onKeyUp()" (keydown)="onKeyDown()" [ngClass]="{ 'invalid': formGroup.controls.name.invalid }">
        </form>
      `,
    styles: [
        '.invalid { border-color: red; color: red; }'
    ]
})
export class FormComponent implements OnInit {

    formGroup: FormGroup;
    subject: Subject<any> = new Subject();

    constructor(private formBuilder: FormBuilder) {}

    ngOnInit(): void {
        this.formGroup = this.formBuilder.group({
            name: [ '' ]
        });

        // Subscribe to the subject, which is triggered with each keyup
        // When the debounce time has passed, we add a validator and update the form control to check validity
        this.subject
            .pipe(debounceTime(500))
            .subscribe(() => {
                    this.formGroup.controls.name.setValidators([ Validators.minLength(5) ]);
                    this.formGroup.controls.name.updateValueAndValidity();
                }
            );
    }

    onKeyUp(): void {
        this.subject.next();
    }

    onKeyDown(): void {
        // When the user starts to type, remove the validator
        this.formGroup.controls.name.clearValidators();
    }

}

这里是 StackBlitz:https://stackblitz.com/edit/debounce-validator

【讨论】:

    【解决方案2】:

    debounceTime 等待提到的时间段,然后调用 subscribe 方法。例如; debounceTime(1000) 将等待 1 秒。通过pipes实现。

    这可以添加到任何订阅方法。以下是工作示例

    import { Component, OnInit } from '@angular/core';
    import { Validators, AbstractControl } from '@angular/forms';
    import { debounceTime } from 'rxjs/operators';
    
    // dynamic forms
    import { FormGroup, FormControl, FormBuilder } from '@angular/forms';
    
    
    @Component({
        selector: 'app-customer-form',
        templateUrl: './customer-form.component.html',
    })
    export class CustomerFormComponent implements OnInit {
    
        emailMessage : string;
    
        private validationMessages = {
            required: "Email field is required",
            email: "Please enter a valid Email"
        }
    
        customerForm: FormGroup;
    
        customer = new Customer();
    
        constructor(private fb: FormBuilder) { }
    
        ngOnInit() {
            this.customerForm = this.fb.group({
                emailAddress: ['',
                    [
                        Validators.required,
                        Validators.email
                    ]
                ]
            })
    
            const emailControl = this.customerForm.get('emailAddress');
            emailControl.valueChanges.pipe( debounceTime(1000) ).subscribe(
                value => this.setEmailMessage(emailControl)
            )
        }
    
        setEmailMessage( c: AbstractControl ) : void {
            this.emailMessage = '';
    
            if ( (c.touched || c.dirty) && c.errors ) {
                this.emailMessage = Object.keys(c.errors).map( key => this.validationMessages[key]).join(' ');
            }
    
        }
    
    }
    

    在您的模板中

    <input 
        class="form-control"
        id="emailId" type="email"
        placeholder="Email (required)"
        formControlName="emailAddress"
        [ngClass]="{ 'is-invalid': emailMessage }"/>
        <span class="invalid-feedback">
        {{ emailMessage }}
        </span>
    

    【讨论】:

      猜你喜欢
      • 2020-06-02
      • 2019-01-02
      • 2018-05-08
      • 2016-04-27
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-01-22
      • 2020-08-25
      相关资源
      最近更新 更多