I have got a template that shows tiles in a particular order:
<template name="container">
{{#each tiles}}{{>tile}}{{/each}}
</template>
Now the container is a list of tiles that is stored as an array in mongodb.
Since I want the tiles to be shown in the same order as they appear in that array, I'm using the following helper:
Template.container.tiles = function () {
return _.map(this.tiles || [], function(tileId) {
return _.extend({
container: this
}, Tiles.findOne({_id: tileId}));
}, this);
};
};
The problem is, that I:
Do not want the entire container to rerender when the any of it's contain tiles changes. (Only the relevent tile should be invalidated).
Do not want the entire container to rerender when a new tile is inserted. The rendered tile should be simply appended or insteted at the respective location.
Do not want the entire container to rerender when the order of the tiles is changed. Instead, when the order changes, the DOM objects that represent the tile should be rearranged without re-rendering the tile itself.
With the above approach I will not meet the requirements, because the each tiles data is marked as a dependency (when running Tiles.findOne({_id: tileId})
) of the entire container and the entire array of tile-ids is part of the containers data and if that changes the entire container template is invalidated.
I'm thinking I should mark the cursor for the container as non-reactive. Something like this:
Containers.findOne({_id: containerId}, {reactive:false});
But I still need to find out when this container changes it's tiles array.
So something like
Deps.autorun(function() {
updateContainer(Containers.findOne({_id: containerId}));
});
But I want that container template to be highly reusable. So whatever solution there it should not require some preparations with dependencies.
Where do declare I run that autorun function? (surely i cannot do that in that helper, right?)
Is this the right approach?
Does anybody have better ideas on how to solve this problem?
Thanks in advance...
The way I usually approach this problem is by creating an auxiliary
Collection
object and populate it with a help of appropriateobserver
. In your case this might be something like:Now, depending on the current container, you can populate the
tiles
collection with corresponding data. Also, you'll probably need to remember each object's index:The helper code is now really simple:
EDIT:
Please note, that in order to prevent the whole list being rerendered every time the container object changes (e.g. the order of tiles changes), you'll need to make a separate
listOfTiles
template that does not depend on the container object itself.