fix(listKeyManager): use a subject instead of emitter (#1646)

This commit is contained in:
Kara
2016-11-01 13:53:12 -07:00
committed by Hans
parent 0883fb295f
commit 3ee1b599de
2 changed files with 31 additions and 11 deletions
+13 -8
View File
@@ -1,5 +1,7 @@
import {EventEmitter, Output, QueryList} from '@angular/core';
import {QueryList} from '@angular/core';
import {UP_ARROW, DOWN_ARROW, TAB} from '../core';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
/**
* This is the interface for focusable items (used by the ListKeyManager).
@@ -16,15 +18,18 @@ export interface MdFocusable {
*/
export class ListKeyManager {
private _focusedItemIndex: number;
/**
* This event is emitted any time the TAB key is pressed, so components can react
* when focus is shifted off of the list.
*/
@Output() tabOut = new EventEmitter<void>();
private _tabOut: Subject<any> = new Subject();
constructor(private _items: QueryList<MdFocusable>) {}
/**
* Observable that emits any time the TAB key is pressed, so components can react
* when focus is shifted off of the list.
*/
get tabOut(): Observable<void> {
return this._tabOut.asObservable();
}
set focusedItemIndex(value: number) {
this._focusedItemIndex = value;
}
@@ -35,7 +40,7 @@ export class ListKeyManager {
} else if (event.keyCode === UP_ARROW) {
this._focusPreviousItem();
} else if (event.keyCode === TAB) {
this.tabOut.emit();
this._tabOut.next(null);
}
}
+18 -3
View File
@@ -1,11 +1,13 @@
// TODO(kara): prevent-close functionality
import {
AfterContentInit,
Attribute,
Component,
ContentChildren,
EventEmitter,
Input,
OnDestroy,
Output,
QueryList,
TemplateRef,
@@ -17,6 +19,7 @@ import {MdMenuInvalidPositionX, MdMenuInvalidPositionY} from './menu-errors';
import {MdMenuItem} from './menu-item';
import {ListKeyManager} from '../core/a11y/list-key-manager';
import {MdMenuPanel} from './menu-panel';
import {Subscription} from 'rxjs/Subscription';
@Component({
moduleId: module.id,
@@ -27,10 +30,13 @@ import {MdMenuPanel} from './menu-panel';
encapsulation: ViewEncapsulation.None,
exportAs: 'mdMenu'
})
export class MdMenu implements MdMenuPanel {
export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
private _keyManager: ListKeyManager;
// config object to be passed into the menu's ngClass
/** Subscription to tab events on the menu panel */
private _tabSubscription: Subscription;
/** Config object to be passed into the menu's ngClass */
_classList: Object;
positionX: MenuPositionX = 'after';
@@ -45,11 +51,20 @@ export class MdMenu implements MdMenuPanel {
if (posY) { this._setPositionY(posY); }
}
// TODO: internal
ngAfterContentInit() {
this._keyManager = new ListKeyManager(this.items);
this._keyManager.tabOut.subscribe(() => this._emitCloseEvent());
this._tabSubscription = this._keyManager.tabOut.subscribe(() => {
this._emitCloseEvent();
});
}
// TODO: internal
ngOnDestroy() {
this._tabSubscription.unsubscribe();
}
/**
* This method takes classes set on the host md-menu element and applies them on the
* menu template that displays in the overlay container. Otherwise, it's difficult