【问题标题】:Duplicate null-id records in ember-dataember-data 中重复的 null-id 记录
【发布时间】:2013-09-07 08:12:26
【问题描述】:

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

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');
        });
      }
    }
  });

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

为了记录,我使用的是 mongodb,所以我使用自定义序列化程序将“_id”属性转换为对 ember-data 友好的“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 中。

【问题讨论】:

    标签: ember.js ember-data


    【解决方案1】:

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

    最好将此信息包含在 official REST adapter documentation 中。

    【讨论】:

      【解决方案2】:

      这确实是一种奇怪的行为。不幸的是,我无法解释您为什么会遇到这种情况:

      您可以在 Route 中的 actions 对象中使用 willTransition 回调,以确保在从它转换离开时,如果 NotesNewController 的 content 属性是脏的(即尚未持久化),它将回滚其事务。

      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);
          }
        }
      });
      

      【讨论】:

      • 感谢您的建议。我已经实现了这一点,在谷歌搜索问题时偶然发现了类似的建议。不幸的是,它没有帮助。使用 Ember Inspector,我可以验证是否存在两个新创建的便笺副本,一个保留在具有 id 的数据库中,另一个是无 id 的本地副本。
      • 是否有解决这个问题(真实的)?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-22
      • 2015-11-03
      • 1970-01-01
      • 2014-05-06
      • 1970-01-01
      • 2015-04-09
      相关资源
      最近更新 更多