feat(core): default to dynamic queries (#32720)
These changes switch to defaulting the `static` flag on `ViewChild` and `ContentChild` queries to `false`, in addition to removing the logic that statically determines whether a query is dynamic. PR Close #32720
This commit is contained in:
parent
0f3a48e4d4
commit
948b01ce55
|
@ -37,7 +37,6 @@ export class ViewCompiler {
|
||||||
outputCtx: OutputContext, component: CompileDirectiveMetadata, template: TemplateAst[],
|
outputCtx: OutputContext, component: CompileDirectiveMetadata, template: TemplateAst[],
|
||||||
styles: o.Expression, usedPipes: CompilePipeSummary[]): ViewCompileResult {
|
styles: o.Expression, usedPipes: CompilePipeSummary[]): ViewCompileResult {
|
||||||
let embeddedViewCount = 0;
|
let embeddedViewCount = 0;
|
||||||
const staticQueryIds = findStaticQueryIds(template);
|
|
||||||
|
|
||||||
let renderComponentVarName: string = undefined !;
|
let renderComponentVarName: string = undefined !;
|
||||||
if (!component.isHost) {
|
if (!component.isHost) {
|
||||||
|
@ -66,7 +65,7 @@ export class ViewCompiler {
|
||||||
const embeddedViewIndex = embeddedViewCount++;
|
const embeddedViewIndex = embeddedViewCount++;
|
||||||
return new ViewBuilder(
|
return new ViewBuilder(
|
||||||
this._reflector, outputCtx, parent, component, embeddedViewIndex, usedPipes,
|
this._reflector, outputCtx, parent, component, embeddedViewIndex, usedPipes,
|
||||||
staticQueryIds, viewBuilderFactory);
|
viewBuilderFactory);
|
||||||
};
|
};
|
||||||
|
|
||||||
const visitor = viewBuilderFactory(null);
|
const visitor = viewBuilderFactory(null);
|
||||||
|
@ -116,7 +115,6 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||||
private reflector: CompileReflector, private outputCtx: OutputContext,
|
private reflector: CompileReflector, private outputCtx: OutputContext,
|
||||||
private parent: ViewBuilder|null, private component: CompileDirectiveMetadata,
|
private parent: ViewBuilder|null, private component: CompileDirectiveMetadata,
|
||||||
private embeddedViewIndex: number, private usedPipes: CompilePipeSummary[],
|
private embeddedViewIndex: number, private usedPipes: CompilePipeSummary[],
|
||||||
private staticQueryIds: Map<TemplateAst, StaticAndDynamicQueryIds>,
|
|
||||||
private viewBuilderFactory: ViewBuilderFactory) {
|
private viewBuilderFactory: ViewBuilderFactory) {
|
||||||
// TODO(tbosch): The old view compiler used to use an `any` type
|
// TODO(tbosch): The old view compiler used to use an `any` type
|
||||||
// for the context in any embedded view. We keep this behaivor for now
|
// for the context in any embedded view. We keep this behaivor for now
|
||||||
|
@ -139,13 +137,11 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.parent) {
|
if (!this.parent) {
|
||||||
const queryIds = staticViewQueryIds(this.staticQueryIds);
|
|
||||||
this.component.viewQueries.forEach((query, queryIndex) => {
|
this.component.viewQueries.forEach((query, queryIndex) => {
|
||||||
// Note: queries start with id 1 so we can use the number in a Bloom filter!
|
// Note: queries start with id 1 so we can use the number in a Bloom filter!
|
||||||
const queryId = queryIndex + 1;
|
const queryId = queryIndex + 1;
|
||||||
const bindingType = query.first ? QueryBindingType.First : QueryBindingType.All;
|
const bindingType = query.first ? QueryBindingType.First : QueryBindingType.All;
|
||||||
const flags =
|
const flags = NodeFlags.TypeViewQuery | calcStaticDynamicQueryFlags(query);
|
||||||
NodeFlags.TypeViewQuery | calcStaticDynamicQueryFlags(queryIds, queryId, query);
|
|
||||||
this.nodes.push(() => ({
|
this.nodes.push(() => ({
|
||||||
sourceSpan: null,
|
sourceSpan: null,
|
||||||
nodeFlags: flags,
|
nodeFlags: flags,
|
||||||
|
@ -412,19 +408,16 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||||
const hostEvents: {context: o.Expression, eventAst: BoundEventAst, dirAst: DirectiveAst}[] = [];
|
const hostEvents: {context: o.Expression, eventAst: BoundEventAst, dirAst: DirectiveAst}[] = [];
|
||||||
this._visitComponentFactoryResolverProvider(ast.directives);
|
this._visitComponentFactoryResolverProvider(ast.directives);
|
||||||
|
|
||||||
ast.providers.forEach((providerAst, providerIndex) => {
|
ast.providers.forEach(providerAst => {
|
||||||
let dirAst: DirectiveAst = undefined !;
|
let dirAst: DirectiveAst = undefined !;
|
||||||
let dirIndex: number = undefined !;
|
ast.directives.forEach(localDirAst => {
|
||||||
ast.directives.forEach((localDirAst, i) => {
|
|
||||||
if (localDirAst.directive.type.reference === tokenReference(providerAst.token)) {
|
if (localDirAst.directive.type.reference === tokenReference(providerAst.token)) {
|
||||||
dirAst = localDirAst;
|
dirAst = localDirAst;
|
||||||
dirIndex = i;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (dirAst) {
|
if (dirAst) {
|
||||||
const {hostBindings: dirHostBindings, hostEvents: dirHostEvents} = this._visitDirective(
|
const {hostBindings: dirHostBindings, hostEvents: dirHostEvents} =
|
||||||
providerAst, dirAst, dirIndex, nodeIndex, ast.references, ast.queryMatches, usedEvents,
|
this._visitDirective(providerAst, dirAst, ast.references, ast.queryMatches, usedEvents);
|
||||||
this.staticQueryIds.get(<any>ast) !);
|
|
||||||
hostBindings.push(...dirHostBindings);
|
hostBindings.push(...dirHostBindings);
|
||||||
hostEvents.push(...dirHostEvents);
|
hostEvents.push(...dirHostEvents);
|
||||||
} else {
|
} else {
|
||||||
|
@ -479,9 +472,8 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _visitDirective(
|
private _visitDirective(
|
||||||
providerAst: ProviderAst, dirAst: DirectiveAst, directiveIndex: number,
|
providerAst: ProviderAst, dirAst: DirectiveAst, refs: ReferenceAst[],
|
||||||
elementNodeIndex: number, refs: ReferenceAst[], queryMatches: QueryMatch[],
|
queryMatches: QueryMatch[], usedEvents: Map<string, any>): {
|
||||||
usedEvents: Map<string, any>, queryIds: StaticAndDynamicQueryIds): {
|
|
||||||
hostBindings:
|
hostBindings:
|
||||||
{context: o.Expression, inputAst: BoundElementPropertyAst, dirAst: DirectiveAst}[],
|
{context: o.Expression, inputAst: BoundElementPropertyAst, dirAst: DirectiveAst}[],
|
||||||
hostEvents: {context: o.Expression, eventAst: BoundEventAst, dirAst: DirectiveAst}[]
|
hostEvents: {context: o.Expression, eventAst: BoundEventAst, dirAst: DirectiveAst}[]
|
||||||
|
@ -492,8 +484,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||||
|
|
||||||
dirAst.directive.queries.forEach((query, queryIndex) => {
|
dirAst.directive.queries.forEach((query, queryIndex) => {
|
||||||
const queryId = dirAst.contentQueryStartId + queryIndex;
|
const queryId = dirAst.contentQueryStartId + queryIndex;
|
||||||
const flags =
|
const flags = NodeFlags.TypeContentQuery | calcStaticDynamicQueryFlags(query);
|
||||||
NodeFlags.TypeContentQuery | calcStaticDynamicQueryFlags(queryIds, queryId, query);
|
|
||||||
const bindingType = query.first ? QueryBindingType.First : QueryBindingType.All;
|
const bindingType = query.first ? QueryBindingType.First : QueryBindingType.All;
|
||||||
this.nodes.push(() => ({
|
this.nodes.push(() => ({
|
||||||
sourceSpan: dirAst.sourceSpan,
|
sourceSpan: dirAst.sourceSpan,
|
||||||
|
@ -619,7 +610,6 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||||
tokenExpr: o.Expression,
|
tokenExpr: o.Expression,
|
||||||
sourceSpan: ParseSourceSpan
|
sourceSpan: ParseSourceSpan
|
||||||
}) {
|
}) {
|
||||||
const nodeIndex = this.nodes.length;
|
|
||||||
// providerDef(
|
// providerDef(
|
||||||
// flags: NodeFlags, matchedQueries: [string, QueryValueType][], token:any,
|
// flags: NodeFlags, matchedQueries: [string, QueryValueType][], token:any,
|
||||||
// value: any, deps: ([DepFlags, any] | any)[]): NodeDef;
|
// value: any, deps: ([DepFlags, any] | any)[]): NodeDef;
|
||||||
|
@ -1086,12 +1076,11 @@ function elementEventNameAndTarget(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcStaticDynamicQueryFlags(
|
function calcStaticDynamicQueryFlags(query: CompileQueryMetadata) {
|
||||||
queryIds: StaticAndDynamicQueryIds, queryId: number, query: CompileQueryMetadata) {
|
|
||||||
let flags = NodeFlags.None;
|
let flags = NodeFlags.None;
|
||||||
// Note: We only make queries static that query for a single item.
|
// Note: We only make queries static that query for a single item and the user specifically
|
||||||
// This is because of backwards compatibility with the old view compiler...
|
// set the to be static. This is because of backwards compatibility with the old view compiler...
|
||||||
if (query.first && shouldResolveAsStaticQuery(queryIds, queryId, query)) {
|
if (query.first && query.static) {
|
||||||
flags |= NodeFlags.StaticQuery;
|
flags |= NodeFlags.StaticQuery;
|
||||||
} else {
|
} else {
|
||||||
flags |= NodeFlags.DynamicQuery;
|
flags |= NodeFlags.DynamicQuery;
|
||||||
|
@ -1099,16 +1088,6 @@ function calcStaticDynamicQueryFlags(
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldResolveAsStaticQuery(
|
|
||||||
queryIds: StaticAndDynamicQueryIds, queryId: number, query: CompileQueryMetadata): boolean {
|
|
||||||
// If query.static has been set by the user, use that value to determine whether
|
|
||||||
// the query is static. If none has been set, sort the query into static/dynamic
|
|
||||||
// based on query results (i.e. dynamic if CD needs to run to get all results).
|
|
||||||
return query.static ||
|
|
||||||
query.static == null &&
|
|
||||||
(queryIds.staticQueryIds.has(queryId) || !queryIds.dynamicQueryIds.has(queryId));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function elementEventFullName(target: string | null, name: string): string {
|
export function elementEventFullName(target: string | null, name: string): string {
|
||||||
return target ? `${target}:${name}` : name;
|
return target ? `${target}:${name}` : name;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue