正在使用有限值而不是来自总集合的值来填充Dopdownlist

时间:2015-06-14 12:01:13

标签: javascript meteor meteor-helper

我有一个下拉列表作为过滤器,然后有总帖子,限制一次只显示4个,除非点击加载更多按钮显示另外4个记录。问题是dropdownlist也只从前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());

2 个答案:

答案 0 :(得分:1)

首先,为了确保我理解你的情况,让我重新说一下: 您有一组文档要使用类别(在专用字段中为每个文档存储)进行排序。

一方面,您希望使用收集文档中所有可能的类别构建下拉列表,以便用户选择一个类别并过滤结果。

另一方面,您希望一次只显示4个项目。这4个显示的项目(以及可以在其后加载的项目)是与过滤类别匹配的4个第一项。

您选择显示4×4项目只是为了避免在用户界面中放入太多内容

我建议你:

您无需使用出版物限制加载的项目。首先,它会降低您的用户界面速度(您每次都必须向服务器请求),其次您无法实现过滤,因为您可能已经注意到了。

一步一步:

  1. 使用简单的return Jobs.find();替换您的出版物。这不是您需要对显示的项目数进行过滤或强制限制的地方。这意味着现在,如果添加console.table(Job.find().fetch());,您将获得所有可用的作业以供显示。这将使下拉列表显示您需要的所有类别,使用_.uniq我建议您在your precedent question中使用
  2. 您可以使用ReactiveVar创建一个Session变量(或一个反应变量)来存储您的当前限制。您可以在模板rendered函数中创建它,甚至可以在模板created函数pageSession.set("limit", 4);中启动它,然后在“加载更多”按钮单击事件中根据需要对其进行修改。

  3. 您将在客户端代码中创建一个函数,以强制执行规则(限制显示的项目编号和分类过滤)。我们称之为filterAndLimitResults。用于返回显示作业的助手将变为如下所示:

    "displayedJobs": function() { return filterAndLimitResults(Job.find()); }

  4. 您不需要“moreResults”帮助器。摆脱它。您只需在更新ReactiveVar

    的更多结果按钮上创建一个事件

    Template.jobsList.events({ "click #showMoreResults": function(e, t) { e.preventDefault(); limit.set(limit.get()+4); },

  5. 您可以使用ReactiveVar创建会话变量(或反应变量),以存储您当前选择的类别。您可以在模板rendered功能中,甚至在模板created功能pageSession.set("chosenCategory", "");中启动它,然后在下拉项目点击事件中根据需要对其进行修改。

  6. 您现在需要写下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;
    };
    
  7. 你应该好好去:-)你几乎可以立即得到你的结果而且他们是被动的。

    ps:遵循相同的逻辑,您也可以毫不费力地按城市和/或任何其他字段进行过滤。

答案 1 :(得分:0)

回复你的评论的简短回答。如果要过滤集合,则需要在服务器 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());

实际上是返回过滤器对象,否则你仍会遇到同样的问题。