我正在尝试有条件地将 Bootstrap col-xs-4 的三个包装成一行。我的 col-xs-4 渲染效果很好,但我不知道如何让它们有条件地排成一行。这是我当前的 NgFor:
<div class="col-xs-4" *ngFor='let linkGroup of linkGroups | siteMapText: siteMapTextFilter; let i=index'>
<ul class="list-unstyled">
<li class="heading">
<div class="clearfix">
<span [className]="linkGroup.ContainerCssClass">
<span [className]="linkGroup.CssClass"></span>
</span>
<a href="#">
<strong class="heading-text">{{linkGroup.Title}}</strong>
</a>
</div>
</li>
<li *ngFor='let link of linkGroup.Links'>
<a href="#" class="link">
<span [className]="link.CssClass"></span>
<span class="item">{{link.Title}}</span>
</a>
</li>
</ul>
</div>
我想做的是这样的事情,但我知道这是错误的,那么正确的做法是什么:
<div *ngIf='i % 3== 0' class="row">
<div class="col-xs-4" *ngFor='let linkGroup of linkGroups | siteMapText: siteMapTextFilter; let i=index'>
<ul class="list-unstyled">
<li class="heading">
<div class="clearfix">
<span [className]="linkGroup.ContainerCssClass">
<span [className]="linkGroup.CssClass"></span>
</span>
<a href="#">
<strong class="heading-text">{{linkGroup.Title}}</strong>
</a>
</div>
</li>
<li *ngFor='let link of linkGroup.Links'>
<a href="#" class="link">
<span [className]="link.CssClass"></span>
<span class="item">{{link.Title}}</span>
</a>
</li>
</ul>
</div>
</div>
编辑
答案正如 Gunter 所建议的那样,重新组织数据以分组到行中。然后我可以将模板组织成这样:
<div class="row" *ngFor='let linkRow of linkRows| siteMapRowText: siteMapTextFilter'>
<div class="col-xs-4" *ngFor='let rowCol of linkRow.RowGroups'>
<ul class="list-unstyled">
<li class="heading">
<div class="clearfix">
<span [className]="rowCol.ContainerCssClass">
<span [className]="rowCol.CssClass"></span>
</span>
<a href="#">
<strong class="heading-text">{{rowCol.Title}}</strong>
</a>
</div>
</li>
<li *ngFor='let link of rowCol.Links'>
<a href="#" class="link">
<span [className]="link.CssClass"></span>
<span class="item">{{link.Title}}</span>
</a>
</li>
</ul>
</div>
</div>
最佳答案
更新
你可以使用一个管道来创建一个新数组,将 4 个项目分组到一个数组中,这样你就可以获得一个数组数组,然后使用嵌套的 ngFor
@Pipe({ name: 'cols' })
export class ColsPipe implements PipeTransform {
transform(value: any[], cols: number) {
var result: any[] = [];
while(value.length) {
result.push(value.splice(0, cols));
}
return result;
}
};
另见 How to split a long array into smaller arrays, with JavaScript
然后像这样使用它
@NgModule({
declarations: [ColsPipe],
exports: [ColsPipe]
})
class MySharedModule()
@NgModule({
imports: [MySharedModule],
...
})
class ModuleWhereColsPipeIsUsed {}
@Component({
selector: '...',
template: `
<div class="row" *ngFor='let linkGroupRow of linkGroups | siteMapText: siteMapTextFilter | cols:4; let i=index'>
<div class="col-xs-4" *ngFor='let linkGroup of linkGroupRow'>...</div>
</div>
`
})
原创
这可以通过使用 ngTemplateOutlet
来实现
首先我们创建一个可重用的组件:
<template #linkGroupTemplate>
<div class="col-xs-4">
<ul class="list-unstyled" let-linkGroup="linkGroup"
>
<li class="heading">
<div class="clearfix">
<span [className]="linkGroup.ContainerCssClass">
<span [className]="linkGroup.CssClass"></span>
</span>
<a href="#">
<strong class="heading-text">{{linkGroup.Title}}</strong>
</a>
</div>
</li>
<li *ngFor='let link of linkGroup.Links'>
<a href="#" class="link">
<span [className]="link.CssClass"></span>
<span class="item">{{link.Title}}</span>
</a>
</li>
</ul>
</div>
</template>
let-linkGroup="linkGroup"
声明一个上下文变量 linkGroup
指的是 linGroup
传递上下文的属性。
然后我们使用ngFor
里面的模板并用 <div class="row">
包裹起来使用在每 4 个项目上,否则打开。
<罢工>罢工>
<罢工><template ngFor let-linkGroup [ngForOf]="linkGroups |siteMapText:siteMapTextFilter" let-i="index">
<template [ngIf]="i % 3 === 0">
<div class="row">
<template [ngTemplateOutlet]="linkGroupTemplate" [ngOutletContext]="{'linkGroup': linkGroup}">
</div>
<template>
<template [ngIf]="i % 3 !== 0">
<template [ngTemplateOutlet]="linkGroupTemplate" [ngOutletContext]="{'linkGroup': linkGroup}">
</template>
</template>
罢工><罢工>罢工>
<ng-container *ngFor="let linkGroup of linkGroups |siteMapText:siteMapTextFilter" let-i="index">
<ng-container *ngIf="i % 3 === 0">
<div class="row">
<template [ngTemplateOutlet]="linkGroupTemplate" [ngOutletContext]="{'linkGroup': linkGroup}"></template>
</div>
<ng-container>
<ng-container *ngIf="i % 3 !== 0">
<template [ngTemplateOutlet]="linkGroupTemplate" [ngOutletContext]="{'linkGroup': linkGroup}"></template>
</ng-container>
</ng-container>
与 [ngOutletContext]="{'linkGroup': linkGroup}"
我们包装实际的 linkGroup
另一个对象中的值,以便我们可以像以前一样在模板中访问它。否则我们需要为每个要使用的属性声明一个变量
let-CssContainerCssClass="ContainerCssClass" let-CssClass="CssClass" let-Title="Title" let-Links="Links"
并删除 linkGroup.
来自所有绑定(bind)。
另见 How to repeat a piece of HTML multiple times without ngFor and without another @Component对于使用 ngTemplateOutlet
的示例(使用 Plunker)和 ngOutletContext
.
关于Angular2 ngFor 父元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38174820/