例えばフォームの値を監視するとき、入力値が常に返ってくるとその数だけイベントが発生してしまう。
knockoutでは変更が完了してから、時間設定まで付けて監視する事ができる。
<input type="text" value="" data-bind="value: instantaneousValue, valueUpdate:'afterkeydown'" />
function AppViewModel() {
this.instantaneousValue = ko.observable('');
// instantaneousValueの入力が完了してから500ms待って反映させる
this.throttledValue = ko.computed(this.instantaneousValue)
.extend({ throttle: 500 });
// computedでいうところのreadみたいなもの -> subscribe
this.throttleValue.subscribe(function(value){
// ここで処理を分けられる
// 例えば、前回から値の変更があれば更新処理を走らせるとか
});
}
ko.applyBindings(new AppViewModel());
例えば、observableした値の変更時に別の処理を走らせたいとする。
subscribeを使わないパターンだとcomputedのwrite内で変更させる手がある。
this.loading = ko.observable(false);
this.etcValue = ko.observable('');
this.etcForm = ko.computed({
read: function () {
return this.etcValue();
},
write: function (value) {
this.etcValue(value);
this.loading(true);
},
owner: this
});
subscribeを使うともっとシンプルに記述することが可能だ。
var self = this;
this.loading = ko.observable(false);
this.etcValue = ko.observable('');
this.etcValue.subscribe(function(val){
self.loading(true);
});
ローディングを仕込みたいのならthrottleと一時的な値を保持するオブジェクトも用意すればもっとスッキリ出来ると思う。
検証してないけど、以下みたいな感じになるかと。
var self = this;
this.loading = ko.observable(false);
this.instantaneousValue = ko.observable('');
this.instantaneousValue.subscribe(function(val){
self.loading(true); // 入力開始でtrue
});
this.etcValue = ko.computed(this.instantaneousValue).extend({ throttle: 500 });
this.etcValue.subscribe(function(val){
// 入力完了から500ms後にloadingをfalseにする
self.loading(false);
});