Skip to content

Commit 981c9a9

Browse files
llorenspujoltinayuangao
authored andcommitted
fix(drawer): drawer running inside the zone keydown event. (#10092)
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 b4b76bd commit 981c9a9

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)