4

我正在创建一个表单,我从后端获取字段。映射后,我有这样的东西:

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用于<fieldTemplate>.

我将开始一项研究,看看是否<ng-template #fieldTemplate>也可以使用@Pipe.

4

1 回答 1

5

在继续我的研究之后,我找不到一种方法来实现我想要的东西@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;
}

这是基础。现在我只需要看看如何申请<ng-container *ngComponentOutlet="TextIboName"></ng-container>我的*ngFor(见OP)。

如果人们要求,我可以用更具体和“最终”的代码更新这个答案。

更新:

template这将是我为在 mapped 上声明的该字段选择 的第一种方法JSON

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

TextIboName, TextIboCode,TextIboSurname等将在一个公共文件夹中声明并导入到 currentcomponent中,只是为了有一个更抽象的方法。

目标是能够在整个 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); }
}
于 2017-03-31T15:38:57.413 回答