【问题标题】:Adding an HTML element for each month on a Calendar Events' list in PugJS在 PugJS 的日历事件列表中为每个月添加一个 HTML 元素
【发布时间】:2021-11-16 23:49:42
【问题描述】:

我正在 PugJS 中构建一个“事件列表”,我正在浏览每个事件,我想为每个月添加一个 html 元素,如下所示:<div data-month="October">。列出该月的事件后,我必须关闭 </div> 并为下个月开始一个新事件。

在后端,我只有一个 title 字段和每个事件的 date 字段。我想在不必添加额外字段的情况下进行此操作,以再次选择“月份”,如果所选月份与date 字段上的月份不同(以便能够列出事件),这可能会带来错误,是否有意义)?

目前,我正在这一步:

each event in calendar_events
  - var str = event.primary.event_date // 2021-10-22
  - var separator = '-';
  - var month = str.split(separator, 2).pop(); // 10

  while (month === '10')
    - month = 'October'

    //- I need to add here a <div data-month="October">

    h2=event.primary.event_title[0].text
    p=event.primary.event_date

    //- After showing all the items,
    //- I need to close that </div>

  while (month === '11')

    - month = 'November'
    //- I need to add here a <div data-month="November">

    h2=event.primary.event_title[0].text
    p=event.primary.event_date

    //- After showing all the items,
    //- I need to close that </div>

问题是我在 10 月份的每个条目都得到一个重复的 &lt;div data-month="October"&gt;,因为我必须在第一行开始迭代:each event in calendar_events。

我将把这个带有 html 版本的 CodePen 链接留在这里,因为我认为你们可以理解我的问题的主要思想:https://codepen.io/ositaka/pen/abwjrPe

【问题讨论】:

  • 你能解释一下“我必须在第一行开始迭代”的意思吗?

标签: pug


【解决方案1】:

如果数据已经按日期排序,试试:

- 
  const calendar_events = [{ pr: { ed: "2021-10-22", et: [ { text: "xx"} ]}},
   { pr: { ed: "2021-10-23", et: [ { text: "yy"} ]}},
   { pr: { ed: "2021-12-25", et: [ { text: "Xmas"} ]}},
   { pr: { ed: "2022-01-01", et: [ { text: "New Year's Day"} ]}} ];
  const getYear = event => event.pr.ed.split("-")[0];
  const getMonth = event => Number(event.pr.ed.split("-", 2).pop());
  const getDay = event => event.pr.ed.split("-")[2];
  const months = ['dummy','jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];

  let current = { year: getYear(calendar_events[0]), month: 0 };
  const incCurrent = () => { 
    if (current.month==12) {
      current.month = 1; current.year++;
    } else current.month++;
  }
- for (let i=0; i<calendar_events.length; i++) {
-   let month = getMonth(calendar_events[i]);
-   if (current.month != month) {
-     while (current.month != month) incCurrent();
  h3 New Month #{months[month]}-#{getYear(calendar_events[i])}
  .events__group(data-month=months[month])
    p #{getDay(calendar_events[i])} - #{calendar_events[i].pr.et[0].text}
    while i<calendar_events.length-1 && getMonth(calendar_events[i+1])==current.month
      - i++;
      p #{getDay(calendar_events[i])} - #{calendar_events[i].pr.et[0].text}
-   }
- }

输出:

<h3>New Month oct-2021</h3>
<div class="events__group" data-month="oct">
  <p>22 - xx</p>
  <p>23 - yy</p>
</div>
<h3>New Month dec-2021</h3>
<div class="events__group" data-month="dec">
  <p>25 - Xmas</p>
</div>
<h3>New Month jan-2022</h3>
<div class="events__group" data-month="jan">
  <p>01 - New Year's Day</p>
</div>

关于 pug 代码的注意事项:

  • 我对一些测试数据进行了硬编码
  • 我添加了一个辅助函数 getMonth 来减少提取深埋在数据对象中的月份值的冗长性
  • 真正的 Javascript(以 - 开头的行或块)和对缩进敏感的 pug 伪 Javascript 混合在一起令人困惑。
  • 数据必须有效以避免无休止的while 循环。示例 2021-13-01 会给您带来麻烦。

【讨论】:

  • 我能够让它工作,但是有一点细节吗?我还必须按年份(首先)对日期进行排序。我一直在尝试扩展您的代码,但并不完全有效。这就是我到目前为止所拥有的:codepen.io/ositaka/pen/VwWVEWE?editors=1010 我添加了一个getYear() 函数,我想我必须模仿你所做的来检查while (currentMonth != month),但是对于每一年。我想我必须在今年的 while 循环之前添加一个额外的 while 循环:while i&lt;calendar_events.length-1 &amp;&amp; getMonth(calendar_events[i+1])==currentMonth
  • @NunoMarques 我已经更新了答案。将current改为一个包含年月的对象,并增加一个增量函数,每次将current向前移动一个月。测试数据已修改为跨越多年。希望这是您所需要的。
  • 它工作了吗:) 非常感谢!作为旁注,我在我的 app.js 文件中添加了以下代码,以按日期“排序”事件,否则它将不起作用。如果有人也需要,这里是代码: calendar_events.sort(function (a, b) { return new Date(a.event_date) - new Date(b.event_date) })
  • 大家也可以在 Vanilla JS 中查看这段代码,这里:codepen.io/ositaka/pen/mdwQagj?editors=1111
  • @NunoMarques 你是在服务器还是在客户端做哈巴狗?
猜你喜欢
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
  • 2021-01-21
  • 2015-05-29
  • 2022-08-11
  • 2011-10-08
相关资源
最近更新 更多