最有效*用Jquery ajax填充select的方法

时间:2010-11-04 12:34:44

标签: jquery ajax web-services select performance

我有几个选择,我使用JQuery Ajax填充。大多数负载很好。但是,这些查询中有一个或两个,在少数情况下会向选择返回大量记录。我想知道我填充选择的方式是否是从客户端代码执行此操作的最有效方式。

我省略了一些东西,使代码更短。

$(function () {
    FillAwcDll()
});
function FillAwcDll() {
FillSelect('poleDdl', 'WebService.asmx/Pole', params, false, null, false);
}

function ServiceCall(method, parameters, onSucess, onFailure) {
    var parms = "{" + (($.isArray(parameters)) ? parameters.join(',') : parameters) + "}"; // to json
    var timer = setTimeout(tooLong, 100000);
    $.ajax({
        type: "POST",
        url: appRoot + "/services/" + method,
        data: parms,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (msg) {
            clearTimeout(timer);
            alert("success");
            if (typeof onSucess == 'function' || typeof onSucess == 'object')
                onSucess(msg.d);
        },
        error: function (msg, err) {

            }
        }
    });

function FillSelect(sel, service, param, hasValue, prompt, propCase) {
    var selectId = 'select#{0}'.format(sel);
    if ($(selectId) == null) {
        alert('Invalid FillSelect ID');
        return;
    }
    $(selectId + ' option').remove();
    $('<option class=\'loading\' value=\'\'>loading...</option>').appendTo(selectId);
    ServiceCall(service,
                param,
                function (data, args) {
                    $(selectId + ' option').remove();

                    if (prompt != null && prompt.length > 0) {
                        $('<option class=\'selectPrompt\' value=\'\' selected>{0}</option>'.format(prompt)).appendTo(selectId);
                    }
                    $.each(data, (hasValue)
                        ? function (i, v) {
                            $('<option value=\'{0}\'>{1}</option>'.format(v.Key, (propCase) ? v.Value.toProperCase() : v.Value)).appendTo(selectId);
                        }
                        : function (i, v) {
                            $('<option value=\'{0}\'>{1}</option>'.format(v, (propCase) ? v.toProperCase() : v)).appendTo(selectId);
                        })

                },
                FailedServiceCall);
                }

String.prototype.format = function () {
    var pattern = /\{\d+\}/g;
    var args = arguments;
    return this.replace(pattern, function (capture) { return args[capture.match(/\d+/)]; });
}

所以这只是循环并填充选择。有一个更好的方法吗?请注意警报(“成功”)线几乎立即触发,因此数据快速恢复,但之后它会挂起尝试填充选择。

更新:(3)这项工作非常顺利。虽然存在一些问题。我有onBlur(调用函数重新加载选择),当onBlur被激活并且选择重新加载时,页面只需要FOREVER加载,所以我必须停止它...不确定为什么?

    ServiceCall(service,
            param,
            function (data, args) {
                var $select = $(selectId);
                var vSelect = '';
                if (prompt != null && prompt.length > 0) {
                    vSelect += '<option class=\'selectPrompt\' value=\'\' selected>{0}</option>'.format(prompt);
                }
                if (hasValue) {
                    $.each(data, function (i, v) {
                        vSelect += '<option value=\'{0}\'>{1}</option>'.format(v.Key, (propCase) ? v.Value.toProperCase() : v.Value);
                    });
                }
                else {
                    $.each(data, function (i, v) {
                        vSelect += '<option value=\'{0}\'>{1}</option>'.format(v, (propCase) ? v.toProperCase() : v);
                    });
                }
                $select.html(vSelect);
                delete vSelect;
                delete data;
            },
            FailedServiceCall);
} 

3 个答案:

答案 0 :(得分:7)

你是否尝试在内存中创建一个jquery对象并填充它,最后将它放在DOM中?

像这样

var vSelect = $('<select/>'); // our virtual select element

并在each方法中使用该附加options

vSelect.append('<option>..</option>');

并在最后在DOM中附加虚拟对象的html

$(selectId).html( vSelect.html() );

可以加速当前代码的其他内容是保持对select元素(而不是其id )的引用并直接追加到它而不是让jquery找到该元素每个追加(就像你现在一样


使用完整代码进行更新

替换FilLSelect中的部分

ServiceCall(service,
            param,
            <SNIP>...<SNIP>,
            FailedServiceCall);
            }

ServiceCall(service,
            param,
            function (data, args) {
                var $select = $(selectId);
                var vSelect = '';
                if (prompt != null && prompt.length > 0) {
                     vSelect += '<option class=\'selectPrompt\' value=\'\' selected>{0}</option>'.format(prompt);
                }
                if (hasValue)
                {
                   $.each(data, function (i, v) {
                        vSelect += '<option value=\'{0}\'>{1}</option>'.format(v.Key, (propCase) ? v.Value.toProperCase() : v.Value);
                    });
                }
                else
                {
                   $.each(data,function (i, v) {
                        vSelect += '<option value=\'{0}\'>{1}</option>'.format(v, (propCase) ? v.toProperCase() : v);
                    });
                }
                 $select.html( vSelect );

            },
            FailedServiceCall);
            }

如果您的页面可以将整个数据作为字符串以

的格式返回

option_value:option_text<TAB>option_value:option_text<TAB>option_value:option_text...然后你可以用正则表达式替换它,然后把它放在select元素中。

var options = data.replace( /([\S ]+)(?=:)(:)([\S ]+)/gi, '<option value="$1">$3</option>');
$(selectID).empty().append(options);

答案 1 :(得分:1)

这是一个通用的,其中msg是从服务器返回的JSON数据对象。

var options = "";

$(msg).each(function() {
   options += $('<option />').val(yourValue).text(yourDisplayValue);
});


$(selectID).empty().append(options);

就个人而言,我更喜欢使用模板系统从javascript插入html。我使用Microsoft's jQuery Templates。这个的语法很简单:

var options = $.tmpl("<option value="${yourValue}">${yourDisplayValue}</option>", msg);

$(selectID).empty().append(options);

选择权在你手中。 :)

答案 2 :(得分:1)

创建一个未附加到dom的临时容器。 使用选项填充容器后,将所有子项附加到选择。

var temp = $('<select></select>');
$('<option></option>').attr('value', 1).text('First').appendTo(temp);
$(selectId).children().remove();
temp.children().detach().appendTo($(selectId));

也许这也会奏效:

$(selectId).html(temp.html());