-2

I am trying to integrate the inline edit with table tr, i tried as follows: when user click edit i am switching to new class added with form.

<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>

But throws error with :

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

In this case how handle? how to fix the error or what is the correct way to do it?

3gwebtrain
  • 14,640
  • 25
  • 121
  • 247
  • Possible duplicate of [\*ngIf and \*ngFor on same element causing error](https://stackoverflow.com/questions/34657821/ngif-and-ngfor-on-same-element-causing-error) – ViqMontana Jul 10 '19 at 06:53
  • This is not exactly a duplicate because there are 2 problems in the code. – SplitterAlex Jul 10 '19 at 07:11

4 Answers4

1

as per angular, You cannot use multiple bindings. You can try using ng-template for loop bindings.

<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>
er_Yasar
  • 150
  • 10
  • This will not work! Replace the host container for ngFor directive with instead of . When you use nothing will render. – SplitterAlex Jul 10 '19 at 07:03
0

You cant have two template binding on the same element in angular, one way to approach is the use of

 <span ></span> 

or by using

<ng-template> </ng-template>
Ram
  • 356
  • 2
  • 14
0

You have two problems:

  • You cannot have two structural directives on the same host element.

  • The else template from ngIf directive should be wrapped in a <ng-template>.

From Angular Documentation:

Someday you'll want to repeat a block of HTML but only when a particular condition is true. You'll try to put both an *ngFor and an *ngIf on the same host element. Angular won't let you. You may apply only one structural directive to an element.

The reason is simplicity. Structural directives can do complex things with the host element and its descendents. When two directives lay claim to the same host element, which one takes precedence? Which should go first, the NgIf or the NgFor? Can the NgIf cancel the effect of the NgFor? If so (and it seems like it should be so), how should Angular generalize the ability to cancel for other structural directives?

There are no easy answers to these questions. Prohibiting multiple structural directives makes them moot. There's an easy solution for this use case: put the *ngIf on a container element that wraps the *ngFor element. One or both elements can be an ng-container so you don't have to introduce extra levels of 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>
SplitterAlex
  • 2,755
  • 2
  • 20
  • 23
0

You should use ng-container which lets you avoid any side effects.

<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>
Yaelet
  • 160
  • 10