2

我正在使用 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”,基本上是从这里复制的:

  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 中。

4

2 回答 2

4

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

最好将此信息包含在官方 REST 适配器文档中。

于 2013-09-07T14:16:17.680 回答
0

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

您可以在 RoutewillTransition中的对象中使用回调actions来确保当它被转换离开时,如果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);
    }
  }
});
于 2013-09-07T10:11:05.990 回答