从JSON响应中创建Ember对象并使用Handlebars展示

3
我尝试使用Ember来查询一个JSON API,将数据创建为对象,然后在我的Handlebars模板中循环遍历这些对象。我能够记录响应和类别数组,并且我可以看到它们都已被创建。但是在我的模板中,我一直收到“未找到类别”的消息。 app.js:
App = Ember.Application.create({
    LOG_TRANSITIONS: true
});

App.Category = Ember.Object.extend();

App.Category.reopenClass({
    list: function() {
        $.getJSON("/api_url").then(function(response) {
                var categories = [];
                for(var i = 0; i < response.length; i++) {
                    // create a Category with a "name" property
                    categories.push(App.Category.create({ name: response[i]}));
                }
            // see screenshot for what this looks like logged to console
            return categories;
        });
    }
});

App.IndexRoute = Ember.Route.extend({
    model: function() {
        return App.Category.list();
    }
});

index.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>My App</title>
    </head>
    <body>

        <script type="text/x-handlebars" data-template-name="application">

        <h1>My App</h1>

        <div class="content">
            {{outlet}}
        </div>

        </script>

        <script type="text/x-handlebars" data-template-name="index">
            <ul>
                {{#each category}}
                    <li>Name: {{name}}</li>
                    {{else}}
                        <li>No categories found</li>
                {{/each}}
            </ul>
        </script>

        <script src="/kory/js/libs/jquery-1.10.2.js"></script>
        <script src="/kory/js/libs/handlebars-1.1.2.js"></script>
        <script src="/kory/js/libs/ember-1.5.0.js"></script>
        <script src="/kory/js/app.js"></script>

    </body>
</html>

示例JSON响应:

[
    "Foo",
    "Bar",
    "Meow",
    "Woof"
]

记录了 categories 数组的截图: 数组截图


1
在你的模板中,你尝试过使用 {{#each}} 而不是 {{#each category}} 吗? - Steve H.
1
刚刚尝试了一下,我得到了这个错误:未捕获的错误:断言失败:#each循环遍历的值必须是一个数组。您传递了(生成的索引控制器) - kmm
1
请检查App.Categories中的list方法。该方法没有返回语句,所以如果您调用它,将不会返回任何内容。 - Myslik
1
@Myslik你是对的,我必须returngetJSON调用。为什么从each语句中删除“category”可以解决问题?这是因为我已经在IndexRoute中设置了作用域吗? - kmm
@kmm 正如您所说。如果您在路由中的 model 钩子中返回数组,则该数组将直接进入控制器的 content 中。因此,没有 category 属性。 - Myslik
@kmm,{{#each}}助手中的参数是您要迭代的控制器属性。您没有控制器,因此Ember创建了一个控制器,该控制器没有名为“category”的属性。 - Steve H.
2个回答

0

被接受的解决方案正好是我遇到的问题。我尝试使用上面提出的解决方案,但它没有解决我的问题。在自己调试了几个小时后,我意识到我们都犯了一个问题!经过进一步评估,看起来其中一个评论注意到了这个问题,但我想更明确地说明一下,因为在不同的论坛上有几个人遇到了这个问题,但没有真正的解决方案。

这段代码:

list: function() {
    $.getJSON("/api_url").then(function(response) {
            var categories = [];
            for(var i = 0; i < response.length; i++) {
                // create a Category with a "name" property
                categories.push(App.Category.create({ name: response[i]}));
            }
        // see screenshot for what this looks like logged to console
        return categories;
    });
}

是异步的。每当REST API返回JSON时,Ember category对象就会被创建并返回。由于它是异步的,模型钩子调用列表函数,并认为调用已完成。

如果修改代码以返回Promise:

list: function() {
    return $.getJSON("/api_url").then(function(response) {
            var categories = [];
            for(var i = 0; i < response.length; i++) {
                // create a Category with a "name" property
                categories.push(App.Category.create({ name: response[i]}));
            }
        // see screenshot for what this looks like logged to console
        return categories;
    });
}

Ember 会阻塞模型钩子,直到承诺成功或失败,因为 Ember 就是这么棒。


0

根据您的设置方式(这是可以的),您应该基于ArrayController类创建一个IndexController:

App.IndexController = Ember.ArrayController.extend({

});

现在你可以使用#each助手循环遍历你的控制器:

<script type="text/x-handlebars" data-template-name="index">
  <ul>
    {{#each}}
      <li>Name: {{name}}</li>
    {{else}}
      li>No categories found</li>
    {{/each}}
  </ul>
</script>

这里是一个快速的JSBin示例:http://jsbin.com/wefof/4/edit


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接