Handlebars render only some elements - javascript

I have the following handlebars template:
<script type="text/x-handlebars" data-template-name="index">
{{log model}}
<button {{action 'getSuggestion'}}>Get suggestion</button>
{{log suggestion}}
{{#if suggestion}}
<p>There is a suggestion</p>
{{else}}
<p>NO suggestion</p>
{{/if}}
<ul>
{{#each item in model}}
<li>{{item}}</li>
{{/each}}
</ul>
</script>
Currently, the two log work as expected, but the button between them is not rendered.
A while ago I've added another <p>text</p> right in the beginning of the template and again, it didn't render.
Do you have any idea why? And is there a specific way to debug Ember applications? I find Handlebars extremely unpredictive, with elements being rendered or not after no specific reason, and with no errors shown...

The thing was pretty simple: I was using a somewhat older version of Ember.js. Updating to the latest one made everything work again.

Related

displaying nested json data using each in Emberjs

I have successfully displayed JSON objects unto my template thanks the answer on my previous stackoverflow post setting data from route to controller error in Emberjs
Now, I am trying to display a nested JSON data objects to my template using the {{#each}} helper.
here is my code:
http://screencast.com/t/3fhpckr4E
It doesn't give me any errors on my dev console and also it just gives me blank text.
I've also wrote the code in different ways but still no luck..
any feedback would be appreciated
thanks,
You can do this in your template as follows:
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each item in model}}
<li>{{item.description}}</li>
<ul>
{{#each childItem in item.items}}
<li>{{childItem.title}}</li>
{{/each}}
</ul>
{{/each}}
</ul>
</script>
Working solution here
The problem with what you are doing is that there is no such thing as data.items.items. Each item in the data.items array has its own items property...

Am I doing it right? {{#each}}

I have a question because I'm curious if I do it right.
As I'm reading all tutorials about Ember.js every one is typing something like that:
{{#each friend in model}}
{{friend.firstName}} {{friend.lastName}}
{{/each}}
And in my app with route for example: app/templates/works/index.hbs I have:
{{#each}}
{{#link-to 'works.work' this.id class="trigger"}}
<h3 class="title">{{name}}</h3>
<p class="description">{{description}}</p>
<img {{bind-attr src=image}}>
{{/link-to}}
{{/each}}
But that still working just fine, so thats just convention or I am doing something wrong all this time?
You should go with the first form, non-context switching form of {{each}}, as the second form is deprecated. See here.
The first form is less confusing as you don't need to think of the context for your properties.

Nested views in Ember.js

I have a container view which, among other things, displays a list of objects, like so:
{{#each}}
<div {{bind-attr class="author.first_name task"}}></div>
{{/each}}
I would like to hook a Javascript function everytime a DOM element is added to this list. I've tried doing:
didInsertElement: function() { ... }
But this hook apparently runs only the first time the view is initialized. I figured that maybe the hook doesn't run because the view is actually inserted once, and what's inserted more than once are just the nested element.
So should I use a nested view?
I tried something along these lines:
{{#each}}
{{#view App.SingleItemView}}
<div {{bind-attr class="author.first_name task"}}></div>
{{/view}}
{{/each}}
But in this case, though it works somehow, it doesn't get passed the necessary data that would render the properties such as author.first_name.
render will give you a new scope and is really easy to assign the content as well
<ul>
{{#each item in controller}}
{{render 'ind' item}}
{{/each}}
</ul>
http://emberjs.jsbin.com/alAKubo/1/edit

Handlebars.js - Getting parent context within an each loop, an if statement and a child object

I understand how to transverse the data source within Handlebars but I have stumbled across a situation I cannot work out.
Using "../" you can reach the parent template scope but when iterating through the child of an object it seems to return the object and not the child.
{{#each content.items}}
{{#if prop}}
<p>{{prop}} + {{../../variable}}</p>
{{/if}}
{{/each}}
The above code snippet works fine if you iterate through an object called 'content' but as soon as you iterate through it's child, 'content.items' it no longer returns the right scope.
Here is a fiddle which demonstrates the issue. http://jsfiddle.net/sidonaldson/MDdn2/
Can anyone shed any light on what is wrong?
It turns out that my original thought was wrong. I've only used Handlebars.js inside the context of Ember.js. Ember provides some extra helpers that aren't available in plain Handlebars, so that wasn't an option. But I did seem to figure out your issue. Check this fiddle.
<p>IN CONTENT</p>
{{#with content}}
{{#each items}}
{{#if prop}}
<p>{{prop}} + {{../../variable}}</p>
{{/if}}
{{/each}}
{{/with}}
<p>OUTSIDE CONTENT</p>
{{#each items}}
{{#if prop}}
<p>{{prop}} + {{../../variable}}</p>
{{/if}}
{{/each}}
I'm not sure why it didn't work in the first place, but using the with helper, then the each helper seemed to work. Hopefully I've come close to what you wanted.

Render Multiple View/Controller Pairs

I am currently rendering a list of views:
<ul>
{{#each newsItem in controller}}
{{view App.NewsItemView contentBinding="newsItem" class="news-item" }}
{{/each}}
</ul>
But I would like to inject a NewsItemController into each view.
I've tried using render, but this only seems to support a single view, giving the exception:
Uncaught Error: Handlebars error: Could not find property 'control'
on object .
I've found a brief mention of using control instead, but this no longer seems to be included.
So how can I render multiple versions of the same view, injecting a separate controller into each one?
{{render}} should be fixed in current master (if you build it from Github). You should be able to use it multiple times if you pass a model:
<ul>
{{#each controller}}
{{render "newsItem" this}}
{{/each}}
</ul>
{{control}} is still there but hidden behind a flag (because it's still experimental). To use it you need to do : ENV.EXPERIMENTAL_CONTROL_HELPER = true before including the ember.js file. If you can avoid using it, it would be better.
However I think the simplest approach would be to use itemController:
<ul>
{{#each controller itemController="newsItem"}}
{{view App.NewsItemView class="news-item" }}
{{/each}}
</ul>
I think you can combine them to make it simpler (I haven't tried it yet):
<ul>
{{each controller itemController="newsItem" itemViewClass="App.NewsItemView"}}
</ul>

Categories

Resources