Что такое ng-template и почему я привязываю к нему *ngIf then else?

Когда я использую *ngIf с оператором then и/или else, зачем мне привязываться к переменной шаблона, которая прикреплена к элементу ng-template? Например:

Это работает:

<div *ngIf="show; else elseBlock">Text to show</div>
<ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>

Но это не работает:

<div *ngIf="show; else elseBlock">Text to show</div>
<div #elseBlock>Alternate text while primary text is hidden</div>

Я также заметил, что добавление класса тоже не работает:

<ng-template #elseBlock class="my-class">
  Alternate text while primary text is hidden
</ng-template>

Что такого особенного в ng-template? Как это отличается?


person Kevin LeStarge    schedule 25.07.2017    source источник
comment
Это связано с тем, что на самом деле делает синтаксис * ngIf (в частности, со звездочкой). Он фактически выскакивает из элемента и создает ng-шаблон. Прочитайте об этом прямо здесь: angular.io/guide/structural-directives#the -звездочка--префикс :-)   -  person LarsMonty    schedule 25.07.2017
comment
эй, есть что-нибудь непонятное в мом ответе?   -  person Max Koretskyi    schedule 28.07.2017


Ответы (4)


Это связано с тем, что все структурные директивы в Angular создают встроенные представления. Встроенное представление создается с использованием как templateRef, так и viewContainerRef. Подробнее о них можно прочитать в разделе Изучение методов манипулирования Angular DOM с использованием ViewContainerRef.

Встроенное представление похоже на основные представления, созданные для компонентов. Представление содержит все узлы, которые вы видите в шаблоне компонента или внутри тега ng-template. Таким образом, встроенное представление похоже на шаблон компонента без класса компонента. Вот несколько примеров того, как структурные директивы создают встроенные представления.

нгесли

  private _updateView() {
    if (this._context.$implicit) {
      ...
        if (this._thenTemplateRef) {
          this._thenViewRef =
              // here embedded view is created
              this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
        }
      }
    } else {
      if (!this._elseViewRef) {
       ...
          this._elseViewRef =
              // here embedded view is created
              this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
        }
      }
    }
  }

нгфор

  private _applyChanges(changes: IterableChanges<T>) {
    const insertTuples: RecordViewTuple<T>[] = [];
    changes.forEachOperation(
        (item: IterableChangeRecord<any>, adjustedPreviousIndex: number, currentIndex: number) => {
          if (item.previousIndex == null) {
            // here embedded view is created
            const view = this._viewContainer.createEmbeddedView(
                this._template, new NgForOfContext<T>(null !, this.ngForOf, -1, -1), currentIndex);
person Max Koretskyi    schedule 25.07.2017
comment
Я ждал твоего ответа здесь. - person yurzui; 25.07.2017
comment
@yurzui: D, я видел, что вы работаете над этим, поэтому решил попытать счастья здесь) - person Max Koretskyi; 25.07.2017

ng-template — это то, как Angular реализовал и расширил template.

Поскольку все структурные директивы, начинающиеся с *, такие как *ngIf, *ngFor и т. д., изменяют DOM, на самом деле за кулисами все время используется шаблон ng. Директива, размещенная на элементе, является просто синтаксическим сахаром над этим.

Блок else не работает ни с каким другим элементом, поскольку его нужно добавлять только при необходимости, поэтому он должен быть в ng-шаблоне.

Вот дополнительная информация об этом.

person Adrian Fâciu    schedule 25.07.2017

<ng-template> очень удобен, когда вы хотите показать или скрыть часть шаблона на основе условия и его обратного действия. В вашем примере:

<div *ngIf="show; else elseBlock">Text to show</div>
<ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>

это позволяет вам делать то, что вы могли бы сделать следующим образом:

<div *ngIf="show">Text to show</div>
<div *ngIf="!show>Alternate text while primary text is hidden</div>

Преимущество заключается в том, что вы можете изолировать часть своего шаблона и «активировать» его при необходимости, как это делает plein с JS. Ставить можно не всегда только после. Это дает вам более структурированный код. Существует также (начиная с Angular 4.3, я думаю) <..*ngIf="condition"; then #template1 else #template2> тоже очень «удобный».

person Vega    schedule 25.07.2017

Это частичный ответ - для класса. Но ссылки на соответствующую информацию тоже в одном месте. Я могу дать вам немного подробностей и о другом подобном понятии. <ng-template> является заполнителем не только для другой части *ngIf, но и в *NgFor

<ng-container> — это что-то похожее, о чем вы не спрашивали, но вы столкнетесь с ним позже, когда будете иметь дело с проекцией контента. Об этом есть видео, которое Джош Морони дал на Youtube. Это относится к @ContentChild и @ContentChildren.

Angular Cheatsheet расскажет вам о синтаксисе для class..

person JGFMK    schedule 25.07.2017