在Ember.js的模板中,当你在#each块中时,如何引用父上下文中的值?

时间:2012-05-19 04:43:42

标签: ember.js

我在模板中有一种情况,我希望在每个块内部的父上下文中使用if块。

代码:

App = Ember.Application.create({});

App.view = Ember.View.extend({
    foo: [1, 2, 3],
    bar: true
});

模板:

<script type="text/x-handlebars">
{{#view App.view}}
    {{#each foo}}
        {{#if bar}}
            {{this}}
        {{/if}}
    {{/each}}
{{/view}}
</script>

这不起作用,因为每个循环内引用的名称都限定为迭代元素。你如何在父语境中引用事物?

演示:http://jsfiddle.net/hekevintran/sMeyC/1/

4 个答案:

答案 0 :(得分:11)

我找到了更好的解决方案。

来自Ember.js视图图层指南(http://emberjs.com/guides/understanding-ember/the-view-layer/):

  

Ember中的把手助手也可以指定变量。例如,{{#with controller.person as tom}}表单指定后代作用域可以访问的tom变量。即使子上下文具有tom属性,tom变量也将取代它。

     

此表单有一个主要好处:它允许您缩短长路径而不会失去对父作用域的访问权。

     

在{{#each}}帮助程序中尤其重要,它提供了{{#person person in people}}形式。在这种形式中,后代上下文可以访问person变量,但保留在模板调用每个变量的范围内。

模板:

<script type="text/x-handlebars" >
    {{#view App.view}}
        {{#each number in view.foo}}
            {{#if view.bar}}
                {{number}}
            {{/if}}
        {{/each}}
    {{/view}}
</script>​

演示:http://jsfiddle.net/hekevintran/hpcJv/1/

答案 1 :(得分:5)

hekevintran的回答意味着您可以使用#with重命名任何变量。我们在使用this的JavaScript中遇到了类似的问题。在JavaScript中,有时您会看到这样的代码来解决它。

var self = this;
doSomething(function() {
  // Here, `this` has changed.
  if (self.bar) {
    console.log(this);
  }
});

在Ember风味手把中,view发生了类似的事情。假设你有App.MyOuterView和其他视图。你可以像这样解决它。

{{#with view as myOuterView}}
  {{#each foo}}
    {{#if myOuterView.bar}}
      {{this}}
    {{/if}}
  {{/each}}
{{/with}}

与JavaScript类似,您基本上可以将view重命名为其他内容,这样它就不会被内部视图遮挡。 {{#each person in people}}只是一个特例。但是使用{{#with view as myView}}重命名是此问题的更通用的解决方案/解决方法,也适用于对view帮助程序的嵌套调用。

答案 2 :(得分:2)

我也对此感到难过。这个线程和另一个线程(Using a container view in ember.js - how to access parent variables from child view)帮助我解决了这个问题。我使用Jonathan的建议做{#with}并且还发现我应该通过调用控制器来访问我的变量。我这样工作:

// I use the #which command to preserve access to the outer context once inside the #each
{{#with view as myOuterView}}
  {{#each myInnerArray}}
    //here, i get my 'name' property from the *controller* of myOuterView
    {{myOuterView.controller.name}}
    // stuff i did in inner array
  {{/each}
{{/with}

答案 3 :(得分:0)

首先无需将if置于each内:

<script type="text/x-handlebars">
  {{#view App.view}}
    {{#if view.bar}}
      {{#each view.foo}}
        {{this}}
      {{/each}}
    {{/if}}
  {{/view}}
</script>

演示:http://jsfiddle.net/ppanagi/NQKvy/35/