2017-03-31 63 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); } 
}