2010-11-04 42 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());