基本的にこれは私がやったことです
- 値のリストがあるか、単一の値しかないかを知る定義済みの構造 /class を作成します。
- リストがテキストのみを表示する場合は、ビュー側でドロップダウンを表示します。
- ルート vm で、手順 1 で作成した構造をネストし、dict を作成します。
VMはこちら
var optionVM = function (name,isList, v) {
var self = this;
self.name=ko.observable(name);
if (isList) self.values = ko.observableArray(v);
else self.value = ko.observable(v);
self.isList = ko.observable(isList);
self.selected = ko.observable();
}
var vm = function () {
var self = this;
var a1Vm = new optionVM('A1',true, [new optionVM('A11',false,111), new optionVM('A12',false,122)]);
var aVm = new optionVM('A',true, [new optionVM('A2',false,'21'), a1Vm]);
var d = new optionVM('Root',true, [aVm, new optionVM('B',false,'B1'),new optionVM('C',false,'C1')]);
self.dict = ko.observable(d);
}
ko.applyBindings(new vm());
これがビューです
<select data-bind='options:dict().values,optionsText:"name",value:dict().selected'>
</select>
<div data-bind="template: {name: 'template-detail', data: dict().selected}"></div>
<script type="text/html" id='template-detail'>
<!-- ko if:$data.isList -->
<span> List:</span>
<select data-bind='options:values,optionsText:"name",value:selected'>
</select>
<div data-bind="template: {name: 'template-detail', data: selected}"></div>
<!-- /ko -->
<!-- ko ifnot:$data.isList -->
Value:<span data-bind="text:value"></span>
<!-- /ko -->
</script>
そして、ここにjsFiddleがあります
改良点:
- isArray を使用して、そのリストが optionVM にあるかどうかを識別できます。
- 一部のオブザーバブルは、変更されない場合は単純な値に置き換えることができます (例: 名前)