Skip to content

Instantly share code, notes, and snippets.

@nantekkotai
Last active December 11, 2015 16:59
Show Gist options
  • Save nantekkotai/4631625 to your computer and use it in GitHub Desktop.
Save nantekkotai/4631625 to your computer and use it in GitHub Desktop.
[knockoutjs]throttleとsubscribeの使い方

時間差で実行するthrottle

例えばフォームの値を監視するとき、入力値が常に返ってくるとその数だけイベントが発生してしまう。
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());

値の更新をコールバックで取得できるsubscribe

例えば、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);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment