web-dev-qa-db-fra.com

Angular passez plusieurs modèles au composant

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:

enter image description here

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.

11
Daniel Grima

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>
    `
})
27
aleroy

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>;
}
2
Dmitrij Kuba