Knockout の foreach ループでチェックボックスを使用することについて多くの質問が投稿されていますが、チェック済みバインディングの初期化が機能する場合と機能しない場合がある理由についての回答は見たことがありません。
この単純なビューモデルでは:
viewModel = function (obj) {
this.AllPossibleThings = ko.observableArray(
[
{ ID: "1", Value: 'Thing1' },
{ ID: "2", Value: 'Thing2' },
{ ID: "3", Value: 'Thing3' },
{ ID: "4", Value: 'Thing4' }
]);
this.selectedThings = ko.observableArray(["2","3"]);
};
$(ko.applyBindings(new viewModel()));
これらを foreach テンプレートに入れると、期待どおりに機能します。4 つのチェックボックスが表示され、2 つと 3 つが事前にチェックされています。
<table>
<tbody data-bind="template: { name: 'ThingTmpl', foreach: AllPossibleThings }">
</tbody>
</table>
<script id="ThingTmpl" type="text/html">
<tr>
<td><input type="checkbox"
data-bind="attr: {value: ID}, checked: $root.selectedThings" /></td>
<td><span data-bind="text: Value"></span></td>
</tr>
</script>
テンプレートなしで同等であるべきことを行うと、同じようには機能しません。
<table>
<tbody data-bind="foreach: AllPossibleThings">
<tr>
<td><input type="checkbox"
data-bind="checked: $root.selectedThings,
attr: {value: ID}" /></td>
<td><span data-bind="text: Value"></span></td>
</tr>
</tbody>
</table>
非テンプレートのものには 4 つのチェックボックスが表示されますが、事前にチェックされたものはありません。しかし、たとえば、最初のチェックボックスをクリックすると、2 と 3 がチェックされます。「selectedThings」配列が作成される前にバインドされ、変更が観察されなかったようです。
両方で実証するフィドル: http://jsfiddle.net/jturnage/j763w/
テンプレート foreach がここで機能するのに、通常の foreach バインディングが機能しない理由を知っている人はいますか?