How to access parent element in nested #each loop

1,665 views
Skip to first unread message

Jonathan Copas

unread,
Mar 13, 2015, 4:42:59 AM3/13/15
to racti...@googlegroups.com
Hi,

I have two loops, one nested inside the other. What I need is a way to access the outer loop's current element once I am inside the inner loop. This can be done in handlebars using ../ to reference the parent element but I could not get it working in Ractive. Here is what I have (with the handlebars style references)

 {{#each sort(rows) :iRow}}
            {{#if !filterRow(.) }}
              <tr data-order="{{.priority}}" data-id="{{iRow}}">
                {{#columns}}
                <td>
                  {{#if ../[.['fieldName']]}}            
                  {{../[.['fieldName']]}}
                  {{/if}}
                </td>
                {{/columns}}
              </tr>
            {{/if}}
 {{/each}}

I just need a way to be able to reference the current element in each iteration of the 'sort(rows)' loop.

Does anyone know how to achieve this?

Many thanks.


Rich Harris

unread,
Mar 13, 2015, 10:19:22 AM3/13/15
to racti...@googlegroups.com
This is slightly tricky with the current syntax. I've occasionally wondered if there's a case for having something like `{{#each sort(rows) as row}}` or `{{#each row in sort(rows)}}` (probably the first as the second is a valid JavaScript expression).

But it's totally possible. The bad way would be this: using the `iRow` index reference you can get the current row with `sort(rows)[iRow]`:

{{#columns}}
 
<td>
   
{{#if sort(rows)[fieldName]}}            
     
{{sort(rows)[fieldName]}}
   
{{/if}}
 
</td>
{{/
columns}}


That's far from ideal, because you have to keep re-sorting `rows`. But you can store the result of sorting `rows` as a computed property:

computed: {
  sortedRows
: function () {
   
// we slice the data so we don't mutate the original array
   
return this.get( 'rows' ).slice().sort( byPriority );
 
}
}


Then, you can use that property as many times as you like in your template without penalty:

{{#columns}}
 
<td>
   
{{#if sortedRows[fieldName]}}            
     
{{sortedRows[fieldName]}}
   
{{/if}}
 
</td>
{{/
columns}}


Here's an example of that in action: http://jsfiddle.net/rich_harris/2gbj06jq/

Cristian Pallarés

unread,
Mar 13, 2015, 10:19:38 AM3/13/15
to racti...@googlegroups.com
I think that you can already use double dots to go up into the context (as stated in the docs), but here's another way to do something like that.

You can use the with directive in order to change the current context. For example, you could write something like this:
{{#each rows}}
 
{{#with { row: . } }}
   
{{#each columns}}
     
{{row[fieldName]}}
   
{{/each}}
 
{{/with}}
{{/each}}

Rich Harris

unread,
Mar 13, 2015, 11:22:17 AM3/13/15
to racti...@googlegroups.com
I'd forgotten about `{{#with { row: . } }}` (or `{{#with { row: this } }}`, my brain copes with that easier) - that's a neat trick.

Chris Reeves

unread,
Mar 13, 2015, 11:26:43 AM3/13/15
to racti...@googlegroups.com
I've wondered if that shouldn't be available with iterative sections directly. A sort of forEach with the arguments reversed. `{{#each rows: i, row}} ... {{#each cols}} {{ row[col.name] }} {{/each}} ... {{/each}}`



Thanks, Chris

--
You received this message because you are subscribed to the Google Groups "Ractive.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ractive-js+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Marty Nelson

unread,
Mar 13, 2015, 11:32:40 AM3/13/15
to racti...@googlegroups.com
I've used the {{#with}} with success, but that's a neat trick Chris. :)

Yes would have to special case the parsing, but IMO {{#each row in rows}} is more readable than {{#each rows as row}}. 

Jonathan Copas

unread,
Mar 16, 2015, 5:39:00 AM3/16/15
to racti...@googlegroups.com
Thanks for the help guys. The trick using '#with' worked perfectly! Good to know for future.

I also just want to say thanks for all the development going into Ractive. After using Angular for a while, we had to switch because it's performance just wasn't up to where we needed it. However using Ractive is a breath of fresh air. The performance is excellent and it is just the right balance (in my opinion anyway) of offering enough structure, but not being too opinionated about how it is implemented. Great work!

Guilherme Aiolfi

unread,
Mar 16, 2015, 9:37:37 AM3/16/15
to racti...@googlegroups.com
Shouldn't those testimonials be in the ractive's site? I've seen a lot of them lately.

--
You received this message because you are subscribed to the Google Groups "Ractive.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ractive-js+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Guilherme R. Aiolfi
Reply all
Reply to author
Forward
0 new messages