2010-11-04 4 views
5

Ich habe mehrere Auswahlen, die ich mit JQuery Ajax bevölkern. Die meisten laden gut. Es gibt jedoch eine oder zwei dieser Abfragen, die in wenigen seltenen Fällen eine Menge Datensätze an die Auswahl zurückgeben. Ich habe mich gefragt, ob die Art und Weise, wie ich die selects bevölkere, der effizienteste Weg ist, dies vom clientseitigen Code aus zu tun.Most * effiziente * Weg zu füllen mit Jquery Ajax

Ich habe etwas weggelassen, um den Code ein wenig kürzer zu machen.

$(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+/)]; }); 
} 

Also dies nur Schleifen und füllt die Auswahl. Gibt es einen besseren Weg, dies zu tun? Beachten Sie, dass die Alarmzeile ("Erfolg") fast sofort ausgelöst wird, so dass die Daten schnell zurückkommen, aber danach hängt es, um die Auswahl zu füllen.

UPDATE: (3) das funktioniert wirklich gut. Obwohl es ein Problem gibt. Ich habe onBlur (Call-Funktion, um neu zu laden wählt) und wenn die onBlur aktiviert ist und die wählt neu laden, die Seite dauert nur FOREVER zu laden, so lange ich muss es stoppen ... nicht sicher warum?

+0

@kralco ist es eine Option, um die zurückgegebenen Daten als 'val formatiert haben: Text' eine pro Zeile? –

+0

oder 'val: text' ' val: text' .. –

+0

@kralco, in Ihrem aktualisierten Beispiel fügen Sie die ganzen Daten in jeder 'Option + =' nicht nur das relevante Element aus der Schleife .. –

Antwort

7

Haben Sie versucht, ein jquery-Objekt im Speicher zu erstellen, dieses zu füllen und am Ende in das DOM zu schreiben?

wie diese

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

und in der each Methode verwenden, die die options

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

und am Ende anhängen im DOM der virtuellen Objekts html

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

anhängen

etwas anderes, das Ihre aktuellen Code beschleunigen würde, ist eine Referenz auf das select Element zu halten (statt dessen id) und stattdessen direkt an sie anhängen jquery von mit dem Element in jedem Anfügen finden (wie Sie jetzt tun)


-Update mit vollständigen Code

den Teil innerhalb FilLSelect

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

mit

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); 
      } 

wenn Sie Seite kann im Format von

option_value:option_text<TAB>option_value:option_text<TAB>option_value:option_text... dann könnte man mit einem regulären Ausdruck a ersetzen tun, um die gesamten Daten als String zurückbringen und es nur in dem select-Elemente setzen.

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

Ich bin ein wenig verwirrt darüber, wie ich diesen Code in den aktuellen Code, den ich habe, setzen würde. Ich bin nicht sehr vertraut mit, wie der ursprüngliche Code tatsächlich funktioniert. – kralco626

+0

@kralco, aktualisiert mit dem vollständigen Codebeispiel .. –

+0

Ihr genial!Das funktioniert in etwa 10 Sekunden, was viel besser ist als, nun, ich lasse es für 20 Minuten in meiner ursprünglichen Lösung laufen und es war nur etwa die Hälfte der Werte! Vielen Dank! Angenommen, es wäre gierig zu fragen, ob es irgendeinen Weg gäbe, es noch effizienter zu machen? Alles andere, was vor sich geht, könnte verändert werden? – kralco626

1

Hier ist eine generische, in der msg Ihr JSON-Datenobjekt vom Server zurückgegeben wird.

Persönlich bevorzuge ich mit einem Templating-System HTML von Javascript einfügen. Ich benutze Microsoft's jQuery Templates. Die Syntax dafür wäre einfach:

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

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

Die Wahl liegt bei Ihnen. :)

+0

ok. Ich habe es herausgefunden. Es ist trotzig besser. (siehe zu Frage bearbeiten) aber immer noch zu langsam. Irgendwelche Ideen, um es schneller zu machen? Nicht sicher, was es vor sich geht, aber es dauerte nur 3,5 Minuten, um abzuschließen, und nichts war in der Auswahlbox, als es fertig war. – kralco626

1

Erstellen Sie einen temporären Container, der nicht an das Dom angehängt ist. Nach dem Füllen des Containers mit den Optionen alle Kinder an die Auswahl anhängen.

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

Vielleicht wird dies auch funktionieren:

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