在Meteor中拆分组

时间:2015-07-04 14:56:09

标签: javascript node.js mongodb meteor

我的收藏集Rows包含字段group1group2group3,这些都是数字。

我可以使用

集合
Template.tplName.helpers({
  rows: function() {
    return Rows.find({});
  },
});

<template name="tplName">
  {{#each rows}}
    {{group1}}, {{group2}}, {{group3}}
  {{/each}}
</template>

但不是在一个页面上打印所有行,而是必须将它们分成多个页面。

在第一页上,我想打印所有唯一group1值的列表。如果我点击group1号码,我将转到另一个页面,其中包含我刚刚点击的group2group1个唯一group2个值的列表。点击group3号码后,我将转到一个新页面,其中包含我已点击的group1号码和group2号码的所有唯一group1, group2, group3, amount ======================= 1, 1, 1, 200 1, 1, 2, 300 1, 2, 1, 250 1, 2, 2, 220 1, 2, 3, 200 2, 1, 1, 305 2, 1, 1, 290 值列表。

如果我的数据集是

<li><a href="?">1</a></li>
<li><a href="?">2</a></li>

我希望第一页列出

<li><a href="?">1</a></li>
<li><a href="?">2</a></li>

如果我在第一页上点击1,我希望下一个第二页列出

<li><a href="?">1</a></li>
<li><a href="?">2</a></li>
<li><a href="?">3</a></li>

如果我在第二页上点击2,我希望下一个第三页列出

var rows = Rows.find().fetch(); // fetch all rows
var group1Numbers = _.pluck(rows, "group1"); // get all group1 numbers
var group1NumbersUnique _.uniq(group1Numbers); // get all unique group1 numbers

我希望我能做的事情是可以理解的: - )

我想我必须检索整个集合,然后将其过滤掉。

group1

给我唯一的group1号码。现在我需要一些方法来告诉路由器(或其他东西)我点击了rows = Rows.find({group1: ?})个号码之一以及_.pluck()的下一个路线,而不是显示所有行。

但如果我使用<template name="groupList"> {{#each groups}} <p><a href="?">{{name}}</a> (amount: {{amount}})</p> {{/each}} </template> ,我会将组号作为列表 - 这可能是删除重复项的最简单方法,但我也需要总和。

我想我可以创建一个模板

this.route('groupListFirst', {
  path: '/groups',
  template: 'groupList',
  waitOn: function() {
    return [
      subs.subscribe('groups'),
    ]
  },
  data: function() {
    var group1List = [
      {
        name: "1",
        amount: 200 + 300 + 250 + 220 + 200,
      },
      {
        name: "2",
        budget: 305 + 290,
      },
    ];

    return {
      groups: group1List,
    }
  },
});

和路线

this.route('groupListSecond', {
  path: '/groups',
  template: 'groupList',
  waitOn: function() {
    return [
      subs.subscribe('groups'),
    ]
  },
  data: function() {
    var group2List = [
      {
        name: "1",
        amount: 200 + 300,
      },
      {
        name: "2",
        budget: 250 + 220 + 200,
      },
    ];

    return {
      groups: group2List,
    }
  },
});
单击其中一个group1链接后,

和一个新路由处于活动状态,显示属于所单击的group1链接的所有group2对象。 因此,如果用户点击组1链接中的“1”,则可能类似于

this.route('groupListThird', {
  path: '/groups',
  template: 'groupList',
  waitOn: function() {
    return [
      subs.subscribe('groups'),
    ]
  },
  data: function() {
    var group3List = [
      {
        name: "1",
        amount: 200,
      },
    ];

    return {
      groups: group3List,
    }
  },
});

如果用户在group2链接中进一步单击1,则为

AllowOverride All

这些路由是手动创建的,因为我不知道如何自动执行此操作并注册用户单击的链接,并仅显示与该组相关的对象。

我想这应该是从集合中完成的,每个文档中都有多个组号,但如果我不能用这个结构,我将不得不将每个组分成不同的集合。

1 个答案:

答案 0 :(得分:1)

有很多部分的长问题!所以这将是一个很长的答案,有很多部分。忍受我:

第1部分:聚合

不,Meteor(尚未)支持mongo级聚合。有这样的包(在服务器上)但不是客户端迷你mongo。所以你是正确的,你需要拉自己的所有记录并自己做(现在)。但是,您还提到要对数据求和(我认为这是基于会计的评论),因此_.pluck()不够好。也许您可以在_.groupBy()中使用_.reduce()_.map() - 也许是这样的:

var group1Totals = _.map(_.groupBy(rows, "group1"), function(documents, key) {
  return {groupId: key,
          total: _.reduce(documents, function(acc, doc) {
                   return acc += doc.amount;
                 }, 0)};
};

这应该为您提供一个具有group1Totalsgroup1属性的新对象数组(称为total)。这足以作为模板助手返回(Meteor将遍历数组以及{{#each}}块内的游标)。您可以稍后重复使用此代码,仅获取第2组的总计,但不是从所有内容开始(rows),您可以使用_.groupBy()将过滤后的列表传递到_.filter()并进行分组由“group2”。

第2部分:路由

Iron Router允许设置parameters to be passed以及数据上下文。您需要定义包含参数的路由,然后设置链接以传递这些参数。同样,您的路线示例可能是:

Router.route('/group1/:groupId', {
  data: function() {
    var groupId = this.params.groupId;
    return Rows.find({group1: groupId});
  }
});

这会将模板的数据上下文(this)设置为您选择的行的子集。但是,您还需要确保链接使用正确的参数调用路由。 Iron Router还为此提供了一个内置帮助器pathFor,您可以在模板中使用这样的帮助器(使用上面定义的结构):

<template name="groupList">
  {{#each groups}}
    <p>
      <a href="{{pathFor route='group1' groupId=groupId}}">
        {{name}}
      </a>
      (amount: {{total}})
    </p>
  {{/each}}
</template>

然后,您应该为三组中的每一组重复此操作(进行适当的调整)。请记住,第2组需要在其.find()选项中包含 组1和组2,因此您可能需要两个路由参数。

尾注

鉴于您目前的结构,这可能是最简单的方法。我不确定非正规化是否适用于会计系统。或者甚至使用NoSQL!但是,我会假设你使用它来报告,而不是记录。这里的解决方案是严格的3组方法,其他组需要手动添加。您可以更加动态地执行操作,但您当前的数据结构并不适合这种情况。您可能需要查看层次关系和节点与叶结构。远远超出了这个问题的范围!

我认为这是你需要/要求的一切。