ngFor-条件模板抛出错误,因为一个元素上不能有多个模板绑定

时间:2019-07-10 06:48:30

标签: angular angular-forms angular8

我试图将内联编辑与表tr集成在一起,我尝试如下:当用户单击“编辑”时,我切换到添加了表单的新类。

<tbody>
               <tr *ngFor="let item of data" *ngIf="item.Id !== editId; else #inlineEdit" [ngClass]="{'editEnabled' : item.Id === editId }">
                    <td>{{item.Id}}</td>
                    <td>{{item.Name}}</td>
                    <td>{{item.Description}}</td>
                    <td>{{item.UpdatedBy}}</td>
                    <td>{{item.UpdatedDate}}</td>
                    <td class="data-user-option">
                        <button type="button" class="edit-item" (click)="confirmEditRow(item)"></button>
                        <!-- <button type="button" class="delete-item" (click)="confirmRemoveRow(item)"></button> -->
                    </td>
                    <ng-container #inlineEdit>
                        <td>{{item.Id}}</td>
                        <td>{{item.Name}}</td>
                        <td>{{item.Description}}</td>
                        <td>{{item.UpdatedBy}}</td>
                        <td>{{item.UpdatedDate}}</td>
                        <td class="data-user-option">
                            <button type="button" class="edit-item" (click)="confirmEditRow(item)"></button>
                        </td>
                    </ng-container>
                </tr>

            </tbody>

但是抛出错误:

Uncaught Error: Template parse errors: Can't have multiple template bindings on one element. Use only one attribute prefixed with * (" </thead> -->

在这种情况下如何处理?如何解决错误或正确的方法是什么?

4 个答案:

答案 0 :(得分:1)

按角度,您不能使用多个绑定。您可以尝试使用ng-template进行循环绑定。

<tbody>
<ng-container *ngFor="let item of data">
               <tr *ngIf="item.Id !== editId; else #inlineEdit" [ngClass]="{'editEnabled' : item.Id === editId }">
                    <td>{{item.Id}}</td>
                    <td>{{item.Name}}</td>
                    <td>{{item.Description}}</td>
                    <td>{{item.UpdatedBy}}</td>
                    <td>{{item.UpdatedDate}}</td>
                    <td class="data-user-option">
                        <button type="button" class="edit-item" (click)="confirmEditRow(item)"></button>
                        <!-- <button type="button" class="delete-item" (click)="confirmRemoveRow(item)"></button> -->
                    </td>
                    <ng-template #inlineEdit>
                        <td>{{item.Id}}</td>
                        <td>{{item.Name}}</td>
                        <td>{{item.Description}}</td>
                        <td>{{item.UpdatedBy}}</td>
                        <td>{{item.UpdatedDate}}</td>
                        <td class="data-user-option">
                            <button type="button" class="edit-item" (click)="confirmEditRow(item)"></button>
                        </td>
                    </ng-template>
                </tr>
</ng-container >
            </tbody>

答案 1 :(得分:0)

同一角度的元素上不能有两个模板绑定,一种方法是使用

 <span ></span> 

或使用

<ng-template> </ng-template>

答案 2 :(得分:0)

您有两个问题:

  • 在同一宿主元素上不能有两个结构指令。

  • ngIf指令中的else模板应包装在<ng-template>中。

  

From Angular Documentation

     

总有一天,您需要重复一段HTML代码,但前提是要满足特定条件。您将尝试将* ngFor和* ngIf放在同一宿主元素上。 Angular不会让你。您只能对一个元素应用一个结构指令。

     

原因是简单。结构化指令可以对宿主元素及其后代进行复杂的处理。当两个指令对同一宿主元素提出要求时,哪个优先? NgIf或NgFor应该先走? NgIf是否可以取消NgFor的效果?如果是这样(看起来应该是这样),Angular应该如何概括取消其他结构性指令的能力?

     

这些问题没有简单的答案。禁止多个结构性指令使它们无济于事。对于这种用例有一个简单的解决方案:将* ngIf放在包装* ngFor元素的容器元素上。一个或两个元素都可以是ng容器,因此您不必引入额外的HTML级别。

<tbody>
  <tr *ngFor="let item of data">
    <ng-container*ngIf="item.Id !== editId; else #inlineEdit" [ngClass]="{'editEnabled' : item.Id === editId }">
     <td>{{item.Id}}</td>
     <td>{{item.Name}}</td>
     <td>{{item.Description}}</td>
     <td>{{item.UpdatedBy}}</td>
     <td>{{item.UpdatedDate}}</td>
     <td class="data-user-option">
     <button type="button" class="edit-item" (click)="confirmEditRow(item)"></button>
                        <!-- <button type="button" class="delete-item" (click)="confirmRemoveRow(item)"></button> -->
    </td>
   </ng-container>
 </tr>
</tbody>

<ng-template #inlineEdit>
  <td>{{item.Id}}</td>
  <td>{{item.Name}}</td>
  <td>{{item.Description}}</td>
  <td>{{item.UpdatedBy}}</td>
  <td>{{item.UpdatedDate}}</td>
  <td class="data-user-option">
    <button type="button" class="edit-item" (click)="confirmEditRow(item)"></button>
   </td>
</ng-template>

答案 3 :(得分:0)

您应该使用ng-container来避免任何副作用。

<tbody>
     <ng-container *ngIf="item.Id !== editId; else #inlineEdit">
               <tr *ngFor="let item of data" [ngClass]="{'editEnabled' : item.Id === editId }">
                    <td>{{item.Id}}</td>
                    <td>{{item.Name}}</td>
                    <td>{{item.Description}}</td>
                    <td>{{item.UpdatedBy}}</td>
                    <td>{{item.UpdatedDate}}</td>
                    <td class="data-user-option">
                        <button type="button" class="edit-item" (click)="confirmEditRow(item)"></button>
                        <!-- <button type="button" class="delete-item" (click)="confirmRemoveRow(item)"></button> -->
                    </td>
                    <ng-container #inlineEdit>
                        <td>{{item.Id}}</td>
                        <td>{{item.Name}}</td>
                        <td>{{item.Description}}</td>
                        <td>{{item.UpdatedBy}}</td>
                        <td>{{item.UpdatedDate}}</td>
                        <td class="data-user-option">
                            <button type="button" class="edit-item" (click)="confirmEditRow(item)"></button>
                        </td>
                    </ng-container>
                </tr>
     </ng-container>
            </tbody>