如何使ArrayController忽略DS.Store的瞬态记录

时间:2013-01-09 23:13:11

标签: ember.js ember-data

我有一个通过ClientsController显示的客户端列表,其内容设置为Client.find(),即RecordArray。用户通过ClientController创建一个新客户端,其内容在路由处理程序中设置为Client.createRecord()。

一切正常,但是,当用户填写客户端的创建表单时,客户端列表会使用新的客户端记录更新,该记录是在路由处理程序中创建的。

在记录保存之前,RecordArray / Store只能识别新记录的最佳方法是什么?

更新: 我最终根据对象状态

过滤了列表
{{#unless item.isNew}} Display the list {{/unless}}

更新 - 2 这是使用过滤器的另一种方法,但是必须首先通过find方法加载存储,App.Client.find()。filter()似乎不像单独调用时两种方法的行为一样。

// Load the store first     
App.Client.find();
    var clients = App.Client.filter(function(client){            
        console.info(client.get('name') + ' ' + client.get('isNew'));  
        return !client.get('isNew');
    });                   
    controller.set('content',clients);  

2 个答案:

答案 0 :(得分:2)

很少有办法解决这个问题:

首先,对于处理客户列表的路由/状态来说,它非常麻烦,它必须不顾一切地过滤掉另一个不相关状态(即newClient状态)遗留下来的垃圾。我认为在离开newClient状态之前删除垃圾记录会更好,一个

if(client.get("isNew")) {
  client.deleteRecord();
}

这将确保它不会蔓延到clientIndex路由或任何其他客户端列表路由,这些路由不应该用于过滤掉垃圾记录。理想情况下,此代码位于exit路由的newClient函数中,因此它可以在路由器转换为另一个名为Client.find()的状态之前删除记录

但是有一个更好的惯用解决方案:https://gist.github.com/4512271

(不确定您使用的是哪个版本的路由器,但这适用于两者)

解决方案是使用事务:而不是直接在createRecord()上调用Client,在事务上调用createRecord(),以便新客户端记录与该事务关联,然后你需要做的只是在exit中调用transaction.rollback() - 你甚至不需要在任何事情上调用isNew,如果保存了客户端记录,它显然不会被滚动回来。

这也是编辑记录的有用模式:1)在enter状态下创建一个事务并将记录添加到其中,例如

enter: function(router, client) {
     this.tx = router.get("store").transaction();
     this.tx.add(client); 
},

然后是exit州的同类事情:

exit: function(router, client) {
     this.tx.rollback();
},

这样,如果用户完成表单并提交给服务器,则回滚将正确/方便地执行任何操作。如果用户编辑了某些表单字段但后退了一半,那么您的exit回调将还原未保存的更改,这样您就不会在{{1}中弹出一些脏的僵尸客户端路由显示未保存的更改。

答案 1 :(得分:1)

不是100%肯定,您是否可以尝试使用

设置ClientsController的内容
Client.filter(function(client){
  return !client.get('isNew'));
});

编辑:为了使这项工作,您必须首先使用Client.find()加载商店。