@@ -411,13 +411,10 @@ export abstract class _MatSelectBase<C>
411411 return this . _value ;
412412 }
413413 set value ( newValue : any ) {
414- // Always re-assign an array, because it might have been mutated.
415- if ( newValue !== this . _value || ( this . _multiple && Array . isArray ( newValue ) ) ) {
416- if ( this . options ) {
417- this . _setSelectionByValue ( newValue ) ;
418- }
414+ const hasAssigned = this . _assignValue ( newValue ) ;
419415
420- this . _value = newValue ;
416+ if ( hasAssigned ) {
417+ this . _onChange ( newValue ) ;
421418 }
422419 }
423420 private _value : any ;
@@ -649,7 +646,7 @@ export abstract class _MatSelectBase<C>
649646 * @param value New value to be written to the model.
650647 */
651648 writeValue ( value : any ) : void {
652- this . value = value ;
649+ this . _assignValue ( value ) ;
653650 }
654651
655652 /**
@@ -874,10 +871,10 @@ export abstract class _MatSelectBase<C>
874871 throw getMatSelectNonArrayValueError ( ) ;
875872 }
876873
877- value . forEach ( ( currentValue : any ) => this . _selectValue ( currentValue ) ) ;
874+ value . forEach ( ( currentValue : any ) => this . _selectOptionByValue ( currentValue ) ) ;
878875 this . _sortValues ( ) ;
879876 } else {
880- const correspondingOption = this . _selectValue ( value ) ;
877+ const correspondingOption = this . _selectOptionByValue ( value ) ;
881878
882879 // Shift focus to the active item. Note that we shouldn't do this in multiple
883880 // mode, because we don't know what option the user interacted with last.
@@ -897,7 +894,7 @@ export abstract class _MatSelectBase<C>
897894 * Finds and selects and option based on its value.
898895 * @returns Option that has the corresponding value.
899896 */
900- private _selectValue ( value : any ) : MatOption | undefined {
897+ private _selectOptionByValue ( value : any ) : MatOption | undefined {
901898 const correspondingOption = this . options . find ( ( option : MatOption ) => {
902899 // Skip options that are already in the model. This allows us to handle cases
903900 // where the same primitive value is selected multiple times.
@@ -924,6 +921,20 @@ export abstract class _MatSelectBase<C>
924921 return correspondingOption ;
925922 }
926923
924+ /** Assigns a specific value to the select. Returns whether the value has changed. */
925+ private _assignValue ( newValue : any | any [ ] ) : boolean {
926+ // Always re-assign an array, because it might have been mutated.
927+ if ( newValue !== this . _value || ( this . _multiple && Array . isArray ( newValue ) ) ) {
928+ if ( this . options ) {
929+ this . _setSelectionByValue ( newValue ) ;
930+ }
931+
932+ this . _value = newValue ;
933+ return true ;
934+ }
935+ return false ;
936+ }
937+
927938 /** Sets up a key manager to listen to keyboard events on the overlay panel. */
928939 private _initKeyManager ( ) {
929940 this . _keyManager = new ActiveDescendantKeyManager < MatOption > ( this . options )
0 commit comments