我正在尝试有条件地将 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
中的模板,并在每 4 个项目上使用 <div class="row">
包裹它,否则将其解开。<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"
并从所有绑定(bind)中删除
linkGroup.
。另请参阅 How to repeat a piece of HTML multiple times without ngFor and without another @Component 以获取使用
ngTemplateOutlet
和 ngOutletContext
的示例(使用 Plunker)。关于Angular2 ngFor 父元素,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38174820/