2014-03-04 111 views
1

我有兩個集合:一個用於文章,一個用於分類。帖子有一個或多個類別。如果某個類別被刪除,我希望更新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。這是客戶端電話,所以也許這並不重要?我仍然覺得有更好的方法來做到這一點。任何幫助?

回答

1

我認爲你正在尋找$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://stackoverflow.com/questions/15464507/understanding-not-permitted-untrusted-code-may-only-update-documents-by-id-m – Tobold