0

I'm trying to use a handlebars each iterator in the following chunk of template code:

<table>
    <tr><th></th><th>Today</th><th>This Month<br>(To Date)</th><th>Last Month</th></tr>
    {{#each Activities}}
        {{examineObject this}} - first -
        <tr><td>{{examineObject this}}</td>
        <td>{{Today}}</td>
        <td>{{ThisMonth}}</td>
        <td>{{LastMonth}}</td></tr>
        {{examineObject this}} - third - 
    {{/each}}
    <tr class='total'><td>Net Change</td>
        <td>{{Totals.Today}}</td>
        <td>{{Totals.ThisMonth}}</td>
        <td>{{Totals.LastMonth}}</td></tr>
</table>

examineObject is a handlebars helper I have written to simply call JSON.stringify() on the variable. I'm doing this to evaluate the context. The helper is simply:

examineObject: function(object){
    return JSON.stringify(object);
}

When I compile and render the template above, something very odd happens. The context of this at both the first and third examineObject call is the individual activity selected by the each iterator. However, the context of this in the second examineObject call (surrounded by html tags) is the context of the entire template - NOT the context of the individual activity selected by the each iterator. Can anyone explain why this would be?

Michael.Lumley
  • 2,345
  • 2
  • 31
  • 53
  • Please post the code for your helper as well. – gfullam Sep 30 '14 at 14:25
  • It's not a problem with the helper, because the context is messed up even when I don't use the helper to test it. Nevertheless, I've posted the helper. – Michael.Lumley Sep 30 '14 at 14:27
  • Is this how you have it set up? Works for me: http://jsfiddle.net/gfullam/5rbpja10/ – gfullam Sep 30 '14 at 14:37
  • No, I am using the `each` iterator, not the `with` iterator, and I am doing inside an HTML table, not an `ol`. I think I have the problem narrowed down to the table itself, because it works fine with most other kinds of HTML elements that I have tested. – Michael.Lumley Sep 30 '14 at 14:40
  • Check the fiddle again. I posted the wrong link at first – gfullam Sep 30 '14 at 14:41
  • Yes, that seems to work. I am not sure why it is not working on my end. It seems to be triggered by closing the `{{var}}` within a `` tag. – Michael.Lumley Sep 30 '14 at 14:45
  • Ok, I've tracked the issue to my handlebars loader. I import my handlebars templates from a file and load them using jQuery.find(). For some reason, jQuery is messing with the template when it is loading it, because the template that gets loaded is different from the template as written. – Michael.Lumley Sep 30 '14 at 14:53
  • Glad you found the problem. You should post it as an answer when you find a solution or a work around for preventing it. – gfullam Sep 30 '14 at 15:03
  • I'll try. The problem seems like one that others are unlikely to run into though. Thanks for your help. – Michael.Lumley Sep 30 '14 at 15:07
  • I wouldn't be so sure. If you ran into it, someone else is quite likely to. I've posted an answer with a link to another SO post showing an asynchronous solution. I think that may work for you. – gfullam Sep 30 '14 at 15:10

1 Answers1

1

Don't use jQuery's .find() to get your handlebars template because it will be scraping a rendered DOM, which may be different from your written file contents.

Instead, try loading your template file asynchronously

Update:

Or if you have a multitude of templates and don't want to run numerous async requests, you may be interested in precompiling the handlebars templates as demonstrated in "Handling handlebars.js like a pro".

Community
  • 1
  • 1
gfullam
  • 11,531
  • 5
  • 50
  • 64
  • 1
    I get where you are coming from, but for resource purposes, I'd rather not make 10 or more async calls every page load to pick up all of the templates. Right now, I'm keeping calls to a minimum with require.js. I'll think further on the problem and if there are any other good options. – Michael.Lumley Sep 30 '14 at 15:31