Knockoutjs - 在使用foreach而不是options

时间:2017-10-30 14:57:09

标签: javascript knockout.js data-binding html-select viewmodel

我有两个选择控件。

一个依赖于另一个。举一个简单的例子,我们假设第一个显示城市列表,而另一个显示每个城市的街道列表。

当页面最初加载时,显示街道的选择控件显示所有可用的街道。但是,一旦用户在第一个选择中选择了一个城市,第二个选择将被过滤以仅显示属于所选城市的街道。

这在使用选项绑定时工作正常,但是,我需要能够生成optgroups和选项绑定不支持它,所以我必须使用foreach绑定。

结果是,无论何时选择城市,都会发生两种意外后果:

  1. 第二个选择(过滤的街道列表)似乎选择了所选城市的第一条街道,即使我使用的是valueAllowUnset:true。 这未反映在视图模型中
  2. 当在第二个选择中实际选择街道然后在第一个选择中选择不同的城市时,第二个选择正确更新以反映列表中的更改,但视图模型不会,从而仍保留先前选择的值(即使它不在列表中)。即使我从第二个选择中删除valueAllowUnset:true,问题仍然存在。
  3. 此问题有解决方法吗?我真的必须使用foreach绑定而不是选项绑定。

    JSFiddle:https://jsfiddle.net/jfxovLna/13/

    var ViewModel = function() {
    
    var self = this;
    
    var regionAndCityArray = [{
     regionName: "Europe",
     cities: [{
       cityName: "London",
       additionalUnimportantInformation: 100
     }, {
       cityName: "Paris",
       additionalUnimportantInformation: 200
     }]
    }, {
     regionName: "North America",
     cities: [{
       cityName: "New York",
       additionalUnimportantInformation: 45
     }]
    }];
    
    var cityAndStreetArray = [{
     cityName: "London",
     streets: [{
       streetName: "Parker",
       streetLength: 5
     }, {
       streetName: "Macklin",
       streetLength: 10
     }, ]
    }, {
      cityName: "New York",
     streets: [{
       streetName: "5th Avenue",
       streetLength: 3
     }, {
       streetName: "Park Ave",
       streetLength: 12
     }]
    }, {
      cityName: "Paris",
     streets: [{
       streetName: "Rue de Turbigo",
       streetLength: 11
     }, {
       streetName: "Rue aux Ours",
       streetLength: 12
     }]
    }];
    
    var getAvailableStreets = function() {
    
     var availableStreets = cityAndStreetArray;
    
     var selectedCity = self.selectedCity();
    
     var selectedRegion = _.find(regionAndCityArray,
       function(region) {
         return _.find(region.cities,
           function(city) {
             return city.cityName === selectedCity;
           });
       });
    
     if (selectedRegion == undefined) {
       return availableStreets;
     }
    
     var filteredStreets = _.filter(cityAndStreetArray,
       function(city) {
         return city.cityName === selectedCity;
       });
    
     return filteredStreets;
    }
    
    self.availableCities = ko.observableArray(regionAndCityArray);
    self.selectedCity = ko.observable();
    self.availbleStreets = ko.computed(getAvailableStreets);
    self.selectedStreet = ko.observable();
    
    };
    var viewModel = new ViewModel();
    ko.applyBindings(viewModel);
    

1 个答案:

答案 0 :(得分:2)

首先,在选择输入中添加一个空选项。

<option value="">Select Street</option>

现在订阅视图模型的selectedCity属性。 每当它发生变化时,以编程方式将selectedStreet设置为''。

viewModel.selectedCity.subscribe(function() { 
  viewModel.selectedStreet(''); 
}, viewModel); 

这样你就可以解决你的问题。

在你的小提琴中做出改变并且它有效。试图更新它。

这是一个小提琴 - https://jsfiddle.net/Shabi_669/w1vcjbjo/