From ec7021a6c63b5cbc5715ee4c9ad46058158c5b19 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Fri, 1 Mar 2019 14:09:45 +1300 Subject: [PATCH] perf: only call beforeViewRender output once when changing view date --- .../day/calendar-day-view.component.ts | 33 +++++++++++-------- .../month/calendar-month-view.component.ts | 26 ++++++++------- .../week/calendar-week-view.component.ts | 33 +++++++++++-------- .../test/calendar-day-view.component.spec.ts | 19 +++++++++++ .../calendar-month-view.component.spec.ts | 19 +++++++++++ .../test/calendar-week-view.component.spec.ts | 19 +++++++++++ 6 files changed, 110 insertions(+), 39 deletions(-) diff --git a/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts b/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts index ce20ee72b..919258252 100644 --- a/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts +++ b/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts @@ -452,32 +452,38 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy { * @hidden */ ngOnChanges(changes: any): void { - if ( + const refreshHourGrid = changes.viewDate || changes.dayStartHour || changes.dayStartMinute || changes.dayEndHour || changes.dayEndMinute || - changes.hourSegments - ) { - this.refreshHourGrid(); - } - - if (changes.events) { - validateEvents(this.events); - } + changes.hourSegments; - if ( + const refreshView = changes.viewDate || changes.events || changes.dayStartHour || changes.dayStartMinute || changes.dayEndHour || changes.dayEndMinute || - changes.eventWidth - ) { + changes.eventWidth; + + if (refreshHourGrid) { + this.refreshHourGrid(); + } + + if (changes.events) { + validateEvents(this.events); + } + + if (refreshView) { this.refreshView(); } + + if (refreshHourGrid || refreshView) { + this.emitBeforeViewRender(); + } } eventDropped( @@ -638,7 +644,6 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy { minute: this.dayEndMinute } }); - this.emitBeforeViewRender(); } private refreshView(): void { @@ -657,12 +662,12 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy { eventWidth: this.eventWidth, segmentHeight: this.hourSegmentHeight }); - this.emitBeforeViewRender(); } private refreshAll(): void { this.refreshHourGrid(); this.refreshView(); + this.emitBeforeViewRender(); } private emitBeforeViewRender(): void { diff --git a/projects/angular-calendar/src/modules/month/calendar-month-view.component.ts b/projects/angular-calendar/src/modules/month/calendar-month-view.component.ts index 41453cc4e..1af598ad8 100644 --- a/projects/angular-calendar/src/modules/month/calendar-month-view.component.ts +++ b/projects/angular-calendar/src/modules/month/calendar-month-view.component.ts @@ -313,7 +313,15 @@ export class CalendarMonthViewComponent * @hidden */ ngOnChanges(changes: any): void { - if (changes.viewDate || changes.excludeDays || changes.weekendDays) { + const refreshHeader = + changes.viewDate || changes.excludeDays || changes.weekendDays; + const refreshBody = + changes.viewDate || + changes.events || + changes.excludeDays || + changes.weekendDays; + + if (refreshHeader) { this.refreshHeader(); } @@ -321,15 +329,14 @@ export class CalendarMonthViewComponent validateEvents(this.events); } - if ( - changes.viewDate || - changes.events || - changes.excludeDays || - changes.weekendDays - ) { + if (refreshBody) { this.refreshBody(); } + if (refreshHeader || refreshBody) { + this.emitBeforeViewRender(); + } + if ( changes.activeDayIsOpen || changes.viewDate || @@ -408,7 +415,6 @@ export class CalendarMonthViewComponent excluded: this.excludeDays, weekendDays: this.weekendDays }); - this.emitBeforeViewRender(); } private refreshBody(): void { @@ -419,7 +425,6 @@ export class CalendarMonthViewComponent excluded: this.excludeDays, weekendDays: this.weekendDays }); - this.emitBeforeViewRender(); } private checkActiveDayIsOpen(): void { @@ -439,10 +444,9 @@ export class CalendarMonthViewComponent } private refreshAll(): void { - this.columnHeaders = null; - this.view = null; this.refreshHeader(); this.refreshBody(); + this.emitBeforeViewRender(); this.checkActiveDayIsOpen(); } diff --git a/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts b/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts index bab573285..ac09b8b37 100644 --- a/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts +++ b/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts @@ -649,20 +649,13 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { * @hidden */ ngOnChanges(changes: any): void { - if ( + const refreshHeader = changes.viewDate || changes.excludeDays || changes.weekendDays || - changes.daysInWeek - ) { - this.refreshHeader(); - } - - if (changes.events) { - validateEvents(this.events); - } + changes.daysInWeek; - if ( + const refreshBody = changes.viewDate || changes.dayStartHour || changes.dayStartMinute || @@ -674,10 +667,23 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { changes.excludeDays || changes.hourSegmentHeight || changes.events || - changes.daysInWeek - ) { + changes.daysInWeek; + + if (refreshHeader) { + this.refreshHeader(); + } + + if (changes.events) { + validateEvents(this.events); + } + + if (refreshBody) { this.refreshBody(); } + + if (refreshHeader || refreshBody) { + this.emitBeforeViewRender(); + } } /** @@ -990,17 +996,16 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { this.daysInWeek ) }); - this.emitBeforeViewRender(); } private refreshBody(): void { this.view = this.getWeekView(this.events); - this.emitBeforeViewRender(); } private refreshAll(): void { this.refreshHeader(); this.refreshBody(); + this.emitBeforeViewRender(); } private emitBeforeViewRender(): void { diff --git a/projects/angular-calendar/test/calendar-day-view.component.spec.ts b/projects/angular-calendar/test/calendar-day-view.component.spec.ts index ceea25897..d90a57478 100644 --- a/projects/angular-calendar/test/calendar-day-view.component.spec.ts +++ b/projects/angular-calendar/test/calendar-day-view.component.spec.ts @@ -1357,6 +1357,25 @@ describe('CalendarDayViewComponent component', () => { fixture.destroy(); }); + it('should only call the beforeViewRender output once when changing the view date', () => { + const fixture: ComponentFixture< + CalendarDayViewComponent + > = TestBed.createComponent(CalendarDayViewComponent); + fixture.componentInstance.ngOnInit(); + fixture.componentInstance.viewDate = new Date('2016-06-27'); + fixture.componentInstance.ngOnChanges({ viewDate: {} }); + const beforeViewRenderCalled = sinon.spy(); + // use subscription to test that it was only called a max of one times + const subscription = fixture.componentInstance.beforeViewRender.subscribe( + beforeViewRenderCalled + ); + fixture.componentInstance.viewDate = new Date('2016-06-28'); + fixture.componentInstance.ngOnChanges({ viewDate: {} }); + expect(beforeViewRenderCalled).to.have.been.calledOnce; + subscription.unsubscribe(); + fixture.destroy(); + }); + it('should expose the view period on the beforeViewRender output', () => { const fixture: ComponentFixture< CalendarDayViewComponent diff --git a/projects/angular-calendar/test/calendar-month-view.component.spec.ts b/projects/angular-calendar/test/calendar-month-view.component.spec.ts index 9404a24a7..504d2d0db 100644 --- a/projects/angular-calendar/test/calendar-month-view.component.spec.ts +++ b/projects/angular-calendar/test/calendar-month-view.component.spec.ts @@ -918,6 +918,25 @@ describe('calendarMonthView component', () => { fixture.destroy(); }); + it('should only call the beforeViewRender output once when changing the view date', () => { + const fixture: ComponentFixture< + CalendarMonthViewComponent + > = TestBed.createComponent(CalendarMonthViewComponent); + fixture.componentInstance.ngOnInit(); + fixture.componentInstance.viewDate = new Date('2016-06-27'); + fixture.componentInstance.ngOnChanges({ viewDate: {} }); + const beforeViewRenderCalled = sinon.spy(); + // use subscription to test that it was only called a max of one times + const subscription = fixture.componentInstance.beforeViewRender.subscribe( + beforeViewRenderCalled + ); + fixture.componentInstance.viewDate = new Date('2016-06-28'); + fixture.componentInstance.ngOnChanges({ viewDate: {} }); + expect(beforeViewRenderCalled).to.have.been.calledOnce; + subscription.unsubscribe(); + fixture.destroy(); + }); + it('should log on invalid events', () => { const stub = sinon.stub(console, 'warn'); const fixture: ComponentFixture< diff --git a/projects/angular-calendar/test/calendar-week-view.component.spec.ts b/projects/angular-calendar/test/calendar-week-view.component.spec.ts index 023c7f90f..39919f666 100644 --- a/projects/angular-calendar/test/calendar-week-view.component.spec.ts +++ b/projects/angular-calendar/test/calendar-week-view.component.spec.ts @@ -1001,6 +1001,25 @@ describe('calendarWeekView component', () => { fixture.destroy(); }); + it('should only call the beforeViewRender output once when changing the view date', () => { + const fixture: ComponentFixture< + CalendarWeekViewComponent + > = TestBed.createComponent(CalendarWeekViewComponent); + fixture.componentInstance.ngOnInit(); + fixture.componentInstance.viewDate = new Date('2016-06-27'); + fixture.componentInstance.ngOnChanges({ viewDate: {} }); + const beforeViewRenderCalled = sinon.spy(); + // use subscription to test that it was only called a max of one times + const subscription = fixture.componentInstance.beforeViewRender.subscribe( + beforeViewRenderCalled + ); + fixture.componentInstance.viewDate = new Date('2016-06-28'); + fixture.componentInstance.ngOnChanges({ viewDate: {} }); + expect(beforeViewRenderCalled).to.have.been.calledOnce; + subscription.unsubscribe(); + fixture.destroy(); + }); + it('should expose the view period on the beforeViewRender output', () => { const fixture: ComponentFixture< CalendarWeekViewComponent