【问题标题】:Ember.js—Why would this.get('model') return a controller?Ember.js——为什么 this.get('model') 返回一个控制器?
【发布时间】:2013-07-04 16:45:30
【问题描述】:

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

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

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

  1. 在控制器上调用 get('model') 会在第 62 行返回一个控制器。
  2. 在第 65 行,证明没有新模型保存到夹具中。
  3. 从帖子控制器创建另一个帖子并保存后,两个帖子都被保存(第 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 控制器中的事实有关?如果是这样,我该如何解决这个问题?

谢谢!

【问题讨论】:

    标签: javascript ember.js ember-data


    【解决方案1】:

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

    没有。

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

    没错。 PostsController 指定了itemController: 'post',因此当帖子模板迭代{{each post in controller}} 时,帖子将被包裹在PostController 中。这很好,但不能与 {{render}} 助手结合使用。当{{render}} 用于{{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. 从帖子控制器创建另一个帖子并保存后,两个帖子都被保存(第 70 行)。

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

    在此处更新小提琴:http://jsfiddle.net/YUHLA/7/

    【讨论】:

    • 感谢您的回复。 this.get('model').save() 似乎实际上并没有向后端发出 POST 请求......应该是这种情况吗?我使用事务制作了一个新的小提琴,它适用于小提琴,但在我的应用程序上,相同的过程无法发出后端的 POST 请求。 jsfiddle.net/YUHLA/9
    • 啊,原来我遇到了与在其父模型的帖子模型上指定“嵌入:始终”相关的问题。将其切换为“嵌入:加载”允许我单独保存后期模型。现在我只需要解决一些与 POST 请求中使用的键相关的谜团,以及它们是否附加了 _id。
    • 太好了,很高兴这有效。回复:使用的键,最好的地方是在 REST 适配器的单元测试中。只需查看为每种类型的请求传递的 ajax 哈希。 github.com/emberjs/data/blob/master/packages/ember-data/tests/…
    猜你喜欢
    • 2020-10-31
    • 2015-02-19
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 2013-08-18
    • 2018-06-01
    相关资源
    最近更新 更多