我有一个应用程序,用户可以在不同的日期时间登记。我的目标是在不同的日期显示谁在那里。
类似的东西:
11/05:Mat,Lisa,Andrew
14/05:丽莎等
我看了一下$ groupby聚合,但是对于我的简单用法来说它似乎很重要。 我也可以在db.find()。fetch()上循环,但我觉得我会失去反应性。
我设法让它适用于一个简单的模板助手:
resultDate = null;
Template.result.helpers({
date: function(){
var date = moment(this.datetime).endOf("day").fromNow();
if(date == resultDate)
return false;
resultDate = date;
return date;
}
}
但是正如你所看到的那样,如果我需要两次调用{{date}},那么它并不是真正的优雅方式,一切都会崩溃。
我已经找了几个小时的合适解决方案而一无所获。有什么想法吗?
谢谢!
答案 0 :(得分:2)
以下是如何在您的收藏中使用此客户端并且不会失去反应性的示例。
关键问题是将一个反应数据源(集合)转换为一个对象数组,这些对象反映了所需的日期输出以及检入人员的名称。 这个数组看起来像:
[
{date: '2015-05-11', names: ['Mat', 'Lisa', 'Andrew']},
{date: '2015-05-14', names: ['Lisa']},
]
我假设你的收集名为Checkin,每个文档中有{2}个字段,date
和name
。
您的收藏是一个反应式数据源。您可以通过observeChanges
收到有关集合更改的通知。
通过触发添加,更改和删除的事件,您可以每天通过签入重建阵列。这些事件都会调用构建实际数组的rebuildCheckinPerDay
。
然后,每次重建时,该数组都会保存在ReactiveVar checkinPerDateVar
中。并且因为ReactiveVar也是一个反应式数据源,每次更改reactiveVar时模板帮助器checkinPerDate
都会重新运行。
构建数组由几个underscorejs函数完成。首先,集合按日期排序并以数组形式提取,然后按日期分组(时间由.endOf('day')
删除),然后映射到最终结构。由于_.groupBy
会将项目作为{id,name,date}返回,因此您必须使用_.pluck
来提取名称。
为了转换日期和方便的模板助手来格式化日期,我使用了momentjs。要实际运行此示例,您必须包含包momentjs:moment
和reactive-var
。
在示例中,显示完整日期。但如果您愿意,可以轻松将其转换为moment(this.datetime).endOf("day").fromNow()
。
完整示例:
检查-in.html。强>
<template name="checkinPerDate">
{{#each checkinPerDate}}
<div>
{{formatDate date}} - {{names}}
</div>
{{/each}}
</template>
检查-in.js。强>
Template.registerHelper('formatDate', function(date) {
return moment(date).format('DD-MM-YYYY');
});
// Reactive variable to hold the array with names per check-in day
var checkinPerDateVar = new ReactiveVar([]);
// Build the array with check-ins per day that mirror the final view in the template
var rebuildCheckinPerDay = function() {
var checkinPerDateArray = _.map(
_.groupBy(Checkin.find({}, {sort: {date : 1}}).fetch(), function(item) {
return moment(item.date).endOf('day');
}), function(dateItem, date) {
return {date: date, names: _.pluck(dateItem, 'name')};
});
checkinPerDateVar.set(checkinPerDateArray);
}
Template.checkinPerDate.onCreated(function() {
this.subscribe('checkin', function() {
var cursor = Checkin.find();
var handle = cursor.observeChanges({
added: function (id, checkin) {
console.log('added ', id, JSON.stringify(checkin));
rebuildCheckinPerDay();
},
changed: function (id, checkin) {
console.log('changed ', id, JSON.stringify(checkin));
rebuildCheckinPerDay();
},
removed: function (id) {
console.log('removed ', id);
rebuildCheckinPerDay();
}
});
});
});
Template.checkinPerDate.helpers({
// This helper function is reactive because of the use of reactive variable checkinPerDateVar.
// It gets rerun each time the variable was changed
checkinPerDate: function () {
var checkinPerDateArray = checkinPerDateVar.get();
return checkinPerDateArray;
}
});
答案 1 :(得分:0)
感谢Jos的回答,但对于我的简单需求,它看起来仍然很重要,这与HTML格式化相关,而不是对象操作。我认为你的答案很适合对请求的复杂处理,但在我的情况下,我只需要显示日期排序记录的日期,而不是在同一天重复。
所以,我制定了我的初始辅助函数,我想我找到了一个更好的方法:
var resultDateVar = [];
Template.result.helpers({
date: function(){
if(!resultDateVar[this._id]){
var date = moment(this.datetime).endOf("day").fromNow();
resultDateVar[this._id] = (resultDateVar.last == date)? false : date;
resultDateVar.last = date;
}
return resultDateVar[this._id]
}
});
我希望它会有所帮助:)