knockout data change applybindings javascript knockout.js data-binding html-select viewmodel

javascript - data - ko applybindings



Knockoutjs: perdiĆ³ el enlace bidireccional para seleccionar el valor al usar foreach en lugar de opciones (1)

Tengo dos controles de selección.

Uno depende del otro. Para un ejemplo simple, supongamos que el primero muestra una lista de ciudades, mientras que el otro muestra una lista de calles en cada ciudad.

Cuando la página se carga inicialmente, el control de selección que muestra las calles muestra todas las calles disponibles. Sin embargo, una vez que el usuario elige una ciudad en la primera selección, la segunda se filtra para mostrar calles que pertenecen solo a la ciudad seleccionada.

Esto funciona bien cuando se usa el enlace de opciones, sin embargo, necesito la capacidad de generar grupos de opciones y el enlace de opciones no lo admite, así que tengo que usar el enlace foreach.

El resultado es que cada vez que se selecciona una ciudad, ocurren dos consecuencias imprevistas:

  1. La segunda selección (la lista filtrada de calles) parece tener la primera calle de la ciudad seleccionada, aunque estoy usando valueAllowUnset: true. Esto no se refleja en el modelo de vista
  2. Al elegir una calle en el segundo seleccionar y luego elegir una ciudad diferente en la primera selección, la segunda seleccionar actualizaciones correctamente para reflejar los cambios en la lista, pero el modelo de vista no lo hace, conservando así el valor previamente seleccionado (aunque ya no está en la lista). Incluso si elimino ValueAllowUnset: verdadero de la segunda selección, el problema persiste.

¿Hay alguna solución a este problema? Realmente tengo que usar el enlace foreach en lugar del enlace de opciones.

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);


Primero, agrega una opción vacía a tu entrada de selección.

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

Ahora suscríbase a la propiedad selectedCity de su modelo de vista. Siempre que cambie, establece programáticamente la Calle seleccionada en ''''.

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

De esta forma puedes resolver tus problemas.

Hizo los cambios en tu violín y funciona. intenta actualizarlo

Aquí hay un violín - https://jsfiddle.net/Shabi_669/w1vcjbjo/