2017-04-26 27 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>; 
}