我已经开始使用knockoutjs并做一些简单的绑定/依赖绑定。我的目标是根据另一个<select>
列表的值填充一个<select>
列表。两者都是从ajax调用加载到我的asp.net webservice。
我有两个<select>
列表
<select id="make" data-bind="options: availableMakes, value: selectedMake, optionsText: 'text', optionsCaption: 'Choose a make'"></select>
<select id="model" data-bind="options: availableModels, value: selectedModel, optionsText: 'text', optionsCaption: 'Choose a model'"></select>
然后我的javascript看起来像这样:
$(function () {
// creating the model
var option = function (text, value) {
this.text = text;
this.value = value;
}
// creating the view model
var searchModel = {
availableMakes: ko.observableArray([]),
availableModels: ko.observableArray([]),
selectedMake: ko.observable(),
selectedModel: ko.observable()
}
// adding in a dependentObservable to update the Models based on the selected Make
searchModel.UpdateModels = ko.dependentObservable(function () {
var theMake = searchModel.selectedMake() ? searchModel.selectedMake().text : '';
if (theMake != '') {
$.ajax({
url: "/data/service/auction.asmx/GetModels",
type: 'GET',
contentType: "application/json; charset=utf-8",
data: '{make:"' + theMake + '"}',
success: function (data) {
var makes = (typeof data.d) == 'string' ? eval('(' + data.d + ')') : data.d;
var mappedModels = $.map(makes, function (item) {
return new option(item.text, item.value);
});
searchModel.availableModels(mappedModels);
},
dataType: "json"
});
}
else {
searchModel.availableModels([]);
}
return null;
}, searchModel);
// binding the view model
ko.applyBindings(searchModel);
// loading in all the makes
$.ajax({
url: "/data/service/auction.asmx/GetMakes",
type: 'GET',
contentType: "application/json; charset=utf-8",
data: '',
success: function (data) {
var makes = (typeof data.d) == 'string' ? eval('(' + data.d + ')') : data.d;
var mappedMakes = $.map(makes, function (item) {
return new option(item.text, item.value);
});
searchModel.availableMakes(mappedMakes);
},
dataType: "json"
});
});
目前这工作如预期的,但我认为我这样做是错误的,因为代码看起来很长,我可以做到这一点,而不使用knockoutjs在更少的代码。此外,我加载availableModels
的方式显然是不正确的,因为我使用的是一个名为UpdateModels
的dependentObsevable,我添加了它,以便根据selectedMake().text
availableModels
我希望这是有意义的,你可以指出一个改进的版本?或者简单地告诉我我如何根据Make选择重新加载模型?
许多谢谢,我认为你的代码看起来很正常。对于UpdateModels
dependentObservable,您实际上可以使用手动订阅selectedMake
,如:
searchModel.selectedMake.subscribe(function (newMake) {
if (newMake) {
//ajax request
}
else {
searchModel.availableModels([]);
}
}, searchModel);
这不会改变功能,只是一种更显式的方式来订阅单个可观察对象的变化。
您也可以选择在绑定中使用optionsValue: 'text'
(或'value'),并且您的selectedMake
将直接设置为文本或值。
如果您的模型是make对象的子对象,那么您甚至可以将模型绑定到selectedMake().models
(将需要防止selectedMake为null,这可以使用DO来完成,1.3控制流绑定,或者像selectedMake() ? selectedMake().models : []
一样内联
从一个相关的角度来看,我对它进行了一些重构,以不使用ajax并简化示例(您可以随时添加它)。但是这里有一个小提琴,它演示了您希望使用一些示例数据做什么。
http://jsfiddle.net/johnpapa/vGg2h/