基本上这就是我所做的
- 创建一个预定义的结构/类,它知道它是否具有值列表或只有一个值。
- 如果其列表仅显示文本,则在视图侧显示下拉列表。
- 在根 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 中。
- 如果某些 observables 不会改变,则可以用简单的值替换(例如:name)