しゃかまる

2013.12.27

Knockout.js入門 その2

こんにちは、村上です。
年の瀬ですね。

前回の記事に引き続き、Knockout.jsについて書きます。
前回はknockoutの導入と、簡単なobesrvableについて書きました。
今回は、その他のobservable機能の

  • Observable Array
  • Computed Observable

について書きます。

なお、少し前にKnockout.js v3.0.0が出ましたが、前回と今回の記事は2.x向けですのでご了承ください。
とは言え、3.0.0は裏側の処理が変わったのがメインで、Application側には影響は無いようです。

Observable Array

前回の記事で書いたko.observableは単一の値をbindするものでしたが
Arrayをbindする場合はこちらを使うことになります。
これを使うと、まとまったデータをHTMLに描画する際に楽になります。

軽くサンプルを書いてみます。今回のサンプルデータ定義はこんな感じです。
名前と得点を定義してます。

個人的にobservableArrayで1番使うと思うのがforeachです。

HTML

JS

このコードは以下のようになります。

名前 得点
タグに書いていますが、

と定義すると、listにbindしてる値をループして表示してくれます。

もうちょっと拡張してみましょう。

Computed Observable

computedというbind方法もあります。
以前はdependentObservableという名前だったようです。

のように指定します。
これはko.observableを拡張したもので、ある特定の処理をした値を保持しておくことができます。

サンプルを示すとこんな感じです。
上の表の得点を変更出来るようにして、得点の降順で並び替えてみましょう。
それぞれの値を変更するnumber要素をつけてますので、値を変更してみてください。

名前 得点

HTML

HTMLはほぼ同じです。
foreachでbindする値をsortListに変更しました。

JS

computedの通常の定義はこんな感じになります。
第1引数で処理した内容が変数にbindされます。

第2引数には実行するcontextを設定します。

contextにはthisの値を入れたselfという変数を入れています。
sortListをHTMLから呼び出していますが、そうするとこのメソッドをwindowから呼び出すことになり
thisがwindowになってしまいます。object内のデータが参照できなくなるので、selfにthisを入れてcontextを保持しています。
何言ってんの?となったらJSのthisについて調べてみると良いです。

第3引数にはcomputedのオプションをもろもろ指定できます。
deferEvaluationについては後述します。

最後に、ko.computedの処理で最近はまったことについて書いておきます。
この辺の内容は、Knockoutのリファレンスでは「ビギナーはとりあえず気にしなくていいよ!」と言ってますが
リファレンスは一度読んだ方が良い気がします。

ko.applyBindingsをした際に、ko.computedで定義されている処理を実行してbindの初期値を入れます。
ですが、処理内容によってはそのタイミングではエラーになってしまうことがあります。
特にAjaxで値を取ってきた値を使用する時などに起こりそうですね。
そういう時に、初期化のタイミングをapplyBindingsではなく実際に呼び出した際にする方法があります。
それが上で指定したdeferEvaluationです。

もう一つ。
ko.comutedでbindした値が更新されるタイミングですが
computedの値を初期化する処理で使用した値が更新されたタイミングになります。
例えば

とした場合、this.fugaやthis.piyoの値が変更されたタイミングで呼び出され、this.hogeが更新されます。
しかし

のようにして始めのreturnで処理が終わると、this.fugaやthis.piyoを参照されません。
そうすると、hogeからfugaやpiyoに対しての依存関係が設定されず、fugaやpiyoを変更してもhogeが更新されなくなります。

ということを知らず、どはまりしました。
もしこの辺りの内容が間違ってたら指摘してもらえると嬉しいです。

今回はこの辺で。
では良いお年を!