Dopdownlist 正在填充有限的值而不是来自总集合的值
Dopdownlist is being populated with limited values instead of values from total collection
我有一个下拉列表作为过滤器,然后有一个帖子总数限制一次只能显示 4 个,除非单击加载更多按钮以显示另外 4 个记录。问题是下拉列表也仅从前 4 条记录加载值。
这是我的出版物
Meteor.publish('allJobs', function(limit){
if(!limit){
return Jobs.find();
}
return Jobs.find({}, {limit: limit});
});
我在控制器中的主要订阅
waitOn: function() {
return Meteor.subscribe("allJobs",4,this.findOptions());
},
模板的助手
Template.jobsList.helpers({
'allJobs': function(){
var filter ={};
var category = Template.instance().selectedCategory.get();
var city = Template.instance().selectedCity.get();
var jtype = Template.instance().selectedJobType.get();
if(jtype)
filter.jtype = jtype;
if(city)
filter.city = city;
if(category)
filter.ccategory = category;
return Jobs.find(filter);
},
'moreResults': function(){
return !(Jobs.find().count() < Session.get("jobsLimit"));
}
});
Template.jobsList.onRendered(function(){
Session.setDefault("jobsLimit", 4);
this.autorun(function(){
Meteor.subscribe("allJobs", Session.get("jobsLimit"));
});
});
我尝试为此再订阅一次,但没有成功。请帮助提供最佳解决方案。
模板
<template name="jobsList">
<div class="col s12 filter-holder">
<div class="col m4 s4 filter-box">
{{> categoryFilter}}
</div>
<div class="col m4 s4 filter-box">
{{> cityFilter}}
</div>
</div>
<div class="col s12">
<ul class="collection" id="listings">
{{#each allJobs}}
<li>
{{> jobItem}}
</li>
{{/each}}
</ul>
{{#if moreResults}}
<button class="load-more" id="showMoreResults" type="submit">Load More
<i class="mdi-content-send right"></i>
</button>
{{/if}}
</div>
</template>
请帮助我陷入这种情况
已更新 js 文件
var limit = new ReactiveVar;
var filterAndLimitResults = function (cursor, limit) {
if (!cursor) {
return [];
}
var chosenCategory = limit.get("chosenCategory");
var raw = cursor.fetch();
// filter category
var filtered = [];
if (!chosenCategory || chosenCategory == "") {
filtered = raw;
} else {
filtered = _.filter(raw, function (item) {
return item.category === chosenCategory;
});
}
if (limit) {
filtered = _.first(filtered, limit);
}
return filtered;
};
//模板创建函数
Template.jobsList.onCreated(function(){
limit.set(4);
limit.set("chosenCategory");
});
// 模板辅助函数
Template.jobsList.helpers({
"displayedJobs": function() {
return filterAndLimitResults(Jobs.find(), (limit.get()));
},
'moreResults': function(){
return !(Jobs.find().count() < limit.get());
}
});
下拉点击过滤
在渲染函数中声明
Template.jobsList.onRendered(function(){
limit.set(4);
chosenCategory.set();
});
而点击事件如下
"click .categoryselection": function(e, t){
e.preventDefault();
chosenCategory.set(chosenCategory.get());
回复您的评论的简短回答。如果你想过滤集合,你需要在服务器 AND 客户端上进行。否则正如我之前所说,您的客户端数据库将仅包含前 4 个自然顺序记录 - 您当前正在执行的过滤仅查看这 4 个记录。您想要发布与过滤器匹配的任何内容(达到限制),以便在客户端上可用。您在客户端再次过滤以确保您获得正确的文档。
TL;DR:
Meteor.publish('allJobs', function(limit){
if(!limit){
return Jobs.find();
}
return Jobs.find({}, {limit: limit});
});
应该是这样的
Meteor.publish('allJobs', function(limit, filter){
if(!filter) {
filter = {};
}
if(!limit) {
return Jobs.find(filter);
}
return Jobs.find(filter, {limit: limit});
});
还要确保行中的 this.findOptions()
;
Meteor.subscribe("allJobs",4,this.findOptions());
实际上返回的是过滤器对象,否则您仍然会遇到同样的问题。
首先,为了确保我理解您的情况,让我重新表述一下:
您有一组要使用类别(为每个文档存储在专用字段中)进行排序的文档。
一方面,您想使用集合文档中所有可能的类别构建一个下拉列表,以便允许用户select 一个类别并过滤结果。
另一方面,您希望一次只显示 4 个项目。这 4 个显示的项目(以及可以在它们之后加载的项目)是匹配过滤类别的前 4 个项目。
您选择 4 乘 4 显示项目只是为了避免在用户界面中放置太多内容
我给你的建议是:
您不需要限制使用出版物加载的项目。首先,它会减慢您的用户界面(您必须每次都向服务器请求),其次您将无法实现您可能已经注意到的过滤。
一步一步:
- 用简单的
return Jobs.find();
替换您的出版物 这里不是您需要进行过滤或强制限制显示项目数量的地方。这意味着现在,如果您添加 console.table(Job.find().fetch());
,您将获得所有可用的职位以供显示。这将使下拉列表显示您需要的所有类别,使用 _.uniq
我建议您在 中使用
您创建一个会话变量(或使用 ReactiveVar
的反应变量)来存储您的当前限制。您在模板 rendered
函数中启动它,甚至在模板 created
函数中启动它:pageSession.set("limit", 4);
并根据需要在 "load more" 按钮单击事件中修改它。
您将在客户端代码中创建一个函数以执行您的规则(限制显示的项目数量和类别过滤)。我们称它为 filterAndLimitResults
。您用来 return 显示作业的助手将变成这样:
"displayedJobs": function() {
return filterAndLimitResults(Job.find());
}
您不需要 "moreResults" 帮手。摆脱那个。您只需在单击更新 ReactiveVar
的更多结果按钮时创建一个事件
Template.jobsList.events({
"click #showMoreResults": function(e, t) {
e.preventDefault();
limit.set(limit.get()+4);
},
您创建一个会话变量(或使用 ReactiveVar
的反应变量)以存储您当前 selected 类别。您在模板 rendered
函数中启动它,甚至在模板 created
函数中启动它:pageSession.set("chosenCategory", "");
并根据需要在下拉项单击事件中修改它。
您现在需要写下您的 filterAndLimitResults
。这是一个未经测试的例子:
var limit = new ReactiveVar;
var chosenCategory= new ReactiveVar;
var filterAndLimitResults = function (cursor) {
if (!cursor) {
return [];
}
var raw = cursor.fetch();
var currentChosenCategory = chosenCategory.get();
// filter category
var filtered = [];
if (!currentChosenCategory || currentChosenCategory == "") {
filtered = raw;
} else {
filtered = _.filter(raw, function (item) {
return item.category === currentChosenCategory ;
});
}
var currentLimit =limit.get();
// enforce your limit
if (currentLimit ) {
filtered = _.first(filtered, currentLimit );
}
return filtered;
};
你应该可以开始了 :-) 你几乎可以立即得到结果,而且它们是反应性的。
ps:遵循相同的逻辑,您也可以按城市过滤 and/or 任何其他字段。
我有一个下拉列表作为过滤器,然后有一个帖子总数限制一次只能显示 4 个,除非单击加载更多按钮以显示另外 4 个记录。问题是下拉列表也仅从前 4 条记录加载值。
这是我的出版物
Meteor.publish('allJobs', function(limit){
if(!limit){
return Jobs.find();
}
return Jobs.find({}, {limit: limit});
});
我在控制器中的主要订阅
waitOn: function() {
return Meteor.subscribe("allJobs",4,this.findOptions());
},
模板的助手
Template.jobsList.helpers({
'allJobs': function(){
var filter ={};
var category = Template.instance().selectedCategory.get();
var city = Template.instance().selectedCity.get();
var jtype = Template.instance().selectedJobType.get();
if(jtype)
filter.jtype = jtype;
if(city)
filter.city = city;
if(category)
filter.ccategory = category;
return Jobs.find(filter);
},
'moreResults': function(){
return !(Jobs.find().count() < Session.get("jobsLimit"));
}
});
Template.jobsList.onRendered(function(){
Session.setDefault("jobsLimit", 4);
this.autorun(function(){
Meteor.subscribe("allJobs", Session.get("jobsLimit"));
});
});
我尝试为此再订阅一次,但没有成功。请帮助提供最佳解决方案。
模板
<template name="jobsList">
<div class="col s12 filter-holder">
<div class="col m4 s4 filter-box">
{{> categoryFilter}}
</div>
<div class="col m4 s4 filter-box">
{{> cityFilter}}
</div>
</div>
<div class="col s12">
<ul class="collection" id="listings">
{{#each allJobs}}
<li>
{{> jobItem}}
</li>
{{/each}}
</ul>
{{#if moreResults}}
<button class="load-more" id="showMoreResults" type="submit">Load More
<i class="mdi-content-send right"></i>
</button>
{{/if}}
</div>
</template>
请帮助我陷入这种情况
已更新 js 文件
var limit = new ReactiveVar;
var filterAndLimitResults = function (cursor, limit) {
if (!cursor) {
return [];
}
var chosenCategory = limit.get("chosenCategory");
var raw = cursor.fetch();
// filter category
var filtered = [];
if (!chosenCategory || chosenCategory == "") {
filtered = raw;
} else {
filtered = _.filter(raw, function (item) {
return item.category === chosenCategory;
});
}
if (limit) {
filtered = _.first(filtered, limit);
}
return filtered;
};
//模板创建函数
Template.jobsList.onCreated(function(){
limit.set(4);
limit.set("chosenCategory");
});
// 模板辅助函数
Template.jobsList.helpers({
"displayedJobs": function() {
return filterAndLimitResults(Jobs.find(), (limit.get()));
},
'moreResults': function(){
return !(Jobs.find().count() < limit.get());
}
});
下拉点击过滤
在渲染函数中声明
Template.jobsList.onRendered(function(){
limit.set(4);
chosenCategory.set();
});
而点击事件如下
"click .categoryselection": function(e, t){
e.preventDefault();
chosenCategory.set(chosenCategory.get());
回复您的评论的简短回答。如果你想过滤集合,你需要在服务器 AND 客户端上进行。否则正如我之前所说,您的客户端数据库将仅包含前 4 个自然顺序记录 - 您当前正在执行的过滤仅查看这 4 个记录。您想要发布与过滤器匹配的任何内容(达到限制),以便在客户端上可用。您在客户端再次过滤以确保您获得正确的文档。
TL;DR:
Meteor.publish('allJobs', function(limit){
if(!limit){
return Jobs.find();
}
return Jobs.find({}, {limit: limit});
});
应该是这样的
Meteor.publish('allJobs', function(limit, filter){
if(!filter) {
filter = {};
}
if(!limit) {
return Jobs.find(filter);
}
return Jobs.find(filter, {limit: limit});
});
还要确保行中的 this.findOptions()
;
Meteor.subscribe("allJobs",4,this.findOptions());
实际上返回的是过滤器对象,否则您仍然会遇到同样的问题。
首先,为了确保我理解您的情况,让我重新表述一下: 您有一组要使用类别(为每个文档存储在专用字段中)进行排序的文档。
一方面,您想使用集合文档中所有可能的类别构建一个下拉列表,以便允许用户select 一个类别并过滤结果。
另一方面,您希望一次只显示 4 个项目。这 4 个显示的项目(以及可以在它们之后加载的项目)是匹配过滤类别的前 4 个项目。
您选择 4 乘 4 显示项目只是为了避免在用户界面中放置太多内容
我给你的建议是:
您不需要限制使用出版物加载的项目。首先,它会减慢您的用户界面(您必须每次都向服务器请求),其次您将无法实现您可能已经注意到的过滤。
一步一步:
- 用简单的
return Jobs.find();
替换您的出版物 这里不是您需要进行过滤或强制限制显示项目数量的地方。这意味着现在,如果您添加console.table(Job.find().fetch());
,您将获得所有可用的职位以供显示。这将使下拉列表显示您需要的所有类别,使用_.uniq
我建议您在 中使用
您创建一个会话变量(或使用
ReactiveVar
的反应变量)来存储您的当前限制。您在模板rendered
函数中启动它,甚至在模板created
函数中启动它:pageSession.set("limit", 4);
并根据需要在 "load more" 按钮单击事件中修改它。您将在客户端代码中创建一个函数以执行您的规则(限制显示的项目数量和类别过滤)。我们称它为
filterAndLimitResults
。您用来 return 显示作业的助手将变成这样:"displayedJobs": function() { return filterAndLimitResults(Job.find()); }
您不需要 "moreResults" 帮手。摆脱那个。您只需在单击更新 ReactiveVar
的更多结果按钮时创建一个事件Template.jobsList.events({ "click #showMoreResults": function(e, t) { e.preventDefault(); limit.set(limit.get()+4); },
您创建一个会话变量(或使用
ReactiveVar
的反应变量)以存储您当前 selected 类别。您在模板rendered
函数中启动它,甚至在模板created
函数中启动它:pageSession.set("chosenCategory", "");
并根据需要在下拉项单击事件中修改它。您现在需要写下您的
filterAndLimitResults
。这是一个未经测试的例子:var limit = new ReactiveVar; var chosenCategory= new ReactiveVar; var filterAndLimitResults = function (cursor) { if (!cursor) { return []; } var raw = cursor.fetch(); var currentChosenCategory = chosenCategory.get(); // filter category var filtered = []; if (!currentChosenCategory || currentChosenCategory == "") { filtered = raw; } else { filtered = _.filter(raw, function (item) { return item.category === currentChosenCategory ; }); } var currentLimit =limit.get(); // enforce your limit if (currentLimit ) { filtered = _.first(filtered, currentLimit ); } return filtered; };
你应该可以开始了 :-) 你几乎可以立即得到结果,而且它们是反应性的。
ps:遵循相同的逻辑,您也可以按城市过滤 and/or 任何其他字段。