我'm having a problem with trying to use Angular' s *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
,或者我的 li
被包装在冗余的容器元素中 .
这个例子plnkr .
请注意控制台错误:
EXCEPTION: TypeError: Cannot read property 'name' of null in [{{thing.name}} in ShellComponent@5:12]
我做错了什么或这是一个错误?
12 回答
这将工作,但元素仍将在DOM中 .
Angular v2不支持同一元素上的多个结构指令 .
作为一种解决方法,使用 <ng-container> 元素,允许您为每个结构指令使用单独的元素,但它是 not stamped to the DOM .
<ng-template>
(在Angular v4之前的<template>
)允许执行相同但使用不同的语法,这会让人感到困惑,不再推荐我还有一个解决方案 .
使用
[hidden]
而不是*ngIf
区别在于
*ngIf
将从DOM中删除元素,而[hidden]
实际上通过设置display:none来播放CSS
样式已更新至angular2 beta 8
现在从angular2 beta 8开始,我们可以在相同的组件see here上使用
*ngIf
和*ngFor
.备用:
有时我们不能在
tr
,th
(table
)或li
(ul
)中使用HTML标签 . 我们不能使用其他HTML标记,但我们必须在相同的情况下执行某些操作,因此我们可以通过这种方式使用HTML5功能标记<template>
.ng使用模板:
ngIf使用模板:
有关angular2 see here中结构指令的更多信息 .
您不能在同一元素上使用多个结构指令 . 将您的元素包装在
ng-template
中并在那里使用一个结构指令正如大家所指出的那样,即使在单个元素中有多个模板指令也可以在角度1.x中工作,但在Angular 2中不允许这样做 . 您可以从这里找到更多信息:https://github.com/angular/angular/issues/7315
2016 angular 2 beta
解决方案是使用
<template>
作为占位符,因此代码就像这样但出于某种原因,上述情况在
2.0.0-rc.4
中无效,在这种情况下你可以使用它更新了答案2018
随着更新,现在2018年角度v6建议使用
<ng-container>
而不是<template>
所以这是更新的答案 .
你不能在同一个元素上使用Angular中的多个
Structural Directive
,它会产生一个糟糕的混淆和结构,所以你需要在两个独立的嵌套元素中应用它们(或者你可以使用ng-container
),从Angular团队中读取这个语句:因此,如果你有类或其他一些属性,你可以使用
ng-container
(Angular4)作为包装器(将从dom中删除)或div或span:你不能在同一个元素上有
ngFor
和ngIf
. 您可以做的是在ngFor
中填充您正在使用的数组,直到单击示例中的切换为止 .这是你可以做到的基本(不太好)的方式:http://plnkr.co/edit/Pylx5HSWIZ7ahoC7wT6P
正如@Zyzle所提到的,@Günter在评论中提到(https://github.com/angular/angular/issues/7315),这是不受支持的 .
同
当列表为空时,没有空的
<li>
元素 . 甚至<ul>
元素也不存在(如预期的那样) .填充列表时,没有冗余容器元素 .
@Zyzle在他的评论中提到的github discussion (4792)也提出了另一个使用
<template>
的解决方案(下面我使用你的原始标记 - 使用<div>
s):此解决方案也不会引入任何额外/冗余容器元素 .
下表仅列出了设置了"beginner"值的项目 . 需要
*ngFor
和*ngIf
来防止html中不需要的行 .最初在
<tr>
标签上有*ngIf
和*ngFor
,但不起作用 . 为*ngFor
循环添加<div>
并将*ngIf
放在<tr>
标记中,按预期工作 .