2017-04-26 58 views
3

我试图创建一个接受多个模板作为输入的组件。这是我的例子:角度传递多个模板到组件

@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中进行,然后使用组件使用的模板指定。

简单的例子:

enter image description here

我可以做一些像这样以迎合这一点:

@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,因此将永远是相同的模板。

+0

您的意思是'ngIf'? –

+0

是的,我已经更新了这个问题,试图更好地解释我的意思。 –

回答

5

我通过使用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> 
    ` 
}) 
+0

这是一个聪明的做法!看起来很整齐:)我一定会尝试一下,让你知道它是如何发展的。 –

+0

这工作得很好,谢谢。我唯一需要添加的是'* nextImpl'的'* ngIf =“i> 0”'我知道这有点奇怪,但在下一个模板中,我得到了两个模板。 –

0

试试这个。

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