2

Knockout.jsでチェックボックスのリストを作成しようとしています。リスト自体は、データにバインドされたソース、およびリスト内のどのアイテムが選択されているかから取得されます。私が持っているモデルは次のようになります。

var ViewModel = function ()
{
   this.areas = [{AreaId: 1, Name: 'Test 1'}, {AreaId: 2, Name: 'Test 2'}, {AreaId: 3, Name: 'Test 3'}];
   this.AreasImpacted = ko.observableArray([1, 2]);
};

次に、 Test 1Test 2、およびTest3というラベルの付いたチェックボックスのリストを作成します。テスト1テスト2をチェックしてもらいたい。私のHTMLは次のようになります。

<span class="areas" data-bind="foreach: areas">
  <label><input type="checkbox" data-bind="value: AreaId, checked: $parent.AreasImpacted" /><span data-bind="text: Name"></span></label>
</span>

これにより、各チェックボックス適切な名前で描画され、各チェックボックスのvalue属性が正しく設定されていることを確認できますが、何もチェックされません。this.AreasImpactedだけに設定してみました2。そうすると、3つのチェックボックスがすべてオンになります。

完全に混乱しています!

アップデート:

モデルを次のように変更した場合:

this.AreasImpacted = ko.observableArray(['1', '2']);

その後、物事は期待どおりに機能します。

推測しなければならないのであれば、for-eachバインディングは各値を文字列に変換していると言えます。これが設計によるものなのか、Knockout.jsのバグなのか知りたいです。入力の値は数値であると期待します。これは、それをバインドしたものだからです。

提出されたバグ:

上記のコードは文書化されたとおりに機能しないため、GitHubにバグを報告しました。

4

1 に答える 1

2

AreaIdレンダリングしている領域のがAreasImpacted配列に含まれているかどうかを確認するために、状況を少し変更する必要があります。

data-bind="value: AreaId, checked: $parent.AreasImpacted.indexOf(AreaId) >= 0"

動作するデモについては、このフィドルを参照してください。

注:この手法を使用して、バインドされたチェックボックスの1つをオンまたはオフにしても、データソースは更新されません。

または、次のように配列を文字列のリストにすることもできます。

this.AreasImpacted = ko.observableArray(['1', '2']);

デモについては、このフィドルを参照してください。


コメントに記載されているように、KnockoutJSのドキュメントは、OPの元の構文が機能することを示唆しているようです。配列内の項目を文字列にすることで、これを機能させることもできます(デモ)。

KnockoutJSソースは、これが発生する理由を教えてくれます。checked.jsデフォルトのバインディングを見て、入力をチェックするかどうかを決定するコードの関連ビットを確認します。

element.checked = ko.utils.arrayIndexOf(value, element.value) >= 0;

このコンテキストでは:

  • valueエリアIDの配列です(OPの元のコードでは数字)
  • element<input .../>チェックボックスHtmlElementです

そのため、element.valueは常に文字列型になります。そのため、配列内の項目も文字列である場合にのみチェックボックスがオンになります。

これがKnockoutJSのバグなのか、それとも予期しない論理的な動作なのか:わかりません。

于 2013-02-11T23:56:54.687 に答える