jquery 使用 templateResult 和 templateSelection 选择 2 (4.0) ajax
jquery select2 (4.0) ajax with templateResult and templateSelection
我的 Select2 在 3.5 上正常工作..
自升级到 v4.0(不是 "full" - 并根据需要更改 keywords/functions)后,我遇到了一个奇怪的问题,即有额外的 AJAX 调用。但是,URL 未定义,因此它们会生成 404 Not Found 错误。 URL 是 https://localhost:8443/myapp/undefined
它们似乎与存在的 templateResult 和 templateSelection 有关。如果我将它们注释掉,select2 可以正常工作(但我的数据未格式化)。
在没有注释掉它们的情况下,我在初始化时得到 mysterious/undefined AJAX 调用一次,然后当我单击 select 框时调用一次,然后调用一次 我键入的每个 个字符(即使我设置了 minimumInputLength)。然而,即使有这些伪造的 AJAX 调用,我的 "real" ajax 调用也会触发并且 return 结果(由 templateResult/templateSelection 正确格式化)。我试过并且没有 "escapeMarkup" 行为没有差异。
是什么触发了这些错误的 AJAX 调用,我该如何阻止它们? (因为否则,它工作得很好)
提前致谢!
编辑
这是演示该问题的完整页面。额外的网络调用是由我在 formatResult 函数中使用的标记生成的。但为什么它 return 正在 html 而它应该处于 "loading" 状态?
好吧,事实证明设置 "placeholder" 会导致未设置加载变量,因此 html 被 returned(带有格式错误的标签)
因此,如果设置了占位符,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>
这里有几个问题可能导致您看到的请求。
- Select2 要求对象的
text
属性指向选项的人类可读版本。这在后台用于匹配选项以及可访问性目的,因此使用它很重要。
- 您只是在检查是否设置了
loading
选项,如果您只处理 "Searching..." 文本,则该选项有效,但如果正在处理其他任何内容,则该选项无效。我建议改为检查是否缺少 image
属性,在这些情况下这似乎是 undefined
。
并回答您提出的具体问题
What is triggering these bad AJAX calls and how can I stop them?
Select2 仅在搜索时触发远程请求,因此任何额外的请求都必须在您的代码中生成。在您的情况下,这是因为您试图在结果中显示图像,但您没有处理图像实际上不存在于对象上的情况。
But why is it returning the html when it should be in a "loading" state?
templateResult
方法用于格式化结果中显示的许多通知,包括 "Searching..." 消息。这允许您对这些消息应用特殊格式,但这也意味着您需要在模板方法中处理它们。通常这应该不是问题,因为它定义了通常用于显示选项的人类可读版本的 text
属性,但是当 属性 不是正在使用。
从4.0版本开始,templateResult
和templateSelection
的值就是"appened"。此行为未记录。
因此,如果您传递 html,则会显示所有标签。
解决方法是 return 一个 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);
};
我的 Select2 在 3.5 上正常工作..
自升级到 v4.0(不是 "full" - 并根据需要更改 keywords/functions)后,我遇到了一个奇怪的问题,即有额外的 AJAX 调用。但是,URL 未定义,因此它们会生成 404 Not Found 错误。 URL 是 https://localhost:8443/myapp/undefined
它们似乎与存在的 templateResult 和 templateSelection 有关。如果我将它们注释掉,select2 可以正常工作(但我的数据未格式化)。
在没有注释掉它们的情况下,我在初始化时得到 mysterious/undefined AJAX 调用一次,然后当我单击 select 框时调用一次,然后调用一次 我键入的每个 个字符(即使我设置了 minimumInputLength)。然而,即使有这些伪造的 AJAX 调用,我的 "real" ajax 调用也会触发并且 return 结果(由 templateResult/templateSelection 正确格式化)。我试过并且没有 "escapeMarkup" 行为没有差异。
是什么触发了这些错误的 AJAX 调用,我该如何阻止它们? (因为否则,它工作得很好)
提前致谢!
编辑 这是演示该问题的完整页面。额外的网络调用是由我在 formatResult 函数中使用的标记生成的。但为什么它 return 正在 html 而它应该处于 "loading" 状态?
好吧,事实证明设置 "placeholder" 会导致未设置加载变量,因此 html 被 returned(带有格式错误的标签)
因此,如果设置了占位符,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>
这里有几个问题可能导致您看到的请求。
- Select2 要求对象的
text
属性指向选项的人类可读版本。这在后台用于匹配选项以及可访问性目的,因此使用它很重要。 - 您只是在检查是否设置了
loading
选项,如果您只处理 "Searching..." 文本,则该选项有效,但如果正在处理其他任何内容,则该选项无效。我建议改为检查是否缺少image
属性,在这些情况下这似乎是undefined
。
并回答您提出的具体问题
What is triggering these bad AJAX calls and how can I stop them?
Select2 仅在搜索时触发远程请求,因此任何额外的请求都必须在您的代码中生成。在您的情况下,这是因为您试图在结果中显示图像,但您没有处理图像实际上不存在于对象上的情况。
But why is it returning the html when it should be in a "loading" state?
templateResult
方法用于格式化结果中显示的许多通知,包括 "Searching..." 消息。这允许您对这些消息应用特殊格式,但这也意味着您需要在模板方法中处理它们。通常这应该不是问题,因为它定义了通常用于显示选项的人类可读版本的 text
属性,但是当 属性 不是正在使用。
从4.0版本开始,templateResult
和templateSelection
的值就是"appened"。此行为未记录。
因此,如果您传递 html,则会显示所有标签。
解决方法是 return 一个 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);
};