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

Commit

Permalink
fix(fxLayoutGap): mutation observer should run outside the ngZone (#370)
Browse files Browse the repository at this point in the history
Inside the ngZone, the mutation observer and _updateWithValue() style changes causes an infinite recursion. MutationObserver handlers should be executed outside the ngZone.

Fixes #329.
  • Loading branch information
ThomasBurleson authored and mmalerba committed Aug 9, 2017
1 parent f0473e9 commit 9fb0877
Showing 1 changed file with 19 additions and 16 deletions.
35 changes: 19 additions & 16 deletions src/lib/flexbox/api/layout-gap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
AfterContentInit,
Optional,
OnDestroy,
NgZone,
} from '@angular/core';
import {Subscription} from 'rxjs/Subscription';

Expand Down Expand Up @@ -65,7 +66,8 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
constructor(monitor: MediaMonitor,
elRef: ElementRef,
renderer: Renderer,
@Optional() @Self() container: LayoutDirective) {
@Optional() @Self() container: LayoutDirective,
private _zone: NgZone) {
super(monitor, elRef, renderer);

if (container) { // Subscribe to layout direction changes
Expand Down Expand Up @@ -114,22 +116,23 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
* NOTE: this does NOT! differentiate between viewChildren and contentChildren
*/
protected _watchContentChanges() {
let onMutationCallback = (mutations) => {
let validatedChanges = (it: MutationRecord) => {
return (it.addedNodes && it.addedNodes.length) ||
(it.removedNodes && it.removedNodes.length);
};

// update gap styles only for child 'added' or 'removed' events
if (mutations.filter(validatedChanges).length) {
this._updateWithValue();
this._zone.runOutsideAngular(() => {

if (typeof MutationObserver !== 'undefined') {
this._observer = new MutationObserver((mutations: MutationRecord[]) => {
let validatedChanges = (it: MutationRecord): boolean => {
return (it.addedNodes && it.addedNodes.length > 0) ||
(it.removedNodes && it.removedNodes.length > 0);
};

// update gap styles only for child 'added' or 'removed' events
if (mutations.some(validatedChanges)) {
this._updateWithValue();
}
});
this._observer.observe(this._elementRef.nativeElement, {childList: true});
}
};

if (typeof MutationObserver !== 'undefined') {
this._observer = new MutationObserver(onMutationCallback);
this._observer.observe(this._elementRef.nativeElement, {childList: true});
}
});
}

/**
Expand Down

0 comments on commit 9fb0877

Please sign in to comment.