带有 templateResult 和 templateSelection 的 jquery select2 (4.0) ajax

Posted

技术标签:

【中文标题】带有 templateResult 和 templateSelection 的 jquery select2 (4.0) ajax【英文标题】:jquery select2 (4.0) ajax with templateResult and templateSelection 【发布时间】:2015-08-25 03:34:45 【问题描述】:

我的 Select2 在 3.5 上工作正常..

自从升级到 v4.0(不是“完整”——并根据需要更改关键字/函数)后,我遇到了一个奇怪的问题,即进行了额外的 AJAX 调用。但是,未定义 URL,因此它们会生成 404 Not Found 错误。网址是https://localhost:8443/myapp/undefined

它们似乎与存在的 templateResult 和 templateSelection 有关。如果我将它们注释掉,则 select2 可以正常工作(但我的数据未格式化)。

由于它们没有被注释掉,我在初始化时得到了一次神秘/未定义的 AJAX 调用,然后当我单击选择框时调用一次,然后为我键入的 每个 字符调用一次(甚至如果我设置 minimumInputLength)。但是,即使使用这些虚假的 AJAX 调用,我的“真实”ajax 调用也会触发并返回结果(由 templateResult/templateSelection 正确格式化。我尝试过使用和不使用“escapeMarkup”,但行为没有区别。

是什么触发了这些糟糕的 AJAX 调用,我该如何阻止它们? (否则,它工作得很好)

提前致谢!

编辑 这是演示该问题的完整页面。额外的网络调用是由我在 formatResult 函数中使用的标记生成的。但是为什么它应该处于“加载”状态时返回html

好吧,事实证明,设置“占位符”会导致加载变量未设置,因此返回了 html(带有格式错误的标签)

因此,如果设置了占位符,则 templateResult 和 templateSelection 也应该检查空 id..

if (result.id == "" || result.loading) return result.text;

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title></title>

<link rel="stylesheet" href="$pageContext.request.contextPath/lib/select2/dist/css/select2.css" />
</head>
<body>

<form id="organization_lookup_form" class="form-horizontal" >
<div>
    Select2 using placeholder <select id="search1" style="width:300px"></select>
</div>
<div style="padding-top:250px">
    Select2 WITHOUT placeholder <select id="search2" style="width:300px"></select>  
</div>
</form>

<script src="$pageContext.request.contextPath/lib/jquery/dist/jquery.min.js"></script>
<script src="$pageContext.request.contextPath/lib/select2/dist/js/select2.min.js"></script>
<script>
$(document).ready(function () 
      function formatResult (result)
          console.log('%o', result);
          if (result.loading) return result.text;
          var html = '<div>'+
                '<img src="' + result.image + '">' +
                '<h4>'+result.label+'</h4></div>';
          return html;
      ;

      $('#search1').select2(
          placeholder: "Search...",
          ajax: 
              url: '/search',
              dataType: 'json',
              data: function (params, page) 
                  return 
                      term: params.term, // search term
                      page: page
                  ;
              ,
              processResults: function (data, page) 
                  return results: data.results;
              ,
              cache: true
          ,
          templateResult : formatResult,
          templateSelection : formatResult,
          escapeMarkup: function(m) 
              // Do not escape HTML in the select options text
              return m;
           ,
          minimumInputLength: 3
      );
      $('#search2').select2(
//        placeholder: "Search...",
          ajax: 
              url: '/search',
              dataType: 'json',
              data: function (params, page) 
                  return 
                      term: params.term, // search term
                      page: page
                  ;
              ,
              processResults: function (data, page) 
                  return results: data.results;
              ,
              cache: true
          ,
          templateResult : formatResult,
          templateSelection : formatResult,
          escapeMarkup: function(m) 
              // Do not escape HTML in the select options text
              return m;
           ,
          minimumInputLength: 3
      );
);
</script>

</body>
</html>

【问题讨论】:

【参考方案1】:

从 4.0 版开始,templateResulttemplateSelection 的值只是“附加”的。此行为未记录在案。

所以如果你传递html,所有的标签都会显示出来。

解决方法是返回一个 jQuery 对象:

 function formatResult (result)
      console.log('%o', result);
      if (result.loading) return result.text;
      var html = '<div>'+
            '<img src="' + result.image + '">' +
            '<h4>'+result.label+'</h4></div>';
      //return html;
      return $(html);
  ;

【讨论】:

【参考方案2】:

这里有几个问题可能会导致您看到的请求。

    Select2 要求对象的text 属性指向选项的人类可读版本。这在后台用于匹配选项以及可访问性目的,因此使用它很重要。 您只是检查是否设置了loading 选项,如果您只处理“正在搜索...”文本,则该选项有效,但在处理其他任何内容时无效。我建议改为检查是否缺少 image 属性,在这些情况下,这似乎是 undefined

并回答您提出的具体问题

是什么触发了这些糟糕的 AJAX 调用,我该如何阻止它们?

Select2 仅在搜索时触发远程请求,因此必须在您的代码中生成任何额外的请求。在您的情况下,这是因为您试图在结果中显示图像,但您没有处理图像实际上不存在于对象上的情况。

但是为什么它应该处于“加载”状态时返回 html?

templateResult 方法用于格式化结果中显示的许多通知,包括“正在搜索...”消息。这允许您对这些消息应用特殊格式,但这也意味着您需要在模板方法中处理它们。通常这应该不是问题,因为它定义了通常用于显示选项的人类可读版本的 text 属性,但是当不使用此属性时会导致问题。

【讨论】:

谢谢凯文。我想这是我困惑的基础。我没想到 templateResult 会用于除了 ajax 调用的结果之外的任何东西。它(和 templateSelection)被 select2 的其他部分调用,因此需要处理其他数据。

以上是关于带有 templateResult 和 templateSelection 的 jquery select2 (4.0) ajax的主要内容,如果未能解决你的问题,请参考以下文章

Select2 v4 和 Bootstrap v4 - 缺少下拉菜单

Api:temple

邮戳:发送带有模板的电子邮件

django Temple

C++ 为类模板提供初始化列表构造函数

html Angular_FORM_VALIDATION(Temple驱动表格)