複数のテンプレートを入力として受け入れるコンポーネントを作成しようとしています。これは私が持っている例です:
_@Component({
selector: 'data-list',
styles: [
require('./data-list.component.scss')
],
template: `
<ng-template
*ngFor="let item of itemsData"
ngFor let-item [ngForOf]="[item]" [ngForTemplate]="itemTemplate"
></ng-template>
`
})
export class DataListComponent {
@Input() itemsData: any[];
@ContentChild(TemplateRef) itemTemplate: TemplateRef<ElementRef>;
}
_
ご覧のとおり、これは私が試しているかなり単純なコンポーネントです。このコンポーネントは、表示されるアイテムのデータとアイテムのテンプレートを受け入れるだけです。このコンポーネントは次のように使用できます。
_<data-list [itemsData]="data">
<ng-template let-item>
<h1>{{ item.header }}</h1>
<div>{{ item.content }}</div>
</ng-template>
</data-list>
_
上記のように、_ng-content
_を使用してテンプレートを渡し、DataListComponent
を@ContentChild(TemplateRef) itemTemplate: TemplateRef<ElementRef>;
で読み取ります。
私の質問は、コンポーネントに複数のテンプレートを渡すことができるかどうかです。
例として、アイテムのテンプレートを渡しますが、最初のアイテムの場合は別のテンプレートが必要です。つまり、最初の項目のチェックはDataListComponent
で行われますが、それを使用するコンポーネントによって指定されたテンプレートを使用します。
簡単な例:
私はこれに応えるためにそのようなことをすることができます:
_@Component({
selector: 'data-list',
styles: [
require('./data-list.component.scss')
],
template: `
<span *ngFor="let item of itemsData; let i = index" >
<ng-template *ngIf="i > 0; else nextTmpl"
ngFor let-item [ngForOf]="[item]" [ngForTemplate]="itemTemplate"
></ng-template>
</span>
<ng-template #nextTmpl>
Next
</ng-template>
`
})
_
ただし、「次のテンプレート」は、DataListComponent
を使用するコンポーネントによって指定されないため、常に同じテンプレートになります。
ContentChildデコレーターで使用できる文字列セレクターを使用して、この同じ問題を解決しました。
データリストコンポーネントを使用する場合は、テンプレート変数を指定する必要があります。
<data-list [itemsData]="data">
<ng-template #firstItemTemplate let-item>
<h1 style="color:red;">{{ item.header }}</h1>
<div>{{ item.content }}</div>
</ng-template>
<ng-template #standardTemplate let-item>
<h1>{{ item.header }}</h1>
<div>{{ item.content }}</div>
</ng-template>
</data-list>
次に、データリストコンポーネントクラス内で、テンプレート変数をコンポーネントのローカル変数に割り当てます。
@Input() itemsData: any[];
@ContentChild('firstItemTemplate') firstItemTemplate: TemplateRef<ElementRef>;
@ContentChild('standardTemplate') standardTemplate: TemplateRef<ElementRef>;
この後、渡されたテンプレートをデータリストコンポーネントからレンダリングできるようになります。
@Component({
selector: 'data-list',
styles: [
require('./data-list.component.scss')
],
template: `
<span *ngFor="let item of itemsData; let i = index" >
<ng-template *ngIf="i == 0; else nextTmpl"
ngFor let-item [ngForOf]="[item]" [ngForTemplate]="firstItemTemplate"
></ng-template>
<ng-template #nextTmpl
ngFor let-item [ngForOf]="[item]" [ngForTemplate]="standardTemplate"
></ng-template>
</span>
`
})
代わりにこれを試してください。
@Component({
selector: 'data-list',
styles: [
require('./data-list.component.scss')
],
template: `
<ng-template ngFor [ngForOf]="itemsData" [ngForTemplate]="itemTemplate"></ng-template>
`
})
export class DataListComponent {
@Input() itemsData: any[];
@ContentChild(TemplateRef) itemTemplate: TemplateRef<ElementRef>;
}