diff --git a/integration/_payload-limits.json b/integration/_payload-limits.json
index b93f10069f..62088d7ca7 100644
--- a/integration/_payload-limits.json
+++ b/integration/_payload-limits.json
@@ -12,7 +12,7 @@
"master": {
"uncompressed": {
"runtime": 1440,
- "main": 12885,
+ "main": 13019,
"polyfills": 38390
}
}
diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts
index 4889294ac1..c87c47c560 100644
--- a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts
+++ b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts
@@ -229,6 +229,9 @@ export function extractQueryMetadata(
const node = unwrapForwardRef(args[0], reflector);
const arg = evaluator.evaluate(node);
+ /** Whether or not this query should collect only static results (see view/api.ts) */
+ let isStatic: boolean = false;
+
// Extract the predicate
let predicate: Expression|string[]|null = null;
if (arg instanceof Reference) {
@@ -263,13 +266,28 @@ export function extractQueryMetadata(
}
descendants = descendantsValue;
}
+
+ if (options.has('static')) {
+ const staticValue = evaluator.evaluate(options.get('static') !);
+ if (typeof staticValue !== 'boolean') {
+ throw new FatalDiagnosticError(
+ ErrorCode.VALUE_HAS_WRONG_TYPE, node, `@${name} options.static must be a boolean`);
+ }
+ isStatic = staticValue;
+ }
+
} else if (args.length > 2) {
// Too many arguments.
throw new Error(`@${name} has too many arguments`);
}
return {
- propertyName, predicate, first, descendants, read,
+ propertyName,
+ predicate,
+ first,
+ descendants,
+ read,
+ static: isStatic,
};
}
diff --git a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts
index 497d59d143..b28c67b354 100644
--- a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts
+++ b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts
@@ -1376,8 +1376,8 @@ describe('compiler compliance', () => {
factory: function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); },
viewQuery: function ViewQueryComponent_Query(rf, ctx) {
if (rf & 1) {
- $r3$.ɵviewQuery(SomeDirective, true);
- $r3$.ɵviewQuery(SomeDirective, true);
+ $r3$.ɵviewQuery(SomeDirective, true, null);
+ $r3$.ɵviewQuery(SomeDirective, true, null);
}
if (rf & 2) {
var $tmp$;
@@ -1434,8 +1434,8 @@ describe('compiler compliance', () => {
…
viewQuery: function ViewQueryComponent_Query(rf, ctx) {
if (rf & 1) {
- $r3$.ɵviewQuery($e0_attrs$, true);
- $r3$.ɵviewQuery($e1_attrs$, true);
+ $r3$.ɵviewQuery($e0_attrs$, true, null);
+ $r3$.ɵviewQuery($e1_attrs$, true, null);
}
if (rf & 2) {
var $tmp$;
@@ -1452,6 +1452,67 @@ describe('compiler compliance', () => {
expectEmit(source, ViewQueryComponentDefinition, 'Invalid ViewQuery declaration');
});
+ it('should support static view queries', () => {
+ const files = {
+ app: {
+ ...directive,
+ 'view_query.component.ts': `
+ import {Component, NgModule, ViewChild} from '@angular/core';
+ import {SomeDirective} from './some.directive';
+
+ @Component({
+ selector: 'view-query-component',
+ template: \`
+
+ \`
+ })
+ export class ViewQueryComponent {
+ @ViewChild(SomeDirective, {static: true}) someDir !: SomeDirective;
+ @ViewChild('foo', {static: false}) foo !: ElementRef;
+ }
+
+ @NgModule({declarations: [SomeDirective, ViewQueryComponent]})
+ export class MyModule {}
+ `
+ }
+ };
+
+ const ViewQueryComponentDefinition = `
+ const $refs$ = ["foo"];
+ const $e0_attrs$ = ["someDir",""];
+ …
+ ViewQueryComponent.ngComponentDef = $r3$.ɵdefineComponent({
+ type: ViewQueryComponent,
+ selectors: [["view-query-component"]],
+ factory: function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); },
+ viewQuery: function ViewQueryComponent_Query(rf, ctx) {
+ if (rf & 1) {
+ $r3$.ɵstaticViewQuery(SomeDirective, true, null);
+ $r3$.ɵviewQuery($refs$, true, null);
+ }
+ if (rf & 2) {
+ var $tmp$;
+ ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.someDir = $tmp$.first));
+ ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.foo = $tmp$.first));
+ }
+ },
+ consts: 1,
+ vars: 0,
+ template: function ViewQueryComponent_Template(rf, ctx) {
+ if (rf & 1) {
+ $r3$.ɵelement(0, "div", $e0_attrs$);
+ }
+ },
+ directives: function () { return [SomeDirective]; },
+ encapsulation: 2
+ });`;
+
+ const result = compile(files, angularFiles);
+ const source = result.source;
+
+ expectEmit(source, ViewQueryComponentDefinition, 'Invalid ViewQuery declaration');
+ });
+
it('should support view queries with read tokens specified', () => {
const files = {
app: {
@@ -1555,8 +1616,8 @@ describe('compiler compliance', () => {
},
contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) {
if (rf & 1) {
- $r3$.ɵcontentQuery(dirIndex, SomeDirective, true);
- $r3$.ɵcontentQuery(dirIndex, SomeDirective, false);
+ $r3$.ɵcontentQuery(dirIndex, SomeDirective, true, null);
+ $r3$.ɵcontentQuery(dirIndex, SomeDirective, false, null);
}
if (rf & 2) {
var $tmp$;
@@ -1615,8 +1676,8 @@ describe('compiler compliance', () => {
…
contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) {
if (rf & 1) {
- $r3$.ɵcontentQuery(dirIndex, $e0_attrs$, true);
- $r3$.ɵcontentQuery(dirIndex, $e1_attrs$, false);
+ $r3$.ɵcontentQuery(dirIndex, $e0_attrs$, true, null);
+ $r3$.ɵcontentQuery(dirIndex, $e1_attrs$, false, null);
}
if (rf & 2) {
var $tmp$;
diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts
index 41f8515b79..29cd9329e4 100644
--- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts
+++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts
@@ -17,13 +17,13 @@ const trim = (input: string): string => input.replace(/\s+/g, ' ').trim();
const varRegExp = (name: string): RegExp => new RegExp(`var \\w+ = \\[\"${name}\"\\];`);
const viewQueryRegExp = (descend: boolean, ref?: string): RegExp => {
- const maybeRef = ref ? `, ${ref}` : ``;
- return new RegExp(`i0\\.ɵviewQuery\\(\\w+, ${descend}${maybeRef}\\)`);
+ const maybeRef = ref ? `${ref}` : `null`;
+ return new RegExp(`i0\\.ɵviewQuery\\(\\w+, ${descend}, ${maybeRef}\\)`);
};
const contentQueryRegExp = (predicate: string, descend: boolean, ref?: string): RegExp => {
- const maybeRef = ref ? `, ${ref}` : ``;
- return new RegExp(`i0\\.ɵcontentQuery\\(dirIndex, ${predicate}, ${descend}${maybeRef}\\)`);
+ const maybeRef = ref ? `${ref}` : `null`;
+ return new RegExp(`i0\\.ɵcontentQuery\\(dirIndex, ${predicate}, ${descend}, ${maybeRef}\\)`);
};
describe('ngtsc behavioral tests', () => {
@@ -1017,7 +1017,7 @@ describe('ngtsc behavioral tests', () => {
expect(jsContents).toMatch(varRegExp('accessor'));
// match `i0.ɵcontentQuery(dirIndex, _c1, true, TemplateRef)`
expect(jsContents).toMatch(contentQueryRegExp('\\w+', true, 'TemplateRef'));
- // match `i0.ɵviewQuery(_c2, true)`
+ // match `i0.ɵviewQuery(_c2, true, null)`
expect(jsContents).toMatch(viewQueryRegExp(true));
});
@@ -1039,9 +1039,9 @@ describe('ngtsc behavioral tests', () => {
env.driveMain();
const jsContents = env.getContents('test.js');
- // match `i0.ɵcontentQuery(dirIndex, TemplateRef, true)`
+ // match `i0.ɵcontentQuery(dirIndex, TemplateRef, true, null)`
expect(jsContents).toMatch(contentQueryRegExp('TemplateRef', true));
- // match `i0.ɵcontentQuery(dirIndex, ViewContainerRef, true)`
+ // match `i0.ɵcontentQuery(dirIndex, ViewContainerRef, true, null)`
expect(jsContents).toMatch(contentQueryRegExp('ViewContainerRef', true));
});
diff --git a/packages/compiler/src/compiler_facade_interface.ts b/packages/compiler/src/compiler_facade_interface.ts
index ad281c618e..10315fc72c 100644
--- a/packages/compiler/src/compiler_facade_interface.ts
+++ b/packages/compiler/src/compiler_facade_interface.ts
@@ -150,6 +150,7 @@ export interface R3QueryMetadataFacade {
predicate: any|string[];
descendants: boolean;
read: any|null;
+ static: boolean;
}
export interface ParseSourceSpan {
diff --git a/packages/compiler/src/jit_compiler_facade.ts b/packages/compiler/src/jit_compiler_facade.ts
index 9d36aa3098..eeff934a04 100644
--- a/packages/compiler/src/jit_compiler_facade.ts
+++ b/packages/compiler/src/jit_compiler_facade.ts
@@ -199,6 +199,7 @@ function convertToR3QueryMetadata(facade: R3QueryMetadataFacade): R3QueryMetadat
predicate: Array.isArray(facade.predicate) ? facade.predicate :
new WrappedNodeExpr(facade.predicate),
read: facade.read ? new WrappedNodeExpr(facade.read) : null,
+ static: facade.static
};
}
diff --git a/packages/compiler/src/render3/r3_identifiers.ts b/packages/compiler/src/render3/r3_identifiers.ts
index 2b156e1354..40e7ee30c7 100644
--- a/packages/compiler/src/render3/r3_identifiers.ts
+++ b/packages/compiler/src/render3/r3_identifiers.ts
@@ -186,6 +186,7 @@ export class Identifiers {
static queryRefresh: o.ExternalReference = {name: 'ɵqueryRefresh', moduleName: CORE};
static viewQuery: o.ExternalReference = {name: 'ɵviewQuery', moduleName: CORE};
+ static staticViewQuery: o.ExternalReference = {name: 'ɵstaticViewQuery', moduleName: CORE};
static loadViewQuery: o.ExternalReference = {name: 'ɵloadViewQuery', moduleName: CORE};
static contentQuery: o.ExternalReference = {name: 'ɵcontentQuery', moduleName: CORE};
static loadContentQuery: o.ExternalReference = {name: 'ɵloadContentQuery', moduleName: CORE};
diff --git a/packages/compiler/src/render3/view/api.ts b/packages/compiler/src/render3/view/api.ts
index afe470a482..d82cc05540 100644
--- a/packages/compiler/src/render3/view/api.ts
+++ b/packages/compiler/src/render3/view/api.ts
@@ -229,6 +229,21 @@ export interface R3QueryMetadata {
* for a given node is to be returned.
*/
read: o.Expression|null;
+
+ /**
+ * Whether or not this query should collect only static results.
+ *
+ * If static is true, the query's results will be set on the component after nodes are created,
+ * but before change detection runs. This means that any results that relied upon change detection
+ * to run (e.g. results inside *ngIf or *ngFor views) will not be collected. Query results are
+ * available in the ngOnInit hook.
+ *
+ * If static is false, the query's results will be set on the component after change detection
+ * runs. This means that the query results can contain nodes inside *ngIf or *ngFor views, but
+ * the results will not be available in the ngOnInit hook (only in the ngAfterContentInit for
+ * content hooks and ngAfterViewInit for view hooks).
+ */
+ static: boolean;
}
/**
diff --git a/packages/compiler/src/render3/view/compiler.ts b/packages/compiler/src/render3/view/compiler.ts
index a79cb4186a..25ec289b01 100644
--- a/packages/compiler/src/render3/view/compiler.ts
+++ b/packages/compiler/src/render3/view/compiler.ts
@@ -457,6 +457,7 @@ function queriesFromGlobalMetadata(
first: query.first,
predicate: selectorsFromGlobalMetadata(query.selectors, outputCtx),
descendants: query.descendants, read,
+ static: !!query.static
};
});
}
@@ -490,10 +491,8 @@ function prepareQueryParams(query: R3QueryMetadata, constantPool: ConstantPool):
const parameters = [
getQueryPredicate(query, constantPool),
o.literal(query.descendants),
+ query.read || o.literal(null),
];
- if (query.read) {
- parameters.push(query.read);
- }
return parameters;
}
@@ -590,9 +589,11 @@ function createViewQueriesFunction(
const tempAllocator = temporaryAllocator(updateStatements, TEMPORARY_NAME);
meta.viewQueries.forEach((query: R3QueryMetadata) => {
+ const queryInstruction = query.static ? R3.staticViewQuery : R3.viewQuery;
+
// creation, e.g. r3.viewQuery(somePredicate, true);
const queryDefinition =
- o.importExpr(R3.viewQuery).callFn(prepareQueryParams(query, constantPool));
+ o.importExpr(queryInstruction).callFn(prepareQueryParams(query, constantPool));
createStatements.push(queryDefinition.toStmt());
// update, e.g. (r3.queryRefresh(tmp = r3.loadViewQuery()) && (ctx.someDir = tmp));
diff --git a/packages/core/src/compiler/compiler_facade_interface.ts b/packages/core/src/compiler/compiler_facade_interface.ts
index a5f1802c2e..a5a209845b 100644
--- a/packages/core/src/compiler/compiler_facade_interface.ts
+++ b/packages/core/src/compiler/compiler_facade_interface.ts
@@ -150,6 +150,7 @@ export interface R3QueryMetadataFacade {
predicate: any|string[];
descendants: boolean;
read: any|null;
+ static: boolean;
}
export interface ParseSourceSpan {
diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts
index f13b2b91da..fd88d0ba06 100644
--- a/packages/core/src/core_render3_private_export.ts
+++ b/packages/core/src/core_render3_private_export.ts
@@ -81,6 +81,7 @@ export {
containerRefreshEnd as ɵcontainerRefreshEnd,
queryRefresh as ɵqueryRefresh,
viewQuery as ɵviewQuery,
+ staticViewQuery as ɵstaticViewQuery,
loadViewQuery as ɵloadViewQuery,
contentQuery as ɵcontentQuery,
loadContentQuery as ɵloadContentQuery,
diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts
index 447538a3b3..e525473d46 100644
--- a/packages/core/src/render3/index.ts
+++ b/packages/core/src/render3/index.ts
@@ -124,6 +124,7 @@ export {
export {
queryRefresh,
viewQuery,
+ staticViewQuery,
loadViewQuery,
contentQuery,
loadContentQuery,
diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts
index 2cede59d00..1a350e7469 100644
--- a/packages/core/src/render3/instructions.ts
+++ b/packages/core/src/render3/instructions.ts
@@ -37,7 +37,7 @@ import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTEXT, DECLARATION_VIEW, Expa
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {appendChild, appendProjectedNode, createTextNode, getLViewChild, insertView, removeView} from './node_manipulation';
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
-import {decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getContextLView, getCurrentDirectiveDef, getElementDepthCount, getIsParent, getLView, getPreviousOrParentTNode, increaseElementDepthCount, isCreationMode, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setIsParent, setPreviousOrParentTNode} from './state';
+import {decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getContextLView, getCurrentDirectiveDef, getElementDepthCount, getIsParent, getLView, getPreviousOrParentTNode, increaseElementDepthCount, isCreationMode, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setIsParent, setPreviousOrParentTNode,} from './state';
import {getInitialClassNameValue, getInitialStyleStringValue, initializeStaticContext as initializeStaticStylingContext, patchContextWithStaticAttrs, renderInitialClasses, renderInitialStyles, renderStyling, updateClassProp as updateElementClassProp, updateContextWithBindings, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling/class_and_style_bindings';
import {BoundPlayerFactory} from './styling/player_factory';
import {ANIMATION_PROP_PREFIX, allocateDirectiveIntoContext, createEmptyStylingContext, forceClassesAsString, forceStylesAsString, getStylingContext, hasClassInput, hasStyleInput, hasStyling, isAnimationProp} from './styling/util';
@@ -784,6 +784,7 @@ export function createTView(
expandoStartIndex: initialViewLength,
expandoInstructions: null,
firstTemplatePass: true,
+ staticViewQueries: false,
initHooks: null,
checkHooks: null,
contentHooks: null,
@@ -2922,20 +2923,23 @@ export function checkView(hostView: LView, component: T) {
try {
namespaceHTML();
- creationMode && executeViewQueryFn(hostView, hostTView, component);
+ creationMode && executeViewQueryFn(RenderFlags.Create, hostTView, component);
templateFn(getRenderFlags(hostView), component);
refreshDescendantViews(hostView);
- !creationMode && executeViewQueryFn(hostView, hostTView, component);
+ // Only check view queries again in creation mode if there are static view queries
+ if (!creationMode || hostTView.staticViewQueries) {
+ executeViewQueryFn(RenderFlags.Update, hostTView, component);
+ }
} finally {
leaveView(oldView);
}
}
-function executeViewQueryFn(lView: LView, tView: TView, component: T): void {
+function executeViewQueryFn(flags: RenderFlags, tView: TView, component: T): void {
const viewQuery = tView.viewQuery;
if (viewQuery) {
setCurrentQueryIndex(tView.viewQueryStartIndex);
- viewQuery(getRenderFlags(lView), component);
+ viewQuery(flags, component);
}
}
diff --git a/packages/core/src/render3/interfaces/view.ts b/packages/core/src/render3/interfaces/view.ts
index 500984ab4d..51c35ee782 100644
--- a/packages/core/src/render3/interfaces/view.ts
+++ b/packages/core/src/render3/interfaces/view.ts
@@ -376,6 +376,14 @@ export interface TView {
*/
expandoStartIndex: number;
+ /**
+ * Whether or not there are any static view queries tracked on this view.
+ *
+ * We store this so we know whether or not we should do a view query
+ * refresh after creation mode to collect static query results.
+ */
+ staticViewQueries: boolean;
+
/**
* The index where the viewQueries section of `LView` begins. This section contains
* view queries defined for a component/directive.
diff --git a/packages/core/src/render3/jit/directive.ts b/packages/core/src/render3/jit/directive.ts
index 81c785c328..d04debf859 100644
--- a/packages/core/src/render3/jit/directive.ts
+++ b/packages/core/src/render3/jit/directive.ts
@@ -169,7 +169,8 @@ export function convertToR3QueryMetadata(propertyName: string, ann: Query): R3Qu
predicate: convertToR3QueryPredicate(ann.selector),
descendants: ann.descendants,
first: ann.first,
- read: ann.read ? ann.read : null
+ read: ann.read ? ann.read : null,
+ static: !!ann.static
};
}
function extractQueriesMetadata(
diff --git a/packages/core/src/render3/jit/environment.ts b/packages/core/src/render3/jit/environment.ts
index 81b440d3c2..f48e1f779b 100644
--- a/packages/core/src/render3/jit/environment.ts
+++ b/packages/core/src/render3/jit/environment.ts
@@ -88,6 +88,7 @@ export const angularCoreEnv: {[name: string]: Function} = {
'ɵpipe': r3.pipe,
'ɵqueryRefresh': r3.queryRefresh,
'ɵviewQuery': r3.viewQuery,
+ 'ɵstaticViewQuery': r3.staticViewQuery,
'ɵloadViewQuery': r3.loadViewQuery,
'ɵcontentQuery': r3.contentQuery,
'ɵloadContentQuery': r3.loadContentQuery,
diff --git a/packages/core/src/render3/query.ts b/packages/core/src/render3/query.ts
index 59e305e41c..e13cc22692 100644
--- a/packages/core/src/render3/query.ts
+++ b/packages/core/src/render3/query.ts
@@ -24,7 +24,7 @@ import {unusedValueExportToPlacateAjd as unused2} from './interfaces/injector';
import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType, unusedValueExportToPlacateAjd as unused3} from './interfaces/node';
import {LQueries, unusedValueExportToPlacateAjd as unused4} from './interfaces/query';
import {CONTENT_QUERIES, HEADER_OFFSET, LView, QUERIES, TVIEW} from './interfaces/view';
-import {getCurrentQueryIndex, getIsParent, getLView, setCurrentQueryIndex} from './state';
+import {getCurrentQueryIndex, getIsParent, getLView, isCreationMode, setCurrentQueryIndex} from './state';
import {createElementRef, createTemplateRef} from './view_engine_compatibility';
const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4;
@@ -338,7 +338,7 @@ function createQuery(
};
}
-type QueryList_ = QueryList& {_valuesTree: any[]};
+type QueryList_ = QueryList& {_valuesTree: any[], _static: boolean};
/**
* Creates and returns a QueryList.
@@ -350,12 +350,13 @@ type QueryList_ = QueryList& {_valuesTree: any[]};
*/
export function query(
// TODO: "read" should be an AbstractType (FW-486)
- predicate: Type| string[], descend?: boolean, read?: any): QueryList {
+ predicate: Type| string[], descend: boolean, read: any): QueryList {
ngDevMode && assertPreviousIsParent(getIsParent());
const lView = getLView();
- const queryList = new QueryList();
+ const queryList = new QueryList() as QueryList_;
const queries = lView[QUERIES] || (lView[QUERIES] = new LQueries_(null, null, null));
- (queryList as QueryList_)._valuesTree = [];
+ queryList._valuesTree = [];
+ queryList._static = false;
queries.track(queryList, predicate, descend, read);
storeCleanupWithContext(lView, queryList, queryList.destroy);
return queryList;
@@ -368,7 +369,10 @@ export function query(
*/
export function queryRefresh(queryList: QueryList): boolean {
const queryListImpl = (queryList as any as QueryList_);
- if (queryList.dirty) {
+ const creationMode = isCreationMode();
+
+ // if creation mode and static or update mode and not static
+ if (queryList.dirty && creationMode === queryListImpl._static) {
queryList.reset(queryListImpl._valuesTree || []);
queryList.notifyOnChanges();
return true;
@@ -376,6 +380,24 @@ export function queryRefresh(queryList: QueryList): boolean {
return false;
}
+/**
+ * Creates new QueryList for a static view query.
+ *
+ * @param predicate The type for which the query will search
+ * @param descend Whether or not to descend into children
+ * @param read What to save in the query
+ */
+export function staticViewQuery(
+ // TODO(FW-486): "read" should be an AbstractType
+ predicate: Type| string[], descend: boolean, read: any): void {
+ const queryList = viewQuery(predicate, descend, read) as QueryList_;
+ const tView = getLView()[TVIEW];
+ queryList._static = true;
+ if (!tView.staticViewQueries) {
+ tView.staticViewQueries = true;
+ }
+}
+
/**
* Creates new QueryList, stores the reference in LView and returns QueryList.
*
@@ -385,8 +407,8 @@ export function queryRefresh(queryList: QueryList): boolean {
* @returns QueryList
*/
export function viewQuery(
- // TODO: "read" should be an AbstractType (FW-486)
- predicate: Type| string[], descend?: boolean, read?: any): QueryList {
+ // TODO(FW-486): "read" should be an AbstractType
+ predicate: Type| string[], descend: boolean, read: any): QueryList {
const lView = getLView();
const tView = lView[TVIEW];
if (tView.firstTemplatePass) {
@@ -419,9 +441,9 @@ export function loadViewQuery(): T {
* @returns QueryList
*/
export function contentQuery(
- directiveIndex: number, predicate: Type| string[], descend?: boolean,
+ directiveIndex: number, predicate: Type| string[], descend: boolean,
// TODO: "read" should be an AbstractType (FW-486)
- read?: any): QueryList {
+ read: any): QueryList {
const lView = getLView();
const tView = lView[TVIEW];
const contentQuery: QueryList = query(predicate, descend, read);
@@ -448,4 +470,4 @@ export function loadContentQuery(): QueryList {
setCurrentQueryIndex(index + 1);
return lView[CONTENT_QUERIES] ![index];
-}
\ No newline at end of file
+}
diff --git a/packages/core/test/acceptance/query_spec.ts b/packages/core/test/acceptance/query_spec.ts
index 162948c9ca..58633ed3ab 100644
--- a/packages/core/test/acceptance/query_spec.ts
+++ b/packages/core/test/acceptance/query_spec.ts
@@ -16,7 +16,8 @@ describe('query logic', () => {
TestBed.configureTestingModule({
declarations: [
AppComp, QueryComp, SimpleCompA, SimpleCompB, StaticViewQueryComp, TextDirective,
- SubclassStaticViewQueryComp, StaticContentQueryComp, SubclassStaticContentQueryComp
+ SubclassStaticViewQueryComp, StaticContentQueryComp, SubclassStaticContentQueryComp,
+ QueryCompWithChanges
]
});
});
@@ -87,48 +88,78 @@ describe('query logic', () => {
expect(comp.viewChildren.length).toBe(2);
});
- fixmeIvy('Must support static view queries in Ivy')
- .it('should set static view child queries in creation mode (and just in creation mode)',
- () => {
- const fixture = TestBed.createComponent(StaticViewQueryComp);
- const component = fixture.componentInstance;
+ it('should set static view child queries in creation mode (and just in creation mode)', () => {
+ const fixture = TestBed.createComponent(StaticViewQueryComp);
+ const component = fixture.componentInstance;
- // static ViewChild query should be set in creation mode, before CD runs
- expect(component.textDir).toBeAnInstanceOf(TextDirective);
- expect(component.textDir.text).toEqual('');
- expect(component.setEvents).toEqual(['textDir set']);
+ // static ViewChild query should be set in creation mode, before CD runs
+ expect(component.textDir).toBeAnInstanceOf(TextDirective);
+ expect(component.textDir.text).toEqual('');
+ expect(component.setEvents).toEqual(['textDir set']);
- // dynamic ViewChild query should not have been resolved yet
- expect(component.foo).not.toBeDefined();
+ // dynamic ViewChild query should not have been resolved yet
+ expect(component.foo).not.toBeDefined();
- const span = fixture.nativeElement.querySelector('span');
- fixture.detectChanges();
- expect(component.textDir.text).toEqual('some text');
- expect(component.foo.nativeElement).toBe(span);
- expect(component.setEvents).toEqual(['textDir set', 'foo set']);
- });
+ const span = fixture.nativeElement.querySelector('span');
+ fixture.detectChanges();
+ expect(component.textDir.text).toEqual('some text');
+ expect(component.foo.nativeElement).toBe(span);
+ expect(component.setEvents).toEqual(['textDir set', 'foo set']);
+ });
- fixmeIvy('Must support static view queries in Ivy')
- .it('should support static view child queries inherited from superclasses', () => {
- const fixture = TestBed.createComponent(SubclassStaticViewQueryComp);
- const component = fixture.componentInstance;
- const divs = fixture.nativeElement.querySelectorAll('div');
- const spans = fixture.nativeElement.querySelectorAll('span');
+ it('should support static view child queries inherited from superclasses', () => {
+ const fixture = TestBed.createComponent(SubclassStaticViewQueryComp);
+ const component = fixture.componentInstance;
+ const divs = fixture.nativeElement.querySelectorAll('div');
+ const spans = fixture.nativeElement.querySelectorAll('span');
- // static ViewChild queries should be set in creation mode, before CD runs
- expect(component.textDir).toBeAnInstanceOf(TextDirective);
- expect(component.textDir.text).toEqual('');
- expect(component.bar.nativeElement).toEqual(divs[1]);
+ // static ViewChild queries should be set in creation mode, before CD runs
+ expect(component.textDir).toBeAnInstanceOf(TextDirective);
+ expect(component.textDir.text).toEqual('');
+ expect(component.bar.nativeElement).toEqual(divs[1]);
- // dynamic ViewChild queries should not have been resolved yet
- expect(component.foo).not.toBeDefined();
- expect(component.baz).not.toBeDefined();
+ // dynamic ViewChild queries should not have been resolved yet
+ expect(component.foo).not.toBeDefined();
+ expect(component.baz).not.toBeDefined();
- fixture.detectChanges();
- expect(component.textDir.text).toEqual('some text');
- expect(component.foo.nativeElement).toBe(spans[0]);
- expect(component.baz.nativeElement).toBe(spans[1]);
- });
+ fixture.detectChanges();
+ expect(component.textDir.text).toEqual('some text');
+ expect(component.foo.nativeElement).toBe(spans[0]);
+ expect(component.baz.nativeElement).toBe(spans[1]);
+ });
+
+ it('should support multiple static view queries (multiple template passes)', () => {
+ const template = `
+
+
+ `;
+ TestBed.overrideComponent(AppComp, {set: new Component({template})});
+ const fixture = TestBed.createComponent(AppComp);
+
+ const firstComponent = fixture.debugElement.children[0].injector.get(StaticViewQueryComp);
+ const secondComponent = fixture.debugElement.children[1].injector.get(StaticViewQueryComp);
+
+ // static ViewChild query should be set in creation mode, before CD runs
+ expect(firstComponent.textDir).toBeAnInstanceOf(TextDirective);
+ expect(secondComponent.textDir).toBeAnInstanceOf(TextDirective);
+ expect(firstComponent.textDir.text).toEqual('');
+ expect(secondComponent.textDir.text).toEqual('');
+ expect(firstComponent.setEvents).toEqual(['textDir set']);
+ expect(secondComponent.setEvents).toEqual(['textDir set']);
+
+ // dynamic ViewChild query should not have been resolved yet
+ expect(firstComponent.foo).not.toBeDefined();
+ expect(secondComponent.foo).not.toBeDefined();
+
+ const spans = fixture.nativeElement.querySelectorAll('span');
+ fixture.detectChanges();
+ expect(firstComponent.textDir.text).toEqual('some text');
+ expect(secondComponent.textDir.text).toEqual('some text');
+ expect(firstComponent.foo.nativeElement).toBe(spans[0]);
+ expect(secondComponent.foo.nativeElement).toBe(spans[1]);
+ expect(firstComponent.setEvents).toEqual(['textDir set', 'foo set']);
+ expect(secondComponent.setEvents).toEqual(['textDir set', 'foo set']);
+ });
});
@@ -290,6 +321,30 @@ describe('query logic', () => {
expect(component.baz.nativeElement).toBe(spans[1]);
});
+ describe('observable interface', () => {
+
+ it('should allow observing changes to query list', () => {
+ const fixture = TestBed.createComponent(QueryCompWithChanges);
+ let changes = 0;
+ fixture.detectChanges();
+
+ fixture.componentInstance.foos.changes.subscribe((value: any) => {
+ changes += 1;
+ expect(value).toBe(fixture.componentInstance.foos);
+ });
+
+ // refresh without setting dirty - no emit
+ fixture.detectChanges();
+ expect(changes).toBe(0);
+
+ // refresh with setting dirty - emit
+ fixture.componentInstance.showing = true;
+ fixture.detectChanges();
+ expect(changes).toBe(1);
+ });
+
+ });
+
});
function initWithTemplate(compType: Type, template: string) {
@@ -406,3 +461,15 @@ class SubclassStaticContentQueryComp extends StaticContentQueryComp {
@ContentChild('baz', {static: false})
baz !: ElementRef;
}
+
+@Component({
+ selector: 'query-with-changes',
+ template: `
+
+ `
+})
+export class QueryCompWithChanges {
+ @ViewChildren('foo') foos !: QueryList;
+
+ showing = false;
+}
diff --git a/packages/core/test/linker/query_integration_spec.ts b/packages/core/test/linker/query_integration_spec.ts
index e93faa1139..a4f11a21b7 100644
--- a/packages/core/test/linker/query_integration_spec.ts
+++ b/packages/core/test/linker/query_integration_spec.ts
@@ -126,7 +126,7 @@ describe('Query API', () => {
]);
});
- modifiedInIvy('Static ViewChild and ContentChild queries are resolved in update mode')
+ modifiedInIvy('Static queries in Ivy require an explicit {static: true} arg')
.it('should set static view and content children already after the constructor call', () => {
const template =
'';
diff --git a/packages/core/test/render3/content_spec.ts b/packages/core/test/render3/content_spec.ts
index a4d82b307c..235a932d0e 100644
--- a/packages/core/test/render3/content_spec.ts
+++ b/packages/core/test/render3/content_spec.ts
@@ -1026,7 +1026,7 @@ describe('content projection', () => {
function(rf: RenderFlags, ctx: any) {
/** @ViewChild(TemplateRef) template: TemplateRef */
if (rf & RenderFlags.Create) {
- viewQuery(TemplateRef as any, true);
+ viewQuery(TemplateRef as any, true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
diff --git a/packages/core/test/render3/host_binding_spec.ts b/packages/core/test/render3/host_binding_spec.ts
index 2185df3317..a1af92fe26 100644
--- a/packages/core/test/render3/host_binding_spec.ts
+++ b/packages/core/test/render3/host_binding_spec.ts
@@ -1011,7 +1011,7 @@ describe('host bindings', () => {
},
contentQueries: (rf: RenderFlags, ctx: any, dirIndex: number) => {
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['foo']);
+ contentQuery(dirIndex, ['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
diff --git a/packages/core/test/render3/inherit_definition_feature_spec.ts b/packages/core/test/render3/inherit_definition_feature_spec.ts
index 7fa9769039..1ec9214fbd 100644
--- a/packages/core/test/render3/inherit_definition_feature_spec.ts
+++ b/packages/core/test/render3/inherit_definition_feature_spec.ts
@@ -382,7 +382,7 @@ describe('InheritDefinitionFeature', () => {
selectors: [['super-comp']],
viewQuery: (rf: RenderFlags, ctx: any) => {
if (rf & RenderFlags.Create) {
- viewQuery(['super'], false);
+ viewQuery(['super'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -418,7 +418,7 @@ describe('InheritDefinitionFeature', () => {
selectors: [['sub-comp']],
viewQuery: (rf: RenderFlags, ctx: any) => {
if (rf & RenderFlags.Create) {
- viewQuery(['sub'], false);
+ viewQuery(['sub'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -561,7 +561,7 @@ describe('InheritDefinitionFeature', () => {
factory: () => new SuperDirective(),
contentQueries: (rf: RenderFlags, ctx: any, dirIndex: number) => {
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['foo'], true);
+ contentQuery(dirIndex, ['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -581,7 +581,7 @@ describe('InheritDefinitionFeature', () => {
factory: () => dirInstance = new SubDirective(),
contentQueries: (rf: RenderFlags, ctx: any, dirIndex: number) => {
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['bar'], true);
+ contentQuery(dirIndex, ['bar'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
diff --git a/packages/core/test/render3/jit/directive_spec.ts b/packages/core/test/render3/jit/directive_spec.ts
index d0e4e9c6c5..46f13a1969 100644
--- a/packages/core/test/render3/jit/directive_spec.ts
+++ b/packages/core/test/render3/jit/directive_spec.ts
@@ -56,7 +56,8 @@ describe('jit directive helper functions', () => {
predicate: ['localRef'],
descendants: false,
first: false,
- read: null
+ read: null,
+ static: false
});
});
@@ -72,7 +73,8 @@ describe('jit directive helper functions', () => {
predicate: ['foo', 'bar', 'baz'],
descendants: true,
first: true,
- read: null
+ read: null,
+ static: false
});
});
@@ -85,7 +87,8 @@ describe('jit directive helper functions', () => {
descendants: true,
first: true,
isViewQuery: true,
- read: Directive
+ read: Directive,
+ static: false
});
expect(converted.predicate).toEqual(Directive);
diff --git a/packages/core/test/render3/query_spec.ts b/packages/core/test/render3/query_spec.ts
index 8f769b4b3f..637ec8cf66 100644
--- a/packages/core/test/render3/query_spec.ts
+++ b/packages/core/test/render3/query_spec.ts
@@ -15,7 +15,7 @@ import {getNativeByIndex} from '../../src/render3/util';
import {bind, container, containerRefreshEnd, containerRefreshStart, directiveInject, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, reference, template, text} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition';
-import {queryRefresh, viewQuery, loadViewQuery, contentQuery, loadContentQuery} from '../../src/render3/query';
+import {queryRefresh, viewQuery, loadViewQuery, contentQuery, loadContentQuery, query} from '../../src/render3/query';
import {getLView} from '../../src/render3/state';
import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound';
@@ -83,8 +83,8 @@ describe('query', () => {
2, 0, [Child], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(Child, false);
- viewQuery(Child, true);
+ viewQuery(Child, false, null);
+ viewQuery(Child, true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -261,9 +261,9 @@ describe('query', () => {
},
viewQuery: function(rf: RenderFlags, ctx: App) {
if (rf & RenderFlags.Create) {
- viewQuery(MyDirective, false);
- viewQuery(Service, false);
- viewQuery(Alias, false);
+ viewQuery(MyDirective, false, null);
+ viewQuery(Service, false, null);
+ viewQuery(Alias, false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -347,7 +347,7 @@ describe('query', () => {
3, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], false);
+ viewQuery(['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -385,8 +385,8 @@ describe('query', () => {
4, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], false);
- viewQuery(['bar'], false);
+ viewQuery(['foo'], false, null);
+ viewQuery(['bar'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -434,7 +434,7 @@ describe('query', () => {
5, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo', 'bar'], undefined);
+ viewQuery(['foo', 'bar'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -472,7 +472,7 @@ describe('query', () => {
3, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], false);
+ viewQuery(['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -545,7 +545,7 @@ describe('query', () => {
2, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -746,7 +746,7 @@ describe('query', () => {
2, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], undefined);
+ viewQuery(['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -817,7 +817,7 @@ describe('query', () => {
2, 0, [Child], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -863,7 +863,7 @@ describe('query', () => {
2, 0, [Child], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -902,7 +902,7 @@ describe('query', () => {
2, 0, [Child], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -942,7 +942,7 @@ describe('query', () => {
3, 0, [Child1, Child2], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo', 'bar'], true);
+ viewQuery(['foo', 'bar'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -982,8 +982,8 @@ describe('query', () => {
3, 0, [Child], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
- viewQuery(['bar'], true);
+ viewQuery(['foo'], true, null);
+ viewQuery(['bar'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -1026,7 +1026,7 @@ describe('query', () => {
2, 0, [Child], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], undefined, ElementRef);
+ viewQuery(['foo'], false, ElementRef);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -1065,7 +1065,7 @@ describe('query', () => {
3, 0, [Child], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo', 'bar'], undefined);
+ viewQuery(['foo', 'bar'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -1266,7 +1266,7 @@ describe('query', () => {
1, 0, [Child], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(TemplateRef as any, false);
+ viewQuery(TemplateRef as any, false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -1315,7 +1315,7 @@ describe('query', () => {
6, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(TemplateRef as any, false);
+ viewQuery(TemplateRef as any, false, null);
viewQuery(TemplateRef as any, false, ElementRef);
}
if (rf & RenderFlags.Update) {
@@ -1401,7 +1401,7 @@ describe('query', () => {
2, 1, [NgIf], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -1463,7 +1463,7 @@ describe('query', () => {
viewQuery: function(rf: RenderFlags, ctx: Cmpt) {
let tmp: any;
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
queryRefresh(tmp = loadViewQuery>()) &&
@@ -1552,7 +1552,7 @@ describe('query', () => {
8, 0, [ViewContainerManipulatorDirective], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -1649,7 +1649,7 @@ describe('query', () => {
viewQuery: (rf: RenderFlags, cmpt: Cmpt) => {
let tmp: any;
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
queryRefresh(tmp = loadViewQuery>()) &&
@@ -1722,7 +1722,7 @@ describe('query', () => {
viewQuery: (rf: RenderFlags, myApp: MyApp) => {
let tmp: any;
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
queryRefresh(tmp = loadViewQuery>()) &&
@@ -1787,7 +1787,7 @@ describe('query', () => {
1, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -1853,7 +1853,7 @@ describe('query', () => {
5, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -1930,7 +1930,7 @@ describe('query', () => {
1, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2011,7 +2011,7 @@ describe('query', () => {
1, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2081,8 +2081,8 @@ describe('query', () => {
3, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
- viewQuery(['foo'], false);
+ viewQuery(['foo'], true, null);
+ viewQuery(['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2119,36 +2119,6 @@ describe('query', () => {
});
- describe('observable interface', () => {
-
- it('should allow observing changes to query list', () => {
- const queryList = new QueryList();
- let changes = 0;
-
- queryList.changes.subscribe({
- next: (arg) => {
- changes += 1;
- expect(arg).toBe(queryList);
- }
- });
-
- // initial refresh, the query should be dirty
- queryRefresh(queryList);
- expect(changes).toBe(1);
-
-
- // refresh without setting dirty - no emit
- queryRefresh(queryList);
- expect(changes).toBe(1);
-
- // refresh with setting dirty - emit
- queryList.setDirty();
- queryRefresh(queryList);
- expect(changes).toBe(2);
- });
-
- });
-
describe('queryList', () => {
it('should be destroyed when the containing view is destroyed', () => {
let queryInstance: QueryList;
@@ -2163,7 +2133,7 @@ describe('query', () => {
2, 0, [], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], false);
+ viewQuery(['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2244,7 +2214,7 @@ describe('query', () => {
3, 0, [SomeDir], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2284,7 +2254,7 @@ describe('query', () => {
factory: () => withContentInstance = new WithContentDirective(),
contentQueries: (rf: RenderFlags, ctx: any, dirIndex: number) => {
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['foo'], true);
+ contentQuery(dirIndex, ['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2307,7 +2277,7 @@ describe('query', () => {
vars: 0,
contentQueries: (rf: RenderFlags, ctx: any, dirIndex: number) => {
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['foo'], false);
+ contentQuery(dirIndex, ['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2468,7 +2438,7 @@ describe('query', () => {
5, 0, [WithContentDirective], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo', 'bar'], true);
+ viewQuery(['foo', 'bar'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2509,7 +2479,7 @@ describe('query', () => {
5, 0, [WithContentDirective], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['bar'], true);
+ viewQuery(['bar'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2535,7 +2505,7 @@ describe('query', () => {
// @ContentChildren('foo, bar, baz', {descendants: true})
// fooBars: QueryList;
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['foo', 'bar', 'baz'], true);
+ contentQuery(dirIndex, ['foo', 'bar', 'baz'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2599,7 +2569,7 @@ describe('query', () => {
// @ContentChildren('foo', {descendants: true})
// fooBars: QueryList;
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['foo'], false);
+ contentQuery(dirIndex, ['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2655,7 +2625,7 @@ describe('query', () => {
// @ContentChildren('foo', {descendants: true})
// fooBars: QueryList;
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['foo'], false);
+ contentQuery(dirIndex, ['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2715,7 +2685,7 @@ describe('query', () => {
// @ContentChildren('foo', {descendants: false})
// foos: QueryList;
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['foo'], false);
+ contentQuery(dirIndex, ['foo'], false, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2736,7 +2706,7 @@ describe('query', () => {
// @ContentChildren('foo', {descendants: true})
// foos: QueryList;
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, ['foo'], true);
+ contentQuery(dirIndex, ['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2812,7 +2782,7 @@ describe('query', () => {
// @ContentChildren(TextDirective, {descendants: true})
// texts: QueryList;
if (rf & RenderFlags.Create) {
- contentQuery(dirIndex, TextDirective, true);
+ contentQuery(dirIndex, TextDirective, true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
@@ -2892,7 +2862,7 @@ describe('query', () => {
viewQuery: function(rf: RenderFlags, ctx: ViewQueryComponent) {
let tmp: any;
if (rf & RenderFlags.Create) {
- viewQuery(TextDirective, true);
+ viewQuery(TextDirective, true, null);
}
if (rf & RenderFlags.Update) {
queryRefresh(tmp = loadViewQuery>()) &&
diff --git a/packages/core/test/render3/styling/players_spec.ts b/packages/core/test/render3/styling/players_spec.ts
index 2f77e83943..15bb9cc68a 100644
--- a/packages/core/test/render3/styling/players_spec.ts
+++ b/packages/core/test/render3/styling/players_spec.ts
@@ -286,7 +286,7 @@ class SuperComp {
},
viewQuery: function(rf: RenderFlags, ctx: SuperComp) {
if (rf & RenderFlags.Create) {
- viewQuery(['child'], true);
+ viewQuery(['child'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;
diff --git a/packages/core/test/render3/view_container_ref_spec.ts b/packages/core/test/render3/view_container_ref_spec.ts
index c3ad8f260c..03b87d8f37 100644
--- a/packages/core/test/render3/view_container_ref_spec.ts
+++ b/packages/core/test/render3/view_container_ref_spec.ts
@@ -2070,7 +2070,7 @@ describe('ViewContainerRef', () => {
},
viewQuery: function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
- viewQuery(['foo'], true);
+ viewQuery(['foo'], true, null);
}
if (rf & RenderFlags.Update) {
let tmp: any;