KnockoutJS和Autocomplete保存了Value和Selected Text

时间:2013-02-12 20:40:22

标签: knockout.js jquery-ui-autocomplete

我正在使用此处的KnockoutJS自动填充代码:

How to create an auto-complete combobox?

一般来说它工作得很好。我正在使用JQuery Ajax调用来获取自动完成的数据。当我输入输入字段,然后从列表中选择一个值,相应的值在Knockout ViewModel中设置。但是,我无法通过自动完成功能设置所选文本值。

(这是为了能够查找SIC编号,给出部分描述)

我定义了:

function Sic(SICCode, SICDescription) {
    var self = this;
    self.SICCode = ko.observable(SICCode);
    self.SICDescription = ko.observable(SICDescription);
}

我的ViewModel有:

    self.SICCode = ko.observable("");
    self.SICDescription = ko.observable("");
    self.SicCodes = ko.observableArray();

,查找功能是:

    self.getSicCode = function (searchTerm, sourceArray) {
        $.getJSON(_serviceURL + "/GetSicFromDescription/" + searchTerm, function (data) {
            if (data.length > 0) {
                var result = [];
                $.map(data, function (item) {
                    result.push(new Sic(item.SicCode, item.Description));
                });
                sourceArray(result);
            }
        });
    }

在输入标签中(它实际上是一个.NET页面(实际上是一个DotNetNuke自定义模块,但这对此无关紧要))我有:

    <div>SIC:<br />
        <input type="text" maxlength="30" 
            data-bind="value: SICDescription, 
            jqAuto: {minLength: 3, autoFocus: true}, jqAutoQuery:getSicCode,
            jqAutoSource: SicCodes, jqAutoSourceLabel: SICDescription, 
            jqAutoValue: SICCode, jqAutoSourceInputValue: 'SICDescription', 
            jqAutoSourceValue: 'SICCode'" />
        <span data-bind="text: SICCode"></span>
    </div>

(我尝试过使用和不使用值:binding)键入输入框将正确执行查找并显示匹配项列表。然后,我可以选择一个并查看范围中的相应数字。

但是,当我单击一个然后将ViewModel数据发送到服务器的按钮时,self.SICDescription()为空... self.SICCode()包含正确的值。

那么,如何将选定的描述填充到ViewModel中?我会假设使用输入字段的值绑定应该已经完成​​了这个技巧。但不行。

无论如何都要做我需要的,或者我将不得不做一些工作(循环返回值的数组并拔出正确的描述)?

感谢。

1 个答案:

答案 0 :(得分:1)

因为knockout observables是函数,所以你可以在其中存储任意数量的对象。我将您的描述值存储在SICCode中。 更改绑定代码的writeValueToModel&amp; option.select部分如下:

 //function that is shared by both select and change event handlers
        function writeValueToModel(valueToWrite,name) {
            if (ko.isWriteableObservable(modelValue)) {
               modelValue(valueToWrite);         
               modelValue.nameProp = ko.observable(name);             
            } else {  //write to non-observable
               if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['jqAutoValue'])
                        allBindings['_ko_property_writers']['jqAutoValue'](valueToWrite );    
            }
        }

        //on a selection write the proper value to the model
        options.select = function(event, ui) {
            var actualValue = ui.item ? ui.item.actualValue : null;
            var value = ui.item ? ui.item.value : null;
            writeValueToModel(actualValue,value);
        };

我将您的描述值存储在SICCode中,并使用另一个可观察的名称,如'nameProp'。

你可以像SICCode.nameProp();

那样得到它的描述

实际上,根据您的情况,您可以通过调用$(“#yourInputID”)来获取描述值.val()

但是对于更复杂的情况,您可以使用上面的代码。

JSFIDDLE DEMO

选择项目后单击测试按钮。