如你所见
<div *ngFor="let number of numbers;let i = index">
<div *ngIf="(number%2 !== 0);else even">
<ul odd>{{number}}</ul>
</div>
<ng-template #even>
<ul even>{{number}}</ul>
</ng-template>
</div>
我正在尝试使用ng-content
选择器渲染值,但它在*ngFor
循环内无效。为什么这样 ?如何使它工作?更像是img
我不想要两个ngFor循环,我希望它能与ng-content一起使用。
答案 0 :(得分:6)
如果没有两个循环,你不能这样做。原因是ng-content
是占位符,它接受内部的动态html。现在,当您在代码中循环时,您不会向even
或odd
选择器分配任何内容。但是,如果您将代码更改为
<child>
<div *ngFor="let number of numbers;let i = index" even>
<div *ngIf="(number%2 !== 0);else even">
<ul>{{number}}</ul>
</div>
<ng-template #even>
<ul>{{number}}</ul>
</ng-template>
<!-- <ul even>Why its rendering and not others??</ul> -->
</div>
</child>
您将看到输出更改为
这是因为没有ng-For
的输出分配给even
选择器。
如果您将模板更改为
<child>
<div *ngFor="let number of numbers;let i = index" odd>
<div *ngIf="(number%2 !== 0)">
<ul>{{number}}</ul>
</div>
</div>
<div *ngFor="let number of numbers;let i = index" even>
<div *ngIf="(number%2 == 0)">
<ul>{{number}}</ul>
</div>
</div>
</child>
它会起作用
另请注意,在ng-For
内,您无法将内容附加到even
或odd
部分,即使该功能可用,也会覆盖最后一个值的部分。
让ng-for
离开它。以下代码
<child>
<div>
<div odd>
This should be under odd
</div>
</div>
</child>
也不会工作
所以你想要实现的目标以及你试图实现它的方式并不受角度的支持。
答案 1 :(得分:3)
你可以用两个循环这样做:
<div>
<ng-container *ngFor="let number of numbers; let isFirst=first">
<h2 *ngIf="isFirst">Odd Numbers</h2>
<p>{{(number%2>0? number : '')}}</p>
</ng-container>
<ng-container *ngFor="let number of numbers; let isFirst=first">
<h2 *ngIf="isFirst">Even</h2>
<p>{{(number%2==0? number : '')}}</p>
</ng-container>
</div>
答案 2 :(得分:2)
其中一个解决方案是对数字数组进行排序。您可以使用自己的管道:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'oddFirst'})
export class OddFirstPipe implements PipeTransform {
transform(numbers: number[], args: any[]): number[] {
const odd = numbers.filter(num => num % 2 !== 0);
const even = numbers.filter(num => num % 2 === 0);
return [...odd, ...even];
}
}
然后您可以在模板中使用它:
<div *ngFor="let number of numbers | oddFirst">
<div *ngIf="(number%2 !== 0);else even">
<ul odd>{{number}}</ul>
</div>
<ng-template #even>
<ul even>{{number}}</ul>
</ng-template>
</div>
答案 3 :(得分:2)
你可以用纯CSS做到。
看一下修改过的StackBlitz。
https://stackblitz.com/edit/angular-zto8w1?file=app/app.component.html
CSS显示网格创造奇迹。请记住,IE上没有(完全)支持它。
答案 4 :(得分:2)
这是因为筑巢。
我运行了一些experiments on stackblitz,似乎内容根本无法嵌套,我们不能责怪*ngFor
。即使在for循环中使用ng-container
也无济于事。
答案 5 :(得分:0)
首先让我们看看投影/ ngContent是什么。
投影是Angular中非常重要的概念。它使开发人员能够构建可重用的组件,并使应用程序更具可扩展性和灵活性。
更简单地说,它有助于动态添加内容,这些内容可以来自服务器,作为组件内部的html或文本,而无需像document.createtextnode()那样创建DOM节点。
投射的参考:https://angular-2-training-book.rangle.io/handout/components/projection.html
投影类似于指令中的angularjs transclusion。 https://docs.angularjs.org/api/ng/directive/ngTransclude
让我们跳到你的问题。
这是正确的,我们需要两个循环来重复奇数和偶数的内容。根据您的要求。原因:ngFor在DOM中添加了相同模板的新实例。
工作代码
https://stackblitz.com/edit/angular-ymznfu?file=app%2Fapp.component.html
<强> App.component.html 强>
<child>
<ng-container odd>//this will work
<ul>{{number[1]}}</ul>
</ng-container>
</child>
<强> child.component.html 强>
<ng-content select="[odd]"></ng-content>
上面的示例将工作原因,我们正在ngContent中投射最外面的dom节点。
您可以尝试在代码下面进行投影
<强> app.component.html 强>
<child>
<ng-container>
<ng-content select="[odd]"></ng-content>
</ng-container>
</child>
上面的代码不会投影原因Angular只检查组件中可用的最外层节点,即代码中的原因
<ul odd>Something</ul>
正在投射而其他人没有。