let-* $implicit in Angular template

Синтаксис let-* позволяет объявить переменную в шаблоне <ng-template>.

<ng-template let-vasya="Василий">
  <div>{{ vasya }}</div>
</ng-template>

Практическое значение let-* раскрывается когда шаблон используется в компоненте и нужно из шаблона обратиться к свойствам и методам компонента. Также этот синтаксис позволяет компоненту избежать коллизий имен.

Например в модальных окнах от ng-bootstrap используется конструкция:

<ng-template #content let-c="close" let-d="dismiss">
  <div class="modal-header">
    <h4>Adding number filter</h4>
    ...
    <button (click)="c('Save click')">Save</button>
  </div>
  ...
</ng-template>

В переменную c записывается метод close() модального окна. В дальнейшей в шаблоне на кнопку сохранения вешается обработчик клика (click)="c('Save click')"

Использование let-* в директиве *ngFor

Запись с *ngFor

<div *ngFor="let tyapk of tyapks; index as i; trackBy: trackByFn">{{ tyapk }}</div>

без сахара становится [ngFor]

<ng-template [ngFor]="let tyapk of tyapks" >
  <div>{{ tyapk }}</div>
</ng-template>

что эквивалентно [ngForOf] с неявной переменной $implicit

<ng-template ngFor let-tyapk="$implicit" [ngForOf]="tyapks" let-i="index" [ngForTrackBy]="trackByFn">
  <div>{{ tyapk }}</div>
</ng-template>

$implicit

Когда Agluar создает шаблон, вызывая метод createEmbeddedView, может передаваться контекст, который будет использоваться внутри <ng-template>.

Использования ключа $implicit в объекте контекста будет устанавливать значение объекта по-умолчанию. Например:

Имеется вызов:

this._viewContainerRef.createEmbeddedView(ourTemplate, { $implicit: 'tyapk' })

шаблон

<ng-template let-foo> 
   {{ foo }}
</ng-template>

тогда следующая записаь эквивалентна:

<ng-template let-foo="$implicit"> 
  {{ foo }}
</ng-template>

В первом и во втором случае foo будет равно tyapk

При этом, если имеется следующий контекст:

{ bar: 'value' }

то переменная объявляется как:

<ng-template let-foo="bar"> 
   {{ foo }}
</ng-template>

ngTemplateOutlet и ngTemplateOutletContext

Имеется шаблон

<ng-template #ourTemplate let-foo let-bar="petya" let-baz>
    <div>{{foo}}</div>
    <div>{{bar}}</div>
    <div>{{baz}}</div>
</ng-template>

Вместо createEmbeddedView можно отрисовать с помощью 2 директив: [ngTemplateOutlet] и [ngTemplateOutletContext] + возможность добавить контекст.

<ng-template 
  [ngTemplateOutlet]="ourTemplate"
  [ngTemplateOutletContext]="{
                               $implicit: 'Иннокентий',
                               bar: 'tyapk'
                             }"
></ng-template>

В foo и baz явно не переданы значения, поэтому они выведут неявное значение Иннокентий.

Пример на stackblitz


Похожие записи

@Directive v/s @Component in Angular

Компоненты создают DOM элементы и добавляют к ним поведение, а директивы только добавляют поведение к существующим DOM элементам

13 августа 2018 г. в Angular

Angular routerLink conditionally

<a [routerLink]="myVar ? '/home' : null" routerLinkActive="is-active">Home</a>
or
<a [routerLink]="myVar ? ['/home'] : []">Home</a>
02 сентября 2019 г. в Angular

Angular. Functions & getters в шаблонах

На каждый цикл механизма обнаружения изменений выполняется метод из шаблона. Если этого надо избежать, то следует использовать pure pipe или результат выполнения присвоить свойству компонента