From c67337b7162c87ce0caa98bca793e52783d5428d Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 20 Apr 2020 16:49:06 +0200 Subject: [PATCH] fix(chips): chip list disabled state out of sync when swapping out form group with a disabled one (#17993) Related to #17872. Ensures that the chip list's disabled state is in sync with its form control, if the control is swapped out with a disabled one. --- src/material/chips/chip-list.spec.ts | 55 +++++++++++++++++++++++++++- src/material/chips/chip-list.ts | 4 ++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/material/chips/chip-list.spec.ts b/src/material/chips/chip-list.spec.ts index d18f6e534a52..09f0901fdce7 100644 --- a/src/material/chips/chip-list.spec.ts +++ b/src/material/chips/chip-list.spec.ts @@ -32,7 +32,15 @@ import { ChangeDetectionStrategy, } from '@angular/core'; import {ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; -import {FormControl, FormsModule, NgForm, ReactiveFormsModule, Validators} from '@angular/forms'; +import { + FormControl, + FormsModule, + NgForm, + ReactiveFormsModule, + Validators, + FormGroup, + FormBuilder, +} from '@angular/forms'; import {MatFormFieldModule} from '@angular/material/form-field'; import {By} from '@angular/platform-browser'; import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations'; @@ -935,6 +943,23 @@ describe('MatChipList', () => { .toBeFalsy(`Expected chip with the old value not to be selected.`); }); }); + + it('should keep the disabled state in sync if the form group is swapped and ' + + 'disabled at the same time', fakeAsync(() => { + fixture = createComponent(ChipListInsideDynamicFormGroup); + fixture.detectChanges(); + const instance = fixture.componentInstance; + const list: MatChipList = instance.chipList; + + expect(list.disabled).toBe(false); + expect(list.chips.toArray().every(chip => chip.disabled)).toBe(false); + + instance.assignGroup(true); + fixture.detectChanges(); + + expect(list.disabled).toBe(true); + expect(list.chips.toArray().every(chip => chip.disabled)).toBe(true); + })); }); describe('chip list with chip input', () => { @@ -1642,3 +1667,31 @@ class ChipListWithRemove { class PreselectedChipInsideOnPush { control = new FormControl('Pizza'); } + + +@Component({ + template: ` +
+ + + Pizza + Pasta + + +
+ ` +}) +class ChipListInsideDynamicFormGroup { + @ViewChild(MatChipList) chipList: MatChipList; + form: FormGroup; + + constructor(private _formBuilder: FormBuilder) { + this.assignGroup(false); + } + + assignGroup(isDisabled: boolean) { + this.form = this._formBuilder.group({ + control: {value: [], disabled: isDisabled} + }); + } +} diff --git a/src/material/chips/chip-list.ts b/src/material/chips/chip-list.ts index 1401774a9176..832828b923c1 100644 --- a/src/material/chips/chip-list.ts +++ b/src/material/chips/chip-list.ts @@ -399,6 +399,10 @@ export class MatChipList extends _MatChipListMixinBase implements MatFormFieldCo // error triggers that we can't subscribe to (e.g. parent form submissions). This means // that whatever logic is in here has to be super lean or we risk destroying the performance. this.updateErrorState(); + + if (this.ngControl.disabled !== this._disabled) { + this.disabled = !!this.ngControl.disabled; + } } }