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:

committed by
Igor Minar

parent
ae16378ee7
commit
a4638d5a81
@ -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: \`
|
||||
<div someDir></div>
|
||||
\`
|
||||
})
|
||||
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$;
|
||||
|
Reference in New Issue
Block a user