Meteor: How to use handlebars within handlebars - javascript

I would like to use to refer to another template within an {{#each}} loop
html:
{{#each listOfItems}}
{{>{{variableOne}}}}
{{/each}}
which should render
<Template name="one">
One
</Template>
or
<Template name="two">
Two
</Template>
depending on the js
other tried syntax include
{{>'{{variableOne}}'}}
or
{{>Template.dynamic template={{variableOne}}}}
Any help or workaround greatly appreciated!

Not sure what are you trying to accomplish. I'm assuming you are using Blaze rendering engine. If you want to pass parameters try this:
{{#each}}
{{> TemplateName variable=variable}}
{{/each}}
Or if you want to show certain template depending on variable value try this (watch out - eq is meant as global helper for comparing values):
{{#each}}
{{#if variable eq 1}}
{{> TemplateOne}}
{{else}}
{{> TemplateTwo}}
{{/if}}
{{/each}}

Assuming that the list you iterate over contains the template names, this will get you what you want:
html:
<template name="hello">
{{#each template in myTemplates}}
{{> Template.dynamic template=template }}
{{/each}}
</template>
<template name='foo'>foo-template</template>
<template name='bar'>bar-template</template>
js:
Template.hello.helpers({
myTemplates() {
return ['foo', 'bar'];
},
});

Related

meteor.js & spacebars - passing variables in nested loop

Context
I’m trying to use Handlebars to loop through events and then nested loop through images. I need to select only the images that correspond to the event that the event loop is currently on.
Problem
I can’t pass the _id of the event inside the image nested. Is there a work-around for this? I realize I can pass variables through a helper but it would be good to know if there is a simpler way.
The following is meta-code for what is not working so far:
//attach venue image to each venue
{{#each myVenues}}
{{#each myImages}}
{{#if myVenues._id == myImages._id}}
<img src="{{this.url}}>
{{/if}}
{{/each}}
{{/each}}
Any help would be appreciated!
More recent versions of spacebars supports referencing the parent. Try:
{{#each myVenues}}
{{#each myImages}}
{{#if ../_id == myImages._id}}
<img src="{{this.url}}>
{{/if}}
{{/each}}
{{/each}}
EDIT:
Christian Fritz pointed out that your conditional logic in the if statement won't work with spacebars. If you set up a helper to evaluate the conditional logic, you can still get this working:
{{#each myVenues}}
{{#each myImages}}
{{ifequals ../_id myImages._id}}
<img src="{{this.url}}>
{{/if}}
{{/each}}
{{/each}}
Then in a helper:
Template.registerHelper('ifequals', function(a,b) {
return a === b;
});

How to set data to a template in meteor

I'm new to meteor i want to set data to a template
In Javascript:
Template.test.helpers({
configDoc:function(){
return Session.get('configDoc');
},
});
In html:
<template name="test">
{{#each doc in configDoc}}
{{> details doc }}
{{/each}}
</template>
I want to set the data on the details template (not shown here) to doc using {{> details doc }} but this is not working for me :-(
Please let me know where I'm going wrong.
See the docs here.
Change Template.test to this:
<template name="test">
{{#each configDoc}}
{{> details}}
{{/each}}
</template>
in Template.details, you can directly display any attributes in the template with{{attrA}}.
Or if you create helper functions the current doc can be accessed as the this object.

ember-cli support for Handlebars #vars in each helper (i.e., #index, #key, #first, #last)

I am getting a compilation error in ember-cli whenever I have a Handelbars template that uses #vars variables (i.e., #index, #key, #first, #last) inside of the each helper. (See http://handlebarsjs.com/#iteration for documentation on these #vars variables inside the each helper.) Below is a simple application built using ember-cli and containing only two files added to the program: routes/application.js and templates/application.hbs. At the bottom of this post is a screenshot of the compilation error message given by ember-cli. Is there an error in my code? Or is this a bug I should report on github # https://github.com/stefanpenner/ember-cli?
routes/application.js
export default Ember.Route.extend({
model: function() {
return ['red', 'blue', 'green'];
}
});
templates/application.hbs
{{#each model}}
{{#index}}: {{this}}
{{/each}}
Screenshot of ember-cli compilation error message:
Here are the versions of the various tools involved:
ember-cli: 0.0.40
node: 0.10.30
npm: 1.4.21
Handlebars: 1.3.0
Ember: 1.6.1
That really isn't related to ember-cli. Ember Handlebars doesn't support the #keyword items.
It's possible to mimic behavior of following Handlebars keywords: #index, #key, #first, #last.
#index
{{#each array as |item index|}}
Index of item: `{{item}}` is: `{{index}}`
{{/each}}
#key
{{#each-in object as |key value|}}
{{key}}: {{value}}
{{/each-in}}
#first
You could also mimic behavior of #first using ember-truth-helpers addon and taking advantage of eq helper - thanks to kristjan reinhold for this idea:
{{#each array as |item index|}}
{{#if (eq index 0)}}
<!-- first element specific html -->
{{else}}
<!-- other html -->
{{/if}}
{{/each}}
Instead of (eq index 0) you can use (eq item array.firstObject).
#last
As dwickern suggested you can use Ember.Array.lastObject to mimic #last behavior.
{{#each array as |item|}}
{{#if (eq item array.lastObject)}}
<!-- last element specific html -->
{{else}}
<!-- other html -->
{{/if}}
{{/each}}

Ember {{#with ... controller=...}} gives "Uncaught TypeError: Cannot read property 'lookupFactory' of undefined"

I'm trying to access properties of a controller (actually a mixin extended by a controller) in Ember, and I need to use the {{#with}} handlebars helper. I get the error:
Cannot read property 'lookupFactory' of undefined
The place I'm trying to specify the controller for each looks like this:
{{#with orders.order controller='ordersIndex'}}
I have also tried just about every combination I can think of:
{{#with orders.order controller='orders'}}
{{#with orders.order controller='Orders'}}
Tried specifying the controller for the route that seems to work:
{{#with orders.order controller='brokerageAccount'}}
{{#with orders.order controller='BrokerageAccount'}}
{{#with orders.order controller='Brokerage'}}
No luck with any of them.
All Code is in JSBin:
http://emberjs.jsbin.com/cabak/1/edit?html,js
Output view of the two routes:
Broken one: (here if you open the console, you'll see the error)
http://emberjs.jsbin.com/cabak/1#/orders
This one works: you'll see some data.
http://emberjs.jsbin.com/cabak/1#/orders/tradier/12345
I guess there is a bug with the {{with}} helper, because if you use the {{#each elem in model}} and update the {{with}} to use the elem variable: {{#with elem.orders.order controller='ordersIndex'}} all works.
This is the updated orders/index template:
<script type="text/x-handlebars" data-template-name="orders/index">
<div class="inline-headers">
<h4><label>Brokerage: </label>{{titleize brokerage}}</h4>
</div>
{{#each elem in model}}
<h4 class="account-header"><label>Account: </label>{{account_number}}</h4>
{{#with elem.orders.order controller='ordersIndex'}}
{{partial "_orders_table"}}
{{/with}}
{{/each}}
</script>
And this is the updated jsbin http://emberjs.jsbin.com/piwuyare/1#/orders

If statement within another if statement in Handlebars templates

These are all objects which I am passing to the handlebars template.
self.template = template({ data: self.model, lang:self.lang, page:self.mainPage, subpage:self.param });
Then inside foreach loop I have an if statement where I am not able to access the parent context element. The code which i have inside the template and the problem is shown bellow:
{{#each data}}
<h1>{{../subpage}}</h1> --> This is giving me a subpage value
{{#if this.brand}}
{{#if ../subpage}}
<h1>WHY IS THIS NOT SHOWING?</h1> --> This is what i am trying to achieve
{{/if}}
{{/if}}
{{/each}}
Any ideas how to achieve this? Thank you very much for all answers/comments!
{{#if this.brand}} goes down into context another level, so you must escape to the parent context not once, but twice.
Your template should thus be:
{{#each data}}
<h1>{{../subpage}}</h1>
{{#if this.brand}}
{{#if ../../subpage}}
<h1>This shows now!</h1>
{{/if}}
{{/if}}
{{/each}}
This should work with a self.model value similar to:
[
{
brand: "Brand A",
otherFields: "here"
}
]
Here is a jsFiddle that demonstrates the solution: nested if statement context escaping
I hope that helps!

Categories