如何在Angular中在一个元素上应用多个模板绑定

120
我正在使用以下模板:

我正在使用以下模板:

<ul [ngClass]="{dispN: !shwFilter,'list-group':true,'autoS':true,'dispB':shwFilter,'myshddw':true}" style=";display: none">
  <li *ngIf="itsNotF && itsNotF.length" [ngClass]="{bgDFF: !colps[j],'list-group-item':true}" *ngFor="let valm1 of itsNotF;let j=index;" (click)="togFltr(j)" style="padding: 0;background: #fff">
    <div *ngIf="valm1 && valm1.type=='1'">
      <h5 style="padding:8px;margin: 0;">{{valm1['header']}}</h5>
      <p style="margin: 8px;">{{valm1['body']}}</p>
      <h6 style="padding:8px;margin: 0;">{{valm1['note']}}</h6>
    </div>
    <div *ngIf="valm1 && valm1.type=='2'" (click)="modlTxt=valm1;notREadVu(j)" data-toggle="modal" data-target="#myModal">
      <h5 style="padding:8px;margin: 0;">{{valm1['header']}}</h5>
      <h6 style="padding:8px;margin: 0;">{{valm1['note']}}</h6>
    </div>
    <div *ngIf="valm1 && valm1.type=='3'">
      <h5 style="padding:8px;margin: 0;">{{valm1['header']}}</h5>
      <p style="margin: 8px;">{{valm1['body']}}</p>
      <h6 style="padding:8px;margin: 0;">{{valm1['note']}}</h6>
    </div>
  </li>
  <li [ngClass]="{bgDFF: !colps[j],'list-group-item':true,'lgOt':true}" (click)="logout()">
    <span class="title">Log Out <i class="fa fa-sign-out"></i></span>
  </li>
</ul>

所以它会产生以下错误:
EXCEPTION: Template parse errors:
Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with * ("one">
  <li *ngIf="itsNotF && itsNotF.length" [ngClass]="{bgDFF: !colps[j],'list-group-item':true}" [ERROR ->]*ngFor="let valm1 of itsNotF;let j=index;" (click)="togFltr(j)" style="padding: 0;background: #fff">
"): App@78:94

之前没有出现错误,我在升级到RC4后遇到了这个问题。

那么有什么解决方法,可以在不改变模板结构的情况下,在单个元素上应用多个模板绑定。


1
ngIfngFor都是结构型指令,它们不能同时存在于同一个元素上。为了解决这个问题,您可以查看此GitHub问题评论 - Pankaj Parkar
但之前(RC1)它是可以工作的。 - Akhilesh Kumar
4个回答

232

在Angular 2中不能在一个元素上同时使用两个模板绑定,比如*ngIf和*ngFor。但是你可以通过将该元素包装在或任何其他元素中来实现相同的效果。最好附加一个<ng-container>,因为它是一个逻辑容器,不会附加到DOM中。例如:

<ng-container *ngIf="condition">
    <li *ngFor="let item of items">
        {{item}}
    </li>
</ng-container>

4
这个解决方案并不总是有效。例如,两个ng-container的情况。 - titusfx
1
我刚刚进行了更改,使用了带有*ngIf="condition"的div,而不是ng-container。同时,我使用的是Angular 6。这个更改对我很有效。 - Günay Gültekin
我尝试使用 div 进行包裹,但没有成功。ng-container 是最适合的元素,因为它是一个逻辑上的包装器。谢谢,伙计。 - Shahid Malik

15
你可以使用以下(展开版本)来保留文档结构(例如,为你的CSS选择器):
<template [ngIf]="itsNotF && itsNotF.length">
    <div [ngClass]="{bgDFF: !colps[j],'list-group-item':true}" *ngFor="let valm1 of itsNotF;let j=index;" (click)="togFltr(j)" style="padding: 0;background: #fff">
    </div>
</template>

4
将你的*ngIf放在父div中,而*ngFor可以保留在原地。
例如:
<div *ngIf="itsNotF && itsNotF.length">
    <div [ngClass]="{bgDFF: !colps[j],'list-group-item':true}" *ngFor="let valm1 of itsNotF;let j=index;" (click)="togFltr(j)" style="padding: 0;background: #fff">
    </div>
</div>

难道没有类似于https://dev59.com/12gv5IYBdhLWcg3wTvA-的解决方案吗? - Akhilesh Kumar
1
这是正确的。如果有助于您的CSS,您可以将父级定义为span。甚至可以创建自定义元素:例如<test *ngIf="1==1"><div></div></test> - Andy-Delosdos
现在我更新了我的情景,现在你可以理解为什么我不能使用你的解决方案,因为“logout”行将始终可见,而修改“ul>li”选择器是不可能的(需要在CSS中进行大量更改)。 - Akhilesh Kumar
我得到的唯一解决方案是使用*ngIf条件复制ul。 - Akhilesh Kumar
不用了...但还是谢谢你 ;) - Cody
显示剩余2条评论

2
如果您正在使用 *ngFor 并想要添加 *ngIf 来检查某个字段,如果条件不是太复杂,我会使用过滤器,在其中运行我的条件并仅返回在该循环中符合条件的项目。希望这可以帮助您。
类似于这样,我只想显示具有描述的项目:
<div class="delivery-disclaimer" *ngFor="let payment of cart.restaurant.payment_method | filter:[{short_name: cart.payment_method}] | onlyDescription" text-wrap>
        <ion-icon item-left name="information-circle"></ion-icon> {{payment.pivot.description}}
    </div>

Before

2
Angular 2 没有 filter 方法。请参见 https://angular.io/docs/ts/latest/guide/pipes.html#!#no-filter-pipe。 - SoftwareAndOutsourcing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接