车把和异步调用
Handlebars and async call
我用这个助手来检查图像是否存在:
Handlebars.registerHelper('checkLogo', function(url) {
UrlExists(url, function(status){
if(status === 200){
return new Handlebars.SafeString(url)
}
else if(status === 404){
console.log('no logo found');
}
});
});
function UrlExists(url, cb){
$.ajax({
url: url,
dataType: 'text',
type: 'GET',
complete: function(xhr){
if(typeof cb === 'function')
cb.apply(this, [xhr.status]);
}
});
}
我在我的模板中这样称呼它(使用 url 作为参数):
<img src="{{checkLogo logo}}"/>
我希望 {{checkLogo logo}}
被 url 替换,但没有返回任何内容。是否可能是因为异步操作,因此必须以不同方式处理?
谢谢
虽然 Handlebars 不支持异步助手,但您仍然可以使用助手来实现这一点。使用助手创建一些独特的 html,并使用 MutationObserver 检测它是否被添加到 DOM。然后,您可以获取添加的 img
元素并根据需要对其进行修改。
一个更简单和更有效的解决方案是使用 img
元素的 onerror
属性来触发一些回调。 Here's an example fiddle. Another fiddle 使用车把模板。
如果您想探索 Handlebars + MutationObserver 方式,我已经创建了一个您可以使用或改编的助手。可在 https://github.com/ekuusela/post-render-bars and demonstrated in this fiddle.
购买
watch.js 定义了一个函数 forHtml(html, callback)
,当在 DOM 中遇到给定的 html 时触发回调。它修改 html 以暂时具有使其独一无二的 class。
helpers.js 定义了助手 renderer
和函数 createRenderer(getHtmlContentFn)
,它将您的函数包装到渲染器中,并且可以传入模板并用作助手的参数.
我也想要这个,找到方法了:
Handlebars.registerHelper('myHelperFunctionName', function (item) {
var element_id = 'temp-prefix-' + item, item_html = false;
// make async call here:
SlowAsyncCallbackPromiseThing(item, function(item_object){
item_html = Handlebars.templates.item(item_object);
$('span#' + element_id).replaceWith(item_html);
});
if(item_html){//cache resolved immediately
return new Handlebars.SafeString(item_html);
}
// If the cache is barren, provide a loading span to be replaced later.
return new Handlebars.SafeString('<span id="' + element_id + '">Loading..</span>');
});
现在,当您加载它时,内部 jQuery 会在它最终解析时简单地替换临时元素。这不是最好的,但它很快并且可以与 Handlebars 一起使用。我使用了很多 localStorage 缓存,所以一些 Promise 会立即解析。解决问题绝对令人头疼,直到我弄清楚为什么它不总是有效。
要使其适应元素的 属性.. 不会那么难,但您需要一些识别元素的方法
我用这个助手来检查图像是否存在:
Handlebars.registerHelper('checkLogo', function(url) {
UrlExists(url, function(status){
if(status === 200){
return new Handlebars.SafeString(url)
}
else if(status === 404){
console.log('no logo found');
}
});
});
function UrlExists(url, cb){
$.ajax({
url: url,
dataType: 'text',
type: 'GET',
complete: function(xhr){
if(typeof cb === 'function')
cb.apply(this, [xhr.status]);
}
});
}
我在我的模板中这样称呼它(使用 url 作为参数):
<img src="{{checkLogo logo}}"/>
我希望 {{checkLogo logo}}
被 url 替换,但没有返回任何内容。是否可能是因为异步操作,因此必须以不同方式处理?
谢谢
虽然 Handlebars 不支持异步助手,但您仍然可以使用助手来实现这一点。使用助手创建一些独特的 html,并使用 MutationObserver 检测它是否被添加到 DOM。然后,您可以获取添加的 img
元素并根据需要对其进行修改。
一个更简单和更有效的解决方案是使用 img
元素的 onerror
属性来触发一些回调。 Here's an example fiddle. Another fiddle 使用车把模板。
如果您想探索 Handlebars + MutationObserver 方式,我已经创建了一个您可以使用或改编的助手。可在 https://github.com/ekuusela/post-render-bars and demonstrated in this fiddle.
购买watch.js 定义了一个函数 forHtml(html, callback)
,当在 DOM 中遇到给定的 html 时触发回调。它修改 html 以暂时具有使其独一无二的 class。
helpers.js 定义了助手 renderer
和函数 createRenderer(getHtmlContentFn)
,它将您的函数包装到渲染器中,并且可以传入模板并用作助手的参数.
我也想要这个,找到方法了:
Handlebars.registerHelper('myHelperFunctionName', function (item) {
var element_id = 'temp-prefix-' + item, item_html = false;
// make async call here:
SlowAsyncCallbackPromiseThing(item, function(item_object){
item_html = Handlebars.templates.item(item_object);
$('span#' + element_id).replaceWith(item_html);
});
if(item_html){//cache resolved immediately
return new Handlebars.SafeString(item_html);
}
// If the cache is barren, provide a loading span to be replaced later.
return new Handlebars.SafeString('<span id="' + element_id + '">Loading..</span>');
});
现在,当您加载它时,内部 jQuery 会在它最终解析时简单地替换临时元素。这不是最好的,但它很快并且可以与 Handlebars 一起使用。我使用了很多 localStorage 缓存,所以一些 Promise 会立即解析。解决问题绝对令人头疼,直到我弄清楚为什么它不总是有效。
要使其适应元素的 属性.. 不会那么难,但您需要一些识别元素的方法