最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Handlebars and async call - Stack Overflow

programmeradmin0浏览0评论

I use this helper to check wether an image exists or not:

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',
        plete:  function(xhr){
            if(typeof cb === 'function')
               cb.apply(this, [xhr.status]);
        }
    });
}

I call it (with a url as arg) in my template like this:

<img src="{{checkLogo logo}}"/>

Im expecting {{checkLogo logo}} to be replaced by the url but nothing gets returned. Is it maybe beacuse of the async action and because of this it has to be handled differently?

Thank you

I use this helper to check wether an image exists or not:

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',
        plete:  function(xhr){
            if(typeof cb === 'function')
               cb.apply(this, [xhr.status]);
        }
    });
}

I call it (with a url as arg) in my template like this:

<img src="{{checkLogo logo}}"/>

Im expecting {{checkLogo logo}} to be replaced by the url but nothing gets returned. Is it maybe beacuse of the async action and because of this it has to be handled differently?

Thank you

Share Improve this question asked Jan 20, 2016 at 16:52 user2915962user2915962 2,7218 gold badges36 silver badges61 bronze badges 2
  • 1 I'm pretty sure that Handlebars does not support asynchronous helpers at all. See also this issue. – robertklep Commented Jan 20, 2016 at 17:43
  • Ok thank you, guess I´ll have to find another way :) – user2915962 Commented Jan 20, 2016 at 17:46
Add a ment  | 

2 Answers 2

Reset to default 3

Though Handlebars doesn't support asynchronous helpers you can still use helpers to achieve this. Create some unique html with a helper and detect it being added to the DOM using MutationObserver. Then you can get a hold of the added img element and modify it however you like.

A much simpler and more efficient solution would be to use the onerror attribute of img element to trigger some callback. Here's an example fiddle. Another fiddle that uses a handlebars template.

If you want to explore the Handlebars + MutationObserver way, I've created a helper that you can use or adapt. It's available at https://github./ekuusela/post-render-bars and demonstrated in this fiddle.

watch.js defines a function forHtml(html, callback) which triggers a callback when the given html is encountered in the DOM. It modifies the html to temporarily have a class that makes it unique.

helpers.js defines the helper renderer and the function createRenderer(getHtmlContentFn) which wraps your function into a renderer and that can be passed in to a template and used as an argument for the helper.

I wanted this as well, found a way:

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>');
});

Now, when you load it, the inner jQuery simply replaces the temporary element when it eventually resolves.. not the best, but it's fast and works with Handlebars. I use a lot of localStorage caching, so some of the Promises resolve instantly. Absolute headache to troubleshoot till I figured out why it wasn't working always.

To adapt that to a property of an element.. wouldn't be that hard, but you'd need some way of identifying the element

发布评论

评论列表(0)

  1. 暂无评论