如何在加载后将过滤结果应用于模板?

时间:2015-05-20 12:05:52

标签: mongodb templates meteor datacontext

这是一个简单的例子:

<template name="mealsList">
  <div class="meals">
    {{#each meals}}
      {{> mealItem}}
    {{/each}}
  </div>
</template>

Template.mealsList.helpers({
  meals: function() {
    return Meals.find({}, { sort: { eatenAt: -1 }});
  }
});

Template.mealsList.events({

  'click .run-filter': function(e) {
    var dateFrom = new Date(moment($('[name=dateFrom]').val()));
    var dateTo = new Date(moment($('[name=dateTo]').val()));

    builtTimeFrom = "01/01/2015 " + $('[name=timeFrom]').val();
    builtTimeTo = "01/01/2015 " + $('[name=timeTo]').val();
    var timeFrom = new Date(moment(builtTimeFrom));
    var timeTo = new Date(moment(builtTimeTo));

    Meteor.call('filterMeals', dateFrom, dateTo, timeFrom, timeTo, function(error, result) {
      if (error)
        return throwError(error.reason);

      console.log(result);
      // How can I apply result to the template?
    });
  }
});

我只想更改运行filterMeals方法后列出的膳食。 result是一个数组对象,由以下内容返回:

Meteor.methods({
  filterMeals: function(dateFrom, dateTo, timeFrom, timeTo) {
    var pipeline = [{
      "$project": {
        "year": { "$year": "$eatenAt" },
        "month": { "$month": "$eatenAt" },
        "day": { "$dayOfMonth": "$eatenAt" },
        "hour": { "$hour": "$eatenAt" },        
        "name" : 1,
        "calories" : 1,
        "eatenAt" : 1,
        "userId" : 1,
          "author" : 1
      }
    },
    {
      "$match": {
        "year": { "$gte": dateFrom.getFullYear(), "$lte": dateTo.getFullYear() },
        "month": { "$gte": dateFrom.getMonth() + 1, "$lte": dateTo.getMonth() + 1 },
        "day": { "$gte": dateFrom.getDate(), "$lte": dateTo.getDate() },
        "hour": { "$gte": timeFrom.getHours(), "$lte": timeTo.getHours() },
      }
    }];

    var result = Meals.aggregate(pipeline);
    return result;
  }
});

2 个答案:

答案 0 :(得分:0)

使用reactive variable,您可以:

<template name="mealsList">
  <div class="meals">
    {{#each meals}}
      {{> mealItem}}
    {{/each}}
  </div>
</template>

Template.mealsList.onCreated(function() {
  this.meals = new ReactiveVar(Meals.find({}, { sort: { eatenAt: -1 }}));
});

Template.mealsList.helpers({
  meals: function() {
    return Template.instance().meals.get();
  }
});

Template.mealsList.events({

  'click .run-filter': function(e, temp) {
    var dateFrom = new Date(moment($('[name=dateFrom]').val()));
    var dateTo = new Date(moment($('[name=dateTo]').val()));

    builtTimeFrom = "01/01/2015 " + $('[name=timeFrom]').val();
    builtTimeTo = "01/01/2015 " + $('[name=timeTo]').val();
    var timeFrom = new Date(moment(builtTimeFrom));
    var timeTo = new Date(moment(builtTimeTo));

    Meteor.call('filterMeals', dateFrom, dateTo, timeFrom, timeTo, function(error, result) {
      if (error)
        return throwError(error.reason);

      temp.meals.set(result);
    });
  }
});

答案 1 :(得分:0)

使用Session变量有一个更简单的模式,但你也可以替换一个反应变量:

Template.mealsList.helpers({
  meals: function() {
    var query = Session.get('myQuery');
    return Meals.find({},query,{ sort: { eatenAt: -1 }});
  }
});

这意味着模板助手是被动的,只要myQuery会话变量发生变化,它就会自动更新结果!没有大惊小怪,没有麻烦。

您可以在事件处理程序中更新查询:

Template.mealsList.events({
  'click .run-filter': function(e) {
    var query = ...; // This needs to be a MongoDB query object pertinent to the collection being queried
    Session.set('myQuery',query)
  }
});

在您点击查询将在模板加载上运行之前,不会设置日期范围,因此您还需要:

Template.mealsList.onCreated(function(){
  var query = Session.get('myQuery');
  if ( !query ){
    query = ... // initialize your query here
    Session.set('myQuery',query); // then stuff it into the session
  }
});

我不知道为什么你有Meteor.call()。您是否还需要从服务器获取文档?

在这种情况下,您应该使用您传入查询参数的订阅。例如,您可以使用以下命令扩展onCreated函数:

Template.mealsList.onCreated(function(){
  var query = Session.get('myQuery');
  if ( !query ){
    query = ... // initialize your query here
    Session.set('myQuery',query); // then stuff it into the session
  }
  var ti = this; // the template instance. We need this because we're about to nest
  ti.autorun(function(){
    ti.subscribe('Meals',query);
  });
});