angular - Async form validation with debounce? -
i wondering how can implement debounce time on async validator.
i have following:
... password: ['',validators.compose([validators.required, this.passwordvalid])] ...
where:
passwordvalid(control:control):{ [key: string]: any; } { return new promise(resolve => { this._http.post('/passwordcheck', control.value) .subscribe( success=>{ resolve(null); }, error=>{ resolve({passwordvalid: false}) } ) }) }
however now, validation triggered @ each keystroke. need add debounce functionality. how can that?
it's not possible out of box since validator directly triggered when input
event used trigger updates. see line in source code:
if want leverage debounce time @ level, need observable directly linked input
event of corresponding dom element. issue in github give context:
in case, workaround implement custom value accessor leveraging fromevent
method of observable.
here sample:
const debounce_input_value_accessor = new provider( ng_value_accessor, {useexisting: forwardref(() => debounceinputcontrolvalueaccessor), multi: true}); @directive({ selector: '[debouncetime]', //host: {'(change)': 'doonchange($event.target)', '(blur)': 'ontouched()'}, providers: [debounce_input_value_accessor] }) export class debounceinputcontrolvalueaccessor implements controlvalueaccessor { onchange = (_) => {}; ontouched = () => {}; @input() debouncetime:number; constructor(private _elementref: elementref, private _renderer:renderer) { } ngafterviewinit() { observable.fromevent(this._elementref.nativeelement, 'keyup') .debouncetime(this.debouncetime) .subscribe((event) => { this.onchange(event.target.value); }); } writevalue(value: any): void { var normalizedvalue = isblank(value) ? '' : value; this._renderer.setelementproperty(this._elementref.nativeelement, 'value', normalizedvalue); } registeronchange(fn: () => any): void { this.onchange = fn; } registerontouched(fn: () => any): void { this.ontouched = fn; } }
and use way:
function validator(ctrl) { console.log('validator called'); console.log(ctrl); } @component({ selector: 'app' template: ` <form> <div> <input [debouncetime]="2000" [ngformcontrol]="ctrl"/> </div> value : {{ctrl.value}} </form> `, directives: [ debounceinputcontrolvalueaccessor ] }) export class app { constructor(private fb:formbuilder) { this.ctrl = new control('', validator); } }
see plunkr: https://plnkr.co/edit/u23zgaxjavzfpesczbpj?p=preview.
Comments
Post a Comment