Skip to content

Commit a0a54aa

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 a0a54aa

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+
* Runs outside the zone the 'keydown' event listener. This avoids change detector to be fired
280+
* on 'any' keydown event that is done inside the drawer. We just re-enters on the zone when
281+
* the keyboard event is from the ESCAPE key and we don't have the 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)