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

hek*_*ran 10 ember.js

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

代码:

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

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

模板:

<script type="text/x-handlebars">
{{#view App.view}}
    {{#each foo}}
        {{#if bar}}
            {{this}}
        {{/if}}
    {{/each}}
{{/view}}
</script>
Run Code Online (Sandbox Code Playgroud)

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

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

hek*_*ran 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>?
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*ran 5

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

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

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

{{#with view as myOuterView}}
  {{#each foo}}
    {{#if myOuterView.bar}}
      {{this}}
    {{/if}}
  {{/each}}
{{/with}}
Run Code Online (Sandbox Code Playgroud)

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