самый эффективный способ заполнить выбор с помощью Jquery ajax - PullRequest
5 голосов
/ 04 ноября 2010

У меня есть несколько выборок, которые я заполняю, используя JQuery Ajax.Большинство грузится нормально.Однако есть один или два из этих запросов, которые в редких случаях возвращают множество записей в выборку.Мне было интересно, является ли способ, которым я заполняю select, является наиболее эффективным способом сделать это из кода на стороне клиента.

Я пропустил некоторые вещи, чтобы сделать код немного короче.

$(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 активируется и выбирает перезагрузить, страница просто загружается НАВСЕГДА, так долго, я должен остановить его ... не знаю почему?

    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 ]

7 голосов
/ 04 ноября 2010

Вы пытались создать объект jquery в памяти и заполнить его, а в конце поместить его в DOM?

, как это

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

и в методе eachиспользуйте его, чтобы добавить options

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

и в конце добавить в DOM HTML-код виртуального объекта

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

, что ускорит ваш текущий код:сохранить ссылку на элемент select ( вместо его идентификатора ) и добавить к нему напрямую, вместо того, чтобы 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);
            }

, если выpage может вернуть целые данные в виде строки в формате

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 голос
/ 04 ноября 2010

Создать временный контейнер, который не привязан к 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());
1 голос
/ 04 ноября 2010

Вот общий пример, где msg - ваш объект данных JSON, возвращаемый с сервера.

var options = "";

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


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

Лично я предпочитаю использовать систему шаблонов для вставки html из javascript.Я использую Шаблоны Microsoft jQuery .Синтаксис для этого был бы прост:

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

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

Выбор за вами.:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...