我正在开始机智 knockout ,我正在尝试创建一个链接 <select>
很像
通常的国家/地区选择器,当您选择一个国家/地区时,州列表会更新为仅显示所选国家/地区的州。
我设法让它几乎按照我想要的方式工作,但问题仍然存在。
我的 friend :
var AppViewModel = function () {
var self = this;
self.categories = [{ Name: "A", Sub: [{ Name: "A1" }, { Name: "A2" }] }, { Name: "B", Sub: [] }];
// the one we are working with.
self.currentCategory = ko.observable(self.categories[0]);
self.currentSubcategory = ko.observable();
};
我的html:
<select data-bind="options: categories,
optionsText: 'Name',
value: currentCategory"></select>
<select data-bind="options: currentCategory().Subcategories,
optionsText: 'Name',
value: currentSubcategory"></select>
如果全部categories
,这效果很好。有Sub
属性(property)已填充。
但是,如果Sub
如果为空,如B
从上面的示例中,当我选择它时,我在控制台中收到错误:Cannot read property 'Name' of undefined
,因为currentCategory().Subcategories
B
将是一个空数组.
我的问题是:我该如何解决这个问题?我预计 knockout 不会尝试渲染任何内容,因为 B.Subcategories
是空的...很奇怪:为什么它不渲染一个空的?
类似问题:
如果我想使用optionsCaption
,那么根据我的理解,我的值不能是一个复杂的对象,因为标题是一个字符串。
所以如果我修改html:
<select data-bind="options: categories,
optionsCaption: 'Select a category',
optionsText: 'Name',
optionsValue: 'Id',
value: currentCategory"></select>
<select data-bind="options: categories[currentCategory].Subcategories,
optionsCaption: 'Select a subcategory',
optionsText: 'Name',
optionsValue: 'Id',
value: currentSubcategory"></select>
我也会遇到同样的问题,因为当 optionsCaption
已选择,currentCategory
不是 categories
的有效索引数组。
这是一个我的代码几乎可以工作的 fiddle ,除了当我选择 B 时,第二个列表不会更新为空,直到我手动选择它。 https://jsfiddle.net/byxL373j/1/
var AppViewModel = function () {
var self = this;
self.categories = [{ Name: "A", Sub: [{ Name: "A1" }, { Name: "A2" }] }, { Name: "B", Sub: [] }];
// the one we are working with.
self.currentCategory = ko.observable();
self.currentSubcategory = ko.observable();
};
var viewModel = new AppViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="options: categories,
optionsText: 'Name',
value: currentCategory"></select>
<select data-bind="foreach: currentCategory().Sub,
value: currentSubcategory">
<option data-bind="text: Name, value: $data"></option>
</select>
最佳答案
在您的第一个问题中,您没有在任何地方定义currentCategory().Subcategories
,那么它总是会显示错误。请改用currentCategory().Sub
。然后您可以在第二次选择时使用可见绑定(bind):
var AppViewModel = function() {
var self = this;
self.categories = [{
Name: "A",
Sub: [{
Name: "A1"
}, {
Name: "A2"
}]
}, {
Name: "B",
Sub: []
}];
// the one we are working with.
self.currentCategory = ko.observable();
self.currentSubcategory = ko.observable();
};
var viewModel = new AppViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="options: categories,
optionsText: 'Name',
value: currentCategory"></select>
<select data-bind="options: currentCategory().Sub,
value: currentSubcategory,
optionsText: 'Name',
visible: currentCategory().Sub.length > 0">
</select>
如果您想显示类别帮助文本,您可以执行以下操作。请注意虚拟 if
绑定(bind) - 它甚至不会尝试查看注释内的代码,除非您的类别首先被选择。这就是使它不会中断/给出控制台错误的原因。
var AppViewModel = function() {
var self = this;
self.categories = [{
Name: "A",
Sub: [{
Name: "A1"
}, {
Name: "A2"
}]
}, {
Name: "B",
Sub: []
}];
// the one we are working with.
self.currentCategory = ko.observable();
self.currentSubcategory = ko.observable();
};
var viewModel = new AppViewModel();
ko.applyBindings(viewModel);
p {
margin: 0;
}
hr {
margin: 22px 0;
}
hr + p {
margin-bottom: 11px;
font-size: 11px;
}
span {
font-weight: bold;
color: purple;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="options: categories,
optionsCaption: 'Select a category',
optionsText: 'Name',
value: currentCategory"></select>
<!-- ko if: currentCategory -->
<select data-bind="options: currentCategory().Sub,
value: currentSubcategory,
optionsCaption: 'Select a subcategory',
optionsText: 'Name',
visible: currentCategory().Sub.length > 0">
</select>
<!-- /ko -->
<hr>
<p>debug:</p>
<p>Selected category:
<span data-bind="if: currentCategory">
<span data-bind="text: currentCategory().Name"></span></span>
<span data-bind="if: !currentCategory()">none</span>
</p>
<p>Selected subcategory:
<span data-bind="if: currentSubcategory">
<span data-bind="text: currentSubcategory().Name"></span></span>
<span data-bind="if: !currentSubcategory()">none</span>
</p>
关于javascript - knockout 链接选择选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37638761/