【发布时间】:2020-05-09 09:34:41
【问题描述】:
我使用 angular 为我的一个项目创建了自定义日历视图。我尝试使用完整的日历库,但它没有提供很多自定义选项。这是我在stackblitz 中的自定义视图。我想渲染事件。但我不明白该怎么做。
【问题讨论】:
标签: javascript html angular sass
我使用 angular 为我的一个项目创建了自定义日历视图。我尝试使用完整的日历库,但它没有提供很多自定义选项。这是我在stackblitz 中的自定义视图。我想渲染事件。但我不明白该怎么做。
【问题讨论】:
标签: javascript html angular sass
这只是一个想法。你有类似的事件
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;
}
});
}
【讨论】: