我正在研究使用Sessions定制分页的Meteor项目。呈现所述项目内容的模板使用ellipsis.js和highlight.js来进行一些DOM格式化。代码看起来像这样:
if (Meteor.isClient) {
Meteor.startup(function () {
Session.setDefault("homePageSize", 10);
Session.setDefault("homePageStart", 0);
});
}
Template.home.articlesPaginated = function() {
return Articles.find({published: true}, {sort: {post_date: -1}, skip: Session.get("homePageStart"), limit: Session.get("homePageSize")});
}
Template.home.rendered = function() {
// Setup ellipsis
$('.ellipsis').dotdotdot({
ellipsis: '...',
wrap: 'word',
fallbackToLetter: true,
after: $('a.blog_continue')
});
// Setup highlight.js
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
}
Template.home.events({
'click .next': function(event) {
var offset = Session.get("homePageStart") + Session.get("homePageSize");
if (offset < 0) {
offset = 0;
}
Session.set("homePageStart", offset);
},
'click .prev': function(event) {
var offset = Session.get("homePageStart") - Session.get("homePageSize");
if (offset < 0) {
offset = 0;
}
Session.set("homePageStart", offset);
}
});
分页工作得很好,但是一旦模板重新渲染,我就会松开所有的ellipsis.js和highlight.js格式。我知道明显的原因是DOM已经改变,并且因为Template.render只在前面运行一次,并且在模板重新渲染时没有发生DOM更新没有被应用。那么,在模板完成后触发ellipsis.js和highlight.js的最佳方法是什么,以便每次模板重新渲染时都会重新调用它?
答案 0 :(得分:2)
基本上,您需要监听Articles
集合中的更改,该集合是服务器数据库的客户端子集,其被剪裁为仅包含当前可见的分页文章。
当您检测到文章子集中的更改时,您需要重新启动ellipsis.js
和highlight.js
的初始化。
您可以按照以下方式重新组织代码:
首先,我们将游标声明定义为一个单独的函数,因为我们需要使用它两次:
function articlesPaginated(){
return Articles.find({
published: true
}, {
sort: {
post_date: -1
},
skip: Session.get("homePageStart"),
limit: Session.get("homePageSize")
});
}
Template.home.helpers({
articlesPaginated:articlesPaginated
});
然后在rendered
回调中,我们需要设置一个依赖于此游标的反应计算,因此每当文章子集更新到新页面时,我们的计算将重新运行。
但是我们需要注意,我们在home模板上定义的帮助器返回相同的游标,因此它将被无效并在同一时间触发DOM刷新... JavaScript是单线程的{{1} } manual指出并发无效计算的执行顺序是不可预测的。
所以我们不能只是在计算中触发省略号/突出显示初始化代码,因为这个设置代码假定DOM已准备就绪,但是在这个精确的时刻我们不知道DOM操作是否刚刚发生或将要发生紧接着。
幸运的是,有一个Tracker.Computation
方法允许我们在并发计算完成后执行代码,因此我们确信到那时DOM状态是正常的。
了解了所有这些含义之后,我们可以编写以下渲染回调:
Tracker.afterFlush
答案 1 :(得分:1)
如果您可以将Articles
放入另一个模板,则可以在插入时单独应用格式。
Template.article.rendered = function () {
// Setup ellipsis
this.$('.ellipsis').dotdotdot({
ellipsis: '...',
wrap: 'word',
fallbackToLetter: true,
after: $('a.blog_continue')
});
// Setup highlight.js
this.$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
};
假设您的模板看起来像这样。
<template name="home">
...
{{#each articlesPaginated}}
{{> article}}
{{/each}}
{{> paginationControls}}
...
</template>
这样做的另一个好处是可以将格式设置为文章,而不是整个DOM。