2

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

var cities1 = ["Paris", "London", "Warsaw", "Moscow"];
var cities2 = ["Rome", "Paris", "Berlin", "Amsterdam"];

我可以将它们分配给绑定到选择元素的 observableArray。问题是当我在这些数组中有一个共同元素时,就像在这个例子中:'Paris'。当我选择“巴黎”然后将 observableArray 中的数据从 city1 切换到 city2 时,我没有得到选择已更改的信息。

请检查我准备说明问题的小提琴:http: //jsfiddle.net/zbkkzdsp/3upSH/ 你知道如何在 observableArray 中切换数据导致选择元素中的“重置”选择吗?

4

1 回答 1

1

正如迈克尔·贝斯特所指出的,城市实际上并没有改变。如果您的城市本身就是视图模型,那么您所描述的将会自动发生。

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

您可以通过在点击事件中设置self.City为来执行此操作'',或者通过订阅self.City.Available并设置self.City''then 来执行此操作。您还需要确保将订阅self.City更新为在更新值为 时不发出警报''

此外,我将您的click事件中的一些重复功能移至第三个功能,并使这两个click功能代理此功能。您的click函数在做完全相同的事情,只是使用不同的数据集,所以这消除了一些代码重复。ATM 看起来很轻率,因为它只有 1 行开始,但是如果您在 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());

作为离别说明,如果您想允许城市名称使用空字符串,或者只是想要一种更强大的方法来在城市被清除时抑制更改警报,您可以向 City 添加一个 sub-observable 并在 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('');
    }

    ...

}
于 2013-03-28T17:40:16.330 回答