Angular 4, How to update [(ngModel)] with a delay

2019-03-20 00:46发布

Since ngModel is updating instantly how to put a delay.

  <input type="text" value="{{item.task_name}}" name="task_name" [(ngModel)]="item.task_name" (ngModelChange)="update_fields([item.task_name])" >

I need to save the task_name with a delay of one seconds by calling update_fields() , To avoid instant calls to service.

Thanks

4条回答
不美不萌又怎样
2楼-- · 2019-03-20 01:00

Add delay inside your update_fields() method.

Like:

public update_fields(data)
  setTimeout(function() {
   //call service
  }, 1000);
查看更多
再贱就再见
3楼-- · 2019-03-20 01:06

Rxjs and Observables are the perfect candidate for this type of task! Here is an example of how it can be achieved:

Template:

<input type="text" [value]="item.task_name"(keyup)="term$.next($event.target.value)">

Component:

import ......

import {Subject} from 'rxjs/Subject';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/switchMap';

@Component{(
  ...
)}
export class YourComponent {

  term$ = new Subject<string>();

  constructor() {
    this.term$
      .debounceTime(1000)
      .distinctUntilChanged()
      .switchMap(term => /*do something*/);
  }
}

subject is a type of object that acts both as an observable and observer - meaning you can both subscribe to it and emit values from it (with next())!

debounceTime waits for the provided time in ms until it allows for new changes

distinctUntilChanges will not allow the same input to pass through two times in a row

switchMap takes the latest observable from the chain so you don't get multiple results at once

查看更多
干净又极端
4楼-- · 2019-03-20 01:12
update_fields(){

  this.service.yourTask(){
    .subscribe(data => {
      setTimeout(()=>{ //your task }, 4000)
    }    
  }
}


someFunction() {
    setTimeout(() => /* code to execute */, 3000)
}
查看更多
唯我独甜
5楼-- · 2019-03-20 01:15

Here's a solution that works with a callback.

view template:

<input ... #element (ngModelChange)="delayAction(element, doSomething, [$event])">

component class:

    actionsByElements = new Map<HTMLElement, Subscription>();

    delayAction(element: HTMLElement, cb: Function, args: any[]) {
      // cancel countdown by element
      let action = this.actionsByElements.get(element);
      if(action) {
        action.unsubscribe();
      }

      // start new countdown by element
      action = timer(1000).subscribe(() => cb.apply(this, args));
      this.actionsByElements.set(element, action);
    }

    doSomething(){...}
查看更多
登录 后发表回答