我尝试创建一个功能,其中有两个(或更多)不同的元素数组,例如:
var cities1 = ["Paris", "London", "Warsaw", "Moscow"];
var cities2 = ["Rome", "Paris", "Berlin", "Amsterdam"];
我可以将它们分配给observableArray,它被绑定到select元素。问题是当我在这些数组中有一个共同的元素时,就像在这个例子中:'Paris'。当我选择'Paris'然后将observableArray中的数据从cities1切换到cities2时,我不会得到选择被更改的信息。
请检查我准备说明问题的小提琴:http://jsfiddle.net/zbkkzdsp/3upSH/ 你是否知道如何在observableArray中切换数据导致select元素中的'resetting'选择?
答案 0 :(得分:1)
迈克尔·贝斯特指出,城市实际上并没有改变。如果您的城市本身就是视图模型,那么您所描述的内容将自动发生。
但是,由于您只有原语,因此您需要明确告诉viewmodel在数组更改时“清除”city的当前值。然后它会自动选择第一个元素。
您可以通过在点击事件中将self.City
设置为''
,或订阅self.City.Available
并将self.City
设置为''
来执行此操作。您还需要确保将订阅更新为self.City
,以便在更新后的值为''
时不提醒。
此外,我将click
事件中的一些重复功能移至第三个功能,并使两个click
函数代理此功能。您的click
函数执行完全相同的操作,只使用不同的数据集,因此这消除了一些代码重复。 ATM似乎是无聊的,因为它只有一行开始,但如果你为City更新添加更多功能,这将帮助你减少错误并更快地进行更改。
我在以下代码示例中提供了清除City值的两种方法,并注释掉了非订阅版本,以供参考。
var cities1 = ["Paris", "London", "Warsaw", "Moscow"];
var cities2 = ["Rome", "Paris", "Berlin", "Amsterdam"];
function MyViewModel() {
var self = this;
self.City = ko.observable();
self.City.Available = ko.observableArray();
self.City.subscribe(function (newValue) {
if(newValue != '') {
alert('City has changed to ' + newValue);
}
});
self.City.Available.subscribe(function(newValue) {
self.City('');
});
self.click1 = function () {
self.loadCityList(cities1);
};
self.click2 = function () {
self.loadCityList(cities2);
};
self.loadCityList = function(cityList) {
// clear city w/o subscription
//self.City('');
self.City.Available(cityList);
}
};
ko.applyBindings(new MyViewModel());
作为一个分页记录,如果您想要允许空字符串用于城市名称,或者只是想要一个更强大的方法来在城市被清除时抑制更改警报,您可以向城市添加一个子观察点并在它之间切换真假。如果你这样做,我会建议添加一个“clearCity”函数来封装所有这些逻辑。 EX
function MyViewModel() {
...
self.City.isLoading = ko.observable(false);
self.City.subscribe(function (newValue)) {
if(self.City.isLoading()) {
self.City.isLoading(false);
} else {
alert('City has changed!');
}
});
...
//could also put this on city as self.City.clearCity
self.clearCity = function() {
self.City.isLoading(true);
self.City('');
}
...
}