我的收藏集Rows
包含字段group1
,group2
和group3
,这些都是数字。
我可以使用
集合Template.tplName.helpers({
rows: function() {
return Rows.find({});
},
});
和
<template name="tplName">
{{#each rows}}
{{group1}}, {{group2}}, {{group3}}
{{/each}}
</template>
但不是在一个页面上打印所有行,而是必须将它们分成多个页面。
在第一页上,我想打印所有唯一group1
值的列表。如果我点击group1
号码,我将转到另一个页面,其中包含我刚刚点击的group2
个group1
个唯一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
这些路由是手动创建的,因为我不知道如何自动执行此操作并注册用户单击的链接,并仅显示与该组相关的对象。
我想这应该是从集合中完成的,每个文档中都有多个组号,但如果我不能用这个结构,我将不得不将每个组分成不同的集合。
答案 0 :(得分: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)};
};
这应该为您提供一个具有group1Totals
和group1
属性的新对象数组(称为total
)。这足以作为模板助手返回(Meteor将遍历数组以及{{#each}}
块内的游标)。您可以稍后重复使用此代码,仅获取第2组的总计,但不是从所有内容开始(rows
),您可以使用_.groupBy()
将过滤后的列表传递到_.filter()
并进行分组由“group2”。
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组方法,其他组需要手动添加。您可以更加动态地执行操作,但您当前的数据结构并不适合这种情况。您可能需要查看层次关系和节点与叶结构。远远超出了这个问题的范围!
我认为这是你需要/要求的一切。