Reputation: 5458
Trying to query a ng-template
with CdkPortalOutlet
is always unsuccessful, and I cant understand why?
<ng-template CdkPortalOutlet></ng-template>
@ViewChild(CdkPortalOutlet) test: CdkPortalOutlet;
Upvotes: 3
Views: 2671
Reputation: 6099
Since Angular 8 @ViewChild
requires to give an extra static
parameter and the documentation is hard to find on what value to set it to. If not set correctly it will result in an undefined
value when trying to retrieve CdkPortalOutlet
with @ViewChild
.
Set @ViewChild(CdkPortalOutlet, { static: true })
when migrating to Angular 8.
How do I choose which static
flag value to use: true
or false
?
We have always recommended retrieving query results in ngAfterContentInit
for content queries.
This is because by the time this lifecycle hook runs, change detection has completed for the relevant nodes and we can guarantee that we have collected all the possible query results.
Most applications will want to use {static: false}
for this reason. This setting will ensure query matches that are dependent on binding resolution (e.g. results inside *ngIf
s or *ngFor
s) will be found by the query.
If you need access to a TemplateRef
in a query to create a view dynamically, you won't be able to do so in ngAfterContentInit
.
Change detection has already run on that view, so creating a new view with the template will cause an ExpressionHasChangedAfterChecked
error to be thrown.
In this case, you will want to set the static
flag to true
and create your view in ngOnInit
.
In most other cases, the best practice is to use {static: false}
.
However, to facilitate the migration to version 8, you may also want to set the static
flag to true
if your component code already depends on the query results being available some time before ngAfterContentInit
.
For example, if your component relies on the query results being populated in the ngOnInit
hook or in @Input
setters, you will need to either set the flag to true
or re-work your component to adjust to later timing.
Note: Selecting the static option means that query results nested in *ngIf
or *ngFor
will not be found by the query.
These results are only retrievable after change detection runs.
Upvotes: 8
Reputation: 214175
In order to use CdkPortalOutlet
directive in AppComponent
template you have import PortalModule
in AppModule
(i.e. NgModule where AppComponent has been declared)
import { PortalModule } from '@angular/cdk/portal';
...
@NgModule({
imports: [ BrowserModule, FormsModule, PortalModule, OverlayModule ],
^^^^^^^^^^^^
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Also the Angular HTML parser is case sensitive so that you need to use it like:
<ng-template cdkPortalOutlet></ng-template>
^^^
lower case
Upvotes: 8