Skip to content

Commit

Permalink
refactor(material/sidenav): Remove use of zone onStable to schedule d…
Browse files Browse the repository at this point in the history
…rawer validation (angular#28682)
  • Loading branch information
mmalerba authored Mar 15, 2024
1 parent 5799c14 commit b77952a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
26 changes: 17 additions & 9 deletions src/material/sidenav/drawer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
discardPeriodicTasks,
flush,
} from '@angular/core/testing';
import {Component, ElementRef, ViewChild} from '@angular/core';
import {Component, ElementRef, ErrorHandler, ViewChild} from '@angular/core';
import {By} from '@angular/platform-browser';
import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
import {MatDrawer, MatSidenavModule, MatDrawerContainer} from './index';
Expand Down Expand Up @@ -461,21 +461,29 @@ describe('MatDrawer', () => {
});

it('should throw when multiple drawers have the same position', fakeAsync(() => {
const errorHandler = jasmine.createSpyObj(['handleError']);

TestBed.configureTestingModule({
imports: [DrawerDynamicPosition],
providers: [
{
provide: ErrorHandler,
useValue: errorHandler,
},
],
}).compileComponents();

const fixture = TestBed.createComponent(DrawerDynamicPosition);
fixture.detectChanges();
tick();

const testComponent: DrawerDynamicPosition = fixture.debugElement.componentInstance;
testComponent.drawer1Position = 'end';

expect(() => {
try {
fixture.detectChanges();
tick(0);
} catch {
tick(0);
}
}).toThrow();
fixture.detectChanges();
tick();

expect(errorHandler.handleError).toHaveBeenCalled();
}));

it('should not throw when drawers swap positions', () => {
Expand Down
21 changes: 15 additions & 6 deletions src/material/sidenav/drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import {DOCUMENT} from '@angular/common';
import {
AfterContentChecked,
AfterContentInit,
afterNextRender,
AfterRenderPhase,
AfterViewInit,
ANIMATION_MODULE_TYPE,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Expand All @@ -32,8 +35,10 @@ import {
ElementRef,
EventEmitter,
forwardRef,
inject,
Inject,
InjectionToken,
Injector,
Input,
NgZone,
OnDestroy,
Expand All @@ -42,18 +47,17 @@ import {
QueryList,
ViewChild,
ViewEncapsulation,
ANIMATION_MODULE_TYPE,
} from '@angular/core';
import {fromEvent, merge, Observable, Subject} from 'rxjs';
import {
debounceTime,
distinctUntilChanged,
filter,
map,
mapTo,
startWith,
take,
takeUntil,
distinctUntilChanged,
mapTo,
} from 'rxjs/operators';
import {matDrawerAnimations} from './drawer-animations';

Expand Down Expand Up @@ -750,6 +754,8 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
return this._userContent || this._content;
}

private _injector = inject(Injector);

constructor(
@Optional() private _dir: Directionality,
private _element: ElementRef<HTMLElement>,
Expand Down Expand Up @@ -933,9 +939,12 @@ export class MatDrawerContainer implements AfterContentInit, DoCheck, OnDestroy
// NOTE: We need to wait for the microtask queue to be empty before validating,
// since both drawers may be swapping positions at the same time.
drawer.onPositionChanged.pipe(takeUntil(this._drawers.changes)).subscribe(() => {
this._ngZone.onMicrotaskEmpty.pipe(take(1)).subscribe(() => {
this._validateDrawers();
});
afterNextRender(
() => {
this._validateDrawers();
},
{injector: this._injector, phase: AfterRenderPhase.Read},
);
});
}

Expand Down

0 comments on commit b77952a

Please sign in to comment.