226

I came across a strange assignment syntax inside an Angular 2 template.

<template let-col let-car="rowData" pTemplate="body">
    <span [style.color]="car[col.field]">{{car[col.field]}}</span>
</template>

It appears that let-col and let-car="rowData" create two new variables col and car that can then be bound to inside the template.

Source: https://www.primefaces.org/primeng/#/datatable/templating

What is this magical let-* syntax called?

How does it work?

What is the difference between let-something and let-something="something else"?

Steven Liekens
  • 13,266
  • 8
  • 59
  • 85
  • 4
    @NiekT. this is different, let-* in angular 2 is template variable scoping – Sterling Archer Mar 23 '17 at 13:57
  • 3
    https://angular.io/docs/ts/latest/guide/structural-directives.html#!#template-input-variable search the word "let " (with a space) and go to around the 9th one. There is a good explanation of what this template variable does – Sterling Archer Mar 23 '17 at 13:58
  • @SterlingArcher Thanks for the correction, I'm quite new to JS and Angular myself. – Nodon Darkeye Mar 23 '17 at 13:59

2 Answers2

234

update Angular 5

ngOutletContext was renamed to ngTemplateOutletContext

See also CHANGELOG.md @ angular/angular

original

Templates (<template>, or <ng-template> since 4.x) are added as embedded views and get passed a context.

With let-col the context property $implicit is made available as col within the template for bindings. With let-foo="bar" the context property bar is made available as foo.

For example if you add a template

<ng-template #myTemplate let-col let-foo="bar">
  <div>{{col}}</div>
  <div>{{foo}}</div>
</ng-template>

<!-- render above template with a custom context -->
<ng-template [ngTemplateOutlet]="myTemplate"
             [ngTemplateOutletContext]="{
                                           $implicit: 'some col value',
                                           bar: 'some bar value'
                                        }"
></ng-template>

See also this answer and ViewContainerRef#createEmbeddedView.

*ngFor also works this way. The canonical syntax makes this more obvious

<ng-template ngFor let-item [ngForOf]="items" let-i="index" let-odd="odd">
  <div>{{item}}</div>
</ng-template>

where NgFor adds the template as an embedded view to the DOM for each item of items and adds a few values (item, index, odd) to the context.

See also Using $implict to pass multiple parameters

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 2
    Thanks for explaining `ngOutletContext`. That was the missing link between what I already knew and the information that I couldn't find in the documentation. – Steven Liekens Mar 23 '17 at 14:17
  • 1
    I don't think it is called `ngTemplateOutletContext` as you've suggested in the release of angular 5. The docs also don't mention anything about it being deprecated. https://angular.io/api/common/NgTemplateOutlet – Jessy Jan 05 '18 at 19:49
  • 5 is not yet released. Not sure what the docs show. The changelog doesn't have anything new about it since then. – Günter Zöchbauer Jan 05 '18 at 21:08
  • 2
    Thank you for this answer, there is a strong lack of documentation on what the `*` syntax is doing. – dook Feb 08 '19 at 20:06
  • Shouldn't be the second ng-template (the one with ngTemplateOutlet) really ng-template. Maybe ng-container would be better? Both will work I guess, but the ng-container is semantically more correct. Or am I wrong? – Ondrej Peterka Mar 21 '19 at 17:51
  • Between let is only supported in template element ;) – Pir Abdul Dec 12 '19 at 05:22
  • What does embedded view means here ? – user8348978 Aug 25 '22 at 09:22
  • 1
    @user8348978 I don't know in detail myself, but it's a part that is rendered by Angular and then the result inserted to the DOM. In this case for each item of `items`. – Günter Zöchbauer Sep 02 '22 at 08:58
  • I still don't understand how I have `` in a template file, where banana doesn't exist anywhere in the controller, but there is an array `arrayStuff` that has a declared Type of say '', with values pushed into it in a forEach loop. yet somehow banana has the data of the array. There is no reference to banana in the controller. and no reference to arrayStuff in the template. Yet it works? How?! – Rin and Len Nov 25 '22 at 09:39
2

The Angular microsyntax lets you configure a directive in a compact, friendly string. The microsyntax parser translates that string into attributes on the <ng-template>. The let keyword declares a template input variable that you reference within the template.

Clashsoft
  • 11,553
  • 5
  • 40
  • 79
dontry
  • 83
  • 3
  • 4