2013-10-18 27 views
1

我有一個模板,顯示了在一個特定的順序瓷磚:隔離反應有序列表中

<template name="container"> 
{{#each tiles}}{{>tile}}{{/each}} 
</template> 

現在容器是存儲在MongoDB中的陣列片的列表。

因爲我想,因爲它們出現在該數組中要以同樣的順序顯示的瓷磚,我用下面的幫助:

Template.container.tiles = function() { 
     return _.map(this.tiles || [], function(tileId) { 
       return _.extend({ 
        container: this 
       }, Tiles.findOne({_id: tileId})); 
     }, this); 
    }; 
}; 

的問題是,我:

  • 不希望整個容器在其中任何一個包含切片時發生重新渲染。 (只有相關的瓦片應該失效)。

  • 不希望整個容器在插入新圖塊時重新渲染。渲染的瓷磚應該簡單地在相應位置附加或嵌入。

  • 當瓷磚的順序發生變化時,不希望整個容器重新變色。相反,當順序改變時,代表瓦片的DOM對象應該重新排列而不重新渲染瓦片本身。

利用上述的方法,我將不能滿足要求,因爲每塊數據被標記爲依賴整個容器的(運行Tiles.findOne({_id: tileId})時)和瓷磚id的整個陣列是所述容器的一部分數據,如果更改了整個容器模板將失效。

我在想我應該將容器的光標標記爲無反應。這樣的事情:

Containers.findOne({_id: containerId}, {reactive:false}); 

但我仍然需要找出當這個容器改變它的瓷磚數組。

因此,像

Deps.autorun(function() { 
    updateContainer(Containers.findOne({_id: containerId})); 
}); 

但我想該容器的模板是高度可重用的。所以無論什麼解決方案都不需要一些依賴的準備。

哪裏聲明我運行該自動運行功能? (當然,我不能那樣做那個幫手,對吧?)

這是正確的做法嗎?

有沒有人有更好的想法如何解決這個問題?

在此先感謝...

回答

1

我通常解決這個問題的方法是創建一個輔助Collection對象,並用適當的observer幫助填充它。在你的情況,這可能是這樣的:

// this one should be "global" 
var tiles = new Meteor.Collection(null); // empty name 

現在,根據目前的容器,可以填充tiles收集與相應的數據。此外,你可能需要記住每個對象的指標:

Deps.autorun(function() { 

    var containerId = ... // get it somehow, e.g. from Session dictionary 
    var tilesIDs = Containers.findOne({_id:containerId}).tiles; 

    tiles.remove({}); // this will be performed any time 
         // the current container changes 

    Tiles.find({ _id : { $in : tilesIDs } }).observeChanges({ 
     added: function (id, fields) { 
      tiles.insert(_.extend({ 
       _index : _.indexOf(tilesIDs, id), 
       _id : id, 
      }, fields); 
     }, 
     changed: ... // you'll also need to implement 
     removed: ... // these to guys 
    }); 

}); 

助手代碼現在非常簡單:

Template.container.tiles = function() { 
    return tiles.find({}, {sort : {_index : 1}}); 
} 

編輯:

請注意,爲了防止整個列表在每次容器對象發生變化時都會重新渲染(例如,切片的順序發生變化),則需要製作一個不依賴於容器對象本身的單獨的模板listOfTiles

+0

這看起來非常好。但是因爲我可能在一個頁面上顯示很多容器,我可能會以某種方式將它包裝到Containers集合的一個轉換函數中? –

+0

好點!但我寧願使用'轉換'函數來收集'Tiles'。請注意,此處的主要任務是查找其父'tiles'列表中某個特定瓦片的「索引」。 –

+0

此外,你可以推廣上述解決方案(但我認爲正確使用轉換函數可能是一個更好的主意)。在這種情況下,您還需要設置'_parent'等字段(用於輔助集合中的圖塊副本),並更仔細地處理觀察者回調。 –