Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

javascript - Nested HandlebarsJS #each helpers with EmberJS not working

I'm slowly starting to get the hang of EmberJS. Unfortunately I've run into an issue I can't seem to work out.

I have a complex data-structure, which I retrieve through JSON, with multiple nested arrays and I can't seem to nest #each helpers.

I've setup my template as follows (shortened):

{{#each Servers}}
     <div class="server">
          <h1>{{unbound Name}}</h1>
          Time: {{jsonDate CurrentTime}}<br />

          <table>
               {{#each Processes}}
                    <tr>
                         <td>{{unbound Name}}</td>
                         <td>{{unbound Location}}</td>
                    </tr>     
               {{/each}}
          </table>
     </div>
{{#/each}}

The second loop doesn't seem to run, when I modify Ember to log a message, #the second each is called, but it seems it doesn't know what to do.

When I replace the second #each with #Queue, it works, but right before the -element an "undefined"-text is inserted for every element in the list (minus 1).

When I move the #each outside of the other loop and put in the direct path to Queue (eg. Servers.0.Queue) it works fine, so it's certainly not the data.

How do I fix this? If nested #each is not possible, how do I prefend the "undefined"-text for the other method? Any other possibilities?

PS. I use unbound for performance reasons, I update the Servers object in one go and observe that, so there is no need to use bound properties - as I've noticed it significantly reduces browser performance (13% CPU Usage, whereas unbound gave me 0%). Not sure if related.

EDIT

Please see: http://jsfiddle.net/PTC9B/7/

The ServerOverview2a-method works after all, apparently ServerOverview2b generates the "undefined"-text I described earlier - probably should file a bug report for that?

My question now is: Why do nested #each not work whereas #Processes does?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It looks like the properties in your hash are causing the troubles: using an Uppercase property Processes doesn't work - if you change it to processes the each helper works as expected, see http://jsfiddle.net/pangratz666/ndkWt/:

<script type="text/x-handlebars" data-template-name="app-server">
    <h1>Default</h1>
    {{#each data.Servers}}
        <div class="server">
            <h1>{{unbound this.Name}}</h1>

            Time: {{unbound this.CurrentTime}}<br />

            <table>
                {{#each this.processes}}
                    <tr>
                        <td>{{unbound Name}}</td>
                        <td>{{unbound Location}}</td>
                    </tr>     
                {{/each}}
            </table>
        </div>
    {{/each}}
</script>?
App = Ember.Application.create({
    ready: function() {
        Ember.View.create({
            templateName: 'app-server',
            dataBinding: 'App.dataController.data'
        }).append();

        App.dataController.getServers();
    }
});

App.dataController = Ember.Object.create({
    data: {},
    getServers: function() {
        this.set('data', Ember.Object.create({
            "Servers": [
                {
                "Name": "USWest",
                "CurrentTime": "1337",
                "processes": [
                    {
                        "Name": "apache.exe",
                        ...
                    }
                ]}
            ]
        }));
    }
});?

IMHO referring to this.Processes should work in the #each helper, so this might be a bug. Are you able to change the property names of the JSON which you get from the server? Otherwise you might write a helper which lowercases your property names of a JSON before it's used ...


Another note: the Application#ready didn't work in your provided JSFiddle, because you specified the JS to be executed onDomReady (select dropdown in upper left corner of JSFiddle). If you change this to no wrap you can access App within your ready callback.


Another note about naming: instances should be named lowerCase and classes UpperCase. So it would be App.serverOverview1 = Ember.View.create({ ... }); in your example.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...