简体   繁体   中英

Angular 4 ng-container vs *ngIf else

I have a big table with many cols, and buttons to change edit mode, for example:

<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.bonusPrice}}</td>
<td>{{item.kcal}}</td>
<td>{{item.weight}}</td>
<td>{{item.type}}</td>
<td>{{item.status}}</td>
...

Which variant will be better, create 2 ng-container s

<ng-container *ngIf="!item.isEdited">
  <td>{{item.name}}</td>
  <td>{{item.price}}</td>
  <td>{{item.bonusPrice}}</td>
  <td>{{item.kcal}}</td>
  <td>{{item.weight}}</td>
  <td>{{item.type}}</td>
  <td>{{item.status}}</td>
</ng-container>

and 

<ng-container *ngIf="item.isEdited">
  <td><input [(ngModel)]="item.name"></td>
  <td><input [(ngModel)]="item.price"></td>
  <td><input [(ngModel)]="item.bonusPrice"></td>
  <td><input [(ngModel)]="item.kcal"></td>
  <td><input [(ngModel)]="item.weight"></td>
  <td><input [(ngModel)]="item.type"></td>
  <td><input [(ngModel)]="item.status"></td>
</ng-container>

or just used *ngIf else in each <td> :

<td>
  <span *ngIf="!item.isEdited; else elseBlock">
      {{item.name}}
  </span>
  <ng-template #elseBlock>
    <input [(ngModel)]="item.name">
  </ng-template>
</td>

which variant better in performance way and any other :) or maybe there is more better approach?

Why not keeping the inputs with their [(ngModel)] and use css to style them? you could toggle their readOnly state or disable, and keep a single approach.

If you want to do it in the template i'd say the ng-container approach will be better as it will replace a whole chunk instead little pieces in each td.

I don't really have any actual data to back this up, but just intuitively, the one that uses the least amount of bindings to do the job is probably going to perform the "best". Comparing all of your examples, mine, and the other commenters, I bet your first example would be the 'fastest' by at least a few microseconds.... ;) I have no intimate knowledge of how Angular's compiler works though - it may specifically optimize for structural directives over statically declared HTMl, who knows. Angular doesn't really have an option to 'bind once' unless you disable change detection entirely, so any bindings will, in theory, stay 'active', but as to whether that actually effects performance realistically, I dunno. I would bet you would have to have a lot of bound elements on the screen before you started to notice even a slight difference.

Usually the time you spend coding and maintaining it will far outweight any milliseconds you gain by optimizing it to the extreme, so the best optimization is usually the one that makes it the easiest to read! :-) With that in mind, I'd use the following approach, as it avoids repetition of both variables and HTML elements as much as possible.

 <ng-container *ngFor="let key of ['name','price','bonusPrice','kcal','weight','type','status']">

    <td *ngIf="!item.isEdited">                     {{item[key]}     </td>
    <td *ngIf="item.isEdited" >   <input [(ngModel)]="item[key]" />  </td>  

 </ng-container>

On a related note... I don't really understand the angular team's motivation behind adding the ngIf / else statement. I haven't yet seen a case where using an ngIf/else statement did something that simply using opposite ngIf statements could not. And the ngIf / else block ends up looking far more convoluted than simply using two polar ngIf's, as you're introducing new elements and symbols into the markup mix that just kinda distracts from the visual cohesion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM