在ember-data中复制null-id记录

时间:2013-09-07 08:12:27

标签: ember.js ember-data

我正在使用ember 1.0和ember-data 1.0.0 beta 1.我有以下路由和控制器来创建和保存简单的注释('AuthenticatedRoute'只是为登录用户定制的路由):< / p>

App.Note = DS.Model.extend({
  title: DS.attr(),
  author: DS.attr(),
  body: DS.attr(),
  createdAt: DS.attr()
});


App.NotesRoute = App.AuthenticatedRoute.extend({
    model: function() { return this.store.find('note'); },
  });

App.NotesNewRoute = App.AuthenticatedRoute.extend({
    model: function() {
      return this.store.createRecord('note');
    }
  });

App.NotesNewController = Ember.ObjectController.extend({
    actions: {
      save: function() {
        var self = this, model = this.get('model');
        model.set('author', localStorage.username);
        model.set('createdAt', new Date());
        model.save().then(function() {
          self.get('target.router').transitionTo('notes.index');
        });
      }
    }
  });

当我保存新笔记时,一切都按预期工作。但是当我离开笔记路线然后返回到它时,笔记列表中会填充一个重复的条目。一个条目具有id,可以编辑,删除等,另一个条目具有第一个条目的所有数据,除了id属性为null。在我看来,即使记录已经提交,ember-data也会保留新创建的记录(尚未提交到数据库,因此还没有id),但我不知道为什么。当我重新加载页面时,列表正确显示,不会出现重复。我究竟做错了什么?

为了记录,我正在使用mongodb,所以我使用自定义序列化程序将'_id'属性转换为ember-data friendly'id',基本上是从here复制的:

  App.NoteSerializer = DS.RESTSerializer.extend({
    normalize: function(type, hash, property) {
      // normalize the '_id'
      var json = { id: hash._id };
      delete hash._id;

      // normalize the underscored properties
      for (var prop in hash) {
        json[prop.camelize()] = hash[prop];
      }

      // delegate to any type-specific normalizations
      return this._super(type, json, property);
    }  
  });

我还应该提到这个问题也存在于ember-data 0.13中。

2 个答案:

答案 0 :(得分:3)

这是我的RESTful服务器中的一个愚蠢的错误。我用204(空)响应而不是预期的ember-data响应POST请求,这是一个201(“创建”)响应,新创建的记录作为有效负载。 This post让我意识到了。

将这些信息包含在official REST adapter documentation

中会很不错

答案 1 :(得分:0)

这确实是奇怪的行为。不幸的是,我无法解释为什么你会遇到这个问题,但是:

您可以在路由中的willTransition对象中使用actions回调,以确保在转移离开时,如果NotesNewController的内容属性为脏(即没有已被持久化),它将回滚其交易。

App.NotesNewRoute = App.AuthenticatedRoute.extend({
  model: function() {
    return this.store.createRecord('note');
  },
  actions: {
    willTransition: function (transition) {
      var model = this.controllerFor('notesNew').get('content');
      if (model.get('isDirty') === true) {
        model.get('transaction').rollback();
      }
      return this._super(transition);
    }
  }
});