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


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

Angular. Can't set breakpoints in VS Code

Вариант решения проблемы, когда не срабатывают точки остановки при разработке Angular приложений в редакторе VS Code
10 апреля 2018 г. в Angular

Об subscribe() vs async

О предпочтительности использования async pipe. При OnPush стратегии не требуется вызывать markForCheck() внутри подписки +решение с несколькими | async pipes развёрнутых в одну переменную (внутри шаблона).

05 января 2019 г. в Angular