流星:当删除另一个集合时删除集合属性

问题描述:

我有两个集合:一个用于文章,一个用于分类。帖子有一个或多个类别。如果某个类别被删除,我希望更新Posts集合,以便发布包含任何不存在的类别。我有这个工作,但我不确定这是最有效的方法。流星:当删除另一个集合时删除集合属性

此代码是当按下类别删除按钮时触发的。这既从集合中删除类别,又遍历包含类别的每个帖子,并更新类别数组以排除已删除的类别。

Template.listCategories.events({ 
    'click .delete-category': function(e){ 
     e.preventDefault(); 
     var category = this.name; 
     Categories.remove(this._id); 

     var posts = Posts.find({categories: category}).fetch(); 
     for (var i=0;i<posts.length;i++){ 
      var cats = _.without(posts[i].categories, category); 
      Posts.update(posts[i]._id, {$set: {categories: cats}}); 
     }  
    } 
}); 

首先,我将'category'变量设置为等于被删除类别的名称。其次,我实际上从集合中删除了类别。

最后,我设置了'posts'变量等于所有包含类别名称的帖子的获取,该类别名称返回一个帖子对象。我遍历帖子,并在下划线的帮助下,使用'_.without'函数返回排除已删除类别的类别数组。然后我调用Posts.update来更新新数组的类别。

不过,我担心的是每次在For循环中调用Posts.update。这是客户端电话,所以也许这并不重要?我仍然觉得有更好的方法来做到这一点。任何帮助?

我认为你正在寻找$pull运营商(docs):

The $pull operator removes all instances of a value from an existing array.

有了这个代码可以简化为这样:

Template.listCategories.events({ 
    'click .delete-category': function(e){ 
     e.preventDefault(); 
     var category = this.name; 
     Categories.remove(this._id); 

     Posts.update({categories: category}, {$pull: {categories: category}}, {multi:true});  
    } 
}); 

NB

It's a client side call, so maybe that doesn't matter as much?

你的断言是错误的,Posts.update不仅仅是一个客户端调用。实际上,使用minimongo的存根模拟更新操作的效果在客户端上执行,而并行更新也在服务器上远程执行。

+0

完美,谢谢! –

+1

其实,我得到一个“错误:不允许,不可信的代码只能通过ID更新文档。”当我使用这个代码。这是否仍然需要在For循环中运行,因为我必须使用帖子ID进行更新? –

+0

啊,是的,你说得对。我忘了Meteor只允许客户端代码一次更新单个文档,并且只有在给出其ID时才会更新。你可以做的就是把代码放到Meteor.method中,或者如你所建议的那样,保持for循环并且在每个迭代中更新一个单独的文章(但仍然使用'$ pull')。另请参阅此:http://*.com/questions/15464507/understanding-not-permitted-untrusted-code-may-only-update-documents-by-id-m – Tobold