У меня есть два элемента управления.
Один зависит от другого. Для простого примера предположим, что первый отображает список городов, а другой отображает список улиц в каждом городе.
Когда страница изначально загружается, элемент управления выбора, отображающий улицы, показывает все доступные улицы. Однако, как только пользователь выбирает город в первом выборе, второй выбор фильтруется для отображения улиц, принадлежащих только выбранному городу.
Это работает нормально при использовании связывания опций, однако мне нужна возможность генерации привязок optgroups и options, которая не поддерживает его, поэтому мне нужно использовать привязку foreach.
В результате получается, что всякий раз, когда выбран город, происходят два непредвиденных последствия:
- Второй выбор (отфильтрованный список улиц), по-видимому, имеет первую улицу выбранного города, хотя я использую valueAllowUnset: true. Это не отражено в модели представления
- Когда вы выбираете улицу во втором выборе, а затем выбираете другой город в первом выборе, второй выбирает правильно, чтобы отражать изменения в списке, но модель представления не делает этого, тем самым сохраняя ранее выбранное значение (хотя он больше не входит в список). Даже если я удалю valueAllowUnset: true из второго select, проблема все равно останется.
Есть ли способ обхода проблемы? Мне действительно нужно использовать привязку 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);