当前位置:K88软件开发文章中心编程语言JavaScriptMeteor → 文章内容

Meteor 分页

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 15:29:03

由 北公爵无欢 创建,路飞 最后一次修改 2016-08-12 分页Microscope 的功能看起来不错。我们可以想象当它 release 之后会很受欢迎。因此我们需要考虑一下随着新帖子越来越多所带来的性能问题。之前我们说过客户端集合会包含服务器端数据的一个子集。我们在帖子和评论集合已经实现了这些。但是现在,如果我们还是一口气发布所有帖子给所有的连接用户。当有成千上万的新帖子时,这会带来一些问题。为了解决这些,我们需要给帖子分页。添加更多的帖子首先是我们的初始化数据,我们需要添加足够的帖子来使分页有意义:// Fixture dataif (Posts.find().count() === 0) { //... Posts.insert({ title: 'The Meteor Book', userId: tom._id, author: tom.profile.name, url: 'http://themeteorbook.com', submitted: new Date(now - 12 * 3600 * 1000), commentsCount: 0 }); for (var i = 0; i < 10; i++) { Posts.insert({ title: 'Test post #' + i, author: sacha.profile.name, userId: sacha._id, url: 'http://google.com/?q=test-' + i, submitted: new Date(now - i * 3600 * 1000), commentsCount: 0 }); }}运行完 meteor reset 重启你的 app, 你会看到如下:无限分页我们将实现一个"无限"的分页。意思是在第一屏显示 10 条帖子和一个在底部显示的 "load more" 链接。点击 "load more" 链接再加载另外 10 条帖子,诸如此类无限的加载。这意味着我们只用一个参数来实现分页,控制在屏幕上显示帖子的数量。现在需要一个方法告诉服务器端返回给客户端帖子的数量。这些发生在路由订阅帖子的过程,我们会利用路由来实现分页。最简单的限制返回帖子数量的方式是将返回数量加到 URL 中,如 http://localhost:3000/25。使用 URL 记录数量的另一个好处是,如果不小心刷新了页面,还会返回 25 条帖子。为了恰当的实现分页,我们需要修改帖子的订阅方法。就像我们之前在评论那章做的,我们需要将订阅部分的代码从 router 级变为 route 级。这个改变内容会比较多,通过代码可以看的比较清楚。首先,停止 Router.configure() 代码块中的 posts 订阅。即删除 Meteor.subscribe('posts'),只留下 notifications 订阅:Router.configure({ layoutTemplate: 'layout', loadingTemplate: 'loading', notFoundTemplate: 'notFound', waitOn: function() { return [Meteor.subscribe('notifications')] }});我们在路由路径中加入参数 postsLimt。 参数后面的 ? 表示参数是可选的。这样路由就能同时匹配 http://localhost:3000/50 和 http://localhost:3000。//...Router.route('/:postsLimit?', { name: 'postsList',});//...需要注意每个路径都会匹配路由 /:parameter?。因为每个路由都会被检查是否匹配当前路径。我们要组织好路由来减少特异性。话句话说,更特殊的路由会优先选择,例如:路由 /posts/:_id 会在前面,而路由 postsList 会放到路由组的最后,因为它太泛泛了可以匹配所有路径。是时候处理难题了,处理订阅和找到正确的数据。我么需要处理 postsLimit 参数不存在的情况。我们给它一个默认值 5, 这样我们能更好的演示分页。//...Router.route('/:postsLimit?', { name: 'postsList', waitOn: function() { var limit = parseInt(this.params.postsLimit) || 5; return Meteor.subscribe('posts', {sort: {submitted: -1}, limit: limit}); }});//...你注意到我们在订阅 posts 时传了一个 js 对象 ({sort: {submitted: -1}, limit: postsLimit}), 这个 js 对象会作为服务器端查询方法 Posts.find() 的可选参数。下面是服务器端的实现代码:Meteor.publish('posts', function(options) { check(options, { sort: Object, limit: Number }); return Posts.find({}, options);});Meteor.publish('comments', function(postId) { check(postId, String); return Comments.find({postId: postId});});Meteor.publish('notifications', function() { return Notifications.find({userId: this.userId});});传递参数我们的订阅代码告诉服务器端,我们信任客户端传来的 JavaScript 对象 (在我们的例子中是 {limit: postsLimit}) 作为 find() 方法的 options 参数。这样我们能通过 browser consle 来传任何 option 对象。在我们的例子中,这样没什么害处,因为用户可以做的无非是改变帖子顺序,或者修改 limit 值(这是我们想让用户做的)。但是对于一个 real-world app 我们必须做必要的限制!幸好通过 check() 方法我们知道用户不能偷偷加入额外的 options (例如 fields, 在某些情况下需要对外暴露 ducoments 的私有数据)。然而,更安全的做法是传递单个参数而不是整个对象,通过这样确保数据安全:Meteor.publish('posts', function(sort, limit) { return Posts.find({}, {sort: sort, limit: limit});});现在我们在 route 级订阅数据,同样的我们可以在这里设置数据的 context。我们要偏离一下之前的模式,我们让 data 函数返回一个 js 对象而不是一个 cursor。 这样我们可以创建一个命名的数据 context。我们称之为 posts。这意味着我们的数据 context 将存在于 posts 中,而不是简单的在模板中隐式的存在于 this 中。除去这一点,代码看起来很相似://...Router.route('/:postsLimit?', { name: 'postsList', waitOn: function() { var limit = parseInt(this.params.postsLimit) || 5; return Meteor.subscribe('posts', {sort: {submitted: -1}, limit: limit}); }, data: function() { var limit = parseInt(this.params.postsLimit) || 5; return { posts: Posts.find({}, {sort: {submitted: -1}, limit: limit}) }; }});//...因为我们在 route 级设置数据 context, 现在我们可以去掉在 posts_list.js 文件中 posts 模板的帮助方法。我们的数据 context 叫做 posts (和 helper 同名),所以我们甚至不需要修改 postsList 模板!下面是我们修改过的 router.js 代码:Router.configure({ layoutTemplate: 'layout', loadingTemplate: 'loading', notFoundTemplate: 'notFound', waitOn: funct

[1] [2] [3]  下一页


Meteor 分页