Access properties of the parent with a Handlebars 'each' loop

Javascripthandlebars.js

Javascript Problem Overview


Consider the following simplified data:

var viewData = {
    itemSize: 20,
    items: [
        'Zimbabwe', 'dog', 'falafel'
    ]
};

And a Handlebars template:

{{#each items}}
    <div style="font-size:{{itemSize}}px">{{this}}</div>
{{/each}}

This won't work because within the each loop, the parent scope is not accessible -- at least not in any way that I've tried. I'm hoping that there's a way of doing this though!

Javascript Solutions


Solution 1 - Javascript

There are two valid ways to achieve this.

Dereference the parent scope with ../

By prepending ../ to the property name, you can reference the parent scope.

{{#each items}}
    <div style="font-size:{{../itemSize}}px">{{this}}</div>
    {{#if this.items.someKey}}
       <div style="font-size:{{../../itemSize}}px">{{this}}</div>  
    {{/if}}
{{/each}}

You can go up multiple levels via repeating the ../. For example, to go up two levels use ../../key.

For more information, see the Handlebars documentation on paths.

Dereference the root scope with @root

By prepending @root to the property path, you can navigate downwards from the topmost scope (as shown in caballerog's answer).

For more information, see the Handlebars documentation on @data variables.

Solution 2 - Javascript

The new method is using dot notation, the slash notation is deprecated (http://handlebarsjs.com/expressions.html).

So, the actual method to access to the parents elements are the following:

@root.grandfather.father.element
@root.father.element

In your specific example, you would use:

{{#each items}}
 <div style="font-size:{{@root.viewData.itemSize}}px">{{this}}</div>
{{/each}}

Another method from the official documentation(http://handlebarsjs.com/builtin_helpers.html) is using alias

> The each helper also supports block parameters, allowing for named > references anywhere in the block. > > {{#each array as |value key|}}
> {{#each child as |childValue childKey|}} > {{key}} - {{childKey}}. {{childValue}}
{{/each}} {{/each}} > > Will create a key and value variable that children may access without > the need for depthed variable references. In the example above, {{key}} > is identical to {{@../key}} but in many cases is more readable.

Solution 3 - Javascript

Unfortunately ../ dereferencing does not seem to work through partials. But we can add properties to the context passed into the partial:

Name: {{parent.name}}

{{#each children}}
    {{> childpartial this parent=../parent}}
{{/each}}

childpartial:

{{name}} is child of {{parent.name}}

More: https://stackoverflow.com/questions/9411538/handlebars-is-it-possible-to-access-parent-context-in-a-partial

Solution 4 - Javascript

We can access parent using {{../parent.propertyname}}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDrew NoakesView Question on Stackoverflow
Solution 1 - JavascriptDrew NoakesView Answer on Stackoverflow
Solution 2 - JavascriptcaballerogView Answer on Stackoverflow
Solution 3 - JavascriptEthermanView Answer on Stackoverflow
Solution 4 - JavascriptJitho v JoyView Answer on Stackoverflow