2017-10-30 16 views
11

두 개의 선택 컨트롤이 있습니다.Knockoutjs - 옵션 대신 foreach를 사용할 때 값을 선택하는 양방향 바인딩을 잃었습니다.

하나는 다른 것에 의존합니다. 간단한 예를 들어 첫 번째가 도시 목록을 표시하고 다른 도시는 각 도시의 거리 목록을 표시한다고 가정 해 봅시다.

페이지가 처음로드 될 때 거리를 표시하는 선택 컨트롤에 사용 가능한 모든 거리가 표시됩니다. 그러나 사용자가 첫 번째 선택에서 도시를 선택하면 두 번째 선택이 필터링되어 선택한 도시에만 속한 거리 만 표시됩니다.

옵션 바인딩을 사용할 때는 정상적으로 작동하지만 optgroups 및 옵션 바인딩 생성 기능이 필요하므로 바인딩이 지원되지 않으므로 foreach 바인딩을 사용해야합니다.

결과는 도시가 선택 될 때마다,이 개 의도하지 않은 결과가 발생한다는 것입니다 :

  1. 두 번째 선택 (거리의 필터링 목록)에도 불구하고, 선택한 선택한 도시의 첫 번째 거리를 가지고있는 것 같습니다 I 'valueAllowUnset :을 사용하고 있습니다. 보기 모델에 반영되지 않음
  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); 

답변

2

첫째, 당신의 선택 입력에 비어있는 옵션을 추가 할 수 있습니다.

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

이제 뷰 모델의 selectedCity 속성을 구독하십시오. 변경 될 때마다 프로그래밍 방식으로 selectedStreet를 ''로 설정하십시오.

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

이렇게하면 두 가지 문제를 모두 해결할 수 있습니다.

피들을 변경하면 효과가 있습니다. 업데이트를 시도합니다. `valueAllowUnset`를 사용할 때 빈 옵션을 추가 할 필요가 없습니다 https://jsfiddle.net/Shabi_669/w1vcjbjo/

+1

- 여기

는 바이올린입니다. 모델 값을'' '대신'undefined'로 설정하면됩니다. –

+0

분명히 내 코드는 제공된 예제보다 복잡하기 때문에'viewModel.selectedStreet ('')'전에 많은 로직을 추가해야한다. 나는 더 나은 해결책을 원했다. 어쨌든 해결 방법 주셔서 감사합니다, 그것은 잘 작동하는 것 같습니다. –

+0

@MichaelBest 감사합니다, 그것은 내가 한 일입니다. –