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

Angular *同一元素上的ngIf和*ngFor导致错误,angular,ngfor,angular-ng-if,Angular,Ngfor,Angular Ng If,尝试在同一元素上使用Angular的*ngFor和*ngIf时遇到问题 当尝试在*ngFor中循环遍历集合时,该集合将被视为null,因此在尝试访问模板中的属性时失败 @组件({ 选择器:“shell”, 模板:` 炮弹开关! {{log(thing)}} {{thing.name} ` }) 导出类ShellComponent实现OnInit{ 公共物品:任何[]=[]; 公共显示:布尔值=假; 构造函数(){} 恩戈尼尼特(){ 这个.东西=[ {name:'abc',id:1}, {姓名:

尝试在同一元素上使用Angular的
*ngFor
*ngIf
时遇到问题

当尝试在
*ngFor
中循环遍历集合时,该集合将被视为
null
,因此在尝试访问模板中的属性时失败

@组件({
选择器:“shell”,
模板:`
炮弹开关!
{{log(thing)}}
{{thing.name}
`
})
导出类ShellComponent实现OnInit{
公共物品:任何[]=[];
公共显示:布尔值=假;
构造函数(){}
恩戈尼尼特(){
这个.东西=[
{name:'abc',id:1},
{姓名:'霍',id:2},
{name:'bar',id:3},
{name:'foo',id:4},
{name:'thing',id:5},
{name:'other',id:6},
]
}
切换(){
this.show=!this.show;
}
日志(东西){
console.log(东西);
}
}
我知道简单的解决方案是将
*ngIf
向上移动一个级别,但是对于像在
ul
中的列表项上循环这样的场景,如果集合是空的,我会得到一个空的
li
,或者我的
li
被包装在冗余容器元素中

举个例子

注意控制台错误:

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

我是做错了什么还是这是一个bug?

在同一个元素上不能有
ngFor
ngIf
。您可以推迟填充您在
ngFor
中使用的数组,直到单击示例中的切换


这里有一个基本的(不是很好的)方法:

正如@Zyzle提到的,@Günter在评论()中提到的,这是不受支持的



{{log(thing)}}
{{thing.name}


当列表为空时,不存在空的
  • 元素。甚至
    元素也不存在(如预期的那样)

    填充列表时,没有冗余的容器元素

    @Zyzle在其评论中提到的另一个解决方案也使用了
    (下面我使用您的原始标记‐使用
    s):

    
    {{log(thing)}}
    {{thing.name}
    
    此解决方案也不引入任何额外/冗余容器元素。

    更新为angular2 beta 8 现在,从angular2 beta 8开始,我们可以在同一组件上使用
    *ngIf
    *ngFor

    备选方案:

    有时我们不能在另一个中使用HTML标记,比如在
    tr
    th
    table
    )或在
    li
    ul
    )。我们不能使用另一个HTML标记,但我们必须在相同的情况下执行一些操作,这样我们就可以用这种方式使用HTML5功能标记

    要使用模板,请执行以下操作:
    
    代码在这里。。。。
    
    ngIf使用模板:
    
    代码在这里。。。。
    

    有关angular2中结构指令的更多信息。

    正如大家所指出的,即使在单个元素中有多个模板指令在Angular1.x中工作,但angular2中不允许。 您可以在此处找到更多信息:

    2016年角2测试版 解决方案是使用
    作为占位符,因此代码如下所示

    <template *ngFor="let nav_link of defaultLinks"  >
       <li *ngIf="nav_link.visible">
           .....
       </li>
    </template>
    
    更新答案2018 有了更新,现在我们建议在2018年使用
    而不是

    这是最新的答案

    <ng-container *ngFor="let nav_link of defaultLinks" >
       <li *ngIf="nav_link.visible">
           .....
       </li> 
    </ng-container>
    
    
    
    .....
    
    
    这将起作用,但元素仍将在DOM中

    。隐藏{
    显示:无;
    }
    

    
    {{log(thing)}}
    {{thing.name}
    
    Angular v2在同一个元素上不支持多个结构指令。
    作为一种解决方法,请使用
    元素,该元素允许您为每个结构指令使用单独的元素,但它未标记到DOM

    
    {{log(thing)}}
    {{thing.name}
    
    在Angular v4之前)允许执行相同的操作,但使用不同的语法,这很容易混淆,不再推荐使用

    
    {{log(thing)}}
    {{thing.name}
    
    
    
      {{item.name}
    下表仅列出设置了“初学者”值的项目。 需要
    *ngFor
    *ngIf
    以防止html中出现不需要的行

    最初在同一个
    标签上有
    *ngIf
    *ngFor
    ,但不起作用。 为
    *ngFor
    循环添加了
    ,并将
    *ngIf
    放置在
    标记中,工作正常

    <table class="table lessons-list card card-strong ">
      <tbody>
      <div *ngFor="let lesson of lessons" >
       <tr *ngIf="lesson.isBeginner">
        <!-- next line doesn't work -->
        <!-- <tr *ngFor="let lesson of lessons" *ngIf="lesson.isBeginner"> -->
        <td class="lesson-title">{{lesson.description}}</td>
        <td class="duration">
          <i class="fa fa-clock-o"></i>
          <span>{{lesson.duration}}</span>
        </td>
       </tr>
      </div>
      </tbody>
    
    </table>
    
    
    {{lesson.description}}
    {{lesson.duration}}
    
    在同一个元素上,不能在Angular中使用多个
    结构指令,这会造成严重的混乱和结构,因此您需要在两个单独的嵌套元素中应用它们(或者可以使用
    ng container
    ),请阅读Angular团队的以下声明:

    每个主体元素一个结构指令

    有一天你会想重复一块HTML,但只有当 特殊情况是正确的。您将尝试将*ngFor和 同一主机元素上的*ngIf。我不会让你的。你可以 对图元仅应用一个结构指令

    原因是简单。结构指令可以做复杂的事情 与宿主元素及其子代一起。当两条指令出台时 声明相同的主体元素,哪个优先?哪个 应该先走,NgIf还是NgFor?NgIf能消除这种影响吗 NgFor的名称?如果是这样(看起来应该是这样),应该怎么做 角度泛化为其他对象取消的能力
    <template [ngIf]="show">
        code here....
    </template>    
    
    <template *ngFor="let nav_link of defaultLinks"  >
       <li *ngIf="nav_link.visible">
           .....
       </li>
    </template>
    
    <template ngFor let-nav_link [ngForOf]="defaultLinks" >
       <li *ngIf="nav_link.visible">
           .....
       </li> 
    </template>
    
    <ng-container *ngFor="let nav_link of defaultLinks" >
       <li *ngIf="nav_link.visible">
           .....
       </li> 
    </ng-container>
    
    <table class="table lessons-list card card-strong ">
      <tbody>
      <div *ngFor="let lesson of lessons" >
       <tr *ngIf="lesson.isBeginner">
        <!-- next line doesn't work -->
        <!-- <tr *ngFor="let lesson of lessons" *ngIf="lesson.isBeginner"> -->
        <td class="lesson-title">{{lesson.description}}</td>
        <td class="duration">
          <i class="fa fa-clock-o"></i>
          <span>{{lesson.duration}}</span>
        </td>
       </tr>
      </div>
      </tbody>
    
    </table>
    
    <div class="right" *ngIf="show">
      <div *ngFor="let thing of stuff">
        {{log(thing)}}
        <span>{{thing.name}}</span>
      </div>
    </div>
    
    <div *ngFor="let thing of show ? stuff : []">
      {{log(thing)}}
      <span>{{thing.name}}</span>
    </div>
    
    <tr *ngFor = "let fruit of fruiArray">
        <ng-template [ngIf] = "fruit=='apple'>
            <td> I love apples!</td>
        </ng-template>
    </tr>
    
    <div [ngClass]="{'disabled-field': !show}" *ngFor="let thing of stuff">
        {{thing.name}}
    </div>
    
    .disabled-field {
        pointer-events: none;
        display: none;
    }
    
    <div *ngIf="stuff.length>0">
      <div *ngFor="let thing of stuff">
        {{log(thing)}}
        <span>{{thing.name}}</span>
      </div>
    </div>
    
    <div *ngFor="let thing of show ? stuff : []">