选择2:预选项目并通过templateSelection更正渲染

Tha*_*dis 5 jquery jquery-select2

使用Select2 v4时,以编程方式设置所选值的建议(实际上是正确的)方法是操作底层的select元素,添加所需的<option>元素,设置值$selectElement.val(<value>)并触发.trigger('change')事件,以便select2插件自行更新来自底层的选择元素.你可以看到这个在这里.

这个问题是当你定义了一个templateSelection,它不仅返回所选值的文本,而且还返回一个完整的HTML DOM(例如,你可以应用样式,添加图像,图标等等,并将其作为渲染选择返回).

templateSelection接受输入,因为它来自数组数据源或ajax数据源等.每个项目代表一个选项,但它可能不仅仅是和idtext.templateSelection可以考虑项目的许多属性来生成渲染输出.

您只能在<option>元素中定义值和文本.您无法定义要设置为选定的实际对象(项目),以便templateSelection可以生成正确的输出.

有没有办法只使用select2的API来实现这个目标?

如果没有,是否还有其他解决方法可以通过正确呈现的代码中选择值templateSelection

Reu*_*ben 5

为了防止像我这样的人遇到这个问题,Select2 v4手册提供了一个答案:https ://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-来源 ajax-select2

以下片段来自文档。本质上,您可以通过 ajax 调用获取初始值,并通过事件以编程方式设置初始值select2:select

// Set up the Select2 control
$('#mySelect2').select2({
    ajax: {
        url: '/api/students'
    }
});

// Fetch the preselected item, and add to the control
var studentSelect = $('#mySelect2');
$.ajax({
    type: 'GET',
    url: '/api/students/s/' + studentId
}).then(function (data) {
    // create the option and append to Select2
    var option = new Option(data.full_name, data.id, true, true);
    studentSelect.append(option).trigger('change');

    // manually trigger the `select2:select` event
    studentSelect.trigger({
        type: 'select2:select',
        params: {
            data: data
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

但是,如果您使用 templateSelection 选项,并返回 jQuery 对象来提供精美的单行格式选择结果,则此解决方案将不起作用。事实上,触发 select2:select 似乎什么也没做。

使用 jQuery,我发现我可以将数据附加到选项,并从 templateSelection 函数中使用此数据作为后备。

// create the option and append to Select2
var option = new Option(data.full_name, data.id, true, true);
$(option).data('raw', data);
studentSelect.append(option).trigger('change')
Run Code Online (Sandbox Code Playgroud)

在 templateSelection 函数中:

templateSelection: function (result) {
    if (!result.id || result.loading) {
        return result.text
    }
    var $container = $(
        '<div class="clearfix">' +
            '<div class="pull-left select2-result__name"></div>' +
            '<div class="pull-right select2-result__finding_name"></div>' +
        '</div>'
    );

    var raw = $(result.element).data('raw')
    $container.find('.select2-result__name').text(result.name || raw.name || result.text)
    $container.find('.select2-result__finding_name').text(result.finding_name_1 || raw.finding_name_1)

    return $container
}
Run Code Online (Sandbox Code Playgroud)

此示例使用多个后备。我们总是尝试使用结果中出现的内容,如正常 ajax 调用中提供的那样,但我们会回退到初始选项中的原始数据,如果缺少,则回退到文本字段。


Jul*_*ire 2

templateSelection是根据选项的文本内容构建对象的回调。返回并显示的对象与选项的内容不是同一回事。选项仍然是简单的 ID 和文本内容。样式是单独处理的。

当您定义时,templateSelection您定义了一个将选项作为参数的函数,因此您可以访问选项的文本和 id 作为可用变量。该函数将返回根据您的模板构建的对象。

看这个例子:

$(document).ready(function() {
  $('.js-example-basic-single').select2({
    width: 'width: 100%',
    templateSelection: formatState
  });
});

$('.js-example-basic-single').val('WY');
$('.js-example-basic-single').trigger('change');

function formatState(state) {
  console.log(state);
  var $state = $(
    '<span>Content from the template: ' + state.element.text + ' ' + state.element.value + '</span>'
  );

  return $state;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<select class="js-example-basic-single" name="state">
  <option value="AL">Alabama</option>
  <option value="WY">Wyoming</option>
</select>
Run Code Online (Sandbox Code Playgroud)

编辑:

由于您可以访问状态,因此您可以访问使用动态数据定义的任何属性。并且您可以访问该元素,因此您还可以拥有数据属性。这允许你做一些更复杂的事情:

$(document).ready(function() {
  $('.js-example-basic-single').select2({
    width: 'width: 100%',
    templateSelection: formatState,
    data: [{
      id: 0,
      text: "Wyoming"
    }, {
      id: 1,
      text: "Alabama",
      selected: true,
      disabled: true,
    }, {
      id: 2,
      text: "Washington",
      selected: true,
      customProp: 'something'
    }]
  });
});



function formatState(state) {
  console.log(state);
  var $state 
  if (state.customProp) {
    $state = $(
      '<span>Content from the template: ' + state.element.text + ' ' + state.element.value + ' and my custom property is <strong>' + state.customProp + '</strong></span>'
    );
  } else {
  $state = $(
      '<span>Content from the template: ' + state.element.text + ' ' + state.element.value + '</span>'
       );
  }

  return $state;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<select class="js-example-basic-single" name="state">
</select>
Run Code Online (Sandbox Code Playgroud)