1

我已经开始使用 knockoutjs 并做一些简单的绑定/依赖绑定。我的目标是<select>根据另一个列表的值填充1 个<select>列表。两者都是从我的 asp.net 网络服务的 ajax 调用中加载的。

所以我有两个<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"
            });

        });

目前这可以按预期工作,但我认为我做错了,因为代码看起来很长,我可以在不使用更少代码的情况下做到这一点。另外,我加载的availableModels方式显然是不正确的,因为我使用了一个名为dependentObsevable UpdateModels,我添加它是为了availableModels根据selectedMake().text

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

非常感谢,

4

2 回答 2

4

我认为您的代码看起来很正常。对于UpdateModelsdependentObservable,其实可以使用手动订阅来点selectedMake赞:

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

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

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

如果您的模型是 make 对象的子项,那么您甚至可以将模型绑定到selectedMake().models(需要防止 selectedMake 为空,这可以使用 DO、1.3 控制流绑定或内联来完成selectedMake() ? selectedMake().models : []

于 2011-09-28T15:26:28.863 回答
2

我同意瑞恩的回答。

稍微考虑一下相关的切线,我对其进行了一些重构,以不使用 ajax 并简化示例(您始终可以将其添加回来)。但是这里有一个小提琴,它演示了您希望如何处理一些示例数据。

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

于 2011-12-30T01:59:45.693 回答