refactor(ivy): remove content query creation from directive factories (#24811)

PR Close #24811
This commit is contained in:
Pawel Kozlowski 2018-07-10 10:43:07 +02:00 committed by Matias Niemelä
parent 328971ffcc
commit 0399c6972a
11 changed files with 205 additions and 75 deletions

View File

@ -39,6 +39,7 @@ export {
T as ɵT,
V as ɵV,
Q as ɵQ,
Qr as ɵQr,
d as ɵd,
P as ɵP,
b as ɵb,
@ -69,6 +70,7 @@ export {
cR as ɵcR,
cr as ɵcr,
qR as ɵqR,
ql as ɵql,
e as ɵe,
p as ɵp,
pD as ɵpD,

View File

@ -48,7 +48,7 @@ export function defineComponent<T>(componentDefinition: {
/**
* Factory method used to create an instance of directive.
*/
factory: () => T | ({0: T} & any[]); /* trying to say T | [T, ...any] */
factory: () => T;
/**
* Static attributes to set on host element.
@ -120,6 +120,14 @@ export function defineComponent<T>(componentDefinition: {
*/
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
/**
* Function to create instances of content queries associated with a given directive.
*/
contentQueries?: (() => void);
/** Refreshes content queries associated with directives in a given view */
contentQueriesRefresh?: ((directiveIndex: number, queryIndex: number) => void);
/**
* Defines the name that can be used in the template to assign this directive to a variable.
*
@ -216,6 +224,8 @@ export function defineComponent<T>(componentDefinition: {
factory: componentDefinition.factory,
template: componentDefinition.template || null !,
hostBindings: componentDefinition.hostBindings || null,
contentQueries: componentDefinition.contentQueries || null,
contentQueriesRefresh: componentDefinition.contentQueriesRefresh || null,
attributes: componentDefinition.attributes || null,
inputs: invertObject(componentDefinition.inputs, declaredInputs),
declaredInputs: declaredInputs,
@ -448,6 +458,14 @@ export const defineDirective = defineComponent as any as<T>(directiveDefinition:
*/
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
/**
* Function to create instances of content queries associated with a given directive.
*/
contentQueries?: (() => void);
/** Refreshes content queries associated with directives in a given view */
contentQueriesRefresh?: ((directiveIndex: number, queryIndex: number) => void);
/**
* Defines the name that can be used in the template to assign this directive to a variable.
*

View File

@ -19,7 +19,7 @@ import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_Vie
import {Type} from '../type';
import {assertDefined, assertGreaterThan, assertLessThan} from './assert';
import {addToViewTree, assertPreviousIsParent, createEmbeddedViewNode, createLContainer, createLNodeObject, createTNode, getDirectiveInstance, getPreviousOrParentNode, getRenderer, isComponent, renderEmbeddedTemplate, resolveDirective} from './instructions';
import {addToViewTree, assertPreviousIsParent, createEmbeddedViewNode, createLContainer, createLNodeObject, createTNode, getPreviousOrParentNode, getRenderer, isComponent, renderEmbeddedTemplate, resolveDirective} from './instructions';
import {VIEWS} from './interfaces/container';
import {ComponentTemplate, DirectiveDefInternal, RenderFlags} from './interfaces/definition';
import {LInjector} from './interfaces/injector';
@ -378,7 +378,7 @@ export function getOrCreateInjectable<T>(
// and matches the given token, return the directive instance.
const directiveDef = defs[i] as DirectiveDefInternal<any>;
if (directiveDef.type === token && directiveDef.diPublic) {
return getDirectiveInstance(node.view[DIRECTIVES] ![i]);
return node.view[DIRECTIVES] ![i];
}
}
}

View File

@ -116,6 +116,11 @@ export {
query as Q,
queryRefresh as qR,
} from './query';
export {
registerContentQuery as Qr,
loadQueryList as ql,
} from './instructions';
export {
pureFunction0 as f0,
pureFunction1 as f1,

View File

@ -8,6 +8,7 @@
import './ng_dev_mode';
import {QueryList} from '../linker';
import {Sanitizer} from '../sanitization/security';
import {assertDefined, assertEqual, assertLessThan, assertNotDefined, assertNotEqual} from './assert';
@ -20,7 +21,7 @@ import {AttributeMarker, InitialInputData, InitialInputs, LContainerNode, LEleme
import {CssSelectorList, NG_PROJECT_AS_ATTR_NAME} from './interfaces/projection';
import {LQueries} from './interfaces/query';
import {ProceduralRenderer3, RComment, RElement, RText, Renderer3, RendererFactory3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer';
import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTEXT, CurrentMatchesList, DIRECTIVES, FLAGS, HEADER_OFFSET, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, RootContext, SANITIZER, TAIL, TData, TVIEW, TView} from './interfaces/view';
import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTENT_QUERIES, CONTEXT, CurrentMatchesList, DIRECTIVES, FLAGS, HEADER_OFFSET, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, RootContext, SANITIZER, TAIL, TData, TVIEW, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {appendChild, appendProjectedNode, canInsertNativeNode, createTextNode, findComponentHost, getChildLNode, getLViewChild, getNextLNode, getParentLNode, insertView, removeView} from './node_manipulation';
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
@ -29,6 +30,7 @@ import {isDifferent, stringify} from './util';
import {ViewRef} from './view_ref';
/**
* Directive (D) sets a property on all component instances using this constant as a key and the
* component's host node (LElement) as the value. This is used in methods like detectChanges to
@ -266,9 +268,11 @@ function refreshView() {
tView.firstTemplatePass = firstTemplatePass = false;
setHostBindings(tView.hostBindings);
refreshContentQueries(tView);
refreshChildComponents(tView.components);
}
/** Sets the host bindings for the current view. */
export function setHostBindings(bindings: number[] | null): void {
if (bindings != null) {
@ -281,6 +285,18 @@ export function setHostBindings(bindings: number[] | null): void {
}
}
/** Refreshes content queries for all directives in the given view. */
function refreshContentQueries(tView: TView): void {
if (tView.contentQueries != null) {
for (let i = 0; i < tView.contentQueries.length; i += 2) {
const directiveDefIdx = tView.contentQueries[i];
const directiveDef = tView.directives ![directiveDefIdx];
directiveDef.contentQueriesRefresh !(directiveDefIdx, tView.contentQueries[i + 1]);
}
}
}
/** Refreshes child components in the current view. */
function refreshChildComponents(components: number[] | null): void {
if (components != null) {
@ -315,7 +331,8 @@ export function createLViewData<T>(
renderer, // renderer
sanitizer || null, // sanitizer
null, // tail
-1 // containerIndex
-1, // containerIndex
null, // contentQueries
];
}
@ -882,6 +899,7 @@ export function createTView(
pipeDestroyHooks: null,
cleanup: null,
hostBindings: null,
contentQueries: null,
components: null,
directiveRegistry: typeof directives === 'function' ? directives() : directives,
pipeRegistry: typeof pipes === 'function' ? pipes() : pipes,
@ -1472,7 +1490,7 @@ export function textBinding<T>(index: number, value: T | NO_CHANGE): void {
//////////////////////////
/**
* Create a directive.
* Create a directive and their associated content queries.
*
* NOTE: directives can be created in order other than the index order. They can also
* be retrieved before they are created in which case the value will be null.
@ -1481,28 +1499,32 @@ export function textBinding<T>(index: number, value: T | NO_CHANGE): void {
* @param directiveDef DirectiveDef object which contains information about the template.
*/
export function directiveCreate<T>(
index: number, directive: T,
directiveDefIdx: number, directive: T,
directiveDef: DirectiveDefInternal<T>| ComponentDefInternal<T>): T {
const instance = baseDirectiveCreate(index, directive, directiveDef);
const instance = baseDirectiveCreate(directiveDefIdx, directive, directiveDef);
ngDevMode && assertDefined(previousOrParentNode.tNode, 'previousOrParentNode.tNode');
const tNode = previousOrParentNode.tNode;
const isComponent = (directiveDef as ComponentDefInternal<T>).template;
if (isComponent) {
addComponentLogic(index, directive, directiveDef as ComponentDefInternal<T>);
addComponentLogic(directiveDefIdx, directive, directiveDef as ComponentDefInternal<T>);
}
if (firstTemplatePass) {
// Init hooks are queued now so ngOnInit is called in host components before
// any projected components.
queueInitHooks(index, directiveDef.onInit, directiveDef.doCheck, tView);
queueInitHooks(directiveDefIdx, directiveDef.onInit, directiveDef.doCheck, tView);
if (directiveDef.hostBindings) queueHostBindingForCheck(index);
if (directiveDef.hostBindings) queueHostBindingForCheck(directiveDefIdx);
}
if (tNode && tNode.attrs) {
setInputsFromAttrs(index, instance, directiveDef.inputs, tNode);
setInputsFromAttrs(directiveDefIdx, instance, directiveDef.inputs, tNode);
}
if (directiveDef.contentQueries) {
directiveDef.contentQueries();
}
return instance;
@ -1918,7 +1940,7 @@ export function componentRefresh<T>(directiveIndex: number, adjustedElementIndex
// Only attached CheckAlways components or attached, dirty OnPush components should be checked
if (viewAttached(hostView) && hostView[FLAGS] & (LViewFlags.CheckAlways | LViewFlags.Dirty)) {
ngDevMode && assertDataInRange(directiveIndex, directives !);
detectChangesInternal(hostView, element, getDirectiveInstance(directives ![directiveIndex]));
detectChangesInternal(hostView, element, directives ![directiveIndex]);
}
}
@ -2537,6 +2559,15 @@ export function loadDirective<T>(index: number): T {
return directives ![index];
}
export function loadQueryList<T>(queryListIdx: number): QueryList<T> {
ngDevMode && assertDefined(
viewData[CONTENT_QUERIES],
'Content QueryList array should be defined if reading a query.');
ngDevMode && assertDataInRange(queryListIdx, viewData[CONTENT_QUERIES] !);
return viewData[CONTENT_QUERIES] ![queryListIdx];
}
/** Gets the current binding value and increments the binding index. */
export function consumeBinding(): any {
ngDevMode && assertDataInRange(viewData[BINDING_INDEX]);
@ -2586,10 +2617,22 @@ export function getTView(): TView {
return tView;
}
export function getDirectiveInstance<T>(instanceOrArray: T | [T]): T {
// Directives with content queries store an array in directives[directiveIndex]
// with the instance as the first index
return Array.isArray(instanceOrArray) ? instanceOrArray[0] : instanceOrArray;
/**
* Registers a QueryList, associated with a content query, for later refresh (part of a view
* refresh).
*/
export function registerContentQuery<Q>(queryList: QueryList<Q>): void {
const savedContentQueriesLength =
(viewData[CONTENT_QUERIES] || (viewData[CONTENT_QUERIES] = [])).push(queryList);
if (firstTemplatePass) {
const currentDirectiveIndex = directives !.length - 1;
const tViewContentQueries = tView.contentQueries || (tView.contentQueries = []);
const lastSavedDirectiveIndex =
tView.contentQueries.length ? tView.contentQueries[tView.contentQueries.length - 2] : -1;
if (currentDirectiveIndex !== lastSavedDirectiveIndex) {
tViewContentQueries.push(currentDirectiveIndex, savedContentQueriesLength - 1);
}
}
}
export function assertPreviousIsParent() {

View File

@ -122,6 +122,14 @@ export interface DirectiveDef<T, Selector extends string> {
*/
factory(): T|[T];
/**
* Function to create instances of content queries associated with a given directive.
*/
contentQueries: (() => void)|null;
/** Refreshes content queries associated with directives in a given view */
contentQueriesRefresh: ((directiveIndex: number, queryIndex: number) => void)|null;
/** Refreshes host bindings on the associated directive. */
hostBindings: ((directiveIndex: number, elementIndex: number) => void)|null;

View File

@ -7,6 +7,7 @@
*/
import {Injector} from '../../di/injector';
import {QueryList} from '../../linker';
import {Sanitizer} from '../../sanitization/security';
import {LContainer} from './container';
@ -16,7 +17,7 @@ import {LQueries} from './query';
import {Renderer3} from './renderer';
/** Size of LViewData's header. Necessary to adjust for it when setting slots. */
export const HEADER_OFFSET = 15;
export const HEADER_OFFSET = 16;
// Below are constants for LViewData indices to help us look up LViewData members
// without having to remember the specific indices.
@ -36,6 +37,7 @@ export const RENDERER = 11;
export const SANITIZER = 12;
export const TAIL = 13;
export const CONTAINER_INDEX = 14;
export const CONTENT_QUERIES = 15;
/**
* `LViewData` stores all of the information needed to process the instructions as
@ -153,6 +155,13 @@ export interface LViewData extends Array<any> {
* in multiple containers, so the parent cannot be shared between view instances).
*/
[CONTAINER_INDEX]: number;
/**
* Stores QueryLists associated with content queries of a directive. This data structure is
* filled-in as part of a directive creation process and is later used to retrieve a QueryList to
* be refreshed.
*/
[CONTENT_QUERIES]: QueryList<any>[]|null;
}
/** Flags associated with an LView (saved in LViewData[FLAGS]) */
@ -413,6 +422,15 @@ export interface TView {
* they will be fed into instructions that expect the raw index (e.g. elementProperty)
*/
hostBindings: number[]|null;
/**
* A list of indices for child directives that have content queries.
*
* Even indices: Directive indices
* Odd indices: Starting index of content queries (stored in CONTENT_QUERIES) for this directive
*/
contentQueries: number[]|null;
}
/**

View File

@ -158,9 +158,6 @@
{
"name": "getChildLNode"
},
{
"name": "getDirectiveInstance"
},
{
"name": "getLViewChild"
},
@ -197,6 +194,9 @@
{
"name": "refreshChildComponents"
},
{
"name": "refreshContentQueries"
},
{
"name": "refreshDynamicEmbeddedViews"
},

View File

@ -446,9 +446,6 @@
{
"name": "getCurrentSanitizer"
},
{
"name": "getDirectiveInstance"
},
{
"name": "getLViewChild"
},
@ -632,6 +629,9 @@
{
"name": "refreshChildComponents"
},
{
"name": "refreshContentQueries"
},
{
"name": "refreshDynamicEmbeddedViews"
},

View File

@ -108,18 +108,17 @@ describe('queries', () => {
static ngComponentDef = $r3$.ɵdefineComponent({
type: ContentQueryComponent,
selectors: [['content-query-component']],
factory: function ContentQueryComponent_Factory() {
return [
new ContentQueryComponent(), $r3$.ɵQ(null, SomeDirective, false),
$r3$.ɵQ(null, SomeDirective, false)
];
factory: function ContentQueryComponent_Factory() { return new ContentQueryComponent(); },
contentQueries: function ContentQueryComponent_ContentQueries() {
$r3$.ɵQr($r3$.ɵQ(null, SomeDirective, false));
$r3$.ɵQr($r3$.ɵQ(null, SomeDirective, false));
},
hostBindings: function ContentQueryComponent_HostBindings(
dirIndex: $number$, elIndex: $number$) {
contentQueriesRefresh: function ContentQueryComponent_ContentQueriesRefresh(
dirIndex: $number$, queryStartIndex: $number$) {
let $tmp$: any;
const $instance$ = $r3$.ɵd<any[]>(dirIndex)[0];
$r3$.ɵqR($tmp$ = $r3$.ɵd<any[]>(dirIndex)[1]) && ($instance$.someDir = $tmp$.first);
$r3$.ɵqR($tmp$ = $r3$.ɵd<any[]>(dirIndex)[2]) && ($instance$.someDirList = $tmp$);
const $instance$ = $r3$.ɵd<ContentQueryComponent>(dirIndex);
$r3$.ɵqR($tmp$ = $r3$.ɵql<any>(queryStartIndex)) && ($instance$.someDir = $tmp$.first);
$r3$.ɵqR($tmp$ = $r3$.ɵql<any>(queryStartIndex + 1)) && ($instance$.someDirList = $tmp$);
},
template: function ContentQueryComponent_Template(
rf: $number$, ctx: $ContentQueryComponent$) {
@ -153,7 +152,7 @@ describe('queries', () => {
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) {
$r3$.ɵE(0, 'content-query-component');
contentQueryComp = $r3$.ɵd<any[]>(0)[0];
contentQueryComp = $r3$.ɵd<ContentQueryComponent>(0);
$r3$.ɵEe(1, 'div', $e2_attrs$);
$r3$.ɵe();
}

View File

@ -12,7 +12,7 @@ import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
import {EventEmitter} from '../..';
import {QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from '../../src/render3/di';
import {AttributeMarker, QueryList, defineComponent, defineDirective, detectChanges, injectViewContainerRef} from '../../src/render3/index';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadDirective} from '../../src/render3/instructions';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadDirective, loadQueryList, registerContentQuery} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition';
import {query, queryRefresh} from '../../src/render3/query';
@ -1684,6 +1684,48 @@ describe('query', () => {
describe('content', () => {
it('should support content queries for directives', () => {
let withContentInstance: WithContentDirective;
class WithContentDirective {
// @ContentChildren('foo') foos;
// TODO(issue/24571): remove '!'.
foos !: QueryList<ElementRef>;
static ngComponentDef = defineDirective({
type: WithContentDirective,
selectors: [['', 'with-content', '']],
factory: () => new WithContentDirective(),
contentQueries:
() => { registerContentQuery(query(null, ['foo'], true, QUERY_READ_FROM_NODE)); },
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
let tmp: any;
withContentInstance = loadDirective<WithContentDirective>(dirIndex);
queryRefresh(tmp = loadQueryList<ElementRef>(queryStartIdx)) &&
(withContentInstance.foos = tmp);
}
});
}
/**
* <div with-content>
* <span #foo></span>
* </div>
* class Cmpt {
* }
*/
const AppComponent = createComponent('app-component', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementStart(0, 'div', [AttributeMarker.SelectOnly, 'with-content']);
{ element(1, 'span', null, ['foo', '']); }
elementEnd();
}
}, [WithContentDirective]);
const fixture = new ComponentFixture(AppComponent);
expect(withContentInstance !.foos.length).toBe(1);
});
// https://stackblitz.com/edit/angular-wlenwd?file=src%2Fapp%2Fapp.component.ts
it('should support view and content queries matching the same element', () => {
let withContentComponentInstance: WithContentComponent;
@ -1696,18 +1738,17 @@ describe('query', () => {
static ngComponentDef = defineComponent({
type: WithContentComponent,
selectors: [['with-content']],
factory: () => {
return [new WithContentComponent(), query(null, ['foo'], true, QUERY_READ_FROM_NODE)];
},
factory: () => new WithContentComponent(),
contentQueries:
() => { registerContentQuery(query(null, ['foo'], true, QUERY_READ_FROM_NODE)); },
template: (rf: RenderFlags, ctx: WithContentComponent) => {
// intentionally left empty, don't need anything for this test
},
hostBindings: function ContentQueryComponent_HostBindings(
dirIndex: number, elIndex: number) {
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
let tmp: any;
withContentComponentInstance = loadDirective<any[]>(dirIndex)[0];
queryRefresh(tmp = loadDirective<any[]>(dirIndex)[1]) &&
(withContentComponentInstance.foos = tmp as QueryList<any>);
withContentComponentInstance = loadDirective<WithContentComponent>(dirIndex);
queryRefresh(tmp = loadQueryList<ElementRef>(queryStartIdx)) &&
(withContentComponentInstance.foos = tmp);
},
});
}
@ -1760,19 +1801,17 @@ describe('query', () => {
type: QueryDirective,
selectors: [['', 'query', '']],
exportAs: 'query',
factory: () => {
factory: () => new QueryDirective(),
contentQueries: () => {
// @ContentChildren('foo, bar, baz', {descendants: true}) fooBars:
// QueryList<ElementRef>;
return [
new QueryDirective(), query(null, ['foo', 'bar', 'baz'], true, QUERY_READ_FROM_NODE)
];
registerContentQuery(query(null, ['foo', 'bar', 'baz'], true, QUERY_READ_FROM_NODE));
},
hostBindings: function ContentQueryComponent_HostBindings(
dirIndex: number, elIndex: number) {
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
let tmp: any;
const instance = loadDirective<any[]>(dirIndex)[0];
queryRefresh(tmp = loadDirective<any[]>(dirIndex)[1]) &&
(instance.fooBars = tmp as QueryList<any>);
const instance = loadDirective<QueryDirective>(dirIndex);
queryRefresh(tmp = loadQueryList<ElementRef>(queryStartIdx)) &&
(instance.fooBars = tmp);
},
});
}
@ -1804,8 +1843,8 @@ describe('query', () => {
elementEnd();
}
if (rf & RenderFlags.Update) {
outInstance = (<any>load(1))[0] as QueryDirective;
inInstance = (<any>load(5))[0] as QueryDirective;
outInstance = load<QueryDirective>(1);
inInstance = load<QueryDirective>(5);
}
},
[QueryDirective]);
@ -1823,18 +1862,16 @@ describe('query', () => {
type: ShallowQueryDirective,
selectors: [['', 'shallow-query', '']],
exportAs: 'shallow-query',
factory: () => {
// @ContentChildren('foo', {descendants: false}) fooBars: QueryList<ElementRef>;
return [
new ShallowQueryDirective(), query(null, ['foo'], false, QUERY_READ_FROM_NODE)
];
factory: () => new ShallowQueryDirective(),
contentQueries: () => {
// @ContentChildren('foo', {descendants: false}) foos: QueryList<ElementRef>;
registerContentQuery(query(null, ['foo'], false, QUERY_READ_FROM_NODE));
},
hostBindings: function ContentQueryComponent_HostBindings(
dirIndex: number, elIndex: number) {
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
let tmp: any;
const instance = loadDirective<any[]>(dirIndex)[0];
queryRefresh(tmp = loadDirective<any[]>(dirIndex)[1]) &&
(instance.foos = tmp as QueryList<any>);
const instance = loadDirective<ShallowQueryDirective>(dirIndex);
queryRefresh(tmp = loadQueryList<ElementRef>(queryStartIdx)) &&
(instance.foos = tmp);
},
});
}
@ -1845,16 +1882,16 @@ describe('query', () => {
type: DeepQueryDirective,
selectors: [['', 'deep-query', '']],
exportAs: 'deep-query',
factory: () => {
// @ContentChildren('foo', {descendants: true}) fooBars: QueryList<ElementRef>;
return [new DeepQueryDirective(), query(null, ['foo'], true, QUERY_READ_FROM_NODE)];
factory: () => new DeepQueryDirective(),
contentQueries: () => {
// @ContentChildren('foo', {descendants: false}) foos: QueryList<ElementRef>;
registerContentQuery(query(null, ['foo'], true, QUERY_READ_FROM_NODE));
},
hostBindings: function ContentQueryComponent_HostBindings(
dirIndex: number, elIndex: number) {
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
let tmp: any;
const instance = loadDirective<any[]>(dirIndex)[0];
queryRefresh(tmp = loadDirective<any[]>(dirIndex)[1]) &&
(instance.foos = tmp as QueryList<any>);
const instance = loadDirective<DeepQueryDirective>(dirIndex);
queryRefresh(tmp = loadQueryList<ElementRef>(queryStartIdx)) &&
(instance.foos = tmp);
},
});
}
@ -1878,8 +1915,8 @@ describe('query', () => {
elementEnd();
}
if (rf & RenderFlags.Update) {
shallowInstance = (<any>load(1))[0] as ShallowQueryDirective;
deepInstance = (<any>load(2))[0] as DeepQueryDirective;
shallowInstance = load<ShallowQueryDirective>(1);
deepInstance = load<DeepQueryDirective>(2);
}
},
[ShallowQueryDirective, DeepQueryDirective]);