Handlebarsではeachループを使って条件文の中に入るとコンテキストが変化し、パス名の記述の繰り返しを避けることができる。しかし、親のコンテキストのデータにアクセスしたいケースでどう書けばよいのか。
参考
http://handlebarsjs.com/#paths
http://stackoverflow.com/questions/17364897/access-to-root-context-in-handlebar-js-template
サンプル
例えばこんなJSONデータがあったとする。
var context = { title: "My First Blog Post!", author: { id: 47, name: "Yehuda Katz" }, body: "My first post. Wheeeee!", comments:[ {id:1,text:"aaa"}, {id:2,text:"bbb"}, {id:3,text:"ccc"}, {id:4,text:"ddd"}, {id:5,text:"eee"} ] };
commentsの繰り返しの際、{{text}}は{{comment.text}}ではなく{{text}}と書ける。
<h1>Comments</h1> <div id="comments"> {{#each comments}} <p>{{text}}</p> {{/each}} </div>
comments内でauthor.idを使いたい場合、eachブロック内からはauthor.idは親コンテキストに属するため「../」を使ってアクセスする。
<h1>Comments</h1> <div id="comments"> {{#each comments}} <p>{{../author}}</p> <p>{{text}}</p> {{/each}} </div>
公式ページには「../」セグメントは親のテンプレートパスを参照し、コンテキストの1階層上という訳ではないと書いてあり、これがどういう意味かというと、{{#}}〜{{/}}のブロックを1セグメントとみなし、これが深くなる(入れ子になる)に従って取得可能なデータのコンテキストが変化するということらしい。
<h1>Comments</h1> <div id="comments"> {{#each comments}} <p>{{../author}}</p> <p>{{text}}</p> {{#if user}} //ここで深くなる!! <p>{{text}}</p> {{/if}} {{/each}} </div>
上記の例でいうとdepth[0]の状態が、#each内ではdepth[1]になり、#ifでdepth[2]になる。
なので、JSON上の最上位(depth[0])にあるauthorをコメント内で存在チェックしつつさらに値を取得するようなケースでは ../../ として2段階上がる必要がある。
<h1>Comments</h1> <div id="comments"> {{#each comments}} <p>{{../author}}</p> <p>{{text}}</p> {{#if ../author}} <p>{{../../author.name}}</p> {{/if}} {{/each}} </div>
説明が分かりにくいと思うので、実際に試してみることを推奨。
デバッガで追う際にはtemplateメソッドのdepthsパラメータの値を追うと良い。