当订阅已经限制了数据集时,是否有必要将限制传递给数据?
Necessary to pass limit to data when subscription already limits the dataset?
在有关分页的示例中,根据应显示的结果数量,将不同的数字传递给路由。
// lib/router.js
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})
};
}
});
我想知道是否还有必要在数据属性中提供 Posts.find() 参数。这里似乎有点多余,因为 waitOn 中的订阅已经限制了我从服务器返回的数据集。我知道数据用于为我的模板的不同部分提供数据上下文。然而,在这里为 data Posts.find() 提供相同的参数似乎是多余的。我试过只使用不带参数的 Posts.find() 并且它有效。
另外,我想知道访问路由器中所有数据的方法是什么?我正在访问单个路由之外的 Posts 集合,我认为我能够访问 Posts 集合中的所有数据。但是,它返回的计数为 0。
// lib/router.js
var totalPostsCount = Posts.find().count()
console.log('total count?')
console.log(totalPostsCount) // output 0
PostsListController = RouteController.extend({
template: 'postsList',
increment: 5,
postsLimit: function() {
return parseInt(this.params.postsLimit) || this.increment;
},
findOptions: function() {
return {sort: {submitted: -1}, limit: this.postsLimit()};
},
subscriptions: function() {
this.postsSub = Meteor.subscribe('posts', this.findOptions());
},
posts: function() {
// console.log("is find limited to subscriptions too??");
// console.log(Posts.find().count())
return Posts.find({}, this.findOptions());
},
data: function() {
// console.log('is data limited to this?')
// console.log(Posts.find().count())
var hasMore = this.posts().count() === this.postsLimit();
var adjustOrNot = this.posts()
if (!hasMore){
var nextPath = this.route.path({postsLimit: this.posts().count()});
}else{
var nextPath = this.route.path({postsLimit: this.postsLimit() + this.increment});
}
return {
posts: this.posts(),
ready:this.postsSub.ready(),
nextPath: hasMore ? nextPath : null
};
}
});
//...
Router.route('/:postsLimit?', {
name: 'postsList'
});
编辑 1:获取所有帖子的代码:
// server
Meteor.publish('allPosts',function(){
return Posts.find({});
})
// lib/router.js
if (Meteor.isClient){
var handle = Meteor.subscribe('allPosts');
if (handle.ready()) {
// This logs the actual count of posts
console.log(Posts.find().count());
} else {
console.log('not ready yet');
}
}
这只会在控制台中输出 'not ready yet',即使页面加载完成也不会改变。
非常感谢您的帮助。
编辑 2:可能的解决方案
我尝试将反应源 ready() 包装在诸如 Tracker.autorun() 之类的计算中,现在它起作用了。
if (Meteor.isClient){
var handle = Meteor.subscribe('allPosts');
Tracker.autorun(function(){
var status = handle.ready();
if (status){
console.log(Posts.find().count())
}else{
console.log('not ready yet')
}
})
}
是的,无论您的订阅如何,您也应该将限制和其他查询选项传递给前端查询。这是因为如果您要同时激活对同一个集合的多个订阅(在大型应用程序中经常这样做),那么订阅的记录最终都会在前端的同一个 Minimongo 集合中。在这种情况下,如果您省略了查询参数,您最终会得到不可预知的结果。在 this excellent explanation. Note also that while iron:router
supports doing subscriptions in the route handlers, it's encouraged 中查看更多信息以在模板生命周期方法中处理它们。
对于您的第二个问题,Posts 集合显示为空的原因是文件顶层的代码在加载文件时立即 运行。此时集合订阅还没有加载,所以前端集合是空的。您需要在一些反应性上下文中检查订阅准备情况,例如模板助手或 Tracker.autorun
,以确保数据已加载:
var handle = Meteor.subscribe('posts');
if (handle.ready()) {
// This logs the actual count of posts
console.log(Posts.find().count());
} else {
// This logs 0 (unless there are other subscriptions to this collection)
console.log(Posts.find().count());
}
在有关分页的示例中,根据应显示的结果数量,将不同的数字传递给路由。
// lib/router.js
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})
};
}
});
我想知道是否还有必要在数据属性中提供 Posts.find() 参数。这里似乎有点多余,因为 waitOn 中的订阅已经限制了我从服务器返回的数据集。我知道数据用于为我的模板的不同部分提供数据上下文。然而,在这里为 data Posts.find() 提供相同的参数似乎是多余的。我试过只使用不带参数的 Posts.find() 并且它有效。
另外,我想知道访问路由器中所有数据的方法是什么?我正在访问单个路由之外的 Posts 集合,我认为我能够访问 Posts 集合中的所有数据。但是,它返回的计数为 0。
// lib/router.js
var totalPostsCount = Posts.find().count()
console.log('total count?')
console.log(totalPostsCount) // output 0
PostsListController = RouteController.extend({
template: 'postsList',
increment: 5,
postsLimit: function() {
return parseInt(this.params.postsLimit) || this.increment;
},
findOptions: function() {
return {sort: {submitted: -1}, limit: this.postsLimit()};
},
subscriptions: function() {
this.postsSub = Meteor.subscribe('posts', this.findOptions());
},
posts: function() {
// console.log("is find limited to subscriptions too??");
// console.log(Posts.find().count())
return Posts.find({}, this.findOptions());
},
data: function() {
// console.log('is data limited to this?')
// console.log(Posts.find().count())
var hasMore = this.posts().count() === this.postsLimit();
var adjustOrNot = this.posts()
if (!hasMore){
var nextPath = this.route.path({postsLimit: this.posts().count()});
}else{
var nextPath = this.route.path({postsLimit: this.postsLimit() + this.increment});
}
return {
posts: this.posts(),
ready:this.postsSub.ready(),
nextPath: hasMore ? nextPath : null
};
}
});
//...
Router.route('/:postsLimit?', {
name: 'postsList'
});
编辑 1:获取所有帖子的代码:
// server
Meteor.publish('allPosts',function(){
return Posts.find({});
})
// lib/router.js
if (Meteor.isClient){
var handle = Meteor.subscribe('allPosts');
if (handle.ready()) {
// This logs the actual count of posts
console.log(Posts.find().count());
} else {
console.log('not ready yet');
}
}
这只会在控制台中输出 'not ready yet',即使页面加载完成也不会改变。
非常感谢您的帮助。
编辑 2:可能的解决方案
我尝试将反应源 ready() 包装在诸如 Tracker.autorun() 之类的计算中,现在它起作用了。
if (Meteor.isClient){
var handle = Meteor.subscribe('allPosts');
Tracker.autorun(function(){
var status = handle.ready();
if (status){
console.log(Posts.find().count())
}else{
console.log('not ready yet')
}
})
}
是的,无论您的订阅如何,您也应该将限制和其他查询选项传递给前端查询。这是因为如果您要同时激活对同一个集合的多个订阅(在大型应用程序中经常这样做),那么订阅的记录最终都会在前端的同一个 Minimongo 集合中。在这种情况下,如果您省略了查询参数,您最终会得到不可预知的结果。在 this excellent explanation. Note also that while iron:router
supports doing subscriptions in the route handlers, it's encouraged 中查看更多信息以在模板生命周期方法中处理它们。
对于您的第二个问题,Posts 集合显示为空的原因是文件顶层的代码在加载文件时立即 运行。此时集合订阅还没有加载,所以前端集合是空的。您需要在一些反应性上下文中检查订阅准备情况,例如模板助手或 Tracker.autorun
,以确保数据已加载:
var handle = Meteor.subscribe('posts');
if (handle.ready()) {
// This logs the actual count of posts
console.log(Posts.find().count());
} else {
// This logs 0 (unless there are other subscriptions to this collection)
console.log(Posts.find().count());
}