First of all, want to emphasize that I had already have a look at many pages e.g. Two switch case values in angular but they cannot fix my problem.
I have the following approach in the html page of my Angular project and I switch according to i parameter without any problem. On the other hand, there is a parameter called loading on component side and I also need to use this value in ngSwitchCase. But the following code does not work and ignore loading parameter's value. So, how can I use it?
<ng-container [ngSwitch]="i">
<ng-container *ngSwitchCase="i === 0 && loading === true">
<!-- other stuff -->
</ng-container>
</ng-container>
Create another ng-container inside with the loading condition.
<ng-container [ngSwitch]="i">
<ng-container *ngSwitchCase="0">
<ng-container *ngIf="loading">
// do stuff
</ng-container>
</ng-container>
</ng-container>
Related
I have a list of child components inside a ngFor:
<ng-container *ngFor="let field of fields">
<button (click)="show = !show">Show</button>
<ng-container *ngIf="show">
<app-field [fieldInfo]="field"></app-field>
</ng-container>
</ng-container>
I want to only show this specific app-field component if show is true, but this is obviously not the way, because it sets show to true for all of the rendered components.
My problem is really that I cant show all of the app-fields because they turn my app into a slow mess when they are displayed (there will be hundreds of them), so I only want to display them when they are needed.
How can I toggle the rendering of each specific component on/off uppon click? Or is there som other solution I could look into?
show variable is global and updating value for show will reflect for all the app-field components, Thus You need to determine and specify a show/hide variable for each component individually.
To do that you should add a show member inside the field Object as follow:
<ng-container *ngFor="let field of fields">
<button (click)="field.show = !field.show">Show</button>
<ng-container *ngIf="field.show">
<app-field [fieldInfo]="field"></app-field>
</ng-container>
</ng-container>
Also found similar solution, check this answer
I needed to only have the component be attached to the DOM when set to be visible. Solved it with the answer in: Thierry Templier answer here
Inside parent component:
public showField: any = {};
Then in parent component template:
<ng-container *ngFor="let field of fields">
<button (click)="showField[childField.id] = !showField[childField.id]">Show</button>
<ng-container *ngIf="showField[childField.id]">
<app-field [fieldInfo]="field"></app-field>
</ng-container>
</ng-container>
This destroys the component when *ngIf is false, which is what I needed in this situation.
Thanks to #yazan for leading me to the answer.
I have layout page as below. Layout is responsible for loading all routs in my project. When we use view1 that will load default condition. same way view2, view3 loads its own condition.
<ng-container [ngSwitch]="routeData?.layout">
<ng-container *ngSwitchCase="'view2'"> Some HTml and <router-outlet></router-outlet></ng-container>
<ng-container *ngSwitchCase="'view3'"> Some HTml and <router-outlet></router-outlet></ng-container>
<ng-container *ngSwitchDefault>Some HTml and <router-outlet></router-outlet></ng-container>
When i have been in the page which using the view1(default layout) and i am trying to navigate the other page which also using the view1. browser URL getting changed but Router-outlet not loading new page.
I have understood that when switch case is executing the same case which is not detecting any changes.
Could you please guys suggest any proper way to update switch case data or any good approach to resolve this issue.
The above issue i have solved using below approach.
<ng-template #temp>
<router-outlet></router-outlet>
</ng-template>
<ng-container [ngSwitch]="routeData?.layout">
<ng-container *ngSwitchCase="'view2'"> Some HTml and <ng-container *templateOutlet="temp"></ng-container></ng-container>
<ng-container *ngSwitchCase="'view3'"> Some HTml and <ng-container *templateOutlet="temp"></ng-container></ng-container>
<ng-container *ngSwitchDefault>Some HTml and <ng-container *templateOutlet="temp"></ng-container></ng-container>
I am using primeng TurboTable where for templates a pTemplate directive is added. And then accordingly DOM gets rendered I am trying to implement a very same approach in my project to create a reusable(DUMB) component. Tried searching for a solution but couldn't find a proper solution. Thought about using ng-container but when passing ng-template from Smart component to child component nothing is happening. PFB a sample of the solution I tried
Smart Component Template
<dumb-component>
<ng-template #content> Content is placed here .... </ng-template>
</dumb-component>
Dumb Component Template
<ng-container *ngTemplateOutlet="content">
</ng-container>
Link to primeng documentation : primeng docs
Since your component Dumb Component receives a template. It needs to access the template with #ContentChild
Dump Component
<ng-container *ngTemplateOutlet="content">
</ng-container>
#ContentChild(TemplateRef) content: TemplateRef<any>;
Example:https://stackblitz.com/edit/angular-ephusu
I have this html code
<empty-list [hidden]="!emptylist" text="There is currently No User"</empty-list>
<div *ngFor="let userObser of userObservables">
<ion-item #emptylist *ngIf="userObser | async as user">
<h2>{{user.displayName}}</h2>
<h3>{{user.email}}</h3>
</ion-item>
</div>
I want to show the empty list if there is no user & hide it if there is at least one.
I know I can do it using a subscribe method,but I want to use async pipe also I need to unsubscribe each time I use a subscribe which is really not efficient.
My question is there a way I could create a local variable inside the ion-item the ntest test if it exists outside & therefore use it in the hidden input ? It's just a suggestion I can't really seem to make it work.
You can use a simple else inside the ngIf to display another template if the condition doesn't match:
<ng-container *ngIf="userObservables.length > 0; else emptyList">
<ng-container *ngFor="let user of userObservables">
<ion-item *ngIf="user | async as user">…</ion-item>
</ng-container>
</ng-container>
<ng-template #emptyList>
<empty-list>…</empty-list>
</ng-template>
Note that I also replaced your seemingly unnecessary div with a ng-container to avoid unnecessary DOM nodes.
As a side note to your own suggestion: template references cannot be accessed from outside the template boundary. Structural directives like *ngIf and *ngFor create their own template, so this becomes a boundary. That's why
<h2>{{ ref.innerText }}</h2>
<ng-container>
<span #ref>Hello, World</span>
</ng-container>
will work, but
<h2>{{ ref.innerText }}</h2>
<ng-container *ngIf="true">
<span #ref>Hello, World</span>
</ng-container>
won't work.
I am trying to use ngIf within an ngFor but it's just breaking my code. Below is my code:
<ion-row *ngIf="{{i % 3}}===0" *ngFor="let category of categories; let i=index">
I need to check if the index mod 3 is equal to zero
You can overwrite your code like:
<ion-row *ngFor="let category of categories; let i=index">
<ng-container *ngIf="{{i % 3}}===0">
...
</ng-container>
</ion-row>
ng-container behaves the same as template but you can use common syntax like *ngIf and *ngFor
you can't put ngIf on the same component as ngFor
Angular disallows such construction
Using i before initializing it in ngFor will never work
If you *ngIf gets a false value the *ngFor would never be created in the first place - see point 1:-)