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

在Ember.js中的模板中,当您位于#each块中时,如何在父上下文中引用值?,ember.js,Ember.js,在模板中有一种情况,我希望在父上下文中的值上使用if块,而在每个块中使用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}

在模板中有一种情况,我希望在父上下文中的值上使用if块,而在每个块中使用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>
<script type="text/x-handlebars" >
    {{#view App.view}}
        {{#each number in view.foo}}
            {{#if view.bar}}
                {{number}}
            {{/if}}
        {{/each}}
    {{/view}}
</script>​

{{{#查看App.view}
{{{每个foo}
{{{#if bar}}
{{this}}
{{/if}
{{/每个}}
{{/view}
这不起作用,因为在each循环中引用的名称的作用域是迭代的元素。您如何在父上下文中引用事物


演示:

我找到了更好的解决方案

从Ember.js视图层指南():

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

此表单有一个主要优点:它允许您缩短长路径,而不会丢失对父作用域的访问

它在{{{each}}helper中尤其重要,它提供了{{{{each}people}形式的每个人。在这种形式中,子代上下文可以访问person变量,但与模板调用每个变量的范围相同

模板:

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

{{{#查看App.view}
{{{#视图中的每个数字。foo}
{{{#if view.bar}
{{number}}
{{/if}
{{/每个}}
{{/view}
​

演示:

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

var self = this;
doSomething(function() {
  // Here, `this` has changed.
  if (self.bar) {
    console.log(this);
  }
});
在余烬风味的车把中,
view
也发生了类似的事情。假设你有App.MyOuterView和它里面的另一个视图。你可以这样做

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

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

首先无需将
if
放在
每个
中:

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

{{{#查看App.view}
{{{#if view.bar}
{{{#each view.foo}
{{this}}
{{/每个}}
{{/if}
{{/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}

如果要使用内联
视图
每个
,以及
如果
,那么使用CollectionView会更好。它还将更快、更少地进行dom操作。你能解释一下CollectionView会有什么帮助吗?@Ryan你能解释一下CollectionView会有什么帮助吗?我们刚刚花了一个小时来研究这个问题,谢谢你的回答!我们一直试图在一个each中使用view,但它没有被设置。为了提出这个问题,这个问题提供了一个例子。很明显,这个问题之所以被提出,是因为需要在外部语境中使用一些东西来在内部语境中使用。你的回答并没有达到同样的效果。@RobinDaugherty你看过被接受的答案了吗?猜猜看。它也不涉及“父上下文”。这只是一个解决办法。我喜欢我的答案。魔术