Каковы практические сценарии директивы * ngTemplateOutlet? - PullRequest
0 голосов
/ 20 октября 2018

Я читал о директиве *ngTemplateOutlet.Эта директива используется для динамического создания шаблона с помощью ссылки на шаблон и объекта контекста в качестве параметров.

Что я хочу знать, так это то, что в Angular есть так много вещей для достижения тех же результатов, что и для * ngTemplateOutlet, таких какas:

  1. Мы можем иметь несколько *ngIf, которые могут отображать различные шаблоны на основе значения переменной компонента в одном и том же компоненте.Аналогичным образом у нас есть [ngSwitch], который будет отображать для нас разные шаблоны на основе разных значений.

  2. Мы могли бы использовать ссылки с *ngIf, ссылаясь на шаблонную переменную ссылки соответствующей переменной.

Для первого случая:

<div *ngIf="condition1"> Content 1 </div>
<div *ngIf="condition2"> Content 2 </div>
<div *ngIf="condition3"> Content 3 </div>

И для последнего:

<ng-container *ngIf="condition then myTemplate else otherTemplate"></ng-container>
<ng-template #myTemplate> Some content... </ng-template>
<ng-template #otherTemplate> Some content... </ng-template>

Если у нас есть такие методы в нашем арсенале, какое дополнительное значение добавляет *ngTemplateOutlet?

В каких случаях практического использования (если они есть) мы не можем использовать вышеуказанные методы и должны использовать директиву *ngTemplateOutlet или это просто другой метод выбора для достижения того же результата?

Ответы [ 3 ]

0 голосов
/ 21 октября 2018

Угловые выходы шаблона могут использоваться для вставки общего шаблона в различные разделы представления, которые не генерируются циклом или не подчиняются условию.Например, вы можете определить шаблон для логотипа компании и вставить его в несколько мест на странице:

<div>
  <ng-container *ngTemplateOutlet="companyLogoTemplate"></ng-container>
  <h1>Company History</h1>
  <div>{{companyHistory}}</div>
</div>
<form (ngSubmit)="onSubmit()">
  <ng-container *ngTemplateOutlet="companyLogoTemplate"></ng-container>
  <h1>User info</h1>
  <label>Name:</label><input type="text" [(ngModel)]="userName" />
  <label>Account ID:</label><input type="text" [(ngModel)]="accountId" />
  <button>Submit</button>
</form>
<div class="footer">
  <ng-container *ngTemplateOutlet="companyLogoTemplate"></ng-container>
</div>

<ng-template #companyLogoTemplate>
  <div class="companyLogo">
    <img [src]="logoSourceUrl">
    <label>The ACME company, {{employeeCount}} people working for you!</label>
  </div>
</ng-template>

Шаблоны и шаблоны также могут помочь сделать компонент настраиваемым.Следующий пример взят из этой статьи от Angular University .

Компонент контейнера вкладок определяет шаблон заголовка вкладки по умолчанию, но позволяет переопределить его с помощью пользовательского шаблонаопределяется как входное свойство.Соответствующий шаблон (по умолчанию или пользовательский) затем вставляется в представление с выходом шаблона:

@Component({
  selector: 'tab-container',
  template: `
    <ng-template #defaultTabButtons>
      <div class="default-tab-buttons">
        ...
      </div>
    </ng-template>
    <ng-container *ngTemplateOutlet="headerTemplate || defaultTabButtons"></ng-container>
    ... rest of tab container component ...
  `
})
export class TabContainerComponent {
    @Input() headerTemplate: TemplateRef<any>; // Custom template provided by parent
}

В родительском компоненте вы определяете пользовательский шаблон заголовка вкладки и передаете его компоненту контейнера вкладок:

@Component({
  selector: 'app-root',
  template: `      
    <ng-template #customTabButtons>
      <div class="custom-class">
        <button class="tab-button" (click)="login()">
          {{loginText}}
        </button>
        <button class="tab-button" (click)="signUp()">
          {{signUpText}}
        </button>
      </div>
    </ng-template>
    <tab-container [headerTemplate]="customTabButtons"></tab-container>      
  `
})
export class AppComponent implements OnInit {
  ...
}

Вы можете увидеть другой расширенный вариант использования в этом сообщении в блоге от alligator.io .

0 голосов
/ 20 августа 2019

Одна вещь, которая делает * ngTemplateOutlet более мощной, чем * ng-content, - это когда вы используете его со входом [ngTemplateOutletContext].Это позволяет вам создать совершенно уникальный шаблон, который может использовать состояние из компонента.

Я использовал это для создания компонента select, который уникально стилизован для каждого клиента, с помощью различных шаблонов, но использует один и тот же код.Вот ссылка StackBlitz .

Одним из примеров преимущества * ngTemplateOutlets над использованием * ngIfs является то, что вашему компоненту не нужно зависеть от внешних пакетов, то есть от Icon lib, если он будет использоваться только одним клиентом.

0 голосов
/ 20 октября 2018

У вас очень правильный вопрос.Если что-то может быть достигнуто простым if или switch случаем, почему мы должны использовать *ngTemplateOutlet?

Независимый компонент

Вы получаете эти мысли, потому что вы думаете об одном независимомКомпонентный уровень.Другими словами, все условия, шаблоны находятся в одном компоненте.Мы можем легко выбрать шаблон на основе определенного условия.

Компонент библиотеки

Динамический шаблон

Когда я говорю Компонент библиотеки, это означает универсальныйкомпонент многократного использования, например Autocompleter или Typeahead и т. д. Эти компоненты предоставляют функциональную часть, однако они позволяют разработчику самостоятельно выбирать template в соответствии со своими потребностями.

Здесь есть подвох, эти шаблоны не находятся в Autocompleter, а взяты из его @ContentChild.

ex:

<ng-autocompleter>
   <ng-template #item let-item>{{item.name}}</ng-template>
<ng-autocompleter>

In вышеНапример, <ng-template> определяется разработчиком в более поздний момент времени, и не является прямой частью <ng-autocompleter>.

Контекст шаблона

Контекст шаблона очень важен всякий раз, когдаСильно настроенный компонент разработан.Получение динамического шаблона (html) недостаточно для достижения цели.Нам нужно привязать значение к ng-template.Поскольку ng-template не является частью ng-autocompleter, нам нужно передать контекст, который содержит все необходимые данные для связывания.

ex: В приведенном выше случае, если вы видите, мы объявили переменную item с помощью let-item но откуда взято item.Это будет определяться контекстом, заданным для *ngTemplateOutlet.

Заключение в одну строку Если мы хотим внедрить шаблоны, которые будут объявлены кем-то в будущем, я не могу обработать этот случай с помощью * ngIfили * ngSwitch.Нам нужно использовать *ngTemplateOutlet.

...