【问题标题】:How to load multiple ng-templates dynamically with ngFor based on object property如何基于对象属性使用 ngFor 动态加载多个 ng 模板
【发布时间】:2020-01-31 14:26:57
【问题描述】:

[步骤1] 我有一个对象“文章”,其中包含多个内容元素的数组。根据元素的类型(例如标题/图像),应显示不同的模板。如果没有必要,我不想为此明确拥有自己的组件,所以我猜测是否需要 ViewChild 或 ContentChild?

我已经查看了所有与 ngTemplate 相关的问题,但还没有找到解决方案。 我试图重写https://stackblitz.com/edit/angular-q1y2vz 来自ngTemplateOutlet with dynamic value,但目前失败。

component.ts

articles: any[] = [ {
    "id_seq": "1234",
    "content":[
      {
        "id": "123456",
        "order": 0,
        "type": "header",
        "data":
          {
            "text": "loremipsum"
          }
      },
      {
        "id": "234567",
        "order": 1,
        "type": "image",
        "data":
          {
            "url": "http://www.google.de/image.jpg"
          }
      }]
  }]

component.html

<ng-container *ngFor="let content of articles[0]?.content;">
  <ng-container [ngTemplateOutlet]="content?.type">
  </ng-container>
</ng-container>


<ng-template #header >
  <p>I'm a header</p>
</ng-template>

<ng-template #image >
  <p>I'm an image</p>
</ng-template>

根据 ngTemplateOutlet 的语法和代码位置,我得到一个错误

templateRef.createEmbeddedView 不是函数

或者什么都不渲染。

如果我输入一个像“header”这样的静态字符串,它就可以工作。所以我猜,内容?。类型不是要走的路。 另一方面,这样的事情可以正常工作:

<accordion>
  <accordion-group heading="articlecontent" [isOpen]="isFirstOpen">
    <div class="accordion_no_side_margin">
      <accordion-group *ngFor="let content of articles[0]?.content"
                       [heading]="content?.type">
        {{ content?.id }}
        {{ content?.order }}
        {{ content?.type }}
        {{ content?.data }}
      </accordion-group>
    </div>
  </accordion-group>
</accordion>

[步骤2] 最终我确实想合并两个代码 sn-ps,以便 ng-template 应该在手风琴内执行。

[步骤3] 稍后我打算添加 ngTemplateOutletContext 并提供一些信息,但其他步骤应该可以正常工作。

目前我正在使用 @angular-devkit/core 8.1.3

【问题讨论】:

    标签: angular accordion ngfor ng-template


    【解决方案1】:

    由于它只是出于某种原因不想与 ngFor 一起工作,所以我尝试了 ngSwitchCase,它运行得很好,从那时起就再也没有落后过 (虽然在外面有模板/ng-containers 会很好)

    <ng-container *ngFor="let content of localArticles[0]?.content">
      <ng-container [ngSwitch]="content?.type">
    
        <ng-container *ngSwitchCase="'header'">
          <p>I'm a header</p>
        </ng-container>
    
        <ng-container *ngSwitchCase="'image'">
          <p>I'm an image</p>
        </ng-container>
    
      </ng-container>
    </ng-container>
    

    【讨论】:

      【解决方案2】:

      不知道代码中的 articles[0]?.content 是什么意思,但可以这样尝试:

      <ng-container *ngFor="let content of articles[0]?.content;">
          <ng-container *ngIf="content?.type == header; then header; else image"></ng-container>
          <ng-template #header >
            <p>I'm a header</p>
          </ng-template>
      
          <ng-template #image >
            <p>I'm an image</p>
          </ng-template>
        </ng-container>
      

      如果上述方法不起作用,请尝试这样您的数组未加载:

      <div *ngIf="articles | async as artic">
        <ng-container *ngFor="let article of artic">
          <ng-container *ngfor="let ar of article.content">
      
            <ng-container *ngIf="ar.type == header; then header; else image"></ng-container>
            <ng-template #header>
              <p>I'm a header</p>
            </ng-template>
      
            <ng-template #image>
              <p>I'm an image</p>
            </ng-template>
          </ng-container>
        </ng-container>
      </div>
      

      如果您有硬编码数组,您可以删除| async 管道。

      回答你在评论中告诉我的内容:

      <div *ngIf="articles | async as artic">
        <ng-container *ngFor="let article of artic">
          <ng-container *ngfor="let ar of article.content">
      
            <ng-container *ngIf="ar.type == 'header'"><p>I'm a header</p></ng-container>
            <ng-container *ngIf="ar.type == 'image'"><p>I'm a header</p></ng-container>
            <ng-container *ngIf="ar.type == 'pain in ass'"><p>I'm a header</p></ng-container>
            <ng-container *ngIf="ar.type == 'love masturbating'"><p>I'm a header</p></ng-container>
            <ng-container *ngIf="ar.type == 'love dogs'"><p>I'm a header</p></ng-container>
      
          </ng-container>
        </ng-container>
      </div>
      

      【讨论】:

      • 有趣的方法,还没见过这个。但不幸的是不起作用。 articles[0]?.content 只是一种解决方法,因为我还没有定义文章模型,并且本地数组中只有一篇文章。
      • 我看到你在那里做了什么(至少部分)。问题是,我有 10 多种类型(标题和图像只是示例),所以使用 if/else 并不是一个真正的选择。另外使用 ngFor 2 次有什么意义...?
      • 因为你在数组中有数组?这就是 2x ngFor 的意义所在。
      • 如果您有 10 多种类型,只需为每种类型使用 *ngIf。喜欢*ngIf="type == header" 下一个*ngIf="type == image" 等等。
      猜你喜欢
      • 2019-03-07
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      • 2019-11-14
      • 1970-01-01
      相关资源
      最近更新 更多