Skip to content

Commit 0342642

Browse files
committed
fix(expansion-panel): toggle not being updated when set programmatically
Fixes the toggle arrow not being flipped when the `expanded` is set programmatically, in addition to the `hideToggle` input not working either. This is a regression from #5549 and is a consequence of the fact that the panel header reaches into the panel to determine what to do with the arrow. Fixes #5623.
1 parent 3bfe7f0 commit 0342642

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

src/lib/expansion/accordion-item.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ export class AccordionItem implements OnDestroy {
3535
@Output() destroyed = new EventEmitter<void>();
3636
/** The unique MdAccordionChild id. */
3737
readonly id = `cdk-accordion-child-${nextId++}`;
38+
3839
/** Whether the MdAccordionChild is expanded. */
39-
@Input() get expanded(): boolean { return this._expanded; }
40+
@Input()
41+
get expanded(): boolean { return this._expanded; }
4042
set expanded(expanded: boolean) {
4143
// Only emit events and update the internal value if the value changes.
4244
if (this._expanded !== expanded) {

src/lib/expansion/expansion-panel-header.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
Host,
1313
ViewEncapsulation,
1414
ChangeDetectionStrategy,
15+
ChangeDetectorRef,
16+
OnDestroy,
1517
} from '@angular/core';
1618
import {
1719
trigger,
@@ -22,6 +24,9 @@ import {
2224
} from '@angular/animations';
2325
import {SPACE, ENTER} from '../core/keyboard/keycodes';
2426
import {MdExpansionPanel, EXPANSION_PANEL_ANIMATION_TIMING} from './expansion-panel';
27+
import {filter} from '../core/rxjs/index';
28+
import {merge} from 'rxjs/observable/merge';
29+
import {Subscription} from 'rxjs/Subscription';
2530

2631

2732
/**
@@ -62,8 +67,22 @@ import {MdExpansionPanel, EXPANSION_PANEL_ANIMATION_TIMING} from './expansion-pa
6267
]),
6368
],
6469
})
65-
export class MdExpansionPanelHeader {
66-
constructor(@Host() public panel: MdExpansionPanel) {}
70+
export class MdExpansionPanelHeader implements OnDestroy {
71+
private _parentChangeSubscription: Subscription | null = null;
72+
73+
constructor(
74+
@Host() public panel: MdExpansionPanel,
75+
private _changeDetectorRef: ChangeDetectorRef) {
76+
77+
// Since the toggle state depends on an @Input on the panel, we
78+
// need to subscribe and trigger change detection manually.
79+
this._parentChangeSubscription = merge(
80+
panel.opened,
81+
panel.closed,
82+
filter.call(panel._inputChanges, changes => !!changes.hideToggle)
83+
)
84+
.subscribe(() => this._changeDetectorRef.markForCheck());
85+
}
6786

6887
/** Toggles the expanded state of the panel. */
6988
_toggle(): void {
@@ -103,6 +122,13 @@ export class MdExpansionPanelHeader {
103122
return;
104123
}
105124
}
125+
126+
ngOnDestroy() {
127+
if (this._parentChangeSubscription) {
128+
this._parentChangeSubscription.unsubscribe();
129+
this._parentChangeSubscription = null;
130+
}
131+
}
106132
}
107133

108134
/**

src/lib/expansion/expansion-panel.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import {
1616
forwardRef,
1717
ChangeDetectionStrategy,
1818
ChangeDetectorRef,
19+
SimpleChanges,
20+
OnChanges,
21+
OnDestroy,
1922
} from '@angular/core';
2023
import {
2124
trigger,
@@ -27,6 +30,7 @@ import {
2730
import {MdAccordion, MdAccordionDisplayMode} from './accordion';
2831
import {AccordionItem} from './accordion-item';
2932
import {UniqueSelectionDispatcher} from '../core';
33+
import {Subject} from 'rxjs/Subject';
3034

3135

3236
/** MdExpansionPanel's states. */
@@ -72,10 +76,13 @@ export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,
7276
]),
7377
],
7478
})
75-
export class MdExpansionPanel extends AccordionItem {
79+
export class MdExpansionPanel extends AccordionItem implements OnChanges, OnDestroy {
7680
/** Whether the toggle indicator should be hidden. */
7781
@Input() hideToggle: boolean = false;
7882

83+
/** Stream that emits for changes in `@Input` properties. */
84+
_inputChanges = new Subject<SimpleChanges>();
85+
7986
constructor(@Optional() @Host() accordion: MdAccordion,
8087
_changeDetectorRef: ChangeDetectorRef,
8188
_uniqueSelectionDispatcher: UniqueSelectionDispatcher) {
@@ -104,6 +111,14 @@ export class MdExpansionPanel extends AccordionItem {
104111
_getExpandedState(): MdExpansionPanelState {
105112
return this.expanded ? 'expanded' : 'collapsed';
106113
}
114+
115+
ngOnChanges(changes: SimpleChanges) {
116+
this._inputChanges.next(changes);
117+
}
118+
119+
ngOnDestroy() {
120+
this._inputChanges.complete();
121+
}
107122
}
108123

109124
@Directive({

0 commit comments

Comments
 (0)