2

是否可以編寫可重用ng-template?很多我的組件使用完全相同的ng-template
例如:角度可重用模板

<kendo-grid> 
    <kendo-grid-column field="group"> 
     <ng-template kendoGridEditTemplate let-dataItem="dataItem" let-formGroup="form"> 
      <kendo-dropdownlist #listGroups [data]="groups" 
           textField="title" 
           valueField="id" 
           [valuePrimitive]="true" 
           [filterable]="true" 
           [formControl]="form.get('groupId')"> 
      </kendo-dropdownlist> 
     </ng-template> 
    </kendo-grid-column> 
</kendo-grid> 

我不想在我的所有組件後面再說這個模板和邏輯。我可以寫自定義組件,縮小這個代碼:

<kendo-grid> 
    <kendo-grid-column field="group"> 
     <ng-template kendoGridEditTemplate let-dataItem="dataItem" let-formGroup="form"> 
      <my-custom-component [formControl]="form.get('groupId')"> 
      </my-custom-component> 
     </ng-template> 
    </kendo-grid-column> 
</kendo-grid> 

但我想做得更多:

<kendo-grid> 
    <kendo-grid-column field="group"> 
     <ng-template [ngTemplateOutlet]="templateFromAnotherSource"> 
     </ng-template> 
    </kendo-grid-column> 
</kendo-grid> 

我發現this threadthis描述ngTemplateOutlet,而不是如何共享多個組件之間的模板。

回答

2

問題是ng-template必須被編譯。要理解爲什麼要閱讀Here is what you need to know about dynamic components in Angular

現在,模板只能作爲組件的一部分進行編譯。因此,您需要使用此模板定義組件,然後您可以使用viewChild或指令訪問此模板工廠。 viewChild你取決於life-cycle hooks and change detection,所以我會採取指導性的方法。這裏是僞代碼:

@Component() { 
    template: '<ng-template requestor>...</ng-template>' 
} 
class NgTemplateProviderComponent { 
    t: TemplateRef; 

    register(t) { 
     this.t = t; 
    } 
} 

@Directive() { 
    selector: 'requestor; 
} 
class TemplateRequestor { 
    constructor(t: TemplateRef, p: NgTemplateProviderComponent) { 
     p.register(t); 
    } 
} 

要了解更多關於使用指令來獲得templateRef閱讀Here is how to get ViewContainerRef before @ViewChild query is evaluated的這種做法。

然後,你需要獲得訪問NgTemplateProviderComponent元件廠,創建它的實例,以獲得templateRef

class SomeComponent { 
    constructor(r: ComponentFactoryResolver, i: Injector) { 
     const f = r.resolveComponentFactory(NgTemplateProviderComponent); 
     const templateRef =f.create(i).instance.t; 
    } 
} 

,然後纔可以使用ngTemplateOutlet指令來呈現模板。

+0

嗨。在博客中閱讀了您的一些帖子後,我決定使用我的第二個選項(模板中的自定義控件)。對於一行額外的代碼,這似乎很多。 我正在尋找更多設計解決方案來插入模板。無需編譯,因爲這將自動完成。無論如何,偉大的職位。謝謝。 此解決方案是否適用於AOT? – Makla

+1

它應該與AOT一起工作。 _無需編譯,因爲這將自動完成_ - 如果您使用webpack,我想你會編寫一個插件來解析模板並插入部分模板,但是這又可能不是您想要的 –