3

这是一个 jsfiddle 演示:http: //jsfiddle.net/YUHLA/5/

这是我在尝试找出创建新记录的正确模式时遇到的问题。我无法保存新创建的记录,并且在途中遇到了一些奇怪的行为。

打开控制台,然后尝试添加新帖子并保存。注意三个奇怪的事件:

  1. 在控制器上调用 get('model') 会在第 62 行返回一个控制器。
  2. 在第 65 行,证明没有新模型保存到固定装置中。
  3. 从 post 控制器创建另一个帖子并保存后,两个帖子都被保存(第 70 行)。

这是javascript:

window.App = Ember.Application.create();

App.Store = DS.Store.extend({
  adapter: DS.FixtureAdapter
});

App.store = App.Store.create();

App.Post = DS.Model.extend({
  title: DS.attr('string'),
  body: DS.attr('string')
});

App.Post.FIXTURES = [
  {
    id: 1,
    title: 'title',
    body: 'body'
  }, {
    id: 2,
    title: 'title two',
    body: 'body two'
  }
];

App.NewPostFormView = Ember.View.extend({
  tagName: "form",
  templateName: "newPostForm",
  submit: function() {
    this.get('controller').save();
    return false;
  }
});

App.ApplicationController = Ember.ObjectController.extend({
  posts: (function() {
    return App.Post.find();
  }).property()
});

App.PostsController = Ember.ArrayController.extend({
  sortProperties: ['id'],
  sortAscending: false,
  itemController: 'post',
  newPost: function() {
    var post;
    return post = App.Post.createRecord({
      title: '',
      body: '',
      isEditing: true
    });
  }
});

App.PostController = Ember.ObjectController.extend({
  save: function() {
    var temp;
    console.log('Starting to save');
    console.log('this.get(\'model\') =', this.get('model'));
    transaction = App.store.transaction();
    this.set('isEditing', false);
    temp = this.get('model');
    temp.get('store').commit(); 
      Ember.run.next(function(){
          console.log('# fixtures:', App.Post.FIXTURES.length);
          App.Post.createRecord(
              {title: 'post four', body: 'four body'}
          ).get('store').commit()
          Ember.run.next(function(){
             console.log('# fixtures:', App.Post.FIXTURES.length);
          });
      });
  }
});

这是否与我从 post 控制器创建模型,然后将其保存在 post 控制器中的事实有关?如果是这样,我该如何解决这个问题?

谢谢!

4

1 回答 1

2

这是否与我从 post 控制器创建模型,然后将其保存在 post 控制器中的事实有关?

不。

  1. 在控制器上调用 get('model') 会在第 62 行返回一个控制器。

正确的。PostsController已指定itemController: 'post',因此当帖子模板迭代{{each post in controller}}帖子时,帖子被包装在PostController. 这很好,但不能与{{render}}助手结合使用。当{{render}}在每个块中使用 to 时{{render post post}},它会呈现帖子模板并将指定的值(帖子变量)包装在 PostController 中。所以你有两个后控制器包装一个后模型。有点矫枉过正。

  1. 在第 65 行,证明没有新模型保存到固定装置中。

所以这里的问题是你有两个不同的商店。App.store() 是在第 14 行创建的全局变量。由于它是第一个创建的,因此它是default store. 它与您的模型使用的那个无关。

在 PostController.save() 中,this.get('model')返回一个控制器。控制器的商店是默认商店。这通常与模型的商店相同,但在这种情况下不是。因此,当您get('store').commit()在没有模型的默认商店中调用它时,什么也不会发生。如果你真的有一个模型(通过修复问题 #1),那就没问题了。或者,如果您没有创建App.store它也可以,因为在这种情况下,默认存储将与您模型的存储相同。

建议不要自己创建 App.store() ,这样做只是令人困惑,可能不是你想要的。一般来说,最好让 ember 创建东西。

  1. 从 post 控制器创建另一个帖子并保存后,两个帖子都被保存(第 70 行)。

正确的。因为在 App.store() 上调用了 commit(),所以 App.Post 的 store 仍然有一个未提交的记录。App.createRecord({}).get('store').commit() 在该存储中创建第二条记录,然后同时提交。

在这里更新小提琴:http: //jsfiddle.net/YUHLA/7/

于 2013-07-07T03:49:23.943 回答