In templates in Ember.js, how do you refer to a value in the parent context when you are inside an #each block?

前端 未结 4 745
栀梦
栀梦 2020-12-25 08:58

I have a situation in a template where I want to use an if block on a value in the parent context while inside an each block.

The code:

App = Ember.A         


        
相关标签:
4条回答
  • 2020-12-25 09:02

    What hekevintran's answer means is that you can rename any variable using #with. We have a similar problem in JavaScript with this. In JavaScript, sometimes you'll see code like this to work around it.

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

    In Ember flavored Handlebars, something similar is happening with view. Say you have App.MyOuterView and another view inside it. You can work around it like this.

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

    Similar to the JavaScript, you can essentially rename view to something else so it doesn't get shadowed by the inner view. {{#each person in people}} is just a special case of that. But renaming using {{#with view as myView}} is the more general solution/workaround to this problem that also works with nested calls to the view helper.

    0 讨论(0)
  • 2020-12-25 09:15

    I found a better solution.

    From the Ember.js View Layer guide (http://emberjs.com/guides/understanding-ember/the-view-layer/):

    Handlebars helpers in Ember may also specify variables. For example, the {{#with controller.person as tom}} form specifies a tom variable that descendent scopes can access. Even if a child context has a tom property, the tom variable will supersede it.

    This form has one major benefit: it allows you to shorten long paths without losing access to the parent scope.

    It is especially important in the {{#each}} helper, which provides a {{#each person in people}} form. In this form, descendent context have access to the person variable, but remain in the same scope as where the template invoked the each.

    The template:

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

    Demo: http://jsfiddle.net/hekevintran/hpcJv/1/

    0 讨论(0)
  • 2020-12-25 09:16

    I was also stumped on this. This thread and this other thread (Using a container view in ember.js - how to access parent variables from child view) helped me with the solution. I used Jonathan's suggestion to do {#with} and also figured out that I should access my variable by calling the controller. Mine worked like this:

    // 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}
    
    0 讨论(0)
  • 2020-12-25 09:27

    No need to place the if inside each in the first place:

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

    Demo: http://jsfiddle.net/ppanagi/NQKvy/35/

    0 讨论(0)
提交回复
热议问题