Skip to content

Commit aebe832

Browse files
author
Matt Lewis
committed
perf(track-by): use track by on all ngFor elements
Fixes #444
1 parent 2d06a76 commit aebe832

11 files changed

+90
-25
lines changed

package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@
184184
"dependencies": {
185185
"angular-draggable-droppable": "^2.0.0",
186186
"angular-resizable-element": "^2.0.0",
187-
"calendar-utils": "^0.1.0",
187+
"calendar-utils": "^0.1.1",
188188
"date-fns": "^1.28.5",
189189
"positioning": "^1.3.1"
190190
}

src/modules/common/calendar-event-actions.component.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Component, Input } from '@angular/core';
22
import { CalendarEvent } from 'calendar-utils';
3+
import { trackByIndex } from './util';
34

45
@Component({
56
selector: 'mwl-calendar-event-actions',
@@ -8,7 +9,7 @@ import { CalendarEvent } from 'calendar-utils';
89
<a
910
class="cal-event-action"
1011
href="javascript:;"
11-
*ngFor="let action of event.actions"
12+
*ngFor="let action of event.actions; trackBy:trackByIndex"
1213
(mwlClick)="action.onClick({event: event})"
1314
[ngClass]="action.cssClass"
1415
[innerHtml]="action.label">
@@ -18,4 +19,5 @@ import { CalendarEvent } from 'calendar-utils';
1819
})
1920
export class CalendarEventActionsComponent {
2021
@Input() event: CalendarEvent;
22+
trackByIndex = trackByIndex;
2123
}

src/modules/common/util.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
CalendarEvent,
3-
validateEvents as validateEventsWithoutLog
3+
validateEvents as validateEventsWithoutLog,
4+
WeekDay
45
} from 'calendar-utils';
56

67
export const validateEvents = (events: CalendarEvent[]) => {
@@ -20,3 +21,11 @@ export function isInside(outer: ClientRect, inner: ClientRect): boolean {
2021
inner.bottom <= outer.bottom
2122
);
2223
}
24+
25+
export const trackByEventId = (index: number, event: CalendarEvent) =>
26+
event.id ? event.id : event;
27+
28+
export const trackByWeekDayHeaderDate = (index: number, day: WeekDay) =>
29+
day.date.toISOString();
30+
31+
export const trackByIndex = (index: number) => index;

src/modules/day/calendar-day-view.component.ts

+28-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { CalendarDragHelper } from '../common/calendar-drag-helper.provider';
2727
import { CalendarResizeHelper } from '../common/calendar-resize-helper.provider';
2828
import { CalendarEventTimesChangedEvent } from '../common/calendar-event-times-changed-event.interface';
2929
import { CalendarUtils } from '../common/calendar-utils.provider';
30-
import { validateEvents } from '../common/util';
30+
import { validateEvents, trackByEventId } from '../common/util';
3131

3232
export interface CalendarDayViewBeforeRenderEvent {
3333
body: {
@@ -65,7 +65,7 @@ export interface DayViewEventResize {
6565
template: `
6666
<div class="cal-day-view" #dayViewContainer>
6767
<mwl-calendar-all-day-event
68-
*ngFor="let event of view.allDayEvents"
68+
*ngFor="let event of view.allDayEvents; trackBy:trackByEventId"
6969
[event]="event"
7070
[customTemplate]="allDayEventTemplate"
7171
[eventTitleTemplate]="eventTitleTemplate"
@@ -75,7 +75,7 @@ export interface DayViewEventResize {
7575
<div class="cal-events">
7676
<div
7777
#event
78-
*ngFor="let dayEvent of view?.events"
78+
*ngFor="let dayEvent of view?.events; trackBy:trackByDayEvent"
7979
class="cal-event-container"
8080
[class.cal-draggable]="dayEvent.event.draggable"
8181
[class.cal-starts-within-day]="!dayEvent.startsBeforeDay"
@@ -109,9 +109,9 @@ export interface DayViewEventResize {
109109
</mwl-calendar-day-view-event>
110110
</div>
111111
</div>
112-
<div class="cal-hour" *ngFor="let hour of hours" [style.minWidth.px]="view?.width + 70">
112+
<div class="cal-hour" *ngFor="let hour of hours; trackBy:trackByHour" [style.minWidth.px]="view?.width + 70">
113113
<mwl-calendar-day-view-hour-segment
114-
*ngFor="let segment of hour.segments"
114+
*ngFor="let segment of hour.segments; trackBy:trackByHourSegment"
115115
[style.height.px]="hourSegmentHeight"
116116
[segment]="segment"
117117
[segmentHeight]="hourSegmentHeight"
@@ -290,6 +290,29 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy {
290290
*/
291291
validateResize: (args: any) => boolean;
292292

293+
/**
294+
* @hidden
295+
*/
296+
trackByEventId = trackByEventId;
297+
298+
/**
299+
* @hidden
300+
*/
301+
trackByDayEvent = (index: number, dayEvent: DayViewEvent) =>
302+
dayEvent.event.id ? dayEvent.event.id : dayEvent.event;
303+
304+
/**
305+
* @hidden
306+
*/
307+
trackByHour = (index: number, hour: DayViewHour) =>
308+
hour.segments[0].date.toISOString();
309+
310+
/**
311+
* @hidden
312+
*/
313+
trackByHourSegment = (index: number, segment: DayViewHourSegment) =>
314+
segment.date.toISOString();
315+
293316
/**
294317
* @hidden
295318
*/

src/modules/month/calendar-month-cell.component.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
TemplateRef
77
} from '@angular/core';
88
import { MonthViewDay, CalendarEvent } from 'calendar-utils';
9+
import { trackByEventId } from '../common/util';
910

1011
@Component({
1112
selector: 'mwl-calendar-month-cell',
@@ -28,7 +29,7 @@ import { MonthViewDay, CalendarEvent } from 'calendar-utils';
2829
<div class="cal-events" *ngIf="day.events.length > 0">
2930
<div
3031
class="cal-event"
31-
*ngFor="let event of day.events"
32+
*ngFor="let event of day.events; trackBy:trackByEventId"
3233
[style.backgroundColor]="event.color.primary"
3334
[ngClass]="event?.cssClass"
3435
(mouseenter)="highlightDay.emit({event: event})"
@@ -96,4 +97,6 @@ export class CalendarMonthCellComponent {
9697
eventClicked: EventEmitter<{ event: CalendarEvent }> = new EventEmitter<{
9798
event: CalendarEvent;
9899
}>();
100+
101+
trackByEventId = trackByEventId;
99102
}

src/modules/month/calendar-month-view-header.component.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Component, Input, TemplateRef } from '@angular/core';
22
import { WeekDay } from 'calendar-utils';
3+
import { trackByWeekDayHeaderDate } from '../common/util';
34

45
@Component({
56
selector: 'mwl-calendar-month-view-header',
@@ -11,7 +12,7 @@ import { WeekDay } from 'calendar-utils';
1112
<div class="cal-cell-row cal-header">
1213
<div
1314
class="cal-cell"
14-
*ngFor="let day of days"
15+
*ngFor="let day of days; trackBy:trackByWeekDayHeaderDate"
1516
[class.cal-past]="day.isPast"
1617
[class.cal-today]="day.isToday"
1718
[class.cal-future]="day.isFuture"
@@ -33,4 +34,6 @@ export class CalendarMonthViewHeaderComponent {
3334
@Input() locale: string;
3435

3536
@Input() customTemplate: TemplateRef<any>;
37+
38+
trackByWeekDayHeaderDate = trackByWeekDayHeaderDate;
3639
}

src/modules/month/calendar-month-view.component.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import differenceInSeconds from 'date-fns/difference_in_seconds/index';
3131
import addSeconds from 'date-fns/add_seconds/index';
3232
import { CalendarEventTimesChangedEvent } from '../common/calendar-event-times-changed-event.interface';
3333
import { CalendarUtils } from '../common/calendar-utils.provider';
34-
import { validateEvents } from '../common/util';
34+
import { validateEvents, trackByIndex } from '../common/util';
3535

3636
export interface CalendarMonthViewBeforeRenderEvent {
3737
header: WeekDay[];
@@ -59,10 +59,10 @@ export interface CalendarMonthViewBeforeRenderEvent {
5959
[customTemplate]="headerTemplate">
6060
</mwl-calendar-month-view-header>
6161
<div class="cal-days">
62-
<div *ngFor="let rowIndex of view.rowOffsets">
62+
<div *ngFor="let rowIndex of view.rowOffsets; trackByIndex">
6363
<div class="cal-cell-row">
6464
<mwl-calendar-month-cell
65-
*ngFor="let day of view.days | slice : rowIndex : rowIndex + (view.totalDaysVisibleInWeek)"
65+
*ngFor="let day of (view.days | slice : rowIndex : rowIndex + (view.totalDaysVisibleInWeek)); trackBy:trackByDate"
6666
[class.cal-drag-over]="day.dragOver"
6767
[ngClass]="day?.cssClass"
6868
[day]="day"
@@ -230,6 +230,16 @@ export class CalendarMonthViewComponent
230230
*/
231231
refreshSubscription: Subscription;
232232

233+
/**
234+
* @hidden
235+
*/
236+
trackByIndex = trackByIndex;
237+
238+
/**
239+
* @hidden
240+
*/
241+
trackByDate = (index: number, day: MonthViewDay) => day.date.toISOString();
242+
233243
/**
234244
* @hidden
235245
*/

src/modules/month/calendar-open-day-events.component.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from '@angular/core';
88
import { trigger, style, transition, animate } from '@angular/animations';
99
import { CalendarEvent } from 'calendar-utils';
10+
import { trackByEventId } from '../common/util';
1011

1112
@Component({
1213
selector: 'mwl-calendar-open-day-events',
@@ -16,7 +17,7 @@ import { CalendarEvent } from 'calendar-utils';
1617
let-events="events"
1718
let-eventClicked="eventClicked">
1819
<div
19-
*ngFor="let event of events"
20+
*ngFor="let event of events; trackBy:trackByEventId"
2021
[ngClass]="event?.cssClass"
2122
mwlDraggable
2223
[dropData]="{event: event}"
@@ -70,4 +71,6 @@ export class CalendarOpenDayEventsComponent {
7071
eventClicked: EventEmitter<{ event: CalendarEvent }> = new EventEmitter<{
7172
event: CalendarEvent;
7273
}>();
74+
75+
trackByEventId = trackByEventId;
7376
}

src/modules/week/calendar-week-view-header.component.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
TemplateRef
77
} from '@angular/core';
88
import { CalendarEvent, WeekDay } from 'calendar-utils';
9+
import { trackByWeekDayHeaderDate } from '../common/util';
910

1011
@Component({
1112
selector: 'mwl-calendar-week-view-header',
@@ -19,7 +20,7 @@ import { CalendarEvent, WeekDay } from 'calendar-utils';
1920
<div class="cal-day-headers">
2021
<div
2122
class="cal-header"
22-
*ngFor="let day of days"
23+
*ngFor="let day of days; trackBy:trackByWeekDayHeaderDate"
2324
[class.cal-past]="day.isPast"
2425
[class.cal-today]="day.isToday"
2526
[class.cal-future]="day.isFuture"
@@ -59,4 +60,6 @@ export class CalendarWeekViewHeaderComponent {
5960
event: CalendarEvent;
6061
newStart: Date;
6162
}> = new EventEmitter<{ event: CalendarEvent; newStart: Date }>();
63+
64+
trackByWeekDayHeaderDate = trackByWeekDayHeaderDate;
6265
}

src/modules/week/calendar-week-view.component.ts

+15-6
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,16 @@ import {
1717
WeekDay,
1818
CalendarEvent,
1919
WeekViewEvent,
20-
WeekViewEventRow,
2120
WeekView,
22-
ViewPeriod,
23-
MonthViewDay
21+
ViewPeriod
2422
} from 'calendar-utils';
2523
import { ResizeEvent } from 'angular-resizable-element';
2624
import addDays from 'date-fns/add_days/index';
2725
import { CalendarDragHelper } from '../common/calendar-drag-helper.provider';
2826
import { CalendarResizeHelper } from '../common/calendar-resize-helper.provider';
2927
import { CalendarEventTimesChangedEvent } from '../common/calendar-event-times-changed-event.interface';
3028
import { CalendarUtils } from '../common/calendar-utils.provider';
31-
import { validateEvents } from '../common/util';
29+
import { validateEvents, trackByIndex } from '../common/util';
3230

3331
export interface WeekViewEventResize {
3432
originalOffset: number;
@@ -62,9 +60,9 @@ export interface CalendarWeekViewBeforeRenderEvent {
6260
(dayHeaderClicked)="dayHeaderClicked.emit($event)"
6361
(eventDropped)="eventTimesChanged.emit($event)">
6462
</mwl-calendar-week-view-header>
65-
<div *ngFor="let eventRow of view.eventRows" #eventRowContainer class="cal-events-row">
63+
<div *ngFor="let eventRow of view.eventRows; trackBy:trackByIndex" #eventRowContainer class="cal-events-row">
6664
<div
67-
*ngFor="let weekEvent of eventRow.row"
65+
*ngFor="let weekEvent of eventRow.row; trackBy:trackByEventId"
6866
#event
6967
class="cal-event-container"
7068
[class.cal-draggable]="weekEvent.event.draggable"
@@ -239,6 +237,17 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
239237
*/
240238
dayColumnWidth: number;
241239

240+
/**
241+
* @hidden
242+
*/
243+
trackByIndex = trackByIndex;
244+
245+
/**
246+
* @hidden
247+
*/
248+
trackByEventId = (index: number, weekEvent: WeekViewEvent) =>
249+
weekEvent.event.id ? weekEvent.event.id : weekEvent;
250+
242251
/**
243252
* @hidden
244253
*/

0 commit comments

Comments
 (0)