2010-11-04 53 views
5

我有幾個選擇,我使用JQuery Ajax填充。大多數加載正常。但有一個或兩個這樣的查詢,在少數情況下會返回很多記錄。我想知道是否我填充選擇的方式是從客戶端代碼中最有效的方式。大多數*有效*方式填充選擇與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被激活和選擇重新加載,頁面只需要加載,只要我必須停止它......不知道爲什麼?

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

@kralco,是一個選項,格式爲'VAL返回的數據:每行text'一個? – 2010-11-08 13:21:09

+0

或'val:text' 'val:text' .. – 2010-11-08 13:29:44

+0

@kralco,在您更新的示例中,您將在每個「選項+ =」中添加整個數據,而不僅僅是循環中的相關項。 – 2010-11-08 13:41:45

回答

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...的格式,那麼你可以做一個正則表達式替換,只是把它在選擇元素。

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

我對如何將這段代碼放入當前的代碼有點困惑。我不太瞭解原始代碼的實際工作原理。 – kralco626 2010-11-08 12:05:19

+0

@kralco,更新了完整的代碼示例.. – 2010-11-08 12:32:02

+0

您的真棒!這在大約10秒鐘內就可以工作,這比我在原始解決方案中運行大約20分鐘的時間要好很多,而且它只是通過值的一半!非常感謝!假設詢問是否有任何方法可以使它更有效率會很貪婪?其他任何事情都可以調整? – kralco626 2010-11-08 12:41:03

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

選擇是你的。 :)

+0

好的。我想到了。它的反抗更好。 (見編輯問題),但仍然太慢。任何想法使其更快?不知道發生了什麼,但完成需要3.5分鐘,完成後沒有任何內容出現在選擇框中。 – kralco626 2010-11-08 12:26:36

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