diff --git a/src/lib/expansion/accordion-item.ts b/src/lib/expansion/accordion-item.ts index 107f799c2377..785a79755f71 100644 --- a/src/lib/expansion/accordion-item.ts +++ b/src/lib/expansion/accordion-item.ts @@ -35,8 +35,10 @@ export class AccordionItem implements OnDestroy { @Output() destroyed = new EventEmitter(); /** The unique MdAccordionChild id. */ readonly id = `cdk-accordion-child-${nextId++}`; + /** Whether the MdAccordionChild is expanded. */ - @Input() get expanded(): boolean { return this._expanded; } + @Input() + get expanded(): boolean { return this._expanded; } set expanded(expanded: boolean) { // Only emit events and update the internal value if the value changes. if (this._expanded !== expanded) { diff --git a/src/lib/expansion/expansion-panel-header.ts b/src/lib/expansion/expansion-panel-header.ts index 1ca826cd5f68..18d7311e7bec 100644 --- a/src/lib/expansion/expansion-panel-header.ts +++ b/src/lib/expansion/expansion-panel-header.ts @@ -12,6 +12,8 @@ import { Host, ViewEncapsulation, ChangeDetectionStrategy, + ChangeDetectorRef, + OnDestroy, } from '@angular/core'; import { trigger, @@ -22,6 +24,9 @@ import { } from '@angular/animations'; import {SPACE, ENTER} from '../core/keyboard/keycodes'; import {MdExpansionPanel, EXPANSION_PANEL_ANIMATION_TIMING} from './expansion-panel'; +import {filter} from '../core/rxjs/index'; +import {merge} from 'rxjs/observable/merge'; +import {Subscription} from 'rxjs/Subscription'; /** @@ -62,8 +67,22 @@ import {MdExpansionPanel, EXPANSION_PANEL_ANIMATION_TIMING} from './expansion-pa ]), ], }) -export class MdExpansionPanelHeader { - constructor(@Host() public panel: MdExpansionPanel) {} +export class MdExpansionPanelHeader implements OnDestroy { + private _parentChangeSubscription: Subscription | null = null; + + constructor( + @Host() public panel: MdExpansionPanel, + private _changeDetectorRef: ChangeDetectorRef) { + + // Since the toggle state depends on an @Input on the panel, we + // need to subscribe and trigger change detection manually. + this._parentChangeSubscription = merge( + panel.opened, + panel.closed, + filter.call(panel._inputChanges, changes => !!changes.hideToggle) + ) + .subscribe(() => this._changeDetectorRef.markForCheck()); + } /** Toggles the expanded state of the panel. */ _toggle(): void { @@ -103,6 +122,13 @@ export class MdExpansionPanelHeader { return; } } + + ngOnDestroy() { + if (this._parentChangeSubscription) { + this._parentChangeSubscription.unsubscribe(); + this._parentChangeSubscription = null; + } + } } /** diff --git a/src/lib/expansion/expansion-panel.ts b/src/lib/expansion/expansion-panel.ts index 8bdc8c1758ba..258ec09bd44e 100644 --- a/src/lib/expansion/expansion-panel.ts +++ b/src/lib/expansion/expansion-panel.ts @@ -16,6 +16,9 @@ import { forwardRef, ChangeDetectionStrategy, ChangeDetectorRef, + SimpleChanges, + OnChanges, + OnDestroy, } from '@angular/core'; import { trigger, @@ -27,6 +30,7 @@ import { import {MdAccordion, MdAccordionDisplayMode} from './accordion'; import {AccordionItem} from './accordion-item'; import {UniqueSelectionDispatcher} from '../core'; +import {Subject} from 'rxjs/Subject'; /** MdExpansionPanel's states. */ @@ -73,10 +77,13 @@ export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2, ]), ], }) -export class MdExpansionPanel extends AccordionItem { +export class MdExpansionPanel extends AccordionItem implements OnChanges, OnDestroy { /** Whether the toggle indicator should be hidden. */ @Input() hideToggle: boolean = false; + /** Stream that emits for changes in `@Input` properties. */ + _inputChanges = new Subject(); + constructor(@Optional() @Host() accordion: MdAccordion, _changeDetectorRef: ChangeDetectorRef, _uniqueSelectionDispatcher: UniqueSelectionDispatcher) { @@ -107,6 +114,14 @@ export class MdExpansionPanel extends AccordionItem { _getExpandedState(): MdExpansionPanelState { return this.expanded ? 'expanded' : 'collapsed'; } + + ngOnChanges(changes: SimpleChanges) { + this._inputChanges.next(changes); + } + + ngOnDestroy() { + this._inputChanges.complete(); + } } @Directive({