From afd89ed8d9fe1e506370aa7cef6abe9fac51593b Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Wed, 20 Dec 2017 12:19:59 +0100 Subject: [PATCH] fix(core): support read option when querying for types (#21187) PR Close #21187 --- packages/core/src/render3/query.ts | 10 ++++--- packages/core/test/render3/query_spec.ts | 33 ++++++++++++++++++++++- packages/core/test/render3/render_util.ts | 1 + 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/packages/core/src/render3/query.ts b/packages/core/src/render3/query.ts index 6a106ae3dc..d3340c0576 100644 --- a/packages/core/src/render3/query.ts +++ b/packages/core/src/render3/query.ts @@ -154,6 +154,7 @@ function getIdxOfMatchingSelector(staticData: LNodeStatic, selector: string): nu } function add(predicate: QueryPredicate| null, node: LNode) { + const nodeInjector = getOrCreateNodeInjectorForNode(node as LElement | LContainer); while (predicate) { const type = predicate.type; if (type) { @@ -164,18 +165,21 @@ function add(predicate: QueryPredicate| null, node: LNode) { i < ii; i++) { const def = ngStaticData[i] as DirectiveDef; if (def.diPublic && def.type === type) { - predicate.values.push(node.view.data[i]); + if (predicate.read !== null) { + predicate.values.push(readFromNodeInjector(nodeInjector, node, predicate.read)); + } else { + predicate.values.push(node.view.data[i]); + } } } } else { - const nodeInjector = getOrCreateNodeInjectorForNode(node as LElement | LContainer); const selector = predicate.selector !; for (let i = 0; i < selector.length; i++) { ngDevMode && assertNotNull(node.staticData, 'node.staticData'); const directiveIdx = getIdxOfMatchingSelector(node.staticData !, selector[i]); // is anything on a node matching a selector? if (directiveIdx !== null) { - if (predicate.read != null) { + if (predicate.read !== null) { predicate.values.push(readFromNodeInjector(nodeInjector, node, predicate.read)); } else { // is local name pointing to a directive? diff --git a/packages/core/test/render3/query_spec.ts b/packages/core/test/render3/query_spec.ts index 71f302d5cd..1df506fcc0 100644 --- a/packages/core/test/render3/query_spec.ts +++ b/packages/core/test/render3/query_spec.ts @@ -77,7 +77,38 @@ describe('query', () => { expect((parent.query1 as QueryList).toArray()).toEqual([child1, child2]); }); - describe('local names', () => { + describe('types predicate', () => { + + it('should query using type predicate and read specified token', () => { + const Child = createDirective(); + let elToQuery; + /** + *
+ * class Cmpt { + * @ViewChildren(Child, {read: ElementRef}) query; + * } + */ + const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + let tmp: any; + if (cm) { + m(0, Q(Child, false, QueryReadType.ElementRef)); + elToQuery = E(1, 'div'); + { D(2, Child.ngDirectiveDef.n(), Child.ngDirectiveDef); } + e(); + } + qR(tmp = m>(0)) && (ctx.query = tmp as QueryList); + }); + + const cmptInstance = renderComponent(Cmpt); + const query = (cmptInstance.query as QueryList); + expect(query.length).toBe(1); + expect(isElementRef(query.first)).toBeTruthy(); + expect(query.first.nativeElement).toEqual(elToQuery); + }); + + }); + + describe('local names predicate', () => { it('should query for a single element and read ElementRef', () => { diff --git a/packages/core/test/render3/render_util.ts b/packages/core/test/render3/render_util.ts index 9a6917ec1b..fab4ee4e4f 100644 --- a/packages/core/test/render3/render_util.ts +++ b/packages/core/test/render3/render_util.ts @@ -85,6 +85,7 @@ export function createDirective(): DirectiveType { static ngDirectiveDef = defineDirective({ type: Directive, factory: () => new Directive(), + features: [PublicFeature], }); }; }