Angular pass multiple templates to Component

两盒软妹~` 提交于 2019-12-30 00:38:55

问题


I'm trying to create a component that accepts multiple templates as inputs. This is the example I have:

@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>;
}

As you can see it's a fairly simple component that I'm trying out. This component simply accepts the data of the items to be displayed as well as the template of the item. This component can be used like so:

<data-list [itemsData]="data">
    <ng-template let-item>
        <h1>{{ item.header }}</h1>
        <div>{{ item.content }}</div>
    </ng-template>
</data-list>

As shown above I'm passing the template using ng-content which is then read by the DataListComponent with @ContentChild(TemplateRef) itemTemplate: TemplateRef<ElementRef>;.

My question is whether it is possible to pass multiple templates to a component.

As an example one would pass the template for the items, but a different template is needed in case it's the first item. This would mean that the check of the first item would be made in the DataListComponent but then use a template specified by the component using it.

Simple example:

I can do something like so to cater for this:

@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>
    `
})

However like so the "Next Template" is not specified by the component using the DataListComponent and therefore will always be the same template.


回答1:


I solved this same issue by using the string selector available to the ContentChild decorator.

You will need to specify template variables when using your data-list component:

<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>

Then, inside your data-list component class, assign the template variables to local variables on the component:

@Input() itemsData: any[];
@ContentChild('firstItemTemplate') firstItemTemplate: TemplateRef<ElementRef>;
@ContentChild('standardTemplate') standardTemplate: TemplateRef<ElementRef>;

After this, you'll be able to render the passed-in templates from your data-list component.

@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>
    `
})



回答2:


Try this instead.

@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>;
}


来源:https://stackoverflow.com/questions/43631813/angular-pass-multiple-templates-to-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!