feat(expansion-panel): support two-way binding for the expanded property (#9327)

* Supports two-way binding to the `expanded` property on the expansion panel.
* Fixes som wrong indentation in the tests.

Fixes #9311.
This commit is contained in:
Kristiyan Kostadinov
2018-01-23 16:55:14 +01:00
committed by Jeremy Elbourn
parent 6f7332b748
commit a72085b5a9
3 changed files with 48 additions and 10 deletions
+10
View File
@@ -37,6 +37,14 @@ export class CdkAccordionItem implements OnDestroy {
@Output() opened: EventEmitter<void> = new EventEmitter<void>();
/** Event emitted when the AccordionItem is destroyed. */
@Output() destroyed: EventEmitter<void> = new EventEmitter<void>();
/**
* Emits whenever the expanded state of the accordion changes.
* Primarily used to facilitate two-way binding.
* @docs-private
*/
@Output() expandedChange: EventEmitter<boolean> = new EventEmitter<boolean>();
/** The unique AccordionItem id. */
readonly id: string = `cdk-accordion-child-${nextId++}`;
@@ -49,6 +57,8 @@ export class CdkAccordionItem implements OnDestroy {
// Only emit events and update the internal value if the value changes.
if (this._expanded !== expanded) {
this._expanded = expanded;
this.expandedChange.emit(expanded);
if (expanded) {
this.opened.emit();
/**
+1 -1
View File
@@ -73,7 +73,7 @@ export type MatExpansionPanelState = 'expanded' | 'collapsed';
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
inputs: ['disabled', 'expanded'],
outputs: ['opened', 'closed'],
outputs: ['opened', 'closed', 'expandedChange'],
animations: [matExpansionAnimations.bodyExpansion],
host: {
'class': 'mat-expansion-panel',
+37 -9
View File
@@ -18,6 +18,7 @@ describe('MatExpansionPanel', () => {
PanelWithCustomMargin,
LazyPanelWithContent,
LazyPanelOpenOnLoad,
PanelWithTwoWayBinding,
],
});
TestBed.compileComponents();
@@ -165,15 +166,31 @@ describe('MatExpansionPanel', () => {
expect(arrow.style.transform).toBe('rotate(180deg)', 'Expected 180 degree rotation.');
}));
it('make sure accordion item runs ngOnDestroy when expansion panel is destroyed', () => {
let fixture = TestBed.createComponent(PanelWithContentInNgIf);
fixture.detectChanges();
let destroyedOk = false;
fixture.componentInstance.panel.destroyed.subscribe(() => destroyedOk = true);
fixture.componentInstance.expansionShown = false;
fixture.detectChanges();
expect(destroyedOk).toBe(true);
});
it('should make sure accordion item runs ngOnDestroy when expansion panel is destroyed', () => {
let fixture = TestBed.createComponent(PanelWithContentInNgIf);
fixture.detectChanges();
let destroyedOk = false;
fixture.componentInstance.panel.destroyed.subscribe(() => destroyedOk = true);
fixture.componentInstance.expansionShown = false;
fixture.detectChanges();
expect(destroyedOk).toBe(true);
});
it('should support two-way binding of the `expanded` property', () => {
const fixture = TestBed.createComponent(PanelWithTwoWayBinding);
const header = fixture.debugElement.query(By.css('mat-expansion-panel-header')).nativeElement;
fixture.detectChanges();
expect(fixture.componentInstance.expanded).toBe(false);
header.click();
fixture.detectChanges();
expect(fixture.componentInstance.expanded).toBe(true);
header.click();
fixture.detectChanges();
expect(fixture.componentInstance.expanded).toBe(false);
});
describe('disabled state', () => {
let fixture: ComponentFixture<PanelWithContent>;
@@ -313,3 +330,14 @@ class LazyPanelWithContent {
</mat-expansion-panel>`
})
class LazyPanelOpenOnLoad {}
@Component({
template: `
<mat-expansion-panel [(expanded)]="expanded">
<mat-expansion-panel-header>Panel Title</mat-expansion-panel-header>
</mat-expansion-panel>`
})
class PanelWithTwoWayBinding {
expanded = false;
}