From 8daa76020d959bbdb2b19bcd4c1e50326e2a9d79 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 19 Mar 2018 21:19:21 +0100 Subject: [PATCH] refactor(input): run autofill monitor outside the NgZone (#10367) Switches the autofill monitor to run outside the `NgZone`, because it toggles classes on the element directly and it has the potential of being fired very often if the user has other animations on the element. Also adds a description to an output that is part of the public API. --- src/cdk/text-field/autofill.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/cdk/text-field/autofill.ts b/src/cdk/text-field/autofill.ts index 7bd13996c72..860a290f46e 100644 --- a/src/cdk/text-field/autofill.ts +++ b/src/cdk/text-field/autofill.ts @@ -14,7 +14,8 @@ import { Injectable, OnDestroy, OnInit, - Output + Output, + NgZone, } from '@angular/core'; import {Observable} from 'rxjs/Observable'; import {empty as observableEmpty} from 'rxjs/observable/empty'; @@ -50,7 +51,7 @@ const listenerOptions: any = supportsPassiveEventListeners() ? {passive: true} : export class AutofillMonitor implements OnDestroy { private _monitoredElements = new Map(); - constructor(private _platform: Platform) {} + constructor(private _platform: Platform, private _ngZone: NgZone) {} /** * Monitor for changes in the autofill state of the given input element. @@ -63,6 +64,7 @@ export class AutofillMonitor implements OnDestroy { } const info = this._monitoredElements.get(element); + if (info) { return info.subject.asObservable(); } @@ -78,8 +80,10 @@ export class AutofillMonitor implements OnDestroy { } }; - element.addEventListener('animationstart', listener, listenerOptions); - element.classList.add('cdk-text-field-autofill-monitored'); + this._ngZone.runOutsideAngular(() => { + element.addEventListener('animationstart', listener, listenerOptions); + element.classList.add('cdk-text-field-autofill-monitored'); + }); this._monitoredElements.set(element, { subject: result, @@ -118,6 +122,7 @@ export class AutofillMonitor implements OnDestroy { selector: '[cdkAutofill]', }) export class CdkAutofill implements OnDestroy, OnInit { + /** Emits when the autofill state of the element changes. */ @Output() cdkAutofill: EventEmitter = new EventEmitter(); constructor(private _elementRef: ElementRef, private _autofillMonitor: AutofillMonitor) {}