Underscore.js - 模板第一次没有编译
Underscore.js - template does not compile on first time
我正在尝试使用 underscore.js 从 ajax 调用(为我提供我需要的 JSON 调用)成功时触发的函数呈现模板。
我遇到了一些奇怪的行为:
- 当 ajax 调用第一次成功时,我得到这个错误:
Uncaught ReferenceError: response is not defined
- 第二次成功时,不刷新页面,一切正常。
我的 JSON 有这样的结构:
{
data: [
item1: {count: "1", url: "http://example1.com", id:"arstd", formatted:"1"},
item2: {count: "53", url: "http://example2.net", id:"hneio", formatted:"0"},
...
]
}
我的 underscore.js 模板:
<script type="text/template" id="count_template">
<% _.each (response.data, function (item) { %>
<a href="<%- item.url %>">
<li>
<p id="<%- item.id %>" class="name">
<%- item.formatted %>
</p>
<p id="<%- item.id %>_count" class="count">
<%- item.count %>
</p>
</li>
</a>
<% }); %>
</script>
我的ajax回调函数:
var on_result_count_fetched = (function () {
var totals = $(".regions .count");
var ajax_loader = $("#ajax_loader");
var c_tl = $('#count_template');
var count_div = $('#res_count');
//getting the template for the count response
if (c_tl) {
var c_template = _.template(c_tl.html());
}
_.templateSettings.variable = "response";
//real callback
return function (response) {
if (response.redirect) {
window.location.replace(data.redirect);
} else {
//hide loading animation
ajax_loader.hide();
if (!response && _.isEmpty(response)) {
var tmp = $("<button>In case of fail: do this other action!</button>")
tmp.click (function() {
fetch_results ("searx");
});
} else {
console.log(response);
var tmp = c_template(response);
}
count_div.empty();
count_div.append(tmp);
}
}
}());
当你说 _.template(some_string)
时,Underscore 将使用 _.templateSettings
中的值来解析 some_string
并将其转换为 JavaScript 函数。一旦 _.template
向您返回编译后的模板函数,_.templateSettings
的内容就不再重要了。
你在做这种事:
var t = _.template(some_string);
_.templateSettings.variable = "response";
因此您的 _.templateSettings.variable
作业来得太晚,无法影响您的 _.template
通话。您需要在 调用 _.template
之前调整 _.templateSettings
,这样:
if (c_tl) {
var c_template = _.template(c_tl.html());
}
_.templateSettings.variable = "response";
应该更像:
if (c_tl) {
_.templateSettings.variable = "response";
var c_template = _.template(c_tl.html());
}
或者您可以完全跳过 _.templateSettings
并说:
var tmp = c_template({ response: response });
调用模板函数时。如果您的其他模板不希望必须使用 response
来访问其数据,那么乱用 _.templateSettings
可能会产生副作用。在一个地方全局配置 _.templateSettings
或完全单独配置往往效果更好。
我正在尝试使用 underscore.js 从 ajax 调用(为我提供我需要的 JSON 调用)成功时触发的函数呈现模板。
我遇到了一些奇怪的行为:
- 当 ajax 调用第一次成功时,我得到这个错误:
Uncaught ReferenceError: response is not defined
- 第二次成功时,不刷新页面,一切正常。
我的 JSON 有这样的结构:
{
data: [
item1: {count: "1", url: "http://example1.com", id:"arstd", formatted:"1"},
item2: {count: "53", url: "http://example2.net", id:"hneio", formatted:"0"},
...
]
}
我的 underscore.js 模板:
<script type="text/template" id="count_template">
<% _.each (response.data, function (item) { %>
<a href="<%- item.url %>">
<li>
<p id="<%- item.id %>" class="name">
<%- item.formatted %>
</p>
<p id="<%- item.id %>_count" class="count">
<%- item.count %>
</p>
</li>
</a>
<% }); %>
</script>
我的ajax回调函数:
var on_result_count_fetched = (function () {
var totals = $(".regions .count");
var ajax_loader = $("#ajax_loader");
var c_tl = $('#count_template');
var count_div = $('#res_count');
//getting the template for the count response
if (c_tl) {
var c_template = _.template(c_tl.html());
}
_.templateSettings.variable = "response";
//real callback
return function (response) {
if (response.redirect) {
window.location.replace(data.redirect);
} else {
//hide loading animation
ajax_loader.hide();
if (!response && _.isEmpty(response)) {
var tmp = $("<button>In case of fail: do this other action!</button>")
tmp.click (function() {
fetch_results ("searx");
});
} else {
console.log(response);
var tmp = c_template(response);
}
count_div.empty();
count_div.append(tmp);
}
}
}());
当你说 _.template(some_string)
时,Underscore 将使用 _.templateSettings
中的值来解析 some_string
并将其转换为 JavaScript 函数。一旦 _.template
向您返回编译后的模板函数,_.templateSettings
的内容就不再重要了。
你在做这种事:
var t = _.template(some_string);
_.templateSettings.variable = "response";
因此您的 _.templateSettings.variable
作业来得太晚,无法影响您的 _.template
通话。您需要在 调用 _.template
之前调整 _.templateSettings
,这样:
if (c_tl) {
var c_template = _.template(c_tl.html());
}
_.templateSettings.variable = "response";
应该更像:
if (c_tl) {
_.templateSettings.variable = "response";
var c_template = _.template(c_tl.html());
}
或者您可以完全跳过 _.templateSettings
并说:
var tmp = c_template({ response: response });
调用模板函数时。如果您的其他模板不希望必须使用 response
来访问其数据,那么乱用 _.templateSettings
可能会产生副作用。在一个地方全局配置 _.templateSettings
或完全单独配置往往效果更好。