Issue with template in ion-item

Hello,

I’m working on an ionic 2 application since many months and since some times, I had an issue that appeared and I don’t find a solution.
Here the code:

<template ngFor let-actionType_l [ngForOf]="actions_m">
    <ion-item no-lines>
        <ion-label>
            {{actionType_l.actionType}}
        </ion-label>
        <ion-checkbox [(ngModel)]="actionType_l.checked"></ion-checkbox>
    </ion-item>
    <ion-item
        no-lines>
        <template id="templateAction" *ngIf="actionType_l.checked" ngFor let-action_l [ngForOf]="actionType_l.actions">
            <ion-item
                no-lines>
                <ion-label>
                    {{action_l.actionNameToShow}}
                </ion-label>
                <ion-checkbox [(ngModel)]="action_l.checked"></ion-checkbox>
            </ion-item>
        </template>
    </ion-item>
</template>

It works fine for a while but now the template with id “templateAction” never appear. If I remove the ion-item around the template all the data appear but it doesn’t have the good layout.

For information, I use ionic framework version 2.2.0 and ionic cli version 2.2.3

Does anyone have a solution to resolve my issue?

Thanks by advance,
Thibault

<template id="templateAction" *ngIf="actionType_l.checked" ngFor let-action_l [ngForOf]="actionType_l.actions">
            <ion-item
                no-lines>
                <ion-label>
                    {{action_l.actionNameToShow}}
                </ion-label>
                <ion-checkbox [(ngModel)]="action_l.checked"></ion-checkbox>
            </ion-item>
        </template>

I don’t know how that could have worked at all, since it uses two directives at the same level (ngIf and ngFor). Put the ngIf on the ion-item if you need it, loop over the template with the ngFor like your already doing. What’s that supposed to do btw?

@ThibaultLap In a template you should [ngIf] instead of *ngIf and you shouldn’t use more than 1 structural directive (in your case, ngIf and ngFor) in the same component.

Also, instead of template I would recommend using ng-container to use the same syntax as the other components. Its just a syntatic sugar, but very useful.

There is also the fact that the template and ng-container don’t appear in the HTML. It’s a good thing, to avoid a lot of nested elements inside others unnecessarily, problems with css selectors, among other problems.

So instead of:

<template id="templateAction" *ngIf="actionType_l.checked" ngFor let-action_l [ngForOf]="actionType_l.actions">
	...
</template>

You can do:

<ng-container *ngIf="actionType_l.checked">
	<ng-container *ngFor="let action_l of actionType_l.actions">
		...
	</ng-container>
</ng-container>

If you really want to have the id be shown in an element, use it in a element like div or similar, but I don’t see a point in doing that.

You can see more about ng-container here.

And I really recommend that you read the Angular docs about structural directives: https://angular.io/guide/structural-directives.

2 Likes

@luukschoen I already tried to put the ngIf on the ion-item and it didn’t work.

@lucasbasquerotto Thanks for your advice but even with that, it doesn’t work. By the way I have the same problem in another file where I have that:

<template ngFor let-action_l [ngForOf]="actions_m">
    <ion-item
        no-lines>
        <ion-label>
            {{action_l.name}}
        </ion-label>
        <ion-checkbox [(ngModel)]="action_l.checked"></ion-checkbox>
    </ion-item>
    <ion-item *ngIf="action_l.id === 'power' && action_l.checked"
        no-lines>
         <!--<ion-select [(ngModel)]="action_l.boxelDeviceCommandArgs[0].value">-->
         <!--    <ion-option value="toggle">Toggle</ion-option>-->
         <!--    <ion-option value="on">On</ion-option>-->
         <!--    <ion-option value="off">Off</ion-option>-->
         <!--</ion-select>-->
         <ion-list radio-group [(ngModel)]="action_l.value">
             <ion-item>
                 <ion-label>Toggle</ion-label>
                 <ion-radio value="toggle"></ion-radio>
             </ion-item>
             <ion-item>
                 <ion-label>On</ion-label>
                 <ion-radio value="on"></ion-radio>
             </ion-item>
             <ion-item>
                 <ion-label>Off</ion-label>
                 <ion-radio value="off"></ion-radio>
             </ion-item>
         </ion-list>
     </ion-item>
     <ion-item *ngIf="action_l.id === 'color' && action_l.checked"
         no-lines>
         <ion-range [(ngModel)]="action_l.value1000" min="0" max="1000" step="1"></ion-range>
     </ion-item>
</template>

In that case, the range in the item with “action_l.id === ‘color’” appear but the list in the item with “action_l.id === ‘power’” never appear even if the select appear if I uncomment it but it has not the good layout. It seems like that I cant have an ion-item into another anymore whereas before that worked.

@ThibaultLap The behaviour of ion-item is a bit specific and it doesn’t allow all kinds of components inside it, although you can make the ion-item see it using the item-content directive:

<ion-list radio-group [(ngModel)]="action_l.value" item-content>
    ...
</ion-list>

See more about ion-item here.

Or you can just use ng-container or similar instead of the external ion-item (nested ion-items may cause unexpected results, and you already have ion-item inside your ion-list):

<ng-container *ngIf="action_l.id === 'power' && action_l.checked" no-lines>
1 Like