【问题标题】:Better Pattern for Filtering Collections过滤集合的更好模式
【发布时间】:2014-06-23 22:17:19
【问题描述】:

我有一个名为 Games 的集合,我希望用户使用复选框过滤集合。每次选中/取消选中复选框时,都会调用流星订阅以显示适当的Games

以下是订阅的示例(不是正确的 mongo 代码):

{region: ['east','west','eu'], skill: ['casual','amatuer','pro'], gamemode: ['ctf','dm','etc']}

在这个特定的游戏中,您可以按地区、技能和游戏模式进行过滤,每个都有多种组合。

编辑:

我需要创建适当的选择器,具体取决于选中的复选框。

首先,我为每个组选中选中的复选框,然后将它们放入一个数组中,然后将该数组设置为会话变量。

// Gamemode Group
'click .mode input[type=checkbox]': function(ev, tpl) {
    var mode = tpl.$('.mode input:checked').map(function () {
        return $(this).val();
    });

    var modeArray = $.makeArray(mode);
    Session.set('dotaMode', modeArray);
    returnFilterQuery();
},

然后我将检查每个组数组以查看它们是否已填充,如果已填充,则将它们添加到我将传递给订阅的最终选择器 (query)。我的问题是我必须检查每个可能的场景,除了if 语句之外什么都没有,一旦我开始添加更多组(游戏模式、区域、技能等)进行搜索,就会有更多的组合。

function returnFilterQuery(){
    //check all fields and create a query object
    var query = { game: 'dota' };
    var gamemode = Session.get('dotaMode');
    var region = Session.get('dotaRegion');
    var skill = Session.get('dotaSkill');

    // if no region or skill is selected, show user all
    if (region.length && skill.length && gamemode.length) {
        query.region = { $in: region };
        query.skill = { $in: skill };
        query.gamemode = { $in: gamemode };
    } else if (region.length && !skill.length && gamemode.length) {
        query.region = { $in: region };
        query.gamemode = { $in: gamemode };
    } else if (!region.length && skill.length && gamemode.length) {
        query.skill = { $in: skill };
        query.gamemode = { $in: gamemode };
    } else if (!region.length && !skill.length && gamemode.length) {
        query.gamemode = { $in: gamemode };
    } else if (region.length && skill.length && !gamemode.length) {
        query.region = { $in: region };
        query.skill = { $in: skill };
    } else if (region.length && !skill.length && !gamemode.length) {
        query.region = { $in: region };
    } else if (!region.length && skill.length && !gamemode.length) {
        query.skill = { $in: skill };
    }

    return Session.set('dotaFilter', query);
};

希望这一切都有意义。我确信必须有更好的方法,我只是现在无法想到一些事情。谢谢。

【问题讨论】:

  • 这感觉与this question 非常相似。我的回答是将选择器传递给发布函数——这在这里也可能是合适的。
  • @DavidWeldon 我的问题不一定是发布/订阅,而是更多关于生成正确选择器的问题,具体取决于选中的复选框。我将编辑我的原始帖子,以更详细地解释我正在尝试做的事情。

标签: mongodb meteor


【解决方案1】:

由于引用了 DotA,我感到特别受到启发来回答这个问题。 :)

因此,如果我正确理解了问题,您应该不需要检查每个组合,而是根据三个会话变量的内容向query 对象重复添加键。我认为以下在逻辑上等同于您上面的returnFilterQuery 函数。

var returnFilterQuery = function() {
  var query = {game: 'dota'};

  var modifyQueryIfArray = function(key, sessionKey) {
    var value = Session.get(sessionKey);
    if (!_.isEmpty(value))
      query[key] = {$in: value};
  };

  modifyQueryIfArray('gamemode', 'dotaMode');
  modifyQueryIfArray('region', 'dotaRegion');
  modifyQueryIfArray('skill', 'dotaSkill');

  return Session.set('dotaFilter', query);
};

请注意,如果会话变量不是数组,isEmpty 可能比 length 更安全。

【讨论】:

  • 非常感谢!效果很好,而且添加额外的游戏和过滤选项更容易!
猜你喜欢
  • 2023-03-10
  • 1970-01-01
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 2019-04-12
  • 1970-01-01
  • 2017-02-15
相关资源
最近更新 更多