Ember.js Handlebars scoping issue - ember.js

I'm having a scoping issue with Handlebars templates. I have a list of modules, each of which contains a list of services. So I have a template like this (with some markup removed):
{{#each controller}}
<a onclick='$(".{{unbound uuid}}").toggle(0);'>
{{#each service in services}}
<div class='{{unbound uuid}}'></div>
{{/each}}
{{/each}}
The problem is that the second {{unbound uuid}} doesn't get substituted. And if I try accessing any other item of the outer scope, the same thing happens. However, the Ember.js site says that using the each ... in helper should preserve outer scope. What am I doing wrong?
(FYI: Using latest version of Ember.js, Ember-data and Handlebars.)

Maybe this is the right syntax?
{{#each item in controller}}
<a onclick='$(".{{unbound item.uuid}}").toggle(0);'>
{{#each service in services}}
<div class='{{unbound item.uuid}}'></div>
{{/each}}
{{/each}}

Related

Ember passing multiple list items in template

Is it possible to pass multiple list of items in template using {{each}}
Can someone guide me on what I am doing,
in my sales-orders.hbs below is my currenet code.
{{#each model as |detail|}}
<li>{{sales-orders-grid detail=detail}}</li>
{{else}}
Blank
{{/each}}
</ul>
Then calling the sales-orders-grid component
Shipping Method
<div class="col-xs-12 col-md-12 col-sm-12 products-item-products border-left padding10">
<ul>
{{#each shippingMethod as |sm|}}
{{sales-orders-grid-shipping-method sm=sm}}
{{/each}}
</ul>
</div>
In my sales-orders-grid-shipping-method component calling is this:
sm.shippingMethodName
What I'm trying to achieve here is to pass list of items in {{each}} in my main template. Is it possible?
To change scope you can use the "with" helper.
http://emberjs.com/api/classes/Ember.Templates.helpers.html#method_with
{{#with user.posts as |blogPosts|}}
<div class="notice">
There are {{blogPosts.length}} blog posts written by {{user.name}}.
</div>
{{#each blogPosts as |post|}}
<li>{{post.title}}</li>
{{/each}}
{{/with}}
I think you can nest multiple "with" helper.
I think the way to go is to restructure your data as:model.list1,model.list2,etc.
Then pass the model and use as necessary.And use nested each to acheive the grid.
Iam only posting this as an answer because I can't comment yet.
So, do get back to me for Clarifications.

In a handlebars template, get the Ember controller from an each loop

I have an each loop that looks something like this:
{{#each controller}}
{{#link-to 'searches.show' this}}
<span>{{name}}</span>
{{/link-to}}
{{/each}}
At the moment, the this in {{#link-to 'searches.show' this}} seems to refer to the content of the controller, rather than to the controller itself. Is there a way to pass in the controller here, rather than its model?
{{#each}}
{{#link-to 'searches.show' controller}}
<span>{{name}}</span>
{{/link-to}}
{{/each}}
This will work fine.

Ember js: accessing variables within a {{view}} helper

I have the following template where I loop over a list of objects and want to have a checkbox that is bound to a field isChecked for that object. This needs to be in a view helper in order to get the for tag to work (I think). When I do this I can't seem to figure out how to keep the binding with the isChecked field.
{{#each listEntry in listEntries}}
{{#view}}
{{view Ember.Checkbox viewName="checkboxView" checkedBinding="listEntry.isChecked"}}
<label {{bindAttr for="view.checkboxView.elementId"}}>Option 1</label>
{{/view}}
{{/each}}
Your question is similar to that, but that approach not work, I think is because the each helper.
But one of the comments say about nesting your component in the label.
I have done that and works.
{{#each listEntry in listEntries}}
<label>
{{view Ember.Checkbox viewName="checkboxView" checkedBinding="listEntry.isChecked"}}
Option 1
</label>
{{/each}}
I have created a jsfiddle showing
This is what I ended up doing. The problem I kept having was the need for the binding for the "for" attribute was not working in conjunction with the checked binding. Things were out of scope. If anyone has a better way to accomplish this, please let me know.
{{#each listEntry in ListEntries}}
{{#if ../isCheckable}}
{{#with ../listEntry}}
{{#view listEntryBinding="this"}}
{{view Ember.Checkbox viewName="checkboxView" checkedBinding="listEntry.isChecked"}}
<label {{bindAttr for="checkboxView.elementId"}}></label>
{{/view}}
{{/with}}
{{/if}}
{{/each}}

Ember iterations: when to use #each User, #each user in controller, #each user in model, etc

I'm confused on how I'm supposed to iterate through arrays of objects and when to use the different possibilities.
So far I've come across:
{{#each user in controller}}
{{#each user in model}}
{{#each user in users}}
{{#each User}}
And I've even switched some of them up a bit just to see if I could break it; for example both
{{#each user in controller}}
and
{{#each user in model}}
output the same code successfully. I was hoping someone knew a simple explanation on when to use each one and what the differences between them are. Thanks!
The following uses of the {{#each}} helper are equivalent:
{{#each user in controller}}
{{#each controller}}
{{#each user in model}}
{{#each model}}
{{#each user in content}}
{{#each content}}
// and a couple of other possible combination, depending on your setup
And since this PR you can also use simply {{#each}}.
The main difference though is how you access the properties and the items itself you are looping over.
Example using user as the accessor:
{{#each user in model}}
{{user.name}}
{{/each}}
Example using this:
{{#each model}}
{{this.name}}
{{/each}}
Example accessing the item properties directly:
{{#each model}}
{{name}}
{{/each}}
Hope this makes things more clear.

Ember.js: Passing model into view

I have a controller with data about user accounts (icon, name, provider, etc.). Within the output of the each loop I have a view that will build a CSS class dynamically based on the provider passed in via that specific model.
<script type="text/x-handlebars" data-template-name="accountItem">
{{#each account in controller}}
{{#view App.AccountView}}
<h4>{{account.name}}</h3>
<img {{bindAttr src="account.icon"}} />
<i {{bindAttr class="account.provider"}}></i>
{{/view}}
{{/each}}
</script>
App.AccountView = Ember.View.extend({
tagName: 'a',
classNames: ['avatar-image'],
providerClass: function(el) {
// do something
}
});
The question I have is two-fold.
How do you pass in "account", or the currently iterated item, into the view?
After you pass it in, how do you reference it?
I'm sure this is something that happens quite often but I can't seem to find any examples. Can anyone offer some input on this please?
Views has a special content property in a view which allows a more simple approach: you just use a name of the model's property without the view.content. part.
Also, when you're iterating over controller, you can omit the name of loop variable and use this instead, like in this guide. This is not necessary but can make the code a bit cleaner.
Also, from within view's template you generally don't need to reference the outside variables although you can if you like..
{{#each controller}}
{{#view App.IndexView contentBinding="this"}}
<h4>{{name}}</h4>
<img {{bindAttr src="icon"}} />
<i {{bindAttr class="provider"}}></i>
<i> {{icon}} </i>
<i>{{provider}}</i>
{{/view}}
{{/each}}
And you can always access the content property from within the view with:
this.get('content');
The currently iterated item can be passed into the view with the help of property bindings and it can be refered as "{{view.property}}" in the template. For example:
{{#each account in controller}}
{{#view App.IndexView itemBinding="account"}}
<h4>{{view.item.name}}</h3>
<img {{bindAttr src="account.icon"}} />
<i {{bindAttr class="account.provider"}}></i>
<i> {{view.item.icon}} </i>
<i>{{view.item.provider}}</i>
{{/view}}
{{/each}}
I have created a simple jsfiddle for the above case. Do check it and let me know if you were able to resolve the issues.
Fiddle url : http://jsfiddle.net/nCyn6/3/