fix(query): clean-up queryref during dehydration

The QueryRef objects persists during dehydration but needs to be
cleaned-up by removing callbacks and previous elements.

Closes #3944

Closes #3948
This commit is contained in:
Rado Kirov
2015-09-01 16:18:45 -07:00
committed by Rado Kirov
parent 44a991e245
commit 01cdd31339
5 changed files with 75 additions and 13 deletions

View File

@ -433,6 +433,7 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
this._preBuiltObjects = null;
this._strategy.callOnDestroy();
this._strategy.dehydrate();
this._clearQueryLists();
}
afterContentChecked(): void {
@ -837,6 +838,12 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
var nestedView = view.getNestedView(view.elementOffset + this.getBoundElementIndex());
return isPresent(nestedView) ? nestedView.rootElementInjectors : [];
}
private _clearQueryLists(): void {
if (isPresent(this._query0) && this._query0.originator === this) this._query0.reset();
if (isPresent(this._query1) && this._query1.originator === this) this._query1.reset();
if (isPresent(this._query2) && this._query2.originator === this) this._query2.reset();
}
}
interface _ElementInjectorStrategy {
@ -1163,4 +1170,9 @@ export class QueryRef {
private _aggregateDirective(inj: ElementInjector, aggregator: any[]): void {
inj.addDirectivesMatchingQuery(this.query, aggregator);
}
reset(): void {
this.list.reset([]);
this.list.removeAllCallbacks();
}
}

View File

@ -89,13 +89,6 @@ class QueryList<T> extends Object
_dirty = true;
}
// TODO(rado): hook up with change detection after #995.
void fireCallbacks() {
if (_dirty) {
_callbacks.forEach((c) => c());
_dirty = false;
}
}
void onChange(callback) {
_callbacks.add(callback);
@ -105,6 +98,10 @@ class QueryList<T> extends Object
_callbacks.remove(callback);
}
void removeAllCallbacks() {
this._callbacks = [];
}
int get length => _results.length;
T get first => _results.first;
T get last => _results.last;
@ -116,4 +113,12 @@ class QueryList<T> extends Object
// Note: we need to return a list instead of iterable to match JS.
return this._results.map(fn).toList();
}
// Internal to the framework.
void fireCallbacks() {
if (_dirty) {
_callbacks.forEach((c) => c());
_dirty = false;
}
}
}

View File

@ -86,17 +86,13 @@ export class QueryList<T> {
this._dirty = true;
}
fireCallbacks(): void {
if (this._dirty) {
ListWrapper.forEach(this._callbacks, (c) => c());
this._dirty = false;
}
}
onChange(callback: () => void): void { this._callbacks.push(callback); }
removeCallback(callback: () => void): void { ListWrapper.remove(this._callbacks, callback); }
removeAllCallbacks(): void { this._callbacks = []; }
toString(): string { return this._results.toString(); }
get length(): number { return this._results.length; }
@ -106,4 +102,12 @@ export class QueryList<T> {
map<U>(fn: (item: T) => U): U[] { return this._results.map(fn); }
[Symbol.iterator](): any { return this._results[Symbol.iterator](); }
// Internal to the framework.
fireCallbacks(): void {
if (this._dirty) {
ListWrapper.forEach(this._callbacks, (c) => c());
this._dirty = false;
}
}
}