Search code examples
facebookknockout.jsxfbml

rendering fb-like buttons with knockoutjs


My page contains list of posts, each post has its own like button. The posts are JSON-ly retrieved from the server. Each like should have ofcourse its own href, which is part of the post json object. So naturally I'd expect this to work (assuming "fb_data" is json object {fb_data: {href: my_post_path}):

(html fb-like widget code, with simple knockoutjs data-bind)
<li class="fb">
    <div class="fb-like" data-send="false" data-layout="button_count" data-width="85" ata-show-faces="false" data-bind="attr: {href: fb_data.href}"></div>
     <span class="like-container"><span class="likebox" title=""></span>&nbsp;Friends<br/>Like this!</span>
</li>

so that didn't work. I tried another approach and implemented custom binding for that purpose:

(html)
<li class="fb">
    <div class="fb-like" data-send="false" data-layout="button_count" data-width="85" data-show-faces="false" data-bind="render_like: fb_data"></div>
    <span class="like-container"><span class="likebox" title=""></ span>&nbsp;Friends<br/>Like this!</span>
</li>

(js)
ko.bindingHandlers.render_like = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        var fb  = valueAccessor();
        $(element).attr(fb);
        FB.XFBML.parse(element);
    }
};

ok, that didn't work either. I turn to the hard, ugly, not elegant way and had this:

(html)
 <li class="fb" data-bind="render_like: fb_data"></li>

(js)
ko.bindingHandlers.render_like = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        var fb   = valueAccessor();
        var fb_like_str = '<div class="fb-like" data-send="false" data layout="button_count" data-width="85" data-show-faces="false"' href="' + fb.href  + '" </div>';
        fb_like_str +=  '<span class="like-container"><span class="likebox" title=""></span>&nbsp;Friends<br/>Like this!</span>';
        $(element).html(fb_like_str);
        FB.XFBML.parse(element);
   }
};

that one worked, but it doesn't feel like the knockout spirit ... what is the problem with the first 2??


Solution

  • OK, I think I've just figured out what the problem was. Initiating my viewModel should come after FB.init, like that -

    window.fbAsyncInit = function() {
        FB.init({appId: 172535899504455, status: true, cookie: true, xfbml: true});
        var myVM = new myViewModel(rec_data, $("#myselector").get(0));
    }
    

    now the nice easy first way is working!