Knockout.js 在替换ObservalArray的内容后重置select元素

Knockout.js 在替换ObservalArray的内容后重置select元素,knockout.js,Knockout.js,我尝试创建一个功能,其中有两个(或更多)不同的元素数组,如: var cities1 = ["Paris", "London", "Warsaw", "Moscow"]; var cities2 = ["Rome", "Paris", "Berlin", "Amsterdam"]; 我可以把它们分配给ObservalArray,它绑定到select元素。问题是当我在这些数组中有一个公共元素时,比如在这个例子中:“Paris”。当我选择“巴黎”,然后将ObservalArray中的数据从citi

我尝试创建一个功能,其中有两个(或更多)不同的元素数组,如:

var cities1 = ["Paris", "London", "Warsaw", "Moscow"];
var cities2 = ["Rome", "Paris", "Berlin", "Amsterdam"];
我可以把它们分配给ObservalArray,它绑定到select元素。问题是当我在这些数组中有一个公共元素时,比如在这个例子中:“Paris”。当我选择“巴黎”,然后将ObservalArray中的数据从cities1切换到cities2时,我没有得到选择已更改的信息

请检查我准备用来说明问题的小提琴:
你知道如何在ObservalArray中切换数据导致在select元素中“重置”选择吗?

正如Michael Best指出的,城市实际上并没有改变。如果您的城市本身就是viewmodels,那么您所描述的将自动发生

但是,由于您只有基本体,因此需要明确地告诉viewmodel在数组更改时“清除”城市的当前值。然后它将自动选择第一个元素

您可以在单击事件中将
self.City
设置为
'
,或者订阅
self.City.Available
并将
self.City
设置为
'
。您还需要确保将订阅更新到
self.City
,以在更新值为
''
时不发出警报

此外,我将
click
事件中的一些重复功能移动到第三个函数,并使这两个
click
函数代理此功能。您的
单击
函数执行的是完全相同的操作,只是使用了不同的数据集,因此这消除了一些代码重复。ATM看起来很无聊,因为它只需要一行代码就可以启动,但如果你在城市更新中添加更多功能,这将帮助你减少bug并更快地进行更改

我在下面的代码示例中提供了两种清除城市值的方法,并注释掉了非订阅版本,以供参考

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());
作为临别赠言,如果您希望允许城市名称使用空字符串,或者只是希望在城市被清除时使用更强大的方法来抑制更改警报,那么您可以向城市添加一个子可观察对象,并在true和false之间切换。如果您这样做了,我建议添加一个“clearCity”函数来封装所有这些逻辑。前

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('');
    }

    ...

}

答案是这个城市没有改变。为什么您希望在未更改时收到通知?这是真的,但我希望select element重新加载列表,从新列表中选择第一个元素,并报告选择的更改。