mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(live-announcer): run outside NgZone (#10631)
Switches to running the timeout from the `LiveAnnouncer` outside the `NgZone`, because it does all of its DOM manipulation directly on the element and it doesn't have to trigger Angular's change detection.
This commit is contained in:
committed by
vivian-hu
parent
a706c8c619
commit
e4cf0599e7
@@ -34,6 +34,7 @@ export class LiveAnnouncer implements OnDestroy {
|
||||
|
||||
constructor(
|
||||
@Optional() @Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN) elementToken: any,
|
||||
private _ngZone: NgZone,
|
||||
@Inject(DOCUMENT) _document: any) {
|
||||
|
||||
// We inject the live element and document as `any` because the constructor signature cannot
|
||||
@@ -60,11 +61,13 @@ export class LiveAnnouncer implements OnDestroy {
|
||||
// - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a
|
||||
// second time without clearing and then using a non-zero delay.
|
||||
// (using JAWS 17 at time of this writing).
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
this._liveElement.textContent = message;
|
||||
resolve();
|
||||
}, 100);
|
||||
return this._ngZone.runOutsideAngular(() => {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
this._liveElement.textContent = message;
|
||||
resolve();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -77,13 +80,13 @@ export class LiveAnnouncer implements OnDestroy {
|
||||
private _createLiveElement(): HTMLElement {
|
||||
const elementClass = 'cdk-live-announcer-element';
|
||||
const previousElements = this._document.getElementsByClassName(elementClass);
|
||||
const liveEl = this._document.createElement('div');
|
||||
|
||||
// Remove any old containers. This can happen when coming in from a server-side-rendered page.
|
||||
for (let i = 0; i < previousElements.length; i++) {
|
||||
previousElements[i].parentNode!.removeChild(previousElements[i]);
|
||||
}
|
||||
|
||||
const liveEl = this._document.createElement('div');
|
||||
liveEl.classList.add(elementClass);
|
||||
liveEl.classList.add('cdk-visually-hidden');
|
||||
|
||||
@@ -146,8 +149,8 @@ export class CdkAriaLive implements OnDestroy {
|
||||
|
||||
/** @docs-private @deprecated @breaking-change 7.0.0 */
|
||||
export function LIVE_ANNOUNCER_PROVIDER_FACTORY(
|
||||
parentDispatcher: LiveAnnouncer, liveElement: any, _document: any) {
|
||||
return parentDispatcher || new LiveAnnouncer(liveElement, _document);
|
||||
parentDispatcher: LiveAnnouncer, liveElement: any, _document: any, ngZone: NgZone) {
|
||||
return parentDispatcher || new LiveAnnouncer(liveElement, _document, ngZone);
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +162,7 @@ export const LIVE_ANNOUNCER_PROVIDER: Provider = {
|
||||
[new Optional(), new SkipSelf(), LiveAnnouncer],
|
||||
[new Optional(), new Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN)],
|
||||
DOCUMENT,
|
||||
NgZone,
|
||||
],
|
||||
useFactory: LIVE_ANNOUNCER_PROVIDER_FACTORY
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user