如何动态初始化select2

Posted

技术标签:

【中文标题】如何动态初始化select2【英文标题】:How to initialize select2 dynamically 【发布时间】:2016-01-04 04:53:26 【问题描述】:

我通过 AJAX 在我的 DOM 中插入多行概念(带有选择和输入文本元素)。我想将这些选择初始化为 select2: 但我不知道正确的方法。

我应该在每一行写javascript吗? (通过AJAX插入html和JS)

我在每个 AJAX 请求中都得到了这个:

<select id="concept0"> 
    <option value="Test"> Test </option>
    <option value="Test2"> Test 2 </option>    
</select>
<script> $("#concept0").select2(); </script>

但我认为在我的 AJAX 响应中返回带有 HTML 的 javascript 是一个错误的想法。还有其他选择吗?

如果我的问题有点愚蠢,谢谢和抱歉...

【问题讨论】:

在这里写下你尝试过的代码 好的。对不起,我会在几分钟内写完 我在每个 AJAX 请求中发送一个计数器,所以效果很好......但我认为这不是正确的方法...... 不,我只想知道动态初始化 select2 的正确方法是什么。我的方法(在 AJAX 响应中返回 HTML 和 javascript)看起来很丑…… 显示您的ajax 部分.. 【参考方案1】:

我会这样构建流程:

对部分选择进行分组以减少 Ajax 请求的数量 使用 'data-' 向部分 HTML 添加标记 使用 AJAX GET 检索部分 html; 初始化元素; [可选] 分离目标父元素 - 性能原因; 将元素附加到目标; [可选]重新附加目标元素; 初始化小部件。

我在这里做了一个模拟:http://jsbin.com/jotitu/edit?js,output

下面是一点解释:

假设您有以下 HTML:

<div id="concept-table-container">
 <table>
   <tr>
     <th>
        No.
     </th>
     <th>
        Name.
     </th>
     <th>
        Option.
     </th>
   </tr>
   <tr>
     <td>1</td>
     <td>abc</td>
     <td></td>
   </tr>
   <tr>
     <td>2</td>
     <td>dce</td>
     <td></td>
   </tr>
   <tr>
     <td>3</td>
     <td>fgh</td>
     <td></td>
   </tr>
 </table>
</div>

对部分选择进行分组以减少 Ajax 请求的数量并使用 'data-' 向部分 HTML 添加标记

如果您可以像这样对部分 HTML 进行分组和编写,则无需对每一行的 Ajax 请求执行此操作。您也可以选择限制它们,但这需要更多的“分页”编程。

<select data-widget="select2" data-row-idx="0"> 
    <option value="Test"> Test </option>
    <option value="Test2"> Test 2 </option>    
</select>
<select data-widget="select2" data-row-idx="1"> 
    <option value="Test"> Test </option>
    <option value="Test2"> Test 2 </option>    
</select>
<select data-widget="select2" data-row-idx="2"> 
    <option value="Test"> Test </option>
    <option value="Test2"> Test 2 </option>    
</select>

使用 AJAX GET 检索部分 html

这里就不赘述了,直接说就够了:

$.get(conceptPartialUrl, successCallback);

初始化元素;

var successCallback = function(data)
  var $fragmentEl = initEls(data);
  // Optionally before appending the selects detach the container;
  appendElements($fragmentEl, $containerEl);
  // Initialize the widgets.
  initSelect2Widgets();
;


var initEls = function(data)
  // Create DOM elements - JQuery Way
  var $fragmentEl = $(data);
  // Return the reference
  return $fragmentEl;
;

将元素附加到目标;

var appendElements = function($fragmentEl, $containerEl)
   var $rows = $containerEl.find('tr');
   $fragmentEl.each(function()     
      var $el = $(this);


      // some matching - you 
      var idx = $el.data('row-idx');

      // that plus 1 is to skip the header        
      // find the row         
      var $row = $rows.eq(idx+1);         
      // find the cell, empty it and append the element  
      $row .find('td').last().text('').append($el);
   );
;

初始化小部件

var initSelect2Widgets = function()
  $containerEl.find('[data-widget="select2"]').select2();
;

【讨论】:

【参考方案2】:

我有另一种解决方法:

正如您在评论中所说,您在每个 ajax 请求中发送一个计数器(我希望您使用该计数器来生成选择的 id),您可以在 ajax 请求之前将其存储在某个元素或 js 变量中。因此,在每个 ajax 请求中,您都有唯一的 counter 值。

您可以使用以下方法初始化您的 select2:

$(document).ajaxComplete(function() 
    $(document).find('your-unique-counter-select-id').select2();
);

【讨论】:

以上是关于如何动态初始化select2的主要内容,如果未能解决你的问题,请参考以下文章

动态添加部分视图后如何重新初始化JQuery

如何动态调整 select2 输入的大小,使其与所选选项的宽度相同?

Select2 在调用时使用动态 Ajax URL

Select2:初始化后如何设置数据?

如何在初始化了select2的输入框上设置默认值?

如何初始化具有相同类的页面上的所有 Select2 下拉菜单