Knockout JS中的多个依赖选择
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Knockout JS中的多个依赖选择相关的知识,希望对你有一定的参考价值。
我正在尝试在Knockout JS中使用一系列依赖选择。我可以让一个人在this线程之后工作,但我很难获得多个操作。
想法是拥有主题和级别,并允许用户一次选择一个主题和一个(或多个)级别。
例如:
用户在主选择中选择“数学”。依赖选择然后将选项更改为“微积分,代数,几何”。用户选择三个中的两个。
到目前为止很简单。
然后,用户想要选择另外一对主题和级别。因此,单击一个按钮,添加另一行主要和从属选择元素。用户选择“英语”和从属选择更改选项为“语言,文学,历史”,以便他们也可以从中选择。
现在有两行选择。一个是主题数学,另一个是学科英语。
我试图让这个工作在jsfiddle,但由于原因我不完全确定这个东西甚至不会加载。
self.subjLevList = ko.observableArray([
{subject: "Math", levels: ["Calculus", "Algebra"]},
{subject: "English", levels: ["Language", "Literature"]} ]);
我一直盯着这个这么久我可能错过了一些明显的东西,但如果有人可以帮助我,那将非常感激:)
修复参考错误
由于原因,我不完全确定这个东西甚至不会加载
您的浏览器的开发者工具是您的朋友。如果您的视图无法呈现,则敲除通常会在控制台中提供方便的错误消息。在你的情况下,第一个是这样的:
未捕获的ReferenceError:无法处理绑定
foreach: function (){return subjLevVM.subjLevList }
消息:subjLevVM
未定义
这意味着你的绑定上下文中有一些错误:没有名为subjLevVM
的属性,因此无法访问数组subjLevList
。
这是一个fiddle,修复了所有参考错误。如果你发现很难找到这些,请看看this answer I wrote earlier。
实现描述的行为
您的目标行为并不容易创建。我开始在你当前的小提琴实现,但不得不改变太多,以至于没有更清楚......
最终,我在一系列Rows
,Labs
和options
中重新实现了这个结构。
- 如果仍然没有使用
Labs
,则只能添加行 - 更改Row的实验室时,您只能从未使用的实验室中选择
每个图层都使用computed
属性来限制选项。如果代码的任何部分不清楚或难以理解,请告诉我,我将很乐意进一步澄清。
var Lab = function(name, id, options, labsInUse) {
this.name = name;
this.id = id;
this.options = options;
this.selectedOptions = ko.observableArray([]);
this.disabled = ko.pureComputed(function() {
return labsInUse().some(function(thatId) {
return thatId === id;
});
});
};
Lab.fromData = function(d, idsInUse) {
return new Lab(d.lab_name, d.id, d.lab_options.split(","), idsInUse);
}
var Row = function(labs) {
this.labs = labs;
this.selectedLab = ko.observable(labs.find(function(l) {
return !l.disabled();
})
);
this.setOptionDisable = function(option, item) {
ko.applyBindingsToNode(option, { disable: item.disabled }, item);
}
};
var App = function(courseData, initialSelection) {
this.rows = ko.observableArray([]);
// Every lab can only be added once
var labIdsInUse = ko.pureComputed(function() {
return this.rows().map(function(r) {
return r.selectedLab() && r.selectedLab().id;
});
}, this);
var labs = courseData.map(function(d) {
return Lab.fromData(d, labIdsInUse)
});
// Display a report of selections
this.selection = ko.pureComputed(function() {
return this.rows()
.map(function(r) {
var lab = r.selectedLab();
return lab.name + ", with subjects: " + lab.selectedOptions().join(", ");
});
}, this);
this.canAdd = ko.pureComputed(function() {
return labs.length > labIdsInUse().length;
}, this);
this.addRow = function() {
this.rows.push(new Row(labs));
}.bind(this);
this.removeRow = function(row) {
this.rows.remove(row);
}.bind(this);
// Set initial selection
Object.keys(initialSelection)
.map(function(labName) {
var row = new Row(labs);
var labToSelect = labs.find(function(lab) {
return lab.name === labName;
});
// Set options
labToSelect.selectedOptions(
initialSelection[labName]
);
// Add lab to row
row.selectedLab(labToSelect);
// Add row to app
this.rows.push(row);
}.bind(this));
};
ko.applyBindings(
new App(
getCourseData(),
{"Math": ["Calculus", "Algebra"], "English": ["Language"]}
)
);
function getCourseData(){return[{id:"1003",lab_name:"Math",lab_index:"1",lab_options:"Calculus,Algebra,Geometry"},{id:"1004",lab_name:"English",lab_index:"2",lab_options:"Language,Literature,History"},{id:"1005",lab_name:"History",lab_index:"3",lab_options:"Ancient,Modern"}]}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach: rows">
<div>
<select data-bind="options: labs, optionsText: 'name', value: selectedLab, optionsAfterRender: setOptionDisable"></select>
<!-- ko with: selectedLab -->
<select data-bind="options: options, selectedOptions: selectedOptions" multiple></select>
<!-- /ko -->
<button data-bind="click: $parent.removeRow">delete</button>
</div>
</div>
<button data-bind="click: addRow, enable: canAdd">add lab</button>
<h3>Selection:</h3>
<ul data-bind="foreach: selection">
<li data-bind="text: $data"></li>
</ul>
以上是关于Knockout JS中的多个依赖选择的主要内容,如果未能解决你的问题,请参考以下文章