fix(ivy): support static ViewChild queries (#28811)

This commit adds support for the `static: true` flag in
`ViewChild` queries. Prior to this commit, all `ViewChild`
queries were resolved after change detection ran. This is
a problem for backwards compatibility because View Engine
also supported "static" queries which would resolve before
change detection.

Now if users add a `static: true` option, the query will be
resolved in creation mode (before change detection runs).
For example:

```ts
@ViewChild(TemplateRef, {static: true}) template !: TemplateRef;
```

This feature will come in handy for components that need
to create components dynamically.

PR Close #28811
This commit is contained in:
Kara Erickson
2019-02-18 17:33:59 -08:00
committed by Igor Minar
parent ae16378ee7
commit a4638d5a81
26 changed files with 340 additions and 163 deletions

View File

@ -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,
};
}