Skip to content

Commit c08f00a

Browse files
committed
fix(drawer): drawer running inside the zone keydown event.
Currently the drawer is listening to the event 'keydown' inside the zone. This makes the change detector be fired every time while whe are pressing 'any' key.
1 parent fe49345 commit c08f00a

File tree

2 files changed

+16
-13
lines changed

2 files changed

+16
-13
lines changed

src/lib/sidenav/drawer.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {startWith} from 'rxjs/operators/startWith';
4141
import {takeUntil} from 'rxjs/operators/takeUntil';
4242
import {debounceTime} from 'rxjs/operators/debounceTime';
4343
import {map} from 'rxjs/operators/map';
44+
import {fromEvent} from 'rxjs/observable/fromEvent';
4445
import {Subject} from 'rxjs/Subject';
4546
import {Observable} from 'rxjs/Observable';
4647
import {matDrawerAnimations} from './drawer-animations';
@@ -119,7 +120,6 @@ export class MatDrawerContent implements AfterContentInit {
119120
'[@transform]': '_animationState',
120121
'(@transform.start)': '_onAnimationStart($event)',
121122
'(@transform.done)': '_onAnimationEnd($event)',
122-
'(keydown)': 'handleKeydown($event)',
123123
// must prevent the browser from aligning text based on value
124124
'[attr.align]': 'null',
125125
'[class.mat-drawer-end]': 'position === "end"',
@@ -258,6 +258,7 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr
258258
private _focusTrapFactory: FocusTrapFactory,
259259
private _focusMonitor: FocusMonitor,
260260
private _platform: Platform,
261+
private _ngZone: NgZone,
261262
@Optional() @Inject(DOCUMENT) private _doc: any) {
262263

263264
this.openedChange.subscribe((opened: boolean) => {
@@ -273,6 +274,20 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr
273274
this._restoreFocus();
274275
}
275276
});
277+
278+
/**
279+
* Listen to `keydown` events outside the zone so that change detection is not run every
280+
* time a key is pressed. Instead we re-enter the zone only if the `ESC` key is pressed
281+
* and we don't have close disabled.
282+
*/
283+
this._ngZone.runOutsideAngular(() => {
284+
fromEvent(this._elementRef.nativeElement, 'keydown').pipe(
285+
filter((event: KeyboardEvent) => event.keyCode === ESCAPE && !this.disableClose)
286+
).subscribe((event) => this._ngZone.run(() => {
287+
this.close();
288+
event.stopPropagation();
289+
}));
290+
});
276291
}
277292

278293
/** Traps focus inside the drawer. */
@@ -382,17 +397,6 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr
382397
});
383398
}
384399

385-
/**
386-
* Handles the keyboard events.
387-
* @docs-private
388-
*/
389-
handleKeydown(event: KeyboardEvent): void {
390-
if (event.keyCode === ESCAPE && !this.disableClose) {
391-
this.close();
392-
event.stopPropagation();
393-
}
394-
}
395-
396400
_onAnimationStart(event: AnimationEvent) {
397401
this._animationStarted.emit(event);
398402
}

src/lib/sidenav/sidenav.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ export class MatSidenavContent extends MatDrawerContent {
5757
'[@transform]': '_animationState',
5858
'(@transform.start)': '_onAnimationStart($event)',
5959
'(@transform.done)': '_onAnimationEnd($event)',
60-
'(keydown)': 'handleKeydown($event)',
6160
// must prevent the browser from aligning text based on value
6261
'[attr.align]': 'null',
6362
'[class.mat-drawer-end]': 'position === "end"',

0 commit comments

Comments
 (0)