Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit 9fb0877

Browse files
ThomasBurlesonmmalerba
authored andcommitted
fix(fxLayoutGap): mutation observer should run outside the ngZone (#370)
Inside the ngZone, the mutation observer and _updateWithValue() style changes causes an infinite recursion. MutationObserver handlers should be executed outside the ngZone. Fixes #329.
1 parent f0473e9 commit 9fb0877

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

src/lib/flexbox/api/layout-gap.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
AfterContentInit,
1717
Optional,
1818
OnDestroy,
19+
NgZone,
1920
} from '@angular/core';
2021
import {Subscription} from 'rxjs/Subscription';
2122

@@ -65,7 +66,8 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
6566
constructor(monitor: MediaMonitor,
6667
elRef: ElementRef,
6768
renderer: Renderer,
68-
@Optional() @Self() container: LayoutDirective) {
69+
@Optional() @Self() container: LayoutDirective,
70+
private _zone: NgZone) {
6971
super(monitor, elRef, renderer);
7072

7173
if (container) { // Subscribe to layout direction changes
@@ -114,22 +116,23 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
114116
* NOTE: this does NOT! differentiate between viewChildren and contentChildren
115117
*/
116118
protected _watchContentChanges() {
117-
let onMutationCallback = (mutations) => {
118-
let validatedChanges = (it: MutationRecord) => {
119-
return (it.addedNodes && it.addedNodes.length) ||
120-
(it.removedNodes && it.removedNodes.length);
121-
};
122-
123-
// update gap styles only for child 'added' or 'removed' events
124-
if (mutations.filter(validatedChanges).length) {
125-
this._updateWithValue();
119+
this._zone.runOutsideAngular(() => {
120+
121+
if (typeof MutationObserver !== 'undefined') {
122+
this._observer = new MutationObserver((mutations: MutationRecord[]) => {
123+
let validatedChanges = (it: MutationRecord): boolean => {
124+
return (it.addedNodes && it.addedNodes.length > 0) ||
125+
(it.removedNodes && it.removedNodes.length > 0);
126+
};
127+
128+
// update gap styles only for child 'added' or 'removed' events
129+
if (mutations.some(validatedChanges)) {
130+
this._updateWithValue();
131+
}
132+
});
133+
this._observer.observe(this._elementRef.nativeElement, {childList: true});
126134
}
127-
};
128-
129-
if (typeof MutationObserver !== 'undefined') {
130-
this._observer = new MutationObserver(onMutationCallback);
131-
this._observer.observe(this._elementRef.nativeElement, {childList: true});
132-
}
135+
});
133136
}
134137

135138
/**

0 commit comments

Comments
 (0)