Mongodb 在有序列表中隔离反应性
我有一个按特定顺序显示瓷砖的模板:Mongodb 在有序列表中隔离反应性,mongodb,meteor,reactive-programming,Mongodb,Meteor,Reactive Programming,我有一个按特定顺序显示瓷砖的模板: <template name="container"> {{#each tiles}}{{>tile}}{{/each}} </template> 问题是,我: 不希望在任何容器的包含平铺更改时重新加载整个容器。(只有相关的地砖应无效) 不希望在插入新磁贴时重新加载整个容器。渲染的平铺应简单地附加或安装在相应的位置 当磁贴顺序更改时,不希望整个容器重新加载。相反,当顺序改变时,应该重新排列表示磁贴的DOM对象,而不必重新渲染磁
<template name="container">
{{#each tiles}}{{>tile}}{{/each}}
</template>
问题是,我:
- 不希望在任何容器的包含平铺更改时重新加载整个容器。(只有相关的地砖应无效)
- 不希望在插入新磁贴时重新加载整个容器。渲染的平铺应简单地附加或安装在相应的位置
- 当磁贴顺序更改时,不希望整个容器重新加载。相反,当顺序改变时,应该重新排列表示磁贴的DOM对象,而不必重新渲染磁贴本身
tiles.findOne({u id:tileId})
时),整个tile id数组都是容器数据的一部分,如果这改变了整个容器模板就会失效
我认为应该将容器的光标标记为非反应性。大概是这样的:
Containers.findOne({_id: containerId}, {reactive:false});
但是我仍然需要知道当这个容器改变它的tiles数组时
大概是
Deps.autorun(function() {
updateContainer(Containers.findOne({_id: containerId}));
});
但我希望容器模板具有高度可重用性。因此,无论有什么解决方案,它都不应该需要一些具有依赖性的准备工作
我在哪里运行自动运行功能?(我当然不能在那个助手身上做到这一点,对吗?)
这是正确的方法吗
有谁对如何解决这个问题有更好的想法吗
提前感谢…我通常处理此问题的方法是创建一个辅助
集合
对象,并在适当的观察者的帮助下填充它。在您的情况下,这可能类似于:
// 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}});
}
编辑:
请注意,为了防止每次容器对象更改时(例如,平铺的顺序更改)都重新提交整个列表,您需要创建一个独立的列表文件
模板,该模板不依赖于容器对象本身。我通常处理此问题的方法是创建一个辅助集合
对象,并在适当的观察者的帮助下填充它。在您的情况下,这可能类似于:
// 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
模板,该模板不依赖于容器对象本身。这看起来非常好。但由于我可能会在一个页面上显示多个容器,我可能会以某种方式将其包装到容器集合的转换函数中?很好!但是我宁愿使用transform
函数进行Tiles
收集。请注意,这里的主要任务是找出特定磁贴在其父级磁贴
列表中的索引是什么。此外,您可以概括上述解决方案(但我认为正确使用变换函数可能是更好的主意)。在这种情况下,您还需要设置类似于\u parent
(用于辅助集合中的平铺副本)的字段,并更仔细地处理观察者回调。@d\u这里是我所说的示例实现:。我希望这会有用。嘿,非常感谢!!我只是尽量避免容器在瓷砖更改时失效,而不是在订单更改或添加新瓷砖时失效。明天将查看你的版本。这看起来很好。但由于我可能会在一个页面上显示多个容器,我可能会以某种方式将其包装到容器集合的转换函数中?很好!但是我宁愿使用transform
函数进行Tiles
收集。请注意,这里的主要任务是找出特定磁贴在其父级磁贴
列表中的索引是什么。此外,您可以概括上述解决方案(但我认为正确使用变换函数可能是更好的主意)。在这种情况下,您还需要设置类似于\u parent
(用于辅助集合中的平铺副本)的字段,并更仔细地处理观察者回调。@d\u这里是我所说的示例实现:。我希望这会有用。嘿,非常感谢!!我只是尽量避免容器在瓷砖更改时失效,而不是在订单更改或添加新瓷砖时失效。明天将检查您的版本。