How can parent component recognise type of let-content
which comes from ngTemplateOutletContext
? Now {{content.type}}
works correctly, but IDE says:
unresolved variable type
How can I type it as Video
?
parent.component.ts:
export interface Video { id: number; duration: number; type: string; } public videos: Video = [{id: 1, duration: 30, type: 'documentary'}];
parent.component.html:
<ul> <li *ngFor="let video of videos"> <tile [bodyTemplate]="tileTemplate" [content]="video"></app-card> </li> </ul> <ng-template #tileTemplate let-content> <h5 class="tile__type">{{content.type}}</h5> </ng-template>
tile.component.ts:
@Component({ selector: 'tile', templateUrl: './tile.component.html', styleUrls: ['./tile.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class CardComponent { @Input() tileTemplate: TemplateRef<any>; @Input() content: Video; }
tile.component.html:
<div ... <ng-container [ngTemplateOutlet]="tileTemplate" [ngTemplateOutletContext]="{ $implicit: content }"> </ng-container> ... </div>
To get started using template reference variables, simply create a new Angular component or visit an existing one. To create a template reference variable, locate the HTML element that you want to reference and then tag it like so: #myVarName .
The ng-template element in Angular allows you to reuse parts of a component template, which in a sense makes it a lightweight subcomponent. By default, its context is not typed, but it can be made strongly typed with a little trick.
ng-template is an Angular element that is used for rendering HTML in a template. However, it is not rendered directly on DOM. If you include an ng-template tag to a template, the tag and the content inside it will be replaced by comment upon render.
To sum up, ng-content is used to display children in a template, ng-container is used as a non-rendered container to avoid having to add a span or a div, and ng-template allows you to group some content that is not rendered directly but can be used in other places of your template or you code.
There is no type inference for let-*
variables. The let-
context is part of the micro syntax parser for Angular, and an IDE can not infer the type as there is no clear origin.
https://gist.github.com/mhevery/d3530294cff2e4a1b3fe15ff75d08855
You can try to silence the IDE warning using $any()
https://angular.io/guide/template-syntax#the-any-type-cast-function
<ng-template #tileTemplate let-content> <h5 class="tile__type">{{$any(content).type}}</h5> </ng-template>
You can force type inference by using a function
<ng-template #tileTemplate let-content> <h5 class="tile__type">{{toVideo(content).type}}</h5> </ng-template> public toVideo(value: any): Video { return value as Video; }
There is an easy workaround to get the IDE to play along and also have code completion using a user-defined type guard:
Create a function in your class which takes the variable as an argument and returns the same variable:
export class CardComponent { ... public video = (item: Video) => item; }
Now simply wrap the variable in your template with the function:
<h5 class="tile__type">{{video(content).type}}</h5>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With