@@ -13,9 +13,10 @@ import {Observable} from 'rxjs/Observable';
1313import * as viewEngine from '../core' ;
1414
1515import { assertNotNull } from './assert' ;
16- import { getOrCreateElementRef , getOrCreateNodeInjectorForNode } from './di' ;
17- import { QueryState } from './interfaces' ;
18- import { LContainer , LElement , LNode , LNodeFlags , LView } from './l_node' ;
16+ import { getOrCreateContainerRef , getOrCreateElementRef , getOrCreateNodeInjectorForNode , getOrCreateTemplateRef } from './di' ;
17+ import { QueryReadType , QueryState } from './interfaces' ;
18+ import { LContainer , LElement , LNode , LNodeFlags , LNodeInjector , LView } from './l_node' ;
19+ import { assertNodeOfPossibleTypes } from './node_assert' ;
1920import { DirectiveDef } from './public_interfaces' ;
2021
2122
@@ -44,6 +45,11 @@ export interface QueryPredicate<T> {
4445 */
4546 selector : string [ ] | null ;
4647
48+ /**
49+ * Indicates which token should be read from DI for this query.
50+ */
51+ read : QueryReadType | null ;
52+
4753 /**
4854 * Values which have been located.
4955 *
@@ -59,14 +65,15 @@ export class QueryState_ implements QueryState {
5965 constructor ( deep ?: QueryPredicate < any > ) { this . deep = deep == null ? null : deep ; }
6066
6167 track < T > (
62- queryList : viewEngine . QueryList < T > , predicate : viewEngine . Type < T > | string [ ] ,
63- descend ?: boolean ) : void {
68+ queryList : viewEngine . QueryList < T > , predicate : viewEngine . Type < T > | string [ ] , descend ?: boolean ,
69+ read ?: QueryReadType ) : void {
6470 // TODO(misko): This is not right. In case of inherited state, a calling track will incorrectly
6571 // mutate parent.
6672 if ( descend ) {
67- this . deep = createPredicate ( this . deep , queryList , predicate ) ;
73+ this . deep = createPredicate ( this . deep , queryList , predicate , read != null ? read : null ) ;
6874 } else {
69- this . shallow = createPredicate ( this . shallow , queryList , predicate ) ;
75+ this . shallow =
76+ createPredicate ( this . shallow , queryList , predicate , read != null ? read : null ) ;
7077 }
7178 }
7279
@@ -99,6 +106,33 @@ export class QueryState_ implements QueryState {
99106 }
100107}
101108
109+ function readDefaultInjectable ( nodeInjector : LNodeInjector , node : LNode ) :
110+ viewEngine . ElementRef | viewEngine . TemplateRef < any > | undefined {
111+ ngDevMode && assertNodeOfPossibleTypes ( node , LNodeFlags . Container , LNodeFlags . Element ) ;
112+ if ( ( node . flags & LNodeFlags . TYPE_MASK ) === LNodeFlags . Element ) {
113+ return getOrCreateElementRef ( nodeInjector ) ;
114+ } else if ( ( node . flags & LNodeFlags . TYPE_MASK ) === LNodeFlags . Container ) {
115+ return getOrCreateTemplateRef ( nodeInjector ) ;
116+ }
117+ }
118+
119+ function readFromNodeInjector ( nodeInjector : LNodeInjector , node : LNode , read : QueryReadType | null ) :
120+ viewEngine . ElementRef | viewEngine . ViewContainerRef | viewEngine . TemplateRef < any > | undefined {
121+ if ( read === null ) {
122+ return readDefaultInjectable ( nodeInjector , node ) ;
123+ } else if ( read === QueryReadType . ElementRef ) {
124+ return getOrCreateElementRef ( nodeInjector ) ;
125+ } else if ( read === QueryReadType . ViewContainerRef ) {
126+ return getOrCreateContainerRef ( nodeInjector ) ;
127+ } else if ( read === QueryReadType . TemplateRef ) {
128+ return getOrCreateTemplateRef ( nodeInjector ) ;
129+ }
130+
131+ if ( ngDevMode ) {
132+ throw new Error ( `Unrecognised read type for queries: ${ read } ` ) ;
133+ }
134+ }
135+
102136function add ( predicate : QueryPredicate < any > | null , node : LNode ) {
103137 while ( predicate ) {
104138 const type = predicate . type ;
@@ -115,12 +149,14 @@ function add(predicate: QueryPredicate<any>| null, node: LNode) {
115149 }
116150 } else {
117151 const staticData = node . staticData ;
152+ const nodeInjector = getOrCreateNodeInjectorForNode ( node as LElement | LContainer ) ;
118153 if ( staticData && staticData . localName ) {
119154 const selector = predicate . selector ! ;
120155 for ( let i = 0 ; i < selector . length ; i ++ ) {
121156 if ( selector [ i ] === staticData . localName ) {
122- predicate . values . push ( getOrCreateElementRef (
123- getOrCreateNodeInjectorForNode ( node as LElement | LContainer ) ) ) ;
157+ const injectable = readFromNodeInjector ( nodeInjector , node , predicate . read ) ;
158+ assertNotNull ( injectable , 'injectable' ) ;
159+ predicate . values . push ( injectable ) ;
124160 }
125161 }
126162 }
@@ -131,7 +167,7 @@ function add(predicate: QueryPredicate<any>| null, node: LNode) {
131167
132168function createPredicate < T > (
133169 previous : QueryPredicate < any > | null , queryList : QueryList < T > ,
134- predicate : viewEngine . Type < T > | string [ ] ) : QueryPredicate < T > {
170+ predicate : viewEngine . Type < T > | string [ ] , read : QueryReadType | null ) : QueryPredicate < T > {
135171 const isArray = Array . isArray ( predicate ) ;
136172 const values = < any > [ ] ;
137173 if ( ( queryList as any as QueryList_ < T > ) . _valuesTree === null ) {
@@ -142,6 +178,7 @@ function createPredicate<T>(
142178 list : queryList ,
143179 type : isArray ? null : predicate as viewEngine . Type < T > ,
144180 selector : isArray ? predicate as string [ ] : null ,
181+ read : read ,
145182 values : values
146183 } ;
147184}
0 commit comments