我正在尝试使用knockout填充依赖下拉列表的默认值。
当值被编码时,它可以工作,但我需要从ajax请求中获取值,然后,第二个下拉选项不会更新。值self.selectedState已更新,但我想因为我还没有填充选项,所以select中的值不是bind。到目前为止,这是我的代码:
function myViewModel(country, state) {
var self = this;
self.selectedCountry = ko.observable();
self.selectedState = ko.observable();
self.availableCountries = ko.observableArray([
{
id: 1, name: 'United States', states: [
{ id: 1, name: 'Alabama' },
{ id: 2, name: 'California' },
]
},
{
id: 2, name: 'Canada', states: [
{ id: 53, name: 'Alberta' },
]
}
]);
self.availableStates = ko.observableArray([]);
self.selectedCountry.subscribe(function() {
self.availableStates([]);
for (var i = 0; i < self.availableCountries().length; i++) {
if (self.availableCountries()[i].id == self.selectedCountry()) {
self.availableStates(self.availableCountries()[i].states);
break;
}
}
});
self.selectedCountry(1).selectedState(2);
}
var viewModel = new myViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="options: availableCountries, optionsText: 'name', optionsValue: 'id', optionsCaption: 'Select a country...',
value: selectedCountry"></select>
<select data-bind="options: availableStates, optionsText: 'name',optionsValue: 'id', value: selectedState, visible: availableStates().length > 0" style="display:none"></select>
当从ajax获取选项时,是否需要做一些特殊的事情?
答案 0 :(得分:1)
问题不在于AJAX,尤其是self.selectedState
在一段时间内没有相应的option
这一事实(在提取选项时)。
来自the docs:
通常,当您在
value
元素上使用<select>
绑定时,它就是 表示您希望关联的模型值描述哪个项目 已选中<select>
。但是如果你设置模型会发生什么 值列表中没有相应条目的东西?该 默认行为是Knockout将模型值覆盖为 将其重置为下拉列表中已选择的任何内容 防止模型和UI失去同步。但是,有时您可能不希望出现这种行为。如果相反你 想要Knockout允许你的模型可观察到具有的值
<select>
中没有相应的条目,然后指定valueAllowUnset: true
。在这种情况下,只要您的模型值无法表示<select>
,<select>
根本没有选定的值 时间,在视觉上由空白表示。
答案 1 :(得分:0)
这是一个利用计算可观察量的绝佳机会。计算似乎非常适合这项工作,因为它可以帮助您避免在跟踪依赖项中设置自己的手动订阅。尝试一下 - 我已经改变了非常你的代码来实现这一目标。
function myViewModel(country, state) {
var self = this;
self.selectedCountry = ko.observable();
self.selectedState = ko.observable();
self.availableCountries = ko.observableArray([{
id: 1,
name: 'United States',
states: [{ id: 1, name: 'Alabama' },
{ id: 2, name: 'California' }, ]
},
{ id: 2,
name: 'Canada',
states: [{ id: 53, name: 'Alberta' }, ]
}]);
self.availableStates = ko.computed(function() {
var states = [];
for (var i = 0; i < self.availableCountries().length; i++) {
if (self.availableCountries()[i].id == self.selectedCountry()) {
states = states.concat(self.availableCountries()[i].states);
break;
}
}
return states;
});
self.selectedCountry(1).selectedState(2);
}
var viewModel = new myViewModel();
ko.applyBindings(viewModel);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="options: availableCountries, optionsText: 'name', optionsValue: 'id', optionsCaption: 'Select a country...',
value: selectedCountry"></select>
<select data-bind="options: availableStates, optionsText: 'name',optionsValue: 'id', value: selectedState, visible: availableStates().length > 0" style="display:none"></select>
&#13;