Angular2:使用管道动态渲染模板

Posted

技术标签:

【中文标题】Angular2:使用管道动态渲染模板【英文标题】:Angular2: Use Pipe to render templates dynamically 【发布时间】:2017-08-25 22:03:03 【问题描述】:

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

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 &lt;fieldTemplate&gt;

我将开始一项研究,看看&lt;ng-template #fieldTemplate&gt; 的使用是否也可能是一个可行的选择,同时我希望有人可以阐明@Pipe 的此功能的可行性。

【问题讨论】:

【参考方案1】:

在继续我的研究之后,我找不到使用 @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 中应用&lt;ng-container *ngComponentOutlet="TextIboName"&gt;&lt;/ng-container&gt;(参见OP)。

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

更新:

这是我为在映射的JSON 上声明的字段选择template 的第一种方法。

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

TextIboNameTextIboCodeTextIboSurname 等类将在一个公共文件夹中声明并导入到当前的component,只是为了有一个更抽象的方法。

目标是能够在整个应用程序中重复使用这些字段。像这样,我将能够在其他地方复制字段TextIboName,而无需复制/粘贴 html 代码或templates

更新 2:

如果我们移动我们的“字段组件”,在我的示例中是 TextIboName 到另一个 @ngModule 中的外部文件夹,或者我们只是想使用来自另一个 @ngModule 的外部类,我们将不得不使用 @987654322 @。

改编以上代码:

@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); 

【讨论】:

以上是关于Angular2:使用管道动态渲染模板的主要内容,如果未能解决你的问题,请参考以下文章

async/await 防止 Angular2 在模板语句中使用时渲染组件

Angular 2中的动态管道

角度-知道模板渲染何时完成-使用异步管道

Angular 2 Universal - 使用手写笔和 pug 模板的服务器端渲染

Angular2-管道

angular2中的递归动态模板编译