feat(query): allow to query for `TemplateRef`
Part of #1989 Closes #3202
This commit is contained in:
parent
5b5d31fa9a
commit
585ea5d600
|
@ -714,6 +714,10 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
|
||||||
}
|
}
|
||||||
|
|
||||||
addDirectivesMatchingQuery(query: Query, list: any[]): void {
|
addDirectivesMatchingQuery(query: Query, list: any[]): void {
|
||||||
|
var templateRef = this._preBuiltObjects.templateRef;
|
||||||
|
if (query.selector === TemplateRef && isPresent(templateRef)) {
|
||||||
|
list.push(templateRef);
|
||||||
|
}
|
||||||
this._strategy.addDirectivesMatchingQuery(query, list);
|
this._strategy.addDirectivesMatchingQuery(query, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -366,10 +366,13 @@ function _createProtoElementInjector(binderIndex, parentPeiWithDistance, renderE
|
||||||
componentDirectiveBinding, directiveBindings) {
|
componentDirectiveBinding, directiveBindings) {
|
||||||
var protoElementInjector = null;
|
var protoElementInjector = null;
|
||||||
// Create a protoElementInjector for any element that either has bindings *or* has one
|
// Create a protoElementInjector for any element that either has bindings *or* has one
|
||||||
// or more var- defined. Elements with a var- defined need a their own element injector
|
// or more var- defined *or* for <template> elements:
|
||||||
// so that, when hydrating, $implicit can be set to the element.
|
// - Elements with a var- defined need a their own element injector
|
||||||
|
// so that, when hydrating, $implicit can be set to the element.
|
||||||
|
// - <template> elements need their own ElementInjector so that we can query their TemplateRef
|
||||||
var hasVariables = MapWrapper.size(renderElementBinder.variableBindings) > 0;
|
var hasVariables = MapWrapper.size(renderElementBinder.variableBindings) > 0;
|
||||||
if (directiveBindings.length > 0 || hasVariables) {
|
if (directiveBindings.length > 0 || hasVariables ||
|
||||||
|
isPresent(renderElementBinder.nestedProtoView)) {
|
||||||
var directiveVariableBindings =
|
var directiveVariableBindings =
|
||||||
createDirectiveVariableBindings(renderElementBinder, directiveBindings);
|
createDirectiveVariableBindings(renderElementBinder, directiveBindings);
|
||||||
protoElementInjector =
|
protoElementInjector =
|
||||||
|
|
|
@ -28,5 +28,5 @@ export class TemplateRef {
|
||||||
/**
|
/**
|
||||||
* Whether this template has a local variable with the given name
|
* Whether this template has a local variable with the given name
|
||||||
*/
|
*/
|
||||||
hasLocal(name: string): boolean { return this._getProtoView().protoLocals.has(name); }
|
hasLocal(name: string): boolean { return this._getProtoView().variableBindings.has(name); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,6 +166,12 @@ class NeedsQueryByVarBindings {
|
||||||
constructor(@Query("one,two") query: QueryList<any>) { this.query = query; }
|
constructor(@Query("one,two") query: QueryList<any>) { this.query = query; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
class NeedsTemplateRefQuery {
|
||||||
|
query: QueryList<TemplateRef>;
|
||||||
|
constructor(@Query(TemplateRef) query: QueryList<TemplateRef>) { this.query = query; }
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class NeedsElementRef {
|
class NeedsElementRef {
|
||||||
elementRef;
|
elementRef;
|
||||||
|
@ -1009,6 +1015,16 @@ export function main() {
|
||||||
expectDirectives(inj.get(NeedsQuery).query, CountingDirective, [0]);
|
expectDirectives(inj.get(NeedsQuery).query, CountingDirective, [0]);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should contain PreBuiltObjects on the same injector', () => {
|
||||||
|
var preBuiltObjects = new PreBuiltObjects(null, null, null, new TemplateRef(<any>new DummyElementRef()));
|
||||||
|
var inj = injector(ListWrapper.concat([
|
||||||
|
NeedsTemplateRefQuery
|
||||||
|
], extraBindings), null,
|
||||||
|
false, preBuiltObjects);
|
||||||
|
|
||||||
|
expect(inj.get(NeedsTemplateRefQuery).query.first).toBe(preBuiltObjects.templateRef);
|
||||||
|
});
|
||||||
|
|
||||||
it('should contain multiple directives from the same injector', () => {
|
it('should contain multiple directives from the same injector', () => {
|
||||||
var inj = injector(ListWrapper.concat([
|
var inj = injector(ListWrapper.concat([
|
||||||
NeedsQuery,
|
NeedsQuery,
|
||||||
|
|
|
@ -10,12 +10,13 @@ import {
|
||||||
it,
|
it,
|
||||||
xit,
|
xit,
|
||||||
TestComponentBuilder,
|
TestComponentBuilder,
|
||||||
asNativeElements
|
asNativeElements,
|
||||||
|
By
|
||||||
} from 'angular2/test_lib';
|
} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
|
||||||
import {Injectable, Optional} from 'angular2/di';
|
import {Injectable, Optional} from 'angular2/di';
|
||||||
import {QueryList} from 'angular2/core';
|
import {QueryList, TemplateRef} from 'angular2/core';
|
||||||
import {Query, ViewQuery, Component, Directive, View} from 'angular2/annotations';
|
import {Query, ViewQuery, Component, Directive, View} from 'angular2/annotations';
|
||||||
|
|
||||||
import {NgIf, NgFor} from 'angular2/angular2';
|
import {NgIf, NgFor} from 'angular2/angular2';
|
||||||
|
@ -126,6 +127,24 @@ export function main() {
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('query for TemplateRef', () => {
|
||||||
|
it('should find TemplateRefs in the light and shadow dom',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
var template = '<needs-tpl><template var-x="light"></template></needs-tpl>';
|
||||||
|
tcb.overrideTemplate(MyComp, template)
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((view) => {
|
||||||
|
view.detectChanges();
|
||||||
|
var needsTpl: NeedsTpl = view.componentViewChildren[0].inject(NeedsTpl);
|
||||||
|
expect(needsTpl.query.first.hasLocal('light')).toBe(true);
|
||||||
|
expect(needsTpl.viewQuery.first.hasLocal('shadow')).toBe(true);
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe("onChange", () => {
|
describe("onChange", () => {
|
||||||
it('should notify query on change',
|
it('should notify query on change',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
@ -545,6 +564,18 @@ class NeedsViewQueryOrder {
|
||||||
constructor(@ViewQuery(TextDirective) query: QueryList<TextDirective>) { this.query = query; }
|
constructor(@ViewQuery(TextDirective) query: QueryList<TextDirective>) { this.query = query; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'needs-tpl'})
|
||||||
|
@View({template: '<template var-x="shadow"></template>'})
|
||||||
|
class NeedsTpl {
|
||||||
|
viewQuery: QueryList<TemplateRef>;
|
||||||
|
query: QueryList<TemplateRef>;
|
||||||
|
constructor(@ViewQuery(TemplateRef) viewQuery: QueryList<TemplateRef>,
|
||||||
|
@Query(TemplateRef) query: QueryList<TemplateRef>) {
|
||||||
|
this.viewQuery = viewQuery;
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Component({selector: 'my-comp'})
|
@Component({selector: 'my-comp'})
|
||||||
@View({
|
@View({
|
||||||
directives: [
|
directives: [
|
||||||
|
@ -558,6 +589,7 @@ class NeedsViewQueryOrder {
|
||||||
NeedsViewQueryIf,
|
NeedsViewQueryIf,
|
||||||
NeedsViewQueryNestedIf,
|
NeedsViewQueryNestedIf,
|
||||||
NeedsViewQueryOrder,
|
NeedsViewQueryOrder,
|
||||||
|
NeedsTpl,
|
||||||
TextDirective,
|
TextDirective,
|
||||||
InertDirective,
|
InertDirective,
|
||||||
NgIf,
|
NgIf,
|
||||||
|
|
Loading…
Reference in New Issue