在路由上序列化会在emberjs中创建额外的模型实例

时间:2013-03-05 16:34:45

标签: ember.js

我想我偶然发现了一个emberjs中的错误,但在我指出它是一个错误之前我想知道我是否先做错了。我有一个艺术家列表(让我们说'主'视图),当用户点击“阅读更多”链接时,他/她可以看到有关该特定艺术家的详细信息。为了使我的网址更具可读性,我正在使用'slug'(序列化)。

这就是我的路由器的样子:

App.Router.map(function(){
  this.resource('artists', function(){
    this.resource('artist', {path:':artist_id'});
  });
});

这就是我的路线的样子:

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

App.ArtistRoute = Ember.Route.extend({
  enter: function(){
    console.log("ENTER: Artistroute");
  },

  serialize: function(model, params) {
    return { artist_id: model.get('slug') };
  }
});

现在,当用户点击艺术家名称然后在插座中呈现详细的艺术家信息时,问题就开始了。出于某种原因,概览列表会使用空的艺术家条目进行更新。

当我注释掉以下行时,问题就会消失:

/*
  serialize: function(model, params) {
    return { artist_id: model.get('slug') };
  },
*/

以下是用户点击“阅读更多”链接之前和之后实施的序列化挂钩的截图:

Before clicking

After clicking

如您所见,突然创建了两个额外的艺术家对象并添加到概览列表中。为什么会这样?

1 个答案:

答案 0 :(得分:2)

  

如您所见,突然创建了两个额外的艺术家对象并添加到概览列表中。为什么会这样?

这种情况正在发生,因为ember(尚未)支持将别名传递给模型的find()方法。如果按slug和id加载相同的记录,最终会在Ember身份映射中存储两条记录。因此,当您加载/artists并调用App.Artist.find()时,您的api会返回一群有1,2,3等ID的艺术家。当用户单击详细信息链接时,ember正在调用App.Artist.find(slug)并使用id = slug而不是数字ID保存响应。

正如您所指出的那样,当您注释掉自定义序列化程序时,工作正常,因为如果没有它,您只需按照数字ID查找艺术家。

针对此问题的一种解决方法您可能会考虑将api更改为仅使用slugs而不是数字ID。然后摆脱自定义序列化器,应该只是工作。您可以在App.ArtistRoute上实现自定义模型挂钩的另一种方法:

App.ArtistRoute = Ember.Route.extend({
  model: function(params) {
    var artists = App.Artist.find({ slug: params.artist_id });

    artists.one("didLoad", function() {
      artists.resolve(artists.get("firstObject"));
    });

    return artists;
  }

  serialize: function(model, params) {
    return { artist_id: model.get('slug') };
  }
});

有关此问题的详细信息,请参阅此博文:http://darthdeus.github.com/blog/2013/01/31/how-to-find-a-model-by-any-attribute-in-ember-dot-js/