J'essaie de créer un composant qui accepte plusieurs modèles comme entrées. Voici l'exemple que j'ai:
@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>;
}
Comme vous pouvez le voir, c'est un composant assez simple que j'essaie. Ce composant accepte simplement les données des éléments à afficher ainsi que le modèle de l'élément. Ce composant peut être utilisé comme ceci:
<data-list [itemsData]="data">
<ng-template let-item>
<h1>{{ item.header }}</h1>
<div>{{ item.content }}</div>
</ng-template>
</data-list>
Comme indiqué ci-dessus, je passe le modèle en utilisant ng-content
Qui est ensuite lu par le DataListComponent
avec @ContentChild(TemplateRef) itemTemplate: TemplateRef<ElementRef>;
.
Ma question est de savoir s'il est possible de passer plusieurs modèles à un composant.
Par exemple, on passerait le modèle pour les éléments, mais un modèle différent est nécessaire au cas où ce serait le premier élément. Cela signifierait que la vérification du premier élément serait effectuée dans le DataListComponent
mais utiliserait ensuite un modèle spécifié par le composant l'utilisant.
Exemple simple:
Je peux faire quelque chose comme ça pour répondre à cela:
@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>
`
})
Cependant, le "Next Template" n'est pas spécifié par le composant utilisant le DataListComponent
et sera donc toujours le même modèle.
J'ai résolu ce même problème en utilisant le sélecteur de chaîne disponible pour le décorateur ContentChild.
Vous devrez spécifier des variables de modèle lors de l'utilisation de votre composant de liste de données:
<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>
Ensuite, dans votre classe de composants de liste de données, affectez les variables de modèle aux variables locales sur le composant:
@Input() itemsData: any[];
@ContentChild('firstItemTemplate') firstItemTemplate: TemplateRef<ElementRef>;
@ContentChild('standardTemplate') standardTemplate: TemplateRef<ElementRef>;
Après cela, vous pourrez rendre les modèles transmis à partir de votre composant de liste de données.
@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>
`
})
Essayez plutôt cela.
@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>;
}