To prepare for pending ngForOf work, the dep from instructions -> query should be broken. This will enable a dep from di -> instructions while avoiding a di -> instructions -> query -> di cycle. Analyzing this cycle also uncovered another problem: the implementation of query() breaks tree-shaking through a hard dependency on DI concepts of TemplateRef, ElementRef, ViewContainerRef. This is fundamentally due to how query() can query for those values without any configuration. Instead, this fix introduces the concept by employing the strategy pattern, and redefining QueryReadType to pass a function which will return one of the above values. This strategy is then used for 'read' instead of an enum in cases where special values should be read from the DI system. PR Close #21430
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {QueryList} from '../../linker';
|
|
import {Type} from '../../type';
|
|
|
|
import {LInjector} from './injector';
|
|
import {LContainerNode, LNode, LViewNode} from './node';
|
|
|
|
|
|
/** Used for tracking queries (e.g. ViewChild, ContentChild). */
|
|
export interface LQuery {
|
|
/**
|
|
* Used to ask query if it should be cloned to the child element.
|
|
*
|
|
* For example in the case of deep queries the `child()` returns
|
|
* query for the child node. In case of shallow queries it returns
|
|
* `null`.
|
|
*/
|
|
child(): LQuery|null;
|
|
|
|
/**
|
|
* Notify `LQuery` that a `LNode` has been created.
|
|
*/
|
|
addNode(node: LNode): void;
|
|
|
|
/**
|
|
* Notify `LQuery` that an `LViewNode` has been added to `LContainerNode`.
|
|
*/
|
|
insertView(container: LContainerNode, view: LViewNode, insertIndex: number): void;
|
|
|
|
/**
|
|
* Notify `LQuery` that an `LViewNode` has been removed from `LContainerNode`.
|
|
*/
|
|
removeView(container: LContainerNode, view: LViewNode, removeIndex: number): void;
|
|
|
|
/**
|
|
* Add additional `QueryList` to track.
|
|
*
|
|
* @param queryList `QueryList` to update with changes.
|
|
* @param predicate Either `Type` or selector array of [key, value] predicates.
|
|
* @param descend If true the query will recursively apply to the children.
|
|
* @param read Indicates which token should be read from DI for this query.
|
|
*/
|
|
track<T>(
|
|
queryList: QueryList<T>, predicate: Type<any>|string[], descend?: boolean,
|
|
read?: QueryReadType<T>|Type<T>): void;
|
|
}
|
|
|
|
export class QueryReadType<T> { private defeatStructuralTyping: any; }
|
|
|
|
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
|
// failure based on types.
|
|
export const unusedValueExportToPlacateAjd = 1;
|