Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): allow users to define timing of ViewChild/ContentChild queries #28810

Closed
wants to merge 2 commits into from

Conversation

Projects
None yet
4 participants
@kara
Copy link
Contributor

kara commented Feb 19, 2019

Prior to this commit, the timing of ViewChild/ContentChild query
resolution depended on the results of each query. If any results
for a particular query were nested inside embedded views (e.g.
*ngIfs), that query would be resolved after change detection ran.
Otherwise, the query would be resolved as soon as nodes were created.

This inconsistency in resolution timing had the potential to cause
confusion because query results would sometimes be available in
ngOnInit, but sometimes wouldn't be available until ngAfterContentInit
or ngAfterViewInit. Code depending on a query result could suddenly
stop working as soon as an *ngIf or an *ngFor was added to the template.

With this commit, users can dictate when they want a particular
ViewChild or ContentChild query to be resolved with the static flag.
For example, one can mark a particular query as static: false to
ensure change detection always runs before its results are set:

@ContentChild('foo', {static: false}) foo !: ElementRef;

This means that even if there isn't a query result wrapped in an
*ngIf or an *ngFor now, adding one to the template later won't change
the timing of the query resolution and potentially break your component.

Similarly, if you know that your query needs to be resolved earlier
(e.g. you need results in an ngOnInit hook), you can mark it as
static: true.

@ViewChild(TemplateRef, {static: true}) foo !: TemplateRef;

Note: this means that your component will not support *ngIf results.

If you do not supply a static option when creating your ViewChild or
ContentChild query, the default query resolution timing will kick in.

Note: This new option only applies to ViewChild and ContentChild queries,
not ViewChildren or ContentChildren queries, as those types already
resolve after CD runs.

@kara kara requested review from angular/fw-compiler as code owners Feb 19, 2019

@googlebot googlebot added the cla: yes label Feb 19, 2019

@ngbot ngbot bot added this to the needsTriage milestone Feb 19, 2019

@kara kara force-pushed the kara:static-option branch 2 times, most recently from 5e9ad62 to 2c25c7a Feb 19, 2019

@kara kara changed the title feat(core): allow users to define timing of ViewChild/ContentChild queries WIP: feat(core): allow users to define timing of ViewChild/ContentChild queries Feb 19, 2019

@kara kara force-pushed the kara:static-option branch from 2c25c7a to 8369e6d Feb 19, 2019

feat(core): allow users to define timing of ViewChild/ContentChild qu…
…eries

Prior to this commit, the timing of `ViewChild`/`ContentChild` query
resolution depended on the results of each query. If any results
for a particular query were nested inside embedded views (e.g.
*ngIfs), that query would be resolved after change detection ran.
Otherwise, the query would be resolved as soon as nodes were created.

This inconsistency in resolution timing had the potential to cause
confusion because query results would sometimes be available in
ngOnInit, but sometimes wouldn't be available until ngAfterContentInit
or ngAfterViewInit. Code depending on a query result could suddenly
stop working as soon as an *ngIf or an *ngFor was added to the template.

With this commit, users can dictate when they want a particular
`ViewChild` or `ContentChild` query to be resolved with the `static`
flag. For example, one can mark a particular query as `static: false`
to ensure change detection always runs before its results are set:

```ts
@ContentChild('foo', {static: false}) foo !: ElementRef;
```

This means that even if there isn't a query result wrapped in an
*ngIf or an *ngFor now, adding one to the template later won't change
the timing of the query resolution and potentially break your component.

Similarly, if you know that your query needs to be resolved earlier
(e.g. you need results in an ngOnInit hook), you can mark it as
`static: true`.

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

Note: this means that your component will not support *ngIf results.

If you do not supply a `static` option when creating your `ViewChild` or
`ContentChild` query, the default query resolution timing will kick in.

Note: This new option only applies to `ViewChild` and `ContentChild`
queries, not `ViewChildren` or `ContentChildren` queries, as those types
already resolve after CD runs.

@kara kara force-pushed the kara:static-option branch from 8369e6d to f7c9dd4 Feb 19, 2019

@kara kara changed the title WIP: feat(core): allow users to define timing of ViewChild/ContentChild queries feat(core): allow users to define timing of ViewChild/ContentChild queries Feb 19, 2019

@jelbourn jelbourn self-requested a review Feb 19, 2019

@IgorMinar
Copy link
Member

IgorMinar left a comment

lgtm but please document the default.

Show resolved Hide resolved packages/core/src/metadata/di.ts Outdated
Show resolved Hide resolved packages/core/src/metadata/di.ts Outdated

@kara kara removed the request for review from jelbourn Feb 19, 2019

@kara

This comment has been minimized.

Copy link
Contributor Author

kara commented Feb 19, 2019

merge-assistance: global approval from igor/misko

@IgorMinar IgorMinar closed this in 19afb79 Feb 19, 2019

devversion added a commit to devversion/angular that referenced this pull request Feb 26, 2019

feat(core): update schematic to migrate to explicit query timing
Introduces an update schematic for the "@angular/core" package
that automatically migrates pre-V8 "ViewChild" and "ContentChild"
queries to the new explicit timing syntax. This is not required
yet, but with Ivy, queries will be "dynamic" by default. Therefore
specifying an explicit query timing ensures that developers can
smoothly migrate to Ivy (once it's the default).

Read more about the explicit timing API here:
angular#28810

devversion added a commit to devversion/angular that referenced this pull request Feb 26, 2019

feat(core): update schematic to migrate to explicit query timing
Introduces an update schematic for the "@angular/core" package
that automatically migrates pre-V8 "ViewChild" and "ContentChild"
queries to the new explicit timing syntax. This is not required
yet, but with Ivy, queries will be "dynamic" by default. Therefore
specifying an explicit query timing ensures that developers can
smoothly migrate to Ivy (once it's the default).

Read more about the explicit timing API here:
angular#28810

devversion added a commit to devversion/angular that referenced this pull request Feb 26, 2019

feat(core): update schematic to migrate to explicit query timing
Introduces an update schematic for the "@angular/core" package
that automatically migrates pre-V8 "ViewChild" and "ContentChild"
queries to the new explicit timing syntax. This is not required
yet, but with Ivy, queries will be "dynamic" by default. Therefore
specifying an explicit query timing ensures that developers can
smoothly migrate to Ivy (once it's the default).

Read more about the explicit timing API here:
angular#28810

devversion added a commit to devversion/angular that referenced this pull request Feb 26, 2019

feat(core): update schematic to migrate to explicit query timing
Introduces an update schematic for the "@angular/core" package
that automatically migrates pre-V8 "ViewChild" and "ContentChild"
queries to the new explicit timing syntax. This is not required
yet, but with Ivy, queries will be "dynamic" by default. Therefore
specifying an explicit query timing ensures that developers can
smoothly migrate to Ivy (once it's the default).

Read more about the explicit timing API here:
angular#28810

devversion added a commit to devversion/angular that referenced this pull request Feb 26, 2019

feat(core): update schematic to migrate to explicit query timing
Introduces an update schematic for the "@angular/core" package
that automatically migrates pre-V8 "ViewChild" and "ContentChild"
queries to the new explicit timing syntax. This is not required
yet, but with Ivy, queries will be "dynamic" by default. Therefore
specifying an explicit query timing ensures that developers can
smoothly migrate to Ivy (once it's the default).

Read more about the explicit timing API here:
angular#28810

devversion added a commit to devversion/angular that referenced this pull request Feb 27, 2019

feat(core): update schematic to migrate to explicit query timing
Introduces an update schematic for the "@angular/core" package
that automatically migrates pre-V8 "ViewChild" and "ContentChild"
queries to the new explicit timing syntax. This is not required
yet, but with Ivy, queries will be "dynamic" by default. Therefore
specifying an explicit query timing ensures that developers can
smoothly migrate to Ivy (once it's the default).

Read more about the explicit timing API here:
angular#28810

devversion added a commit to devversion/angular that referenced this pull request Mar 1, 2019

feat(core): update schematic to migrate to explicit query timing
Introduces an update schematic for the "@angular/core" package
that automatically migrates pre-V8 "ViewChild" and "ContentChild"
queries to the new explicit timing syntax. This is not required
yet, but with Ivy, queries will be "dynamic" by default. Therefore
specifying an explicit query timing ensures that developers can
smoothly migrate to Ivy (once it's the default).

Read more about the explicit timing API here:
angular#28810

devversion added a commit to devversion/angular that referenced this pull request Mar 5, 2019

feat(core): update schematic to migrate to explicit query timing
Introduces an update schematic for the "@angular/core" package
that automatically migrates pre-V8 "ViewChild" and "ContentChild"
queries to the new explicit timing syntax. This is not required
yet, but with Ivy, queries will be "dynamic" by default. Therefore
specifying an explicit query timing ensures that developers can
smoothly migrate to Ivy (once it's the default).

Read more about the explicit timing API here:
angular#28810

AndrewKushnir added a commit that referenced this pull request Mar 5, 2019

feat(core): update schematic to migrate to explicit query timing (#28983
)

Introduces an update schematic for the "@angular/core" package
that automatically migrates pre-V8 "ViewChild" and "ContentChild"
queries to the new explicit timing syntax. This is not required
yet, but with Ivy, queries will be "dynamic" by default. Therefore
specifying an explicit query timing ensures that developers can
smoothly migrate to Ivy (once it's the default).

Read more about the explicit timing API here:
#28810

PR Close #28983
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.