mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(listKeyManager): use a subject instead of emitter (#1646)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user