Knockoutjs - 在使用foreach而不是选项时丢失了双向绑定选择值

Avi*_*hen 11 javascript data-binding html-select viewmodel knockout.js

我有两个选择控件.

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

页面最初加载时,显示街道的选择控件显示所有可用的街道.然而,一旦用户在第一选择中选择城市,则过滤第二选择以仅显示属于所选城市的街道.

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

结果是,无论何时选择城市,都会出现两个意外后果:

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

这个问题有解决方法吗?我真的必须使用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);
Run Code Online (Sandbox Code Playgroud)

Coo*_*ter 2

首先,向您的选择输入添加一个空选项。

<option value="">Select Street</option>
Run Code Online (Sandbox Code Playgroud)

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

viewModel.selectedCity.subscribe(function() { 
  viewModel.selectedStreet(''); 
}, viewModel); 
Run Code Online (Sandbox Code Playgroud)

这样您就可以解决您的两个问题。

在你的小提琴中进行了更改并且它起作用了。尝试更新它。

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