Javascript 如何创建反应式&;非反应性流星模板?
我正与一个奇怪的问题作斗争。一旦文档使用某个属性更新,它就不再与发布查询匹配。Meteor将其从DOM中删除,并将其从客户端集合中删除 我需要列表保持在原位,这样用户仍然可以返回并撤消他们的选择。然而,我需要他们不显示在下一页加载 如果我将整个集合发送到客户端,然后如果它返回的结果超过0,则将reactive false设置为false,那么我可以模拟我所追求的。刷新时,仅显示未选择的列表。显然,这对性能不好 我的发布查询基本上只是过滤出正确的列表类型,并提取 在用户没有选择喜欢/不喜欢的列表中。这是在增加限制,但我做不到 它不会丢失以前选择的列表Javascript 如何创建反应式&;非反应性流星模板?,javascript,meteor,Javascript,Meteor,我正与一个奇怪的问题作斗争。一旦文档使用某个属性更新,它就不再与发布查询匹配。Meteor将其从DOM中删除,并将其从客户端集合中删除 我需要列表保持在原位,这样用户仍然可以返回并撤消他们的选择。然而,我需要他们不显示在下一页加载 如果我将整个集合发送到客户端,然后如果它返回的结果超过0,则将reactive false设置为false,那么我可以模拟我所追求的。刷新时,仅显示未选择的列表。显然,这对性能不好 我的发布查询基本上只是过滤出正确的列表类型,并提取 在用户没有选择喜欢/不喜欢的列表中
Meteor.publish('listings', function(type, limit, ulid) {
var query, options;
query = {
type: type,
completed: true,
'public': true
};
options = {
sort: {title: 1},
limit: 1000 // debugging, should be param
};
// if user is logged in, get their listing id
if (ulid) {
query.likedBy = { $ne: ulid };
query.dislikedBy = { $ne: ulid };
}
return Listings.find(query, options);
});
// client, simulates the effect I need, but doesn't work if you increase limit
Template.listings.helpers({
listings: function() {
var listType, results;
listType = Session.get('listingType');
results = Listings.find({type: listType }, {reactive: false}).fetch();
// prevents race condition where sometimes listings come through anyway
if (Meteor.user()) {
var ul = Session.get('userListing')._id;
results.likedBy = { $ne: ul };
results.dislikedBy = { $ne: ul };
}
// if results haven't arrived fetch again with reactivity
if (!results.length) {
results = Listings.find({ type: listType }).fetch();
}
// append a 'no listings avail.' card to the end of results
// If no results are found, user only sees not found card
results.push({type: 'empty'});
return results;
}
});
为了直观,每个文档一次显示一个,用户向右滑动
要获取新列表,请返回并查看/撤消旧列表
-----------------------
| |
| |-----------------| |
| | | |
| | | |
| | | |
| | listing #1 | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| |-----------------| |
| |
-----------------------
这是一个有趣的问题。您并不是真正想让模板成为被动和非被动的,而是想办法在用户“会话”期间保持某些文档的发布,即使某个字段已更改,这通常会导致文档取消发布 想到的一个解决方案是,如果在当前会话期间添加了“喜欢”或“不喜欢”,则第二次发布可以保留那些被喜欢或不喜欢的文档。两个发布可以从同一个集合发布,结果是客户端上的集合是这两个发布的联合 因此,当用户单击“喜欢”或“不喜欢”时,您会将该文档的_id添加到会话变量中,该变量是一个要保持发布的文档数组。使用deps.autorun中的订阅,您可以将此_id列表以反应方式发送到服务器,并告诉服务器在正常发布的同时发布这些文档 一个问题是,当文档从一个订阅/发布中取出并放入另一个订阅/发布时,集合中文档的顺序会发生变化。您可能需要在服务器上使用排序 Listings.find()在助手中,以防止顺序更改。另外,根据延迟,当文档从一个发布中删除并添加到另一个发布中时,列表可能仍会“闪烁” 下面是代码可能的样子:
//Server side publish
Meteor.publish('listingsForSession', function(listingIds) {
check(listingIds, [String]);
if(listingIds.length > 0){
return Listings.find({_id: {$in: listingIds}});
}
});
//Client side subscription
Deps.autorun(function () {
if(Meteor.userId()){
Meteor.subscribe("listingsForSession", Session.get("listingIdsToKeep"));
}
});
//Click handler to keep track of documents that have been liked/disliked
Template.listings.events({
'click .like, click .dislike': function(event){
event.preventDefault();
var listingId = $(event.currentTarget).data("id"); //Or however you get the document _id
var listingIdsToKeep = Session.get("listingIdsToKeep");
listingIdsToKeep.push(listingId);
Session.set('listingIdsToKeep', listingIdsToKeep);
}
});
不确定这是否是最好的解决方案,但它可以工作。太棒了!这看起来很有希望。我醒来后会试试这个。另一件我尝试过但失败的事情是在会话中创建一个单独的数组。基本上,我会观察/自动运行查询,然后将旧/新数据合并到会话变量中。然后将该会话变量输入模板。然而,我有可怕的问题保持更新。这是伟大的!保持秩序和防止闪烁的关键是在做出喜欢/不喜欢之前将id插入会话数组。事实上,在listings控制器(而不是ui事件)中,我必须在Meteor-like方法周围包装一个带有0的setTimeout,以使其等待。太棒了,谢谢@Dysko!这与问题无关,但我注意到在您提供的代码中,您的助手正在使用find().fetch()并返回结果数组。我假设您正在模板中使用{{{each listings}}块来呈现每个项目。如果您可以绕过推送空的“no items card”的需要,那么最好返回从查找中得到的集合游标,而不是获取数组并返回数组。当你给{{{#each}}块一个集合游标时,Meteor会更聪明地只重新呈现改变的项目,而不是数组中的每个项目。谢谢你的提示!现在我想起来了,我应该能够在模板中通过在
每个
块之后添加一个节点来实现这一点。这样,滑动插件的末端仍然有一个额外的,Meteor不会删除它。