fix(injectors): reset the construction counter in dynamic strategy.
Adds tests for hydrate / dehydrate in cycle. Closes #3635
This commit is contained in:
parent
5f7d4faa88
commit
272ad61ab1
|
@ -673,7 +673,7 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
|
||||||
|
|
||||||
private _addViewQuery(queryRef: QueryRef, host: ElementInjector): void {
|
private _addViewQuery(queryRef: QueryRef, host: ElementInjector): void {
|
||||||
if (isBlank(queryRef) || !queryRef.isViewQuery || this._hasQuery(queryRef)) return;
|
if (isBlank(queryRef) || !queryRef.isViewQuery || this._hasQuery(queryRef)) return;
|
||||||
if (host._query0.originator == host) {
|
if (queryRef.originator == host) {
|
||||||
// TODO(rado): Replace this.parent check with distanceToParent = 1 when
|
// TODO(rado): Replace this.parent check with distanceToParent = 1 when
|
||||||
// https://github.com/angular/angular/issues/2707 is fixed.
|
// https://github.com/angular/angular/issues/2707 is fixed.
|
||||||
if (!queryRef.query.descendants && isPresent(this.parent)) return;
|
if (!queryRef.query.descendants && isPresent(this.parent)) return;
|
||||||
|
@ -863,8 +863,8 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
|
||||||
|
|
||||||
getRootViewInjectors(): ElementInjector[] {
|
getRootViewInjectors(): ElementInjector[] {
|
||||||
var view = this._preBuiltObjects.view;
|
var view = this._preBuiltObjects.view;
|
||||||
return view.getNestedView(view.elementOffset + this.getBoundElementIndex())
|
var nestedView = view.getNestedView(view.elementOffset + this.getBoundElementIndex());
|
||||||
.rootElementInjectors;
|
return isPresent(nestedView) ? nestedView.rootElementInjectors : [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,6 +1068,7 @@ class ElementInjectorDynamicStrategy implements _ElementInjectorStrategy {
|
||||||
hydrate(): void {
|
hydrate(): void {
|
||||||
var inj = this.injectorStrategy;
|
var inj = this.injectorStrategy;
|
||||||
var p = inj.protoStrategy;
|
var p = inj.protoStrategy;
|
||||||
|
inj.resetConstructionCounter();
|
||||||
|
|
||||||
for (var i = 0; i < p.keyIds.length; i++) {
|
for (var i = 0; i < p.keyIds.length; i++) {
|
||||||
if (p.bindings[i] instanceof DirectiveBinding && isPresent(p.keyIds[i]) &&
|
if (p.bindings[i] instanceof DirectiveBinding && isPresent(p.keyIds[i]) &&
|
||||||
|
|
|
@ -35,6 +35,7 @@ import {
|
||||||
import {
|
import {
|
||||||
Attribute,
|
Attribute,
|
||||||
Query,
|
Query,
|
||||||
|
ViewQuery,
|
||||||
ComponentMetadata,
|
ComponentMetadata,
|
||||||
DirectiveMetadata,
|
DirectiveMetadata,
|
||||||
LifecycleEvent
|
LifecycleEvent
|
||||||
|
@ -51,9 +52,11 @@ import {QueryList} from 'angular2/src/core/compiler/query_list';
|
||||||
@IMPLEMENTS(AppView)
|
@IMPLEMENTS(AppView)
|
||||||
class DummyView extends SpyObject {
|
class DummyView extends SpyObject {
|
||||||
changeDetector;
|
changeDetector;
|
||||||
|
elementOffset: number;
|
||||||
constructor() {
|
constructor() {
|
||||||
super(AppView);
|
super(AppView);
|
||||||
this.changeDetector = null;
|
this.changeDetector = null;
|
||||||
|
this.elementOffset = 0;
|
||||||
}
|
}
|
||||||
noSuchMethod(m) { return super.noSuchMethod(m); }
|
noSuchMethod(m) { return super.noSuchMethod(m); }
|
||||||
}
|
}
|
||||||
|
@ -159,6 +162,12 @@ class NeedsQuery {
|
||||||
constructor(@Query(CountingDirective) query: QueryList<CountingDirective>) { this.query = query; }
|
constructor(@Query(CountingDirective) query: QueryList<CountingDirective>) { this.query = query; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
class NeedsViewQuery {
|
||||||
|
query: QueryList<CountingDirective>;
|
||||||
|
constructor(@ViewQuery(CountingDirective) query: QueryList<CountingDirective>) { this.query = query; }
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class NeedsQueryByVarBindings {
|
class NeedsQueryByVarBindings {
|
||||||
query: QueryList<any>;
|
query: QueryList<any>;
|
||||||
|
@ -850,6 +859,41 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("getRootViewInjectors", () => {
|
||||||
|
it("should return an empty array if there is no nested view", () => {
|
||||||
|
var inj = injector(extraBindings);
|
||||||
|
expect(inj.getRootViewInjectors()).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("dehydrate", () => {
|
||||||
|
function cycleHydrate(inj: ElementInjector, host=null): void {
|
||||||
|
// Each injection supports 3 query slots, so we cycle 4 times.
|
||||||
|
for (var i = 0; i < 4; i++) {
|
||||||
|
inj.dehydrate();
|
||||||
|
inj.hydrate(null, host, defaultPreBuiltObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it("should handle repeated hydration / dehydration", () => {
|
||||||
|
var inj = injector(extraBindings);
|
||||||
|
cycleHydrate(inj);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle repeated hydration / dehydration with query present", () => {
|
||||||
|
var inj = injector(ListWrapper.concat([NeedsQuery], extraBindings));
|
||||||
|
cycleHydrate(inj);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("should handle repeated hydration / dehydration with view query present", () => {
|
||||||
|
var inj = injector(extraBindings);
|
||||||
|
var host = injector(ListWrapper.concat([NeedsViewQuery], extraBindings));
|
||||||
|
|
||||||
|
cycleHydrate(inj, host);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("lifecycle", () => {
|
describe("lifecycle", () => {
|
||||||
it("should call onDestroy on directives subscribed to this event", () => {
|
it("should call onDestroy on directives subscribed to this event", () => {
|
||||||
var inj = injector(ListWrapper.concat(
|
var inj = injector(ListWrapper.concat(
|
||||||
|
|
Loading…
Reference in New Issue