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


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

RxJs Subjects

Выдержки из доклада Андрея Алексеева (Tinkoff) про RxJs (Subject, Behaviour Subject, Replay Subject, Async Subject). Применение в Angular.

Angular dependency injection

Определение Provider (useClass, useValue, useFactory ), Injector. Декоратор @Inject, ключ multi: true

13 ноября 2018 г. в Angular