ChatGPT解决这个技术问题 Extra ChatGPT

Using ngIf without an extra element in Angular 2

Can I use ngIf without an extra container element?

<tr *ngFor="...">
  <div *ngIf="...">
    ...
  </div>
  <div *ngIf="!...">
    ...
  </div>
</tr>

It doesn't work in a table because that would make invalid HTML.


C
Community

ng-container is preferred over template:

<ng-container *ngIf="expression">

See:

Angular 2 ng-container

https://github.com/angular/angular.io/issues/2303


You should add a sample "generate" HTML snippet, to make it clear that an HTML element doesn't get created.
I come here twice a day. I can't get to stick that in my head.
ng-container seems to generate a div in our case?
j
janispritzkau

I found a method for that on: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#star-template.

You can simply use the <template> tag and replace *ngIf with [ngIf] like this.

<template [ngIf]="...">
  ...
</template>

good but *ngIf itslef creates an template tag ,by default angular directives prefix with * creates an template tag. so both are same [ngIf] and *ngIf
With *ngIf you have an element inside the template, you do not if you write the template yourself. Under certain circumstances the extra element could interfere.
Can we put template tag inside, tr/td tag?
Yes it's kind of a special element. Per definition it's not allowed w3.org/TR/html401/struct/tables.html#h-11.2.3 but it will work and render. If Iam using *ngIf it isn't working btw. but with [ngIf] it does. May I ask if you can tell me why that is?
@sascha10000 Because having *ngIf="foo" is equivalent to the wrapping <template [ngIf]="foo"> tag. In short, template + [] == *, so [] != *. * makes sense in any element except template.
P
Pankaj Parkar

You can't put div directly inside tr, that would make invalid HTML. tr can only have td/th/table element in it & inside them you could have other HTML elements.

You could slightly change your HTML to have *ngFor over tbody & have ngIf over tr itself like below.

<tbody *ngFor="...">
  <tr *ngIf="...">
    ...
  </tr>
  <tr  *ngIf="!...">
    ...
  </tr>
  ..
</tbody>

It would basically solve the problem but you'll trade off the core ability you get with tbody. If you have a big table you can fix the head an just scroll the tbody. Your tbody would have the role of tr and tr would have the role of an additional wrapper. If there's no need for scrolling and fixing the head at top this is a pragmatic solution. My reference for what I said: w3.org/TR/html401/struct/tables.html#h-11.2.3
S
Sourabh Shah

adding brackets resolves this issue

 <ng-container *ngIf="(!variable| async)"></ng-container>

J
Jitendra

You can try this:

<ng-container *ngFor="let item of items;">
    <tr *ngIf="item.active">
        <td>{{item.name}}</td>
    </tr>
 </ng-container>
 

Here, I have iterate loop in ng container so it will not create extra dom and later in tr tag check condition if I want to render or not.