Skip to content

Commit 3ee1b59

Browse files
karahansl
authored andcommitted
fix(listKeyManager): use a subject instead of emitter (#1646)
1 parent 0883fb2 commit 3ee1b59

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

src/lib/core/a11y/list-key-manager.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import {EventEmitter, Output, QueryList} from '@angular/core';
1+
import {QueryList} from '@angular/core';
22
import {UP_ARROW, DOWN_ARROW, TAB} from '../core';
3+
import {Observable} from 'rxjs/Observable';
4+
import {Subject} from 'rxjs/Subject';
35

46
/**
57
* This is the interface for focusable items (used by the ListKeyManager).
@@ -16,14 +18,17 @@ export interface MdFocusable {
1618
*/
1719
export class ListKeyManager {
1820
private _focusedItemIndex: number;
21+
private _tabOut: Subject<any> = new Subject();
22+
23+
constructor(private _items: QueryList<MdFocusable>) {}
1924

2025
/**
21-
* This event is emitted any time the TAB key is pressed, so components can react
26+
* Observable that emits any time the TAB key is pressed, so components can react
2227
* when focus is shifted off of the list.
2328
*/
24-
@Output() tabOut = new EventEmitter<void>();
25-
26-
constructor(private _items: QueryList<MdFocusable>) {}
29+
get tabOut(): Observable<void> {
30+
return this._tabOut.asObservable();
31+
}
2732

2833
set focusedItemIndex(value: number) {
2934
this._focusedItemIndex = value;
@@ -35,7 +40,7 @@ export class ListKeyManager {
3540
} else if (event.keyCode === UP_ARROW) {
3641
this._focusPreviousItem();
3742
} else if (event.keyCode === TAB) {
38-
this.tabOut.emit();
43+
this._tabOut.next(null);
3944
}
4045
}
4146

src/lib/menu/menu-directive.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// TODO(kara): prevent-close functionality
22

33
import {
4+
AfterContentInit,
45
Attribute,
56
Component,
67
ContentChildren,
78
EventEmitter,
89
Input,
10+
OnDestroy,
911
Output,
1012
QueryList,
1113
TemplateRef,
@@ -17,6 +19,7 @@ import {MdMenuInvalidPositionX, MdMenuInvalidPositionY} from './menu-errors';
1719
import {MdMenuItem} from './menu-item';
1820
import {ListKeyManager} from '../core/a11y/list-key-manager';
1921
import {MdMenuPanel} from './menu-panel';
22+
import {Subscription} from 'rxjs/Subscription';
2023

2124
@Component({
2225
moduleId: module.id,
@@ -27,10 +30,13 @@ import {MdMenuPanel} from './menu-panel';
2730
encapsulation: ViewEncapsulation.None,
2831
exportAs: 'mdMenu'
2932
})
30-
export class MdMenu implements MdMenuPanel {
33+
export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
3134
private _keyManager: ListKeyManager;
3235

33-
// config object to be passed into the menu's ngClass
36+
/** Subscription to tab events on the menu panel */
37+
private _tabSubscription: Subscription;
38+
39+
/** Config object to be passed into the menu's ngClass */
3440
_classList: Object;
3541

3642
positionX: MenuPositionX = 'after';
@@ -45,11 +51,20 @@ export class MdMenu implements MdMenuPanel {
4551
if (posY) { this._setPositionY(posY); }
4652
}
4753

54+
// TODO: internal
4855
ngAfterContentInit() {
4956
this._keyManager = new ListKeyManager(this.items);
50-
this._keyManager.tabOut.subscribe(() => this._emitCloseEvent());
57+
this._tabSubscription = this._keyManager.tabOut.subscribe(() => {
58+
this._emitCloseEvent();
59+
});
60+
}
61+
62+
// TODO: internal
63+
ngOnDestroy() {
64+
this._tabSubscription.unsubscribe();
5165
}
5266

67+
5368
/**
5469
* This method takes classes set on the host md-menu element and applies them on the
5570
* menu template that displays in the overlay container. Otherwise, it's difficult

0 commit comments

Comments
 (0)