selectedMake 是一个 observable,它的值将是 cascadingOption 实例。要在您的 span:text 绑定中使用它,您需要:
<span data-bind="text: selectedMake().text"></span>
当你使用 subscribe 时它会起作用,因为你得到了 observable 的值。
Select2 尝试将选择元素与其内部状态同步。不幸的是,它依赖于每个具有 Id 值的选项。因为您不使用 optionsValue 绑定,所以这不起作用。我也使用了 select2,但我已经更改了他们的代码以使用 optionIndex 而不是 Id 和一个相当复杂的 select2 绑定来管理差异,例如 Ajax 和多选。
但是,您的示例使用 select2...
- 创建一个 observable 来存储 Id。
- 更改您的值绑定以使用 Id observable
- 添加一个 optionsValue 绑定以从您的源选项返回一个唯一的 Id。这将用于同步 select2 选项和 select 选项。
- 添加对 Id observable 的订阅以过滤选项并从选项数组中返回对象
- 为可观察值添加订阅以保持 Id 同步(注意 2 个订阅之间的无限循环)
我已更新您的JSFiddle,但差异如下。在此我创建了一个包装函数来构建一个可观察/ id 对,并在两者之间进行订阅。
select绑定有不同的value绑定值,增加了optionValue绑定
span 绑定具有不同的文本绑定值。
HTML
<div>
<select id="make" data-bind="options: carMakers, value: selectedMake.id, optionsValue: 'text', optionsText : 'text', optionsCaption : 'Select your make', select2: {}"></select><br/>
Selected Make: <span data-bind="text: selectedMake().text"></span><br/>
<select id="type" data-bind="options: carTypes, value: selectedType.id, optionsValue: 'text', optionsText : 'text', optionsCaption : 'Select your type', enable : carTypes, select2: {}"></select><br/>
Selected Model: <span data-bind="text: selectedType().text"></span><br/>
<select id="model" data-bind="options: carModels, value: selectedModel.id, optionsValue: 'text', optionsText : 'text', optionsCaption : 'Select your Model', enable: carModels, select2: {}"></select><br/>
Selected Model: <span data-bind="text: selectedModel().text"></span><br/>
</div>
Javascript
var makeObservableForSelect2 = function( sourceOptions, idSelector ) {
var target = ko.observable({});
target.id = ko.observable();
target.id.subscribe( function(id) {
var realSource = ko.unwrap(sourceOptions)
if ( !realSource ) {
return;
};
// Don't set target if id already matches to stop infinite loop.
if ( target() && target()[idSelector] === id ) {
return;
}
target( realSource.filter( function(item) { return item[idSelector] === id; } )[0] || {} );
} );
target.subscribe( function(value) {
// Don't set id if id already matches to stop infinite loop.
if ( target.id() && value[idSelector] === target.id() ) {
return;
}
target.id(value[idSelector]);
});
return target;
};
var viewModel = {
carMakers: buildData()
};
viewModel.selectedMake = makeObservableForSelect2( viewModel.carMakers, 'text');
viewModel.carTypes = ko.computed(function(){
return viewModel.selectedMake() ? viewModel.selectedMake().childOptions : null;
});
viewModel.selectedType = makeObservableForSelect2( viewModel.carTypes, 'text');
viewModel.carModels = ko.computed(function(){
return viewModel.selectedType() ? viewModel.selectedType().childOptions : null;
});
viewModel.selectedModel = makeObservableForSelect2( viewModel.carModels, 'text');