NgModelは遅延の設定方法を即座に更新しているため。
<input type="text" value="{{item.task_name}}" name="task_name" [(ngModel)]="item.task_name" (ngModelChange)="update_fields([item.task_name])" >
サービスへの即時呼び出しを避けるために、update_fields()を呼び出してtask_nameを1秒の遅延で保存する必要があります。
ありがとう
RxjsおよびObservablesは、このタイプのタスクの完璧な候補です!達成方法の例を次に示します。
テンプレート:
_<input type="text" [value]="item.task_name"(keyup)="term$.next($event.target.value)">
_
コンポーネント:
_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
は、オブザーバブルとオブザーバーの両方として機能するオブジェクトのタイプです。つまり、サブスクライブして値を出力することができます(next()
を使用)。
debounceTime
は、新しい変更が許可されるまで、指定されたミリ秒単位の時間待機します
distinctUntilChanges
は、同じ入力が連続して2回通過することを許可しません
switchMap
はチェーンから最新のオブザーバブルを取得するため、一度に複数の結果を取得することはありません
Fredrik Lundinによる回答をAngular 6で更新:
テンプレート:
<input type="text" [value]="item.task_name" (keyup)="term$.next($event.target.value)">
コンポーネント:
import ......
import { Subject, EMPTY } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
@Component{(
...
)}
export class YourComponent implements OnDestroy {
term$ = new Subject<string>();
private searchSubscription: Subscription;
constructor() {
this.searchSubscription = this.term$.pipe(
debounceTime(1000),
distinctUntilChanged(),
switchMap(term => {
/*do something*/
return EMPTY;
})
).subscribe();
}
ngOnDestroy() {
//remember to unsubscribe on destroy
if (this.searchSubscription) {
this.searchSubscription.unsubscribe();
this.searchSubscription = null;
}
}
}
update_fields()
メソッド内に遅延を追加します。
お気に入り:
public update_fields(data)
setTimeout(function() {
//call service
}, 1000);
update_fields(){
this.service.yourTask(){
.subscribe(data => {
setTimeout(()=>{ //your task }, 4000)
}
}
}
someFunction() {
setTimeout(() => /* code to execute */, 3000)
}
callbackで動作するソリューションを次に示します。
テンプレートを表示:
<input ... #element (ngModelChange)="delayAction(element, doSomething, [$event])">
コンポーネントクラス:
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(){...}