サンプルソースは以下です。
<html> <head> <script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script> </head> <body> <!-- foreach をネストする際、内側の foreach で使用する配列に "$root" をつけないとエラーになる --> <div data-bind="foreach: {data: array1, as: '$value1' }"> <p data-bind="text: $value1"></p> <div data-bind="foreach: {data: $root.array2, as: '$value2' }"> <p data-bind="text: $value2"></p> </div> </div> <!-- "$index" は単独だと出力できるが、文字列連結時等は "$index()" としないとエラーになる --> <!-- "$parentContext.$index" も同様 --> <div data-bind="foreach: {data: array1, as: '$value1' }"> <p data-bind="text: $index"></p> <p data-bind="text: $index() + ':' + $value1"></p> <div data-bind="foreach: {data: $root.array2, as: '$value2' }"> <p data-bind="text: $parentContext.$index"></p> <p data-bind="text: $parentContext.$index() + ':' + $value2"></p> </div> </div> <script> function ViewModel() { var self = this; self.array1 = ko.observableArray(['foo', 'bar', 'baz']); self.array2 = ko.observableArray(['FOO', 'BAR', 'BAZ']); }; ko.applyBindings(new ViewModel()); </script> </body> </html>
コメントに書いてある通りですが
1.
foreach をネストする際、内側の foreach で使用する配列に "$root" をつけないとエラーになる
2.
"$index" は単独だと出力できるが、文字列連結時等は "$index()" としないとエラーになる("$parentContext.$index" も同様)
で、ハマった。。。
P.S.
まだほんの少し使った程度ですが、JSはjQueryがメイン。という開発の中に、双方向バインディングだけ付け足したい時とかは便利かなと思いました。jQueryの処理も好きに書いて良い(という思想な)はずなので、例えばチームのメンバ的に、AngularJSだと(主にディレクティブ周りで)敷居が高くなってしまい導入に躊躇するような状況でも、Knockout.jsなら比較的楽に導入出来る気がします。(制約が緩いほど秩序は保ちにくくなってしまうはずですが。)