Angular2 ngSwitch only with <template>
I would like to use ngSwitch to conditionally render some content, but I want this content to be the only one that will be displayed in the DOM. I will illustrate an example.
This is what I have:
<div [ngSwitch]="thing.name"> <template ngSwitchWhen="foo"> <div>FOOOOOO</div> </template> <template ngSwitchWhen="bar"> <div>BARRRR</div> </template> <template ngSwitchWhen="cat"> <div>CAT</div> </template>¯ <template ngSwitchWhen="dog"> <div>DOG</div> </template> </div> I want to change the parent element from <div> to <template> , so only the innermost elements are actually inserted in the DOM. I suspect this is possible, because I know that you can do something like this with ngFor , that is:
<template ngFor [ngForOf]="things" let-thing="$implicit">
However, I was not able to figure out how I can get it to work with ngSwitch
Now it is supported from the moment of release. The following code can be applied to your example:
<div [ngSwitch]="thing.name"> <template [ngSwitchCase]="foo"> <div>FOOOOOO</div> </template> <template [ngSwitchCase]="bar"> <div>BARRRR</div> </template> <template [ngSwitchCase]="cat"> <div>CAT</div> </template>¯ <template [ngSwitchCase]="dog"> <div>DOG</div> </template> </div> See more for more information.
If you want to remove the attached tag, you can use ng-container instead of div. Then you need to provide everything you want in the switch enclosure (here below the "divs"). Thanks @Stephane Leger for the trick
<ng-container [ngSwitch]="thing.name"> <div [ngSwitchCase]="'foo'"> Inner content 1 </div> <div [ngSwitchCase]="'bar'"> Inner content 2 </div> <div [ngSwitchCase]="'cat'"> Inner content 3 </div>¯ <div [ngSwitchCase]="'dog'"> Inner content 4 </div> </ng-container> Starting with Angular 6 ng-template or template does not work, use ng-container
<div [ngSwitch]="'case 3'"> <ng-container *ngSwitchCase="'case 1'"> <li > Case 1</li> </ng-container> <ng-container *ngSwitchCase="'case 2'"> <li > Case 2</li> </ng-container> <ng-container *ngSwitchCase="'case 3'"> <li > Case 3</li> </ng-container> </div> This is not supported. See this question https://github.com/angular/angular/issues/3306
From this comment https://github.com/angular/angular/issues/3306#issuecomment-125368361
It works as intended. I know this is a little strange. But if we change he
<ul *ng-switch="value"> <li *ng-switch-when="'1'">is 1</li> <li *ng-switch-when="'2'">is 2</li> <li *ng-switch-default>is another value</li> </ul>What would he say that
<ul>should not be created untilng-switchdecides that it should be created. This means that nestedng-switch-whenwill never be created. Ifng-switchsomehow missed itself, it would remove the<ul>, which would change the user behavior. Thus, there is no easy way to create nesting.Think of
ng-switchas a container. He always is and thinks ofng-switch-whenas templates that may or may not. the container cannot be removed and therefore cannot have*
<div [ngSwitch] = "thing.name"> <p *ngSwitchCase="'red'">para Red</p> <div *ngSwitchCase="foo">FOOOOOO</div> <div *ngSwitchCase="bar">BARRRR</div> <div *ngSwitchCase="cat">CAT</div> <div *ngSwitchCase="dog">DOG</div> <p *ngSwitchDefault>universe..</p> </div> <ng-container [ngSwitch]="activeLayout"> <ng-container *ngSwitchCase="'layout1'" [ngTemplateOutlet]="template1"></ng-container> <ng-container *ngSwitchDefault [ngTemplateOutlet]="defaultTemplate"></ng-container> </ng-container> This is my solution when I need to switch another ng template. I hope this works for you.