3

我正在尝试用 ember 构建一个简单的类别浏览器。我有两个非常简单的观点。当用户访问时,/他们将看到所有类别的列表,当他们单击该列表中的类别时,他们将被定向到#/1010 是 id 的位置。

我的问题是,当用户单击/路线上的类别时,我收到以下错误

TypeError: arrangedContent.addArrayObserver is not a function
[Break On This Error]   

didChange: 'arrangedContentArrayDidChange'

如果我在路由处刷新页面,#/10则会对我的后端进行正确的 api 调用/api/categories?parent=99。在过渡期间引发此错误的我可能做错了什么?下面是我的代码的完整示例。

模板:

<script type="text/x-handlebars">
  {{outlet}}
</script>

<script type="text/x-handlebars" data-template-name="categories">
    {{#each category in controller}}
        <p>{{#linkTo 'category' category}}{{ category.name }}{{/linkTo}}</p>
    {{/each}}
</script>

<!--this is an array instead of object -->
<script type="text/x-handlebars" data-template-name="category">
    {{#each category in controller}}
        <p>{{category.name}}</p>
    {{/each}}
</script>

Javascript:

var App = Ember.Application.create();

App.Router.map(function(){
    this.resource('categories', { path : '/' });
    this.resource('category', { path : '/:category_id' });
});

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

//this is causing the error possibly
    App.CategoryRoute = Ember.Route.extend({
        model: function(params){
            return App.Category.find({parent: params.category_id});
        }
    });

App.CategoryController = Ember.ArrayController.extend();

// Models
App.Store = DS.Store.extend({
  revision: 11,
  adapter: 'DS.RESTAdapter'
});

DS.RESTAdapter.configure("plurals", {
  category: "categories"
});

App.Category = DS.Model.extend({
  name: DS.attr('string'),
  parent_id: DS.attr('number')
});

调试信息:

DEBUG: Ember.VERSION : 1.0.0-rc.1
DEBUG: Handlebars.VERSION : 1.0.0-rc.3
DEBUG: jQuery.VERSION : 1.9.0
4

2 回答 2

4

提示:写完这篇文章后,我意识到你可能没有得到正确的模型钩子。当您通过 url 进入您的应用程序时,将调用此钩子。它将 URL 转换为适当的模型,并使用此模型转换为 Route。我猜你认为这个 model() 钩子会用 {{#linkTo}} 的参数调用?不是这种情况!

这不起作用,因为您将单个模型传递给模板中的 #linkTo 助手。所以 Ember 想要将这个单一对象设置为 ArrayController 的内容。这会导致您的错误。你的模型钩子返回一个数组。经验法则:您应该始终将相同的数据结构传递给您在模型挂钩中返回的#linkTo。

因此,我建议使用事件而不是 linkTo 并执行以下操作:

<script type="text/x-handlebars" data-template-name="categories">
    {{#each category in controller}}
        <p {{action 'showParentCategory' category}}>{{category.name}}</p>
    {{/each}}
</script>

App.CategoriesRoute = Ember.Route.extend({
    model: function(){
        return App.Category.find();
    },
    events: {
      showParentCategory : function(parentCategory){
        var cats = App.Category.find({parent: parentCategory.get("category_id")});
        this.transitionTo("category", cats);
      }
    }
});

我在这里做了什么?

  1. 我创建了一个名为“showParentCategory”的操作。
  2. 由于这是关于路由的操作,因此我正在您的 CategoriesRoute 中处理此事件。如您所见,事件/动作处理程序是在您的路由的 events 属性中声明的。
  3. 我在那里执行与您的模型挂钩中相同的逻辑,然后我使用获取的类别手动调用transitinTo。

更新:如何序列化 通过实现序列化,您是在告诉 Ember 将什么放入您的 url。

App.CategoryRoute = Ember.Route.extend({
    model: function(params){
        return App.Category.find({parent: params.category_id});
    },
    serialize : function(models){
        var first = models.objectAt(0);
        return {
            category_id : first.get("parentId")
        }
    }
});
于 2013-03-11T15:54:11.383 回答
0

如果您对数值执行 #each 而不是对模板中的数组内容执行此操作,则会出现此问题。

我的“民意调查”模型中有一个数值计数。我在迭代,

{{#each poll in content.count}} {{/each}}

我认为,我们只能在 ember 数组上使用#each。

于 2015-12-17T09:16:50.487 回答