【问题标题】:Knockoutjs - lost two way binding to select value when using foreach instead of optionsKnockoutjs - 使用 foreach 而不是选项时丢失了两种方式绑定来选择值
【发布时间】:2018-04-11 14:45:01
【问题描述】:

我有两个选择控件。

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

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

这在使用选项绑定时可以正常工作,但是,我需要能够生成选项组并且选项绑定不支持它,所以我必须使用 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);

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

    在您的小提琴中进行了更改,并且可以正常工作。尝试更新它。

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

    【讨论】:

    • 您在使用valueAllowUnset 时不需要添加空白选项。只需将模型值设置为undefined 而不是''
    • 显然我的代码比提供的示例复杂,所以我必须在viewModel.selectedStreet('') 之前添加很多逻辑。我希望有一个更好的解决方案。无论如何,感谢您的解决方法,它似乎工作正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多