6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
- import { FactoryProvider , Injectable , OnDestroy , Optional , SkipSelf } from '@angular/core' ;
10
- import { DateAdapter } from '@angular/material/core ' ;
9
+ import { FactoryProvider , Injectable , Optional , SkipSelf , OnDestroy } from '@angular/core' ;
10
+ import { DateAdapter } from './date-adapter ' ;
11
11
import { Observable , Subject } from 'rxjs' ;
12
12
13
13
/** A class representing a range of dates. */
14
14
export class DateRange < D > {
15
- /**
16
- * Ensures that objects with a ` start` and `end` property can't be assigned to a variable that
17
- * expects a `DateRange`
18
- */
19
- // tslint:disable-next-line:no-unused-variable
20
- private _disableStructuralEquivalency : never ;
15
+ constructor (
16
+ /** The start date of the range. */
17
+ readonly start : D | null ,
18
+ /** The end date of the range. */
19
+ readonly end : D | null ) { }
20
+ }
21
21
22
- /** The start date of the range. */
23
- readonly start : D | null ;
22
+ type ExtractDateTypeFromSelection < T > = T extends DateRange < infer D > ? D : NonNullable < T > ;
24
23
25
- /** The end date of the range. */
26
- readonly end : D | null ;
24
+ /** Event emitted by the date selection model when its selection changes. */
25
+ export interface DateSelectionModelChange < S > {
26
+ /** New value for the selection. */
27
+ selection : S ;
27
28
28
- constructor ( range ?: { start ?: D | null , end ?: D | null } | null ) {
29
- this . start = range && range . start || null ;
30
- this . end = range && range . end || null ;
31
- }
29
+ /** Object that triggered the change. */
30
+ source : unknown ;
32
31
}
33
32
34
- type ExtractDateTypeFromSelection < T > = T extends DateRange < infer D > ? D : NonNullable < T > ;
35
-
36
33
/** A selection model containing a date selection. */
37
34
export abstract class MatDateSelectionModel < S , D = ExtractDateTypeFromSelection < S > >
38
35
implements OnDestroy {
39
- /** Subject used to emit value change events. */
40
- private _valueChangesSubject = new Subject < void > ( ) ;
36
+ private _selectionChanged = new Subject < DateSelectionModelChange < S > > ( ) ;
41
37
42
- /** Observable of value change events . */
43
- valueChanges : Observable < void > = this . _valueChangesSubject . asObservable ( ) ;
38
+ /** Emits when the selection has changed . */
39
+ selectionChanged : Observable < DateSelectionModelChange < S > > = this . _selectionChanged . asObservable ( ) ;
44
40
45
41
/** The current selection. */
46
- get selection ( ) : S { return this . _selection ; }
47
- set selection ( s : S ) {
48
- this . _selection = s ;
49
- this . _valueChangesSubject . next ( ) ;
42
+ readonly selection : S ;
43
+
44
+ protected constructor (
45
+ /** Date adapter used when interacting with dates in the model. */
46
+ protected readonly adapter : DateAdapter < D > ,
47
+ /** Initial selection. */
48
+ selection : S ) {
49
+ this . selection = selection ;
50
50
}
51
51
52
- protected constructor ( protected readonly adapter : DateAdapter < D > , private _selection : S ) { }
52
+ /**
53
+ * Updates the current selection in the model.
54
+ * @param value New selection that should be assigned.
55
+ * @param source Object that triggered the selection change.
56
+ */
57
+ updateSelection ( value : S , source : unknown ) {
58
+ ( this as { selection : S } ) . selection = value ;
59
+ this . _selectionChanged . next ( { selection : value , source} ) ;
60
+ }
53
61
54
62
ngOnDestroy ( ) {
55
- this . _valueChangesSubject . complete ( ) ;
63
+ this . _selectionChanged . complete ( ) ;
56
64
}
57
65
58
66
/** Adds a date to the current selection. */
@@ -61,10 +69,8 @@ export abstract class MatDateSelectionModel<S, D = ExtractDateTypeFromSelection<
61
69
/** Checks whether the current selection is complete. */
62
70
abstract isComplete ( ) : boolean ;
63
71
64
- /**
65
- * Checks whether the current selection is the same as the selection in the given selection model.
66
- */
67
- abstract isSame ( other : MatDateSelectionModel < D > ) : boolean ;
72
+ /** Checks whether the current selection is identical to the passed-in selection. */
73
+ abstract isSame ( other : S ) : boolean ;
68
74
69
75
/** Checks whether the current selection is valid. */
70
76
abstract isValid ( ) : boolean ;
@@ -76,16 +82,16 @@ export abstract class MatDateSelectionModel<S, D = ExtractDateTypeFromSelection<
76
82
/** A selection model that contains a single date. */
77
83
@Injectable ( )
78
84
export class MatSingleDateSelectionModel < D > extends MatDateSelectionModel < D | null , D > {
79
- constructor ( adapter : DateAdapter < D > , date ?: D | null ) {
80
- super ( adapter , date || null ) ;
85
+ constructor ( adapter : DateAdapter < D > ) {
86
+ super ( adapter , null ) ;
81
87
}
82
88
83
89
/**
84
90
* Adds a date to the current selection. In the case of a single date selection, the added date
85
91
* simply overwrites the previous selection
86
92
*/
87
93
add ( date : D | null ) {
88
- this . selection = date ;
94
+ super . updateSelection ( date , this ) ;
89
95
}
90
96
91
97
/**
@@ -94,12 +100,9 @@ export class MatSingleDateSelectionModel<D> extends MatDateSelectionModel<D | nu
94
100
*/
95
101
isComplete ( ) { return this . selection != null ; }
96
102
97
- /**
98
- * Checks whether the current selection is the same as the selection in the given selection model.
99
- */
100
- isSame ( other : MatDateSelectionModel < any > ) : boolean {
101
- return other instanceof MatSingleDateSelectionModel &&
102
- this . adapter . sameDate ( other . selection , this . selection ) ;
103
+ /** Checks whether the current selection is identical to the passed-in selection. */
104
+ isSame ( other : D ) : boolean {
105
+ return this . adapter . sameDate ( other , this . selection ) ;
103
106
}
104
107
105
108
/**
@@ -122,8 +125,8 @@ export class MatSingleDateSelectionModel<D> extends MatDateSelectionModel<D | nu
122
125
/** A selection model that contains a date range. */
123
126
@Injectable ( )
124
127
export class MatRangeDateSelectionModel < D > extends MatDateSelectionModel < DateRange < D > , D > {
125
- constructor ( adapter : DateAdapter < D > , range ?: { start ?: D | null , end ?: D | null } | null ) {
126
- super ( adapter , new DateRange ( range ) ) ;
128
+ constructor ( adapter : DateAdapter < D > ) {
129
+ super ( adapter , new DateRange < D > ( null , null ) ) ;
127
130
}
128
131
129
132
/**
@@ -143,7 +146,7 @@ export class MatRangeDateSelectionModel<D> extends MatDateSelectionModel<DateRan
143
146
end = null ;
144
147
}
145
148
146
- this . selection = new DateRange < D > ( { start, end} ) ;
149
+ super . updateSelection ( new DateRange < D > ( start , end ) , this ) ;
147
150
}
148
151
149
152
/**
@@ -154,15 +157,10 @@ export class MatRangeDateSelectionModel<D> extends MatDateSelectionModel<DateRan
154
157
return this . selection . start != null && this . selection . end != null ;
155
158
}
156
159
157
- /**
158
- * Checks whether the current selection is the same as the selection in the given selection model.
159
- */
160
- isSame ( other : MatDateSelectionModel < any > ) : boolean {
161
- if ( other instanceof MatRangeDateSelectionModel ) {
162
- return this . adapter . sameDate ( this . selection . start , other . selection . start ) &&
163
- this . adapter . sameDate ( this . selection . end , other . selection . end ) ;
164
- }
165
- return false ;
160
+ /** Checks whether the current selection is identical to the passed-in selection. */
161
+ isSame ( other : DateRange < D > ) : boolean {
162
+ return this . adapter . sameDate ( this . selection . start , other . start ) &&
163
+ this . adapter . sameDate ( this . selection . end , other . end ) ;
166
164
}
167
165
168
166
/**
0 commit comments