Ember数据:在DS.Store.createRecord上刷新模型

Ember-data: model refresh on DS.Store.createRecord

本文关键字:createRecord 刷新 模型 Store DS 数据 Ember      更新时间:2023-12-07

Embsters!

我正试图弄清楚为什么在创建新记录并将其保存到商店后,我的模型没有被刷新

My route计算model如下:

model: function (params) {
  var postID = params.post_id,
      userID = this.get('session.currentUser.id');
  var post = this.store.findRecord('post', postID) ;
  var followings = this.store.query('post-following', {
      filter: { post: postID }
  }) ;
  var userFollowing = this.store.queryRecord('post-following', {
      filter: { post: postID, user: userID }
  }) ;
  return new Ember.RSVP.hash({
      post:          post,
      followings:    followings,
      userFollowing: userFollowing
  });
}

然后我的模板渲染列表按钮

{{#each model.followings as |following|}}
    ...
{{/each}}
{{#if model.userFollowing}}
    <button {{action 'follow'}}>Follow</button>
{{else}}
    <button {{action 'unFollow'}}>Unfollow</button>
{{/if}}

我的控制器创建/删除相关的post-following记录:

actions: {
    follow: function () {
        var user = this.get('session.currentUser'),
            post = this.get('model.post') ;
        this.store.createRecord('post-following', {
            user: user,
            post: post
        }).save();
    },
    unFollow: function () {
        this.get('model.userFollowing').destroyRecord() ;
    }
}  

单击[Follow]按钮时:

  • 发送成功的CCD_ 4请求
  • 按钮未更新
  • 列表未更新

当我(然后刷新页面)单击[Unfollow]按钮时:

  • 发送成功的CCD_ 6请求
  • 按钮未更新
  • 列表已更新

你知道我做错了什么吗
我的有效载荷可能有问题吗?


编辑:解决了

听起来我对余烬的期望太高了。

该框架不会在store.createRecord('post-following', {...})调用时自动更新我的post-following的数组。

然后我调整了我的控制器逻辑,以"手动"更新我的模型:

// in follow action…
userFollowing.save().then( function(){
    var followings = store.query('post-following', {
        filter: { post: postID }
    }).then( function (followings) {
        _this.set('model.userFollowing', userFollowing);
        _this.set('model.followings', followings);
    }) ;
});
// in unFollow action…
userFollowing.destroyRecord().then( function () {
    _this.set('model.userFollowing', null);
    _this.notifyPropertyChange('model.followings') ;
}); 

请注意我的后端API设计受到@duizendnegen的批评(请参阅评论)。本文中的更多最佳实践。

谢谢你的帮助
Brou

对于这类问题,有一个较小的、复制的问题(例如通过Ember Twiddle)确实很有帮助

从根本上讲,新的post-following记录与filter不匹配:它被过滤为属性{ post: 123 },而您的post-following对象在{ post: { id: 123, name: "" } }的行中包含一些内容。此外,您的post-following对象不包含名为filter的属性,也不包含它可能是什么——即它对服务器执行的查询与您希望在客户端上筛选的查询不同。

我在这里的方法是,作为对followunfollow操作的响应,更新model,包括userFollowingfollowings

您的问题是没有将属性model重新设置为指向新创建的对象。您总是在访问相同的model属性,即使在创建新属性之后也是如此。

首先要注意的是,在路由中的model钩子之后,会调用执行以下操作的setupController钩子:

controller.set('model', resolvedModel)

这意味着默认情况下,每次加载路由时都会设置控制器上的model属性(model钩子解析)。但是,在创建新记录后,这种情况不会发生,因此必须明确执行:

let newModel = this.store.createRecord('post-following', {
  user: user,
  post: post
})
// since model.save() returns a promise
// we wait for a successfull save before
// re-setting the `model` property
newModel.save().then(() => {
  this.set('model', newModel);
});

为了获得更清晰的设计,我还建议您为model属性创建一个别名,更具体地描述您的模型,或者如果您也在控制器上进行一些初始设置,则覆盖setupController的默认行为。所以要么:

export default Ember.Controller.extend({
  // ...
  blog: Ember.computed.alias('model') // more descriptive model name   
  // ...
});

或者:

export default Ember.Route.extend({
  // ...
  setupController(controller, resolvedModel) {
    controller.set('blog', resolvedModel); // more descriptive model name 
    // do other setup
  }
  // ...
});

您的模型是在进入页面时设置的。当进行更改时,您的模型不会更改。销毁记录时更新列表的唯一原因是因为它已经不存在了。单击"关注"按钮或"取消关注"按钮后重新加载模型,或手动更改列表/按钮的值。