Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ng-template - typed variable

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> 
like image 758
ssuperczynski Avatar asked Apr 01 '19 15:04

ssuperczynski


People also ask

How do I pass a template reference variable in component?

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 .

What type is ng-template?

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.

Can we use ng-template inside ng-template?

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.

What is difference between template and ng-template?

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.


2 Answers

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; } 
like image 60
Reactgular Avatar answered Sep 16 '22 14:09

Reactgular


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> 
like image 42
Rei Mavronicolas Avatar answered Sep 20 '22 14:09

Rei Mavronicolas