如何使用基于对象的 ngFor 动态加载多个 ng 模板 属性
How to load multiple ng-templates dynamically with ngFor based on object property
[第一步]
我有一个对象 "article",它有一个包含多个内容元素的数组。根据元素的类型(例如 header/image),应显示不同的模板。如果没有必要,我不想为此明确拥有自己的组件,所以我猜测是否需要 ViewChild 或 ContentChild?
我已经调查了所有与 ngTemplate 相关的问题,但还没有找到解决方案。
我试图重写 https://stackblitz.com/edit/angular-q1y2vz
来自 ,但到目前为止失败了。
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 is not a function
或者什么都不渲染。
如果我输入像 "header" 这样的静态字符串,它就可以工作。所以我猜,content?.type 不是要走的路。
另一方面,像这样的东西工作正常:
<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>
[第二步]
最终我确实想合并这两个代码片段,以便 ng-template 应该在手风琴内部执行。
[第三步]
稍后我打算添加 ngTemplateOutletContext 并提供一些信息,但如果没有它,其他步骤应该也能正常工作。
目前我正在使用
@angular-devkit/core 8.1.3
不知道你的代码中的 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>
由于它出于某种原因不想与 ngFor 一起工作,我尝试了 ngSwitchCase,它工作得很好,从那以后就再也没有回头
(虽然在外面有 templates/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>
[第一步] 我有一个对象 "article",它有一个包含多个内容元素的数组。根据元素的类型(例如 header/image),应显示不同的模板。如果没有必要,我不想为此明确拥有自己的组件,所以我猜测是否需要 ViewChild 或 ContentChild?
我已经调查了所有与 ngTemplate 相关的问题,但还没有找到解决方案。
我试图重写 https://stackblitz.com/edit/angular-q1y2vz
来自
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 is not a function
或者什么都不渲染。
如果我输入像 "header" 这样的静态字符串,它就可以工作。所以我猜,content?.type 不是要走的路。 另一方面,像这样的东西工作正常:
<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>
[第二步] 最终我确实想合并这两个代码片段,以便 ng-template 应该在手风琴内部执行。
[第三步] 稍后我打算添加 ngTemplateOutletContext 并提供一些信息,但如果没有它,其他步骤应该也能正常工作。
目前我正在使用 @angular-devkit/core 8.1.3
不知道你的代码中的 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>
由于它出于某种原因不想与 ngFor 一起工作,我尝试了 ngSwitchCase,它工作得很好,从那以后就再也没有回头 (虽然在外面有 templates/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>