mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(datepicker): calendar input changes not being propagated on child views (#12004)
Fixes the new values for the calendar's `minDate`, `maxDate` and `dateFilter` not being propagated to the current calendar view until the next change detection cycle. Fixes #11737.
This commit is contained in:
committed by
Jeremy Elbourn
parent
32da0388ce
commit
b1d4fe15b7
@@ -10,7 +10,7 @@ import {
|
||||
} from '@angular/cdk/testing';
|
||||
import {Component, NgZone} from '@angular/core';
|
||||
import {ComponentFixture, TestBed, async, inject} from '@angular/core/testing';
|
||||
import {DEC, FEB, JAN, MatNativeDateModule, NOV} from '@angular/material/core';
|
||||
import {DEC, FEB, JAN, MatNativeDateModule, NOV, JUL} from '@angular/material/core';
|
||||
import {By} from '@angular/platform-browser';
|
||||
import {Direction, Directionality} from '@angular/cdk/bidi';
|
||||
import {MatCalendar} from './calendar';
|
||||
@@ -32,6 +32,7 @@ describe('MatCalendar', () => {
|
||||
StandardCalendar,
|
||||
CalendarWithMinMax,
|
||||
CalendarWithDateFilter,
|
||||
CalendarWithSelectableMinDate,
|
||||
],
|
||||
providers: [
|
||||
MatDatepickerIntl,
|
||||
@@ -399,6 +400,37 @@ describe('MatCalendar', () => {
|
||||
|
||||
expect(calendarInstance.multiYearView._init).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update the minDate in the child view if it changed after an interaction', () => {
|
||||
fixture.destroy();
|
||||
|
||||
const dynamicFixture = TestBed.createComponent(CalendarWithSelectableMinDate);
|
||||
dynamicFixture.detectChanges();
|
||||
|
||||
const calendarDebugElement = dynamicFixture.debugElement.query(By.directive(MatCalendar));
|
||||
const disabledClass = 'mat-calendar-body-disabled';
|
||||
calendarElement = calendarDebugElement.nativeElement;
|
||||
calendarInstance = calendarDebugElement.componentInstance;
|
||||
|
||||
let cells = Array.from(calendarElement.querySelectorAll('.mat-calendar-body-cell'));
|
||||
|
||||
expect(cells.slice(0, 9).every(c => c.classList.contains(disabledClass)))
|
||||
.toBe(true, 'Expected dates up to the 10th to be disabled.');
|
||||
|
||||
expect(cells.slice(9).every(c => c.classList.contains(disabledClass)))
|
||||
.toBe(false, 'Expected dates after the 10th to be enabled.');
|
||||
|
||||
(cells[14] as HTMLElement).click();
|
||||
dynamicFixture.detectChanges();
|
||||
cells = Array.from(calendarElement.querySelectorAll('.mat-calendar-body-cell'));
|
||||
|
||||
expect(cells.slice(0, 14).every(c => c.classList.contains(disabledClass)))
|
||||
.toBe(true, 'Expected dates up to the 14th to be disabled.');
|
||||
|
||||
expect(cells.slice(14).every(c => c.classList.contains(disabledClass)))
|
||||
.toBe(false, 'Expected dates after the 14th to be enabled.');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('calendar with date filter', () => {
|
||||
@@ -521,3 +553,28 @@ class CalendarWithDateFilter {
|
||||
return !(date.getDate() % 2) && date.getMonth() !== NOV;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<mat-calendar
|
||||
[startAt]="startAt"
|
||||
(selectedChange)="select($event)"
|
||||
[selected]="selected"
|
||||
[minDate]="selected">
|
||||
</mat-calendar>
|
||||
`
|
||||
})
|
||||
class CalendarWithSelectableMinDate {
|
||||
startAt = new Date(2018, JUL, 0);
|
||||
selected: Date;
|
||||
minDate: Date;
|
||||
|
||||
constructor() {
|
||||
this.select(new Date(2018, JUL, 10));
|
||||
}
|
||||
|
||||
select(value: Date) {
|
||||
this.minDate = this.selected = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ export class MatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes
|
||||
constructor(_intl: MatDatepickerIntl,
|
||||
@Optional() private _dateAdapter: DateAdapter<D>,
|
||||
@Optional() @Inject(MAT_DATE_FORMATS) private _dateFormats: MatDateFormats,
|
||||
changeDetectorRef: ChangeDetectorRef) {
|
||||
private _changeDetectorRef: ChangeDetectorRef) {
|
||||
|
||||
if (!this._dateAdapter) {
|
||||
throw createMissingDateImplError('DateAdapter');
|
||||
@@ -288,7 +288,7 @@ export class MatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes
|
||||
}
|
||||
|
||||
this._intlChanges = _intl.changes.subscribe(() => {
|
||||
changeDetectorRef.markForCheck();
|
||||
_changeDetectorRef.markForCheck();
|
||||
this.stateChanges.next();
|
||||
});
|
||||
}
|
||||
@@ -320,6 +320,9 @@ export class MatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes
|
||||
const view = this._getCurrentViewComponent();
|
||||
|
||||
if (view) {
|
||||
// We need to `detectChanges` manually here, because the `minDate`, `maxDate` etc. are
|
||||
// passed down to the view via data bindings which won't be up-to-date when we call `_init`.
|
||||
this._changeDetectorRef.detectChanges();
|
||||
view._init();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user