我在尝试在同一个元素上使用Angular的*ngFor和*ngIf时遇到了一个问题。
当试图在*ngFor中循环该集合时,该集合被视为null,因此当试图在模板中访问其属性时失败。
@Component({
selector: 'shell',
template: `
<h3>Shell</h3><button (click)="toggle()">Toggle!</button>
<div *ngIf="show" *ngFor="let thing of stuff">
{{log(thing)}}
<span>{{thing.name}}</span>
</div>
`
})
export class ShellComponent implements OnInit {
public stuff:any[] = [];
public show:boolean = false;
constructor() {}
ngOnInit() {
this.stuff = [
{ name: 'abc', id: 1 },
{ name: 'huo', id: 2 },
{ name: 'bar', id: 3 },
{ name: 'foo', id: 4 },
{ name: 'thing', id: 5 },
{ name: 'other', id: 6 },
]
}
toggle() {
this.show = !this.show;
}
log(thing) {
console.log(thing);
}
}
我知道简单的解决方案是将*ngIf移动到一个级别,但对于像在ul中循环列表项这样的场景,如果集合为空,我最终会得到一个空li,或者我的lis被多余的容器元素包装。
比如在这个地方。
注意控制台错误:
EXCEPTION: TypeError: Cannot read property 'name' of null in [{{thing.name}} in ShellComponent@5:12]
是我做错了什么还是这是个bug?
正如每个人都指出的那样,即使在一个元素中有多个模板指令在angular 1中也是有效的。x在Angular 2中是不允许的。
你可以在这里找到更多信息:https://github.com/angular/angular/issues/7315
2016年角2
解决方案是使用<template>作为占位符,因此代码如下所示
<template *ngFor="let nav_link of defaultLinks" >
<li *ngIf="nav_link.visible">
.....
</li>
</template>
但出于某种原因,上述在2.0.0-rc中不工作。在那种情况下你可以用这个
<template ngFor let-nav_link [ngForOf]="defaultLinks" >
<li *ngIf="nav_link.visible">
.....
</li>
</template>
2018年最新答案
随着更新,现在在2018年angular v6推荐使用<ng-container>而不是<template>
这是最新的答案。
<ng-container *ngFor="let nav_link of defaultLinks" >
<li *ngIf="nav_link.visible">
.....
</li>
</ng-container>
正如每个人都指出的那样,即使在一个元素中有多个模板指令在angular 1中也是有效的。x在Angular 2中是不允许的。
你可以在这里找到更多信息:https://github.com/angular/angular/issues/7315
2016年角2
解决方案是使用<template>作为占位符,因此代码如下所示
<template *ngFor="let nav_link of defaultLinks" >
<li *ngIf="nav_link.visible">
.....
</li>
</template>
但出于某种原因,上述在2.0.0-rc中不工作。在那种情况下你可以用这个
<template ngFor let-nav_link [ngForOf]="defaultLinks" >
<li *ngIf="nav_link.visible">
.....
</li>
</template>
2018年最新答案
随着更新,现在在2018年angular v6推荐使用<ng-container>而不是<template>
这是最新的答案。
<ng-container *ngFor="let nav_link of defaultLinks" >
<li *ngIf="nav_link.visible">
.....
</li>
</ng-container>