Dopdownlist is being populated with limited values instead of values from total collection

岁酱吖の 提交于 2019-12-02 11:55:15
Billybobbonnet

First, just to be sure I understand your situation, let me rephrase it: You have a collection of documents that you want to sort using categories (which are stored for each document in a dedicated field).

On one hand, you want to build a dropdown using all the possible categories in your collection documents in order to allow the user to select a category and filter the results.

On the other hand, you want to display only 4 items at a time. These 4 displayed items (and those who could be loaded after them) are the 4 first items matching the filtered category.

Your choice of displaying items 4 by 4 is only to avoid to put too much content in user interface

What I advise you is:

You don't need to limit the items you load using your publication. First, it will slow down your user interface (you have to request to the server each time), second you wont be able to achieve the filtering as you may have noticed.

Step by step:

  1. replace your publication with a simple return Jobs.find(); This is not the place where you need to do your filtering or enforce limit to the number of displayed items. It means that now, if you add a console.table(Job.find().fetch()); you will get all the available jobs for display. That will make the dropdown display all the categories you need, using the _.uniq I advised you to use in your precedent question
  2. You create a Session variable (or a reactive variable using ReactiveVar) to store your current limit. you initate it in your template rendered function, or even in the template created function: pageSession.set("limit", 4); and you modify it as you need in your "load more" button click event.

  3. You will create a function in your client code in order to enforce your rules (limit to displayed items number and categry filtering). Let's call it filterAndLimitResults. The helper that you use to return the displayed jobs will become something like this:

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

  4. You don't need a "moreResults" helper. Get rid of that. You just create an event on click on the more results button where you update your ReactiveVar

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

  5. You create a Session variable (or a reactive variable using ReactiveVar) in order to store your currently selected category. you initate it in your template rendered function, or even in the template created function: pageSession.set("chosenCategory", ""); and you modify it as you need in your dropdown items click event.

  6. You need now to write your filterAndLimitResults. Here is an untested example:

    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;
    };
    

And you should be good to go :-) You get your results almost instantly and they are reactive.

ps: following the same logic, you should have no trouble to filter by cities too and/or any other field.

Short answer in reply to your comment. If you want to filter the collection you need to do it on the server AND the client. Otherwise as I said before your client database will only contain the first 4 natural order records - the filtering you are currently doing is only looking at those 4 records. You want to publish anything that matches the filter (up to the limit) so that this is available on the client. You filter again on the client to ensure you're getting the correct documents.

TL;DR:

Meteor.publish('allJobs', function(limit){
  if(!limit){
    return Jobs.find();
  }
  return Jobs.find({}, {limit: limit});
});

should be something like

Meteor.publish('allJobs', function(limit, filter){
  if(!filter) {
    filter = {};
  }
  if(!limit) {
    return Jobs.find(filter);
  }
  return Jobs.find(filter, {limit: limit});
});

Also make sure that this.findOptions() in the line;

Meteor.subscribe("allJobs",4,this.findOptions());

is actually returning the filter object otherwise you'll still have the same issue.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!