Пользовательский шаблон (включение без ng-содержимого) для компонента списка в Angular2

У меня есть компонент списка, который показывает только имена. Компонент списка должен иметь возможность принимать пользовательский шаблон, который будет предоставлен пользователем.

Компонент списка

import {Component } from 'angular2/core';

@Component({
  selector: 'my-list',
  template: `<p>This is List</p>
     <ul>
       <li *ngFor="#i of data"><div class='listItem'>{{i.name}}</div></li>
    </ul>`
})
export class MyList implements OnInit{ 
    data: Array<any> = [{name: 'John', age: 26},{name: 'Kevin', age: 26},  {name:'Simmons', age:26}];
}

Мое требование

<my-list>
   <div>{{i.name}}-{{i.age}}</div> //user should be able to provide custom template like this
</my-list>

Я пробовал это с нг-контентом, но выдает ошибку. В angular 1 то же самое используется для работы с включенным контентом. есть ли у нас какая-либо альтернатива ручной трансклюзии в angular 2, и если нет, то как мы могли бы реализовать эту функцию в angular2.

Вот плункер

3 ответа

Решение

Вам нужно использовать ngForTemplate, я создал PrimeNG DataList и многие другие DataComponents, используя эту технику, и она прекрасно работает. Демо;

http://www.primefaces.org/primeng/

Код;

https://github.com/primefaces/primeng/blob/master/src/app/components/datalist/datalist.ts

В вашем компоненте определите templateRef с помощью contentchild;

@ContentChild(TemplateRef) itemTemplate: TemplateRef;

Ваш шаблон становится;

template: `<p>This is List</p>
     <ul>
       <template ngFor [ngForOf]="data" [ngForTemplate]="itemTemplate"></template>
    </ul>`

Так что ваши пользователи могут определять контент как;

<my-list>
   <template #anything>
        <div>{{anything.i.name}}-{{anything.i.age}}</div>
   </template>
</my-list>

В прошлом был вопрос об этом (см. Использование содержимого шаблона компонента в angular 2), и это, похоже, не поддерживается.

Здесь есть две вещи:

  • Когда вы предоставляете шаблон ввода для компонента, ваш i переменная оценивается относительно текущего компонента, а не my-list один. Если вы хотите использовать его свойства, вы должны сделать что-то вроде этого:

    <my-list #myList>
      <div>{{myList.i.name}}-{{myList.i.age}}</div> //user should be able to provide custom template like this
    </my-list>
    
  • Другая проблема заключается в возможности использования ng-content внутри цикла, и это не поддерживается. Я думаю, что мы могли бы добавить проблему для этого...

Вот планкр, который я использовал для своих тестов: https://plnkr.co/edit/a06vVP?p=preview.

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

Другие вопросы по тегам