先上效果圖:
文檔結構:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Knockout.js多級select綁定</title>
</head>
<body>
<span id="container">
<select data-bind="options:child, optionsText:'name', optionsValue:'id',optionsCaption: 'Choose...',value:selected,event:{change:OnSelected}"></select>
<!--ko if:typeof child ==='function' && child().length>0-->
<span data-bind="template: { name: 'ko_child',foreach:child }"></span>
<!--/ko-->
</span>
<script type="text/html" id="ko_child">
<!--ko if:id()==$parentContext.$data.selected() && typeof child ==='function' && child().length>0-->
<select data-bind="options:child, optionsText:'name', optionsValue:'id',optionsCaption: 'Choose...',value:selected"></select>
<!--ko if:child().length>0-->
<span data-bind="template: { name: 'ko_child',foreach:child }"></span>
<!--/ko-->
<!--/ko-->
</script>
</body>
</html>
<script src="../../Script/knockout/knockout3.4.0.min.js"></script>
<script src="../../Script/knockout/knockout.mapping-latest.js"></script>
腳本:
var data = [
{
"id": 1,
"pid": 0,
"name": "K12課程",
"child": [
{
"id": 5,
"pid": 1,
"name": "4-5歲K課程",
"child": []
},
{
"id": 6,
"pid": 1,
"name": "5-6歲G1課程",
"child": []
},
{
"id": 7,
"pid": 1,
"name": "6-7歲G2課程",
"child": []
},
{
"id": 8,
"pid": 1,
"name": "7-8歲G3課程",
"child": []
},
{
"id": 9,
"pid": 1,
"name": "8-9歲G4課程",
"child": []
},
{
"id": 10,
"pid": 1,
"name": "9-10歲G5課程",
"child": []
},
{
"id": 11,
"pid": 1,
"name": "10-11歲G6課程",
"child": []
},
{
"id": 12,
"pid": 1,
"name": "11-12歲G7課程",
"child": []
},
{
"id": 13,
"pid": 1,
"name": "12歲以上G8課程",
"child": []
}
]
},
{
"id": 2,
"pid": 0,
"name": "特色課程",
"child": [
{
"id": 14,
"pid": 2,
"name": "3-6歲幼兒藝術探索",
"child": []
},
{
"id": 15,
"pid": 2,
"name": "7-8歲藝術開拓",
"child": []
}
]
},
{
"id": 3,
"pid": 0,
"name": "戴維斯",
"child": [
{
"id": 16,
"pid": 3,
"name": "G1課程",
"child": []
},
{
"id": 17,
"pid": 3,
"name": "G2課程",
"child": []
},
{
"id": 18,
"pid": 3,
"name": "G3課程",
"child": []
}
]
},
{
"id": 4,
"pid": 0,
"name": "國際教授講座",
"child": [
{
"id": 19,
"pid": 4,
"name": "帕克斯講座",
"child": [{
id: 21,
pid: 19,
name: '三國志',
child: [{
id: 23,
pid: 21,
name: '上志'
}, {
id: 24,
pid: 21,
name: '中志'
}, {
id: 25,
pid: 21,
name: '下志'
}]
}, {
id: 22,
pid: 19,
name: '紅樓夢'
}]
},
{
"id": 20,
"pid": 4,
"name": "王怡華大概念",
"child": []
}
]
}
];
var items = {};
function setSelected(list) {
for (var i = 0, n = list.length; i < n; i++) {
list[i].selected = '';
if (list[i].child && list[i].child instanceof Array && list[i].child.length > 0)
setSelected(list[i].child);
}
}
setSelected(data);
items.child = data;
items.selected = '';
var VM = ko.mapping.fromJS(items);
ko.applyBindings(VM, document.getElementById('container'));
function ClearChildSelected(item) {
item.forEach(function (value, index, array) {
if (typeof value.selected === 'function') value.selected('');
if (typeof value.child === 'function') ClearChildSelected(value.child());
});
}
function OnSelected($data, event) {
ClearChildSelected($data.child());
}
function SetValue(id) {
FindAndSet(VM, id);
}
function FindAndSet(item, id) {
if (!item.child) return;
var childs = item.child();
for (var i = 0, n = childs.length; i < n; i++) {
if (childs[i].id() === id) {
item.selected(id);
FindAndSet(VM, childs[i].pid());
return;
} else {
FindAndSet(childs[i], id);
}
}
}