Guillaume Gaujac
Guillaume Gaujac

Reputation: 1651

*ngIf won't open a template

I have a .html file to show some values. I add a condition with "*ngIf" inside my tag to find a value that ends with "Rechercher ...". Perhaps I can't find how to make it work. I try several things and now I just have a boolean with a value at true to find if I can switch between my template but he still won't open one of them.

Original (working)

<datalist id="{{row.LISTID}}">
    <option value="{{value}}">{{value}}</option>
    <option *ngFor="let i of tableEquipmentDataTmp[row.LISTID]" value="{{i.OBJECTID}}"> {{i.OBJECTID}}
    </option>
</datalist>

Changes (not working)

<datalist id="{{row.LISTID}}">
    <option value="{{value}}">{{value}}</option>
    <div *ngFor="let i of tableObjectDataTmp[row.LISTID]">
        <ng-template *ngIf="isTrue else disabled_lock">
            <option value="{{i.OBJECTID}}">{{i.OBJECTID}}</option>
        </ng-template>
        <ng-template #disabled_lock>
            <option value="{{i.OBJECTID}}" disabled>{{i.OBJECTID}}</option>
        </ng-template>
    </div>
</datalist>

ts (edit)

export class HeaderComponent implements OnInit {
    isTrue = true;
    ngOnInit() {
        this.isTrue = true;
    }
}

Thanks in advance for your responses.

Upvotes: 0

Views: 747

Answers (3)

Martin Parenteau
Martin Parenteau

Reputation: 73731

As explained in the Angular documentation, an ngTemplate cannot be displayed by itself; it must be displayed by a structural directive. By using the *ngIf shorthand syntax in your markup, you end up with this equivalent markup:

<ng-template [ngIf]="isTrue" [ngIfElse]="disabled_lock">
  <ng-template>
    <option value="{{i.OBJECTID}}">{{i.OBJECTID}}</option>
  </ng-template>
</ng-template>
<ng-template #disabled_lock>
  <option value="{{i.OBJECTID}}" disabled>{{i.OBJECTID}}</option>
</ng-template>

The outer ngTemplate of the ngIf part is appropriately controlled by the ngIf directive but the inner ngTemplate has no structural directive applied to it. As a result, it is never displayed.

One possible solution is to use the explicit ngIf notation, as suggested in SoCo's answer. Another solution is to apply the *ngIf directive to the option element:

<option *ngIf="isTrue else disabled_lock" value="{{i.OBJECTID}}">{{i.OBJECTID}}</option>
<ng-template #disabled_lock>
  <option value="{{i.OBJECTID}}" disabled>{{i.OBJECTID}}</option>
</ng-template>

In cases where the first ngTemplate would contain several elements, you could replace it with an ng‑container:

<ng-container *ngIf="isTrue else disabled_lock">
  <option value="value1">Caption 1</option>
  <option value="value2">Caption 2</option>
</ng-container>
<ng-template #disabled_lock>
  <option value="value3" disabled>Caption 3</option>
</ng-template>

You can experiment with the following stackblitz examples: the first one is similar to your current code while the second one applies the *ngIf directive to an HTML element instead of an ngTemplate.


All that being said, your code example doesn't really need an ngIf structural directive since the two parts differ only by the disabled property. You could just bind that property:

<option value="{{i.OBJECTID}}" [disabled]="!isTrue">{{i.OBJECTID}}</option>

Upvotes: 3

SoCo
SoCo

Reputation: 1954

Try changing <ng-template> *ngIf syntax from

<ng-template *ngIf="isTrue else disabled_lock">

to

<ng-template [ngIf]="isTrue" [ngIfElse]="disabled_lock">

Here is a small demo demonstrating how it works.

You can read more about the *ngIf directive here

Upvotes: 1

Evaldas Buinauskas
Evaldas Buinauskas

Reputation: 14077

I think the issue is that you're checking isTrue, but not i.isTrue.

<datalist id="{{row.LISTID}}">
    <option value="{{value}}">{{value}}</option>
    <div *ngFor="let i of tableObjectDataTmp[row.LISTID]">
        <ng-template *ngIf="i.isTrue else disabled_lock">
            <option value="{{i.OBJECTID}}">{{i.OBJECTID}}</option>
        </ng-template>
        <ng-template #disabled_lock>
            <option value="{{i.OBJECTID}}" disabled>{{i.OBJECTID}}</option>
        </ng-template>
    </div>
</datalist>

Upvotes: 2

Related Questions