web-dev-qa-db-fra.com

Angular 4, Comment mettre à jour [(ngModel)] avec un délai de 1 seconde

Puisque ngModel met à jour instantanément comment mettre un délai.

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

Je dois enregistrer le nom de la tâche avec un délai d'une seconde en appelant update_fields (), afin d'éviter les appels instantanés au service. 

Merci

8
user1879901

Rxjs et Observables sont le candidat idéal pour ce type de tâche! Voici un exemple de la façon dont cela peut être réalisé:

Modèle:

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

Composant:

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 est un type d'objet qui agit à la fois comme observable et comme observateur. Vous pouvez donc vous y abonner et en émettre des valeurs (avec next())!

debounceTime attend le temps fourni en ms jusqu'à ce qu'il permette de nouvelles modifications

distinctUntilChanges ne permettra pas à la même entrée de passer deux fois de suite

switchMap prend la dernière observation de la chaîne pour ne pas obtenir plusieurs résultats à la fois

18
Fredrik Lundin

Ajoutez un délai dans votre méthode update_fields().

Comme:

public update_fields(data)
  setTimeout(function() {
   //call service
  }, 1000);
0
anoop
update_fields(){

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


someFunction() {
    setTimeout(() => /* code to execute */, 3000)
}
0
Rahul Singh

Voici une solution qui fonctionne avec un callback .

voir le gabarit:

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

classe de composant:

    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(){...}
0
Martin Cremer