Knockout JS中的相关可观察数组

我已经开始玩knockoutjs并做一些简单的绑定/依赖绑定。 我的目标是根据另一个列表的值填充1个列表。 两者都是从ajax调用加载到我的asp.net webservice。

所以我有两个列表

   

然后我的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而添加了这些selectedMake().text

我希望这是有道理的,你可以指出这个的改进版本? 或者简单地告诉我如何根据Make选择重新加载模型?

非常感谢,

我认为你的代码看起来很正常。 对于UpdateModels dependentObservable,您实际上可以使用对selectedMake的手动订阅:

 searchModel.selectedMake.subscribe(function (newMake) { if (newMake) { //ajax request } else { searchModel.availableModels([]); } }, searchModel); 

这不会改变function,只是订阅单个可观察更改的更明确的方式。

您还可以选择在optionsValue: 'text'中使用optionsValue: 'text' (或’value’),您的selectedMake将直接设置为文本或值。

如果你的模型是make对象的子代,那么你甚至可以将模型绑定到selectedMake().models (需要防止selectedMake为null,这可以使用DO,1.3控制流绑定或内联类似selectedMake() ? selectedMake().models : []

我同意Ryan的回答。

在相关的切线上稍微考虑一下,我重构了一下,不使用ajax并简化示例(你可以随时添加它)。 但这里有一个小提琴,演示了你想要用一些样本数据做什么。

http://jsfiddle.net/johnpapa/vGg2h/