2017-03-31 60 views
3

我正在創建一個表單,從後端獲取字段。映射後,我有這樣的事情:Angular2:使用管道動態地呈現模板

genericFilters: { 
     iboId: { 
      'display': false, 
      'template': '' 
     }, 
     iboCode: { 
      'display': true, 
      'template': 'text_input_iboCode', 
      /*'template': 'text/iboCode'*/ 
     }, 
     iboName: { 
      'display': true, 
      'template': 'text_input_iboName' 
     }, 
     iboSurname: { 
      'display': true, 
      'template': 'text_input_iboSurname' 
     }, 
     iboRank: { 
      'display': false, 
      'template': 'multiselect_iboRank', 
      /*'template': 'select/multi_iboRank',*/ 
     }, 
     iboEmail: { 
      'display': false, 
      'template': 'text_input_iboEmail' 
     }, 
     iboNewsletter: { 
      'display': true, 
      'template': 'simple_select_iboNewsletter', 
      /*'template': 'select/simple_iboNewsletter',*/ 
     }, 
    }; 

我這背後的想法是在一個應用程序級別創建表單域的每個字段類型(checkboxmultiselecttextradio等)。並使用上面映射的JSON將某個字段類型應用於來自後端的每個接收字段。

在我的例子中,場iboId應有的字段類型<text_input_iboCode>

所以,在我看來,我不希望有這樣的事情:

<text_input_iboCode></text_input_iboCode> 
<text_input_iboName></text_input_iboName> 
<text_input_iboSurname></text_input_iboSurname> 

我真的希望有創作形式更加抽象的,是這樣的:

<div *ngFor="let field of genericFilters | dynamicTemplateProcessorPipe"> 
    {{field.template}} <!--This should equal '<text_input_iboName>' for example--> 
</div> 

問題:

我要問月亮嗎?這甚至有可能嗎?有其他更好的方法來實現嗎?我濫用@Pipe功能嗎?

我實際上使用@Pipe進行翻譯,格式化,在模板中循環使用objects等。我猜我也可以使用它們來return a <fieldTemplate>

我將開始研究,看看<ng-template #fieldTemplate>的使用是否也是一種可行的選擇,同時我希望有人能夠通過@Pipe瞭解該功能的可行性。

回答

4

在繼續我的研究之後,我找不到用@Pipe實現我想要的方法,並且有一個很好的理由:@Pipe並不意味着要這樣工作。

我發現改爲Angular 4的NgComponentOutlet

我開始用它來工作,但我的第一個例子是這樣的:

@Component({selector: 'text-input-ibo-name', template: '<input type="text" name="ibo_name">'}) 
class TextIboName { 
} 
@Component({ 
    selector: 'ng-my-form', 
    template: `<ng-container *ngComponentOutlet="TextIboName"></ng-container>` 
}) 
class NgMyForm { 
    // This field is necessary to expose HelloWorld to the template. 
    TextIboName = TextIboName; 
} 

這是基礎。現在我只需要看看如何在我的*ngFor中應用<ng-container *ngComponentOutlet="TextIboName"></ng-container>(請參閱OP)。

如果有人要求,我可以用更具體和最終的代碼來更新這個答案。

更新:

這將是我的第一選擇template的是在映射JSON宣佈領域的做法。

<div *ngFor="let field of genericFilters | dynamicTemplateProcessorPipe"> 
    <ng-container *ngComponentOutlet="{{field.template}}"></ng-container> 
</div> 

的類TextIboNameTextIboCodeTextIboSurname等將在公用文件夾中聲明並導入到當前的component,只是爲了有一個更抽象的方法。

目標是能夠在所有App中重複使用這些字段。像這樣,我將能夠在其他地方複製字段TextIboName,而無需複製/粘貼HTML代碼或templates

更新2:

如果我們把我們的「場分量」,在我的例子是TextIboName到外部文件夾內的另一@ngModule或者我們只是想用一個外部類從另一個@ngModule我們將有使用NgModuleFactory

改編上面的代碼:

@Component({ 
    selector: 'ng-my-form', 
    template: ` 
    <ng-container *ngComponentOutlet="TextIboName; 
             ngModuleFactory: myModule;"></ng-container>` 
}) 
class NgMyForm { 
    // This field is necessary to expose OtherModuleComponent to the template. 
    TextIboName = TextIboName; 
    myModule: NgModuleFactory<any>; 
    constructor(compiler: Compiler) { this.myModule = compiler.compileModuleSync(OtherModule); } 
}