0

我正在使用此处找到的 KnockoutJS 自动完成代码:

如何创建一个自动完成的组合框?

一般来说,它工作得很好。我正在使用 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>

(我尝试过使用和不使用 value: binding)在输入框中输入内容将正确进行查找并显示匹配项的列表。然后我可以选择一个并在跨度中查看相应的数字。

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

那么,如何将选定的描述填充到 ViewModel 中?我会假设使用输入字段的值绑定应该可以解决问题。但是不行。

无论如何我需要做一些事情,还是我必须做一些工作(循环遍历返回值的数组并提取正确的描述)?

谢谢。

4

1 回答 1

1

因为敲除 observables 是函数,所以你可以在其中存储任意数量的对象。我会将您的描述值存储在 SICCode 中。像这样更改绑定代码的 writeValueToModel & 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 演示

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

于 2013-02-13T07:11:11.243 回答