我遇到这种情况,当从可计算的KO属性更改下拉列表时,下拉列表的绑定值observable不会自动同步。 这有点棘手,因为下拉列表是从另一个下拉列表中选择的值填充的,但为了使这一点更加清晰,我创建了这个测试小提琴来演示问题:https://jsfiddle.net/n3wjack/gzmb792p/
以下是如何模拟问题:
所选宠物标签未更新以显示Jane的第一只宠物的名称。 如果您对宠物下拉列表进行更改,则会再次更新该值。 我不能保证用户会这样做,所以我不确定该值是否正确。
那么如何解决这个问题,或者我做错了什么?
-
我还包括下面的代码,显然这是必需的。
JS:
var petOwners = [
{ name: "John", pets: ["Blacky","Mozart"] },
{ name: "Jane", pets: ["Polly", "Felix"]}
];
var viewModel = {
availableOwners: ko.observableArray(petOwners),
selectedOwner: ko.observable(),
selectedPet: ko.observable()
}
viewModel.availablePets = ko.computed(function(){
console.log("** availablePets computed **")
var result = [];
if (viewModel.selectedOwner())
{
console.log(viewModel.selectedOwner());
result = viewModel.selectedOwner().pets;
}
console.log(result);
return result;
}, this);
viewModel.peekPet = function (){
document.getElementById("peekoutput").innerHTML += "selectedPet = " + viewModel.selectedPet.peek() + "</br>";
}
ko.applyBindings(viewModel);
HTML:
<select data-bind="foreach:availableOwners, value:selectedOwner">
<option data-bind="text: name, value: $data"></option>
</select>
<i>
( selected: <span data-bind="text: selectedOwner().name"></span> )
</i>
<p>
This dropdown shows the pets of the owner, selected in the above dropdown.
</p>
<select data-bind="foreach:availablePets, value: selectedPet">
<option data-bind="text: $data, value: $data"></option>
</select>
<p>
<i>
Selected pet: <span data-bind="text: selectedPet"></span>
</i>
</p>
<p>
The selected pet however doesn't update to be in sync with the first pet in the dropdown, when you change the owner dropdown. :(
</p>
<p>
<button data-bind="click: peekPet">Peek selected pet</button>
</p>
<code id="peekoutput">
</code>
答案 0 :(得分:1)
这是一种不同的方法。宠物成为一系列物体。然后你使用选项绑定。这是小提琴。
https://jsfiddle.net/0o89pmju/22/
的javascript
var petOwners = [{
name: "John",
pets: ["Blacky", "Mozart"]
}, {
name: "Jane",
pets: ["Polly", "Felix"]
}];
function petOwner(data) {
var self = this;
this.name = ko.observable(data.name);
this.selectedPet = ko.observable('');
this.pets = ko.observableArray(data.pets);
}
function viewModel() {
var self = this;
this.petOwners = ko.observableArray('');
this.selectedPetOwner = ko.observable('');
}
var vm = new viewModel();
(function($) {
ko.applyBindings(vm); //bind the knockout model
$.each(petOwners, function(i, item) {
vm.petOwners.push(new petOwner(item));
});
console.log(ko.toJS(vm));
})(jQuery);
HTML
choose a pet owner:
<select data-bind="options: petOwners,
optionsText: 'name',
value: selectedPetOwner,
optionsCaption: 'Choose...'"></select>
<div data-bind="with: selectedPetOwner">
Choose a pet:
<select data-bind="options: pets, value: selectedPet"></select>
</div>
答案 1 :(得分:1)
您需要做的就是订阅所选所有者的更改:
var viewModel = {
availableOwners: ko.observableArray(petOwners),
selectedOwner: ko.observable(),
selectedPet: ko.observable()
}
viewModel.selectedOwner.subscribe(function(){
if(viewModel.selectedOwner().pets.length > 0) {
viewModel.selectedPet(viewModel.selectedOwner().pets[0]);
}
});
还有一个替代绑定选项,用于将所选内容与没有订阅的集合同步:
<select data-bind="options: availablePets, optionsText: $data, optionsValue: $data, value: selectedPet"></select>
答案 2 :(得分:0)
这是因为当它刷新列表时,你没有选择任何宠物。默认情况下,它显示第一个,但并不意味着他被选中。
您可以添加指令以实际选择列表中的第一个:
viewModel.availablePets = ko.computed(function(){
console.log("** availablePets computed **")
var result = [];
if (viewModel.selectedOwner())
{
console.log(viewModel.selectedOwner());
result = viewModel.selectedOwner().pets;
//something like this to mark your first pet as selected.
viewModel.selectedPet(result[0]);
}
console.log(result);
return result;
}, this);