* ngIf和* ngFor在同一元素上导致错误

本文翻译自:*ngIf and *ngFor on same element causing error

I'm having a problem with trying to use Angular's *ngFor and *ngIf on the same element. 我在尝试在同一元素上使用Angular的*ngFor*ngIf问题。

When trying to loop through the collection in the *ngFor , the collection is seen as null and consequently fails when trying to access its properties in the template. 当尝试遍历*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);
  }

}

I know the easy solution is to move the *ngIf up a level but for scenarios like looping over list items in a ul , I'd end up with either an empty li if the collection is empty, or my li s wrapped in redundant container elements. 我知道简单的解决方案是将*ngIf提升到一个级别,但是对于诸如循环遍历ul列表项之类的方案,如果集合为空,我最终将得到一个空li ,或者将我的li包裹在冗余容器中元素。

Example at this plnkr . plnkr的示例

Note the console error: 注意控制台错误:

EXCEPTION: TypeError: Cannot read property 'name' of null in [{{thing.name}} in ShellComponent@5:12]

Am I doing something wrong or is this a bug? 我是在做错什么还是错误?


#1楼

参考:https://stackoom.com/question/2LQ57/ngIf和-ngFor在同一元素上导致错误


#2楼

You can't have ngFor and ngIf on the same element. 您不能在同一元素上使用ngForngIf What you could do is hold off on populating the array you're using in ngFor until the toggle in your example is clicked. 您可以做的就是推迟填充您在ngFor使用的数组,直到单击示例中的切换开关为止。

Here's a basic (not great) way you could do it: http://plnkr.co/edit/Pylx5HSWIZ7ahoC7wT6P 这是您可以执行的基本(不太好)方法: http : //plnkr.co/edit/Pylx5HSWIZ7ahoC7wT6P


#3楼

As @Zyzle mentioned, and @Günter mentioned in a comment ( https://github.com/angular/angular/issues/7315 ), this is not supported. 正如@Zyzle提到的和@Günter在评论中提到的( https://github.com/angular/angular/issues/7315 ),不支持此功能。

With

<ul *ngIf="show">
  <li *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </li>
</ul>

there are no empty <li> elements when the list is empty. 当列表为空时,没有空的<li>元素。 Even the <ul> element does not exist (as expected). 甚至<ul>元素也不存在(按预期)。

When the list is populated, there are no redundant container elements. 填充列表后,将没有多余的容器元素。

The github discussion (4792) that @Zyzle mentioned in his comment also presents another solution using <template> (below I'm using your original markup ‐ using <div> s): @Zyzle在他的评论中提到的github讨论(4792)也提出了使用<template>另一种解决方案(在下面,我使用的是原始的标记-using <div> ):

<template [ngIf]="show">
  <div *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </div>
</template>

This solution also does not introduce any extra/redundant container elements. 此解决方案也不会引入任何多余/冗余的容器元素。


#4楼

Updated to angular2 beta 8 更新到angular2 beta 8

Now as from angular2 beta 8 we can use *ngIf and *ngFor on same component see here . 现在从angular2 beta 8开始,我们可以在同一组件上使用*ngIf*ngFor请参见此处

Alternate: 备用:

Sometimes we can't use HTML tags inside another like in tr , th ( table ) or in li ( ul ). 有时我们不能在另一个内部使用HTML标记,例如trthtable )或liul )。 We cannot use another HTML tag but we have to perform some action in same situation so we can HTML5 feature tag <template> in this way. 我们不能使用其他HTML标记,但必须在相同情况下执行某些操作,因此我们可以以这种方式使用HTML5功能标记<template>

ngFor using template: ng对于使用模板:

<template ngFor #abc [ngForOf]="someArray">
    code here....
</template>

ngIf using template: ng如果使用模板:

<template [ngIf]="show">
    code here....
</template>    

For more information about structural directives in angular2 see here . 有关angular2中的结构指令的更多信息, 请参见此处


#5楼

As everyone pointed out even though having multiple template directives in a single element works in angular 1.x it is not allowed in Angular 2. you can find more info from here : https://github.com/angular/angular/issues/7315 每个人都指出,即使单个元素中包含多个模板指令也可以在angular 1.x中使用,但在Angular 2中是不允许的。您可以在此处找到更多信息: https : //github.com/angular/angular/issues/ 7315

2016 angular 2 beta 2016角2 Beta

solution is to use the <template> as a placeholder, so the code goes like this 解决方案是使用<template>作为占位符,因此代码如下所示

<template *ngFor="let nav_link of defaultLinks"  >
   <li *ngIf="nav_link.visible">
       .....
   </li>
</template>

but for some reason above does not work in 2.0.0-rc.4 in that case you can use this 但是由于上述原因,在这种情况下您无法使用2.0.0-rc.4

<template ngFor let-nav_link [ngForOf]="defaultLinks" >
   <li *ngIf="nav_link.visible">
       .....
   </li> 
</template>

Updated Answer 2018 更新的答案2018

With updates, right now in 2018 angular v6 recommend to use <ng-container> instead of <template> 有了更新,Angular v6现在建议在2018年使用<ng-container>代替<template>

so here is the updated answer. 所以这是更新的答案。

<ng-container *ngFor="let nav_link of defaultLinks" >
   <li *ngIf="nav_link.visible">
       .....
   </li> 
</ng-container>

#6楼

This will work but the element will still in the DOM. 这将起作用,但是元素仍将在DOM中。

.hidden{
    display: none;
}

<div [class.hidden]="!show" *ngFor="let thing of stuff">
  {{log(thing)}}
  <span>{{thing.name}}</span>
</div>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值