简体   繁体   English

Blaze模板助手仅在空格键中返回,在Meteor / Mongo中的每个循环中

[英]Blaze template helper only returning on in a Spacebars each loop in Meteor/Mongo

I have a helper which should find all events that correspond to a given month and year argument and return them as an array for the template to loop through. 我有一个助手,该助手应该找到与给定的月份和年份参数相对应的所有事件,并将它们作为数组循环返回以供模板循环。 It appears my helper is only returning for the first instance of year though rather than looping and I don't understand why. 看来我的助手虽然只是一年级的第一年,但没有循环,我也不知道为什么。

Here's the template: 这是模板:

  <template name="list">
  <ul id="ulShell">
    {{#each year in getYears}}
      <li class="liYear">
        <h2>{{year}}</h2>
      </li>
      <ul class="ulSubShell">
        {{#each month in (getMonths year)}}
          <li class="liMonth">
            <h3>{{month}}</h3>
          </li>
          <ul>
            {{#each event in (getEvents month year)}}
              <li>
                <h4>{{dayOfWeek event.start}} – {{formatDate event.start}}</h4>
                <div class="divEvent">{{event.title}} <span class="spanDep pull-right">{{event.department}}</span></div>
              </li>
            {{/each}}
          </ul>
        {{/each}}
      </ul>
    {{/each}}
  </ul>
  </template>

and here's the logic: 这是逻辑:

  let monthNames = ["January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
  ];

  let today = new Date();
  //today.setDate(today.getDate());

  let upcoming = {
    start: {
      $gt: today.toISOString()
    }
  }

  let findYears = function(){
    var selectedDep = Session.get('selectedDep');
    var distinctYears = _.uniq(Events.find( { $and: [ upcoming, selectedDep ] }, {
      sort: {start: 1}, fields: {start: true}
    }).fetch().map(function(x) {
      var d = Number(x.start.substring(0, 4));
      return d;
    }), true);
    return distinctYears;
  };

  let findMonths = function(year){
    var selectedDep = Session.get('selectedDep');
    var query = {
      start: {
        $gt: new Date(year - 1, 11, 31, 21, 59, 59, 999).toISOString(),
        $lt: new Date(year + 1, 0, 0, 22, 00, 00, 001).toISOString()
      }
    }
    var distinctMonths = _.uniq(Events.find( { $and: [ upcoming, query, selectedDep ] }, {
      sort: {start: 1}, fields: {start: true}
    }).fetch().map(function(x) {
        var d = Number(x.start.substring(5, 7));
        return monthNames[d];    
    }), true);
    return distinctMonths;
  };

  ///////////  I think this is where the problem is. Maybe with the forEach() function?
  let findEvents = function(month, year){
    var selectedDep = Session.get('selectedDep');
    var events = Events.find( { $and: [ upcoming, selectedDep ] }, {sort: {start: 1}}).fetch();
    var finalEvents = new Array();
    events.forEach(function(event){
      var mDigits = monthNames.indexOf(month);
      mDigits += 1
      mDigits = mDigits.toString();
      var yearMonthSlice;
      if(mDigits.length === 1){
        yearMonthSlice = year+"-"+"0"+mDigits;
      }else if(mDigits.length === 2){
        yearMonthSlice = year+"-"+mDigits;
      }
      var getStart = event.start.substring(0, 7);
      if(yearMonthSlice === getStart){
        finalEvents.push(event);
      }
    });
    return finalEvents;
  };

  Template.list.onCreated( () => {
    let template = Template.instance();
    template.subscribe( 'events' );
  });

  Template.list.helpers({
    getYears() {
      foundYears = findYears();
      return foundYears;
    },
    getMonths(year) {
      foundMonthNames = findMonths(year);
      return foundMonthNames;
    },
    getEvents(month, year) {
      var foundEvents = findEvents(month, year);
      return foundEvents;
    },
    formatDate(start) {
      var dayNumber = start.substring(8, 10);
      return dayNumber;
    },
    dayOfWeek(start) {
      var days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
      var x = Number(new Date(start).getDay());
      var dayName = days[x];
      return dayName;
    }
  });

The list is rending in my browser like this: 该列表正像这样在我的浏览器中呈现:

列表的屏幕截图

Any help would be very much appreciated. 任何帮助将不胜感激。 I'm new to all of this especially Blaze/Spacebars/Meteor/MongoDB 我是这一切的新手,尤其是Blaze / Spacebars / Meteor / MongoDB

Let's simplify your example down to the bare minimum in blaze assuming that dates are stored as dates instead of strings! 让我们简单地将示例简化到最低限度, 假设日期存储为日期而不是字符串!

We're going to: 我们将要:

  1. Find the list of unique years corresponding to all the events 查找与所有事件对应的唯一年份列表
  2. Find the list of unique month numbers corresponding to the year we are looking at 查找与我们要查看的年份相对应的唯一月份列表
  3. Find all the events that are in that month and year combination 查找该月份和年份组合中的所有事件
  4. Do as little date math as possible and no string manipulations 尽可能少地进行日期数学运算,而无需字符串操作

html: 的HTML:

<template name="list">
  {{#each year in getYears}}
    {{year}}
    {{#each monthNumber in getMonths}}
      {{monthName monthNumber}}
      {{#each event in (getEvents monthNumber year)}}
        {{start}}
      {{/each}}
    {{/each}}
   {{/each}}
</template>

js: js:

Template.list.helpers({
  getYears(){
    const years = Events.find({},{sort: {start: 1}}).map(event=>event.start.getFullYear()));
    return _.uniq(years)
  },
  getMonths(year){
    const months = Events.find(
      {start: {$gte: new Date(year,0,1), $lt: new Date(year+1,0,1)}},
      {sort: {start: 1}})
      .map(event=>event.start.getMonth()));
    return _.uniq(months); // this returns integers in [0,11]
  },
  getEvents(monthNumber,year){
    return Events.find(
      {start: {$gte: new Date(year,monthNumber,1), $lt: new Date(year,monthNumber+1,1)}},
      {sort: {start: 1}});
  },
  monthName(month){
    return monthNames[month];
});

Note that the javascript Date() class is smart enough to wrap the year when month > 11 - ditto for the remaining date fields. 请注意,javascript Date()类足够聪明,可以在month > 11时包装年份,其余日期字段也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM