【问题标题】:How to render event in custom built calendar如何在自定义构建的日历中呈现事件
【发布时间】:2020-05-09 09:34:41
【问题描述】:

我使用 angular 为我的一个项目创建了自定义日历视图。我尝试使用完整的日历库,但它没有提供很多自定义选项。这是我在stackblitz 中的自定义视图。我想渲染事件。但我不明白该怎么做。

我的期望是这样的

【问题讨论】:

    标签: javascript html angular sass


    【解决方案1】:

    这只是一个想法。你有类似的事件

    events:any[]=[{
        startDate:'2020-01-06',
        endDate:'2020-01-08',
        event:'Hello word'
      }]
    

    当您渲染日历时,添加“数据属性”并放置一个模板变量引用以允许我们使用 ViewChildren 获取它 - 获取“行”,因为这在两个不同的星期内调用事件时很重要。有趣的是,您将显示的日期作为数据日属性提供。为此创建一个函数,如

    getDate(day:any,row:number)
      {
        if (day.isSameMonth)
          return this.currentMonth.getFullYear()+'-'+('0'+(this.currentMonth.getMonth()+1)).slice(-2)
                  +'-'+('0'+day.day).slice(-2)
        if (row==0)
        {
          return this.currentMonth.getMonth()?
             this.currentMonth.getFullYear()+'-'+
             ('0'+this.currentMonth.getMonth()).slice(-2)+'-'+
             ('0'+day.day).slice(-2):
             (this.currentMonth.getFullYear()-1)+'-12-'+('0'+day.day).slice(-2)
        }
          return this.currentMonth.getMonth()!=11?
             this.currentMonth.getFullYear()+'-'+
             ('0'+this.currentMonth.getMonth()+2).slice(-2)+'-'+
             ('0'+day.day).slice(-2):
             (this.currentMonth.getFullYear()+1)+'-01-'+('0'+day.day).slice(-2)
    
      }
    
    <div #daysCell 
      [attr.data-day]="getDate(days,i)"
      [attr.data-row]="i"
      [ngClass] = "{'today-cell':days.isToday === true}">
        {{days.day}}
    </div>
    

    将 div 中的事件渲染为

    <div *ngFor="let evento of events;let i=index">
      <div #event [attr.data-event]="i" class="event">{{evento.event}}</div>
    </div>
    

    嗯,有趣的部分。我们得到“细胞”和“事件”作为

      @ViewChildren('daysCell') cells:QueryList<ElementRef>
      @ViewChildren('event') eventsCells:QueryList<ElementRef>
    

    在函数 renderEvent 中,您使用 Renderer2 将位置左上角分配给您的元素

    renderEvents(){
        const cells=this.cells.map(x=>{
          return {
            pos:x.nativeElement.getBoundingClientRect(),
            day:x.nativeElement.getAttribute('data-day'),
            row:x.nativeElement.getAttribute('data-row'),
          }
    
        })
        this.eventsCells.forEach((x:any,index:number)=>{
          const cellStart=cells.find(c=>c.day==this.events[index].startDate)
          const cellEnd=cells.find(c=>c.day==this.events[index].endDate)
          this.render.setStyle(x.nativeElement,'top',(cellStart.pos.top+1)+'px')
          this.render.setStyle(x.nativeElement,'left',(cellStart.pos.left+1)+'px')
          this.render.setStyle(x.nativeElement,'width',
              (cellEnd.pos.left-cellStart.pos.left+cellEnd.pos.width)+'px')
        })
      }
    

    嗯,这只是一个近似值。您需要检查该事件是否在两周内,是否显示了一个事件......以及另一个调整(我希望 minnor 调整)

    你可以在stackblitz看到

    更新如果我们想在一个日期中放置多个事件,我们需要为“事件”添加一个属性,例如我们可以称为“行”,所以,“顶部”变成了像

    this.render.setStyle(
          x.nativeElement,
          "top",
          (this.events[index].row
            ? this.events[index].row *
                (2 + x.nativeElement.getBoundingClientRect().height) +
              cellStart.pos.top
            : cellStart.pos.top + 1) + "px"
        );
    

    现在,困难在于知道如何将值赋予“行”。为此,我们需要循环事件,将被占用的天数存储在一个数组中,如果有人被占用,则增加该行。噗。做一个函数

    getEventsRows() {
        const datesOcupped: any[] = [];
        this.events.forEach(x => {
          x.row = 0;
          const startDate = new Date(x.startDate).getTime();
          const endDate = new Date(x.endDate).getTime();
    
          for (let date = startDate;date <= endDate;date = date + 24 * 60 * 60 * 1000) {
            const dateOcupped = datesOcupped.length? 
                  datesOcupped.find(x => x.time == date): null;
            if (!dateOcupped) {
              datesOcupped.push({
                time: date,
                row: 0
              });
            } else dateOcupped.row++;
    
            x.row = dateOcupped? dateOcupped.row > x.row?
                                 dateOcupped.row: x.row: 0;
          }
        });
      }
    

    【讨论】:

    • 我有一个问题,如果我在同一天有另一个活动,它将取代我的旧活动。我该如何解决?您的意见高度赞赏。谢谢。
    • 我只是在更新的答案中提出了一个想法:“事件”必须有一个属性,称之为,例如“row”,所以我们需要根据这个“row”改变“top”。好吧,为了计算“行”,我们将每个事件的“占用的日期”存储在一个数组中。注意:当单元格高度不够时请考虑
    猜你喜欢
    • 2011-11-03
    • 2019-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多