@@ -36,16 +36,7 @@ import {BooleanInput, coerceArray, coerceBooleanProperty} from '@angular/cdk/coe
36
36
import { SelectionModel } from '@angular/cdk/collections' ;
37
37
import { defer , merge , Observable , Subject } from 'rxjs' ;
38
38
import { filter , map , startWith , switchMap , takeUntil } from 'rxjs/operators' ;
39
- import {
40
- AbstractControl ,
41
- ControlValueAccessor ,
42
- NG_VALIDATORS ,
43
- NG_VALUE_ACCESSOR ,
44
- ValidationErrors ,
45
- Validator ,
46
- ValidatorFn ,
47
- Validators ,
48
- } from '@angular/forms' ;
39
+ import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms' ;
49
40
import { Directionality } from '@angular/cdk/bidi' ;
50
41
51
42
/** The next id to use for creating unique DOM IDs. */
@@ -256,16 +247,9 @@ export class CdkOption<T = unknown> implements ListKeyManagerOption, Highlightab
256
247
useExisting : forwardRef ( ( ) => CdkListbox ) ,
257
248
multi : true ,
258
249
} ,
259
- {
260
- provide : NG_VALIDATORS ,
261
- useExisting : forwardRef ( ( ) => CdkListbox ) ,
262
- multi : true ,
263
- } ,
264
250
] ,
265
251
} )
266
- export class CdkListbox < T = unknown >
267
- implements AfterContentInit , OnDestroy , ControlValueAccessor , Validator
268
- {
252
+ export class CdkListbox < T = unknown > implements AfterContentInit , OnDestroy , ControlValueAccessor {
269
253
/** The id of the option's host element. */
270
254
@Input ( )
271
255
get id ( ) {
@@ -416,9 +400,6 @@ export class CdkListbox<T = unknown>
416
400
/** Callback called when the listbox value changes */
417
401
private _onChange : ( value : readonly T [ ] ) => void = ( ) => { } ;
418
402
419
- /** Callback called when the form validator changes. */
420
- private _onValidatorChange = ( ) => { } ;
421
-
422
403
/** Emits when an option has been clicked. */
423
404
private _optionClicked = defer ( ( ) =>
424
405
( this . options . changes as Observable < CdkOption < T > [ ] > ) . pipe (
@@ -438,40 +419,6 @@ export class CdkListbox<T = unknown>
438
419
/** A predicate that does not skip any options. */
439
420
private readonly _skipNonePredicate = ( ) => false ;
440
421
441
- /**
442
- * Validator that produces an error if multiple values are selected in a single selection
443
- * listbox.
444
- * @param control The control to validate
445
- * @return A validation error or null
446
- */
447
- private _validateUnexpectedMultipleValues : ValidatorFn = ( control : AbstractControl ) => {
448
- const controlValue = this . _coerceValue ( control . value ) ;
449
- if ( ! this . multiple && controlValue . length > 1 ) {
450
- return { 'cdkListboxUnexpectedMultipleValues' : true } ;
451
- }
452
- return null ;
453
- } ;
454
-
455
- /**
456
- * Validator that produces an error if any selected values are not valid options for this listbox.
457
- * @param control The control to validate
458
- * @return A validation error or null
459
- */
460
- private _validateUnexpectedOptionValues : ValidatorFn = ( control : AbstractControl ) => {
461
- const controlValue = this . _coerceValue ( control . value ) ;
462
- const invalidValues = this . _getInvalidOptionValues ( controlValue ) ;
463
- if ( invalidValues . length ) {
464
- return { 'cdkListboxUnexpectedOptionValues' : { 'values' : invalidValues } } ;
465
- }
466
- return null ;
467
- } ;
468
-
469
- /** The combined set of validators for this listbox. */
470
- private _validators = Validators . compose ( [
471
- this . _validateUnexpectedMultipleValues ,
472
- this . _validateUnexpectedOptionValues ,
473
- ] ) ! ;
474
-
475
422
ngAfterContentInit ( ) {
476
423
if ( typeof ngDevMode === 'undefined' || ngDevMode ) {
477
424
this . _verifyNoOptionValueCollisions ( ) ;
@@ -614,6 +561,19 @@ export class CdkListbox<T = unknown>
614
561
*/
615
562
writeValue ( value : readonly T [ ] ) : void {
616
563
this . _setSelection ( value ) ;
564
+
565
+ if ( typeof ngDevMode === 'undefined' || ngDevMode ) {
566
+ const selected = this . selectionModel . selected ;
567
+ const invalidValues = this . _getInvalidOptionValues ( selected ) ;
568
+
569
+ if ( ! this . multiple && selected . length > 1 ) {
570
+ throw Error ( 'Listbox cannot have more than one selected value in multi-selection mode.' ) ;
571
+ }
572
+
573
+ if ( invalidValues . length ) {
574
+ throw Error ( 'Listbox has selected values that do not match any of its options.' ) ;
575
+ }
576
+ }
617
577
}
618
578
619
579
/**
@@ -625,23 +585,6 @@ export class CdkListbox<T = unknown>
625
585
this . disabled = isDisabled ;
626
586
}
627
587
628
- /**
629
- * Validate the given control
630
- * @docs -private
631
- */
632
- validate ( control : AbstractControl < any , any > ) : ValidationErrors | null {
633
- return this . _validators ( control ) ;
634
- }
635
-
636
- /**
637
- * Registers a callback to be called when the form validator changes.
638
- * @param fn The callback to call
639
- * @docs -private
640
- */
641
- registerOnValidatorChange ( fn : ( ) => void ) {
642
- this . _onValidatorChange = fn ;
643
- }
644
-
645
588
/** Focus the listbox's host element. */
646
589
focus ( ) {
647
590
this . element . focus ( ) ;
@@ -901,7 +844,6 @@ export class CdkListbox<T = unknown>
901
844
const selected = this . selectionModel . selected ;
902
845
this . _invalid =
903
846
( ! this . multiple && selected . length > 1 ) || ! ! this . _getInvalidOptionValues ( selected ) . length ;
904
- this . _onValidatorChange ( ) ;
905
847
this . changeDetectorRef . markForCheck ( ) ;
906
848
}
907
849
0 commit comments