2018-07-06 13:49:35 -07:00

280 lines
7.4 KiB
HTML

<!-- #docplaster -->
<!-- #docregion -->
<h1>&lt;ng-container&gt;</h1>
<!-- #docregion ngif -->
<div *ngIf="hero">{{hero.name}}</div>
<!-- #enddocregion ngif -->
<hr>
<h3>&lt;ng-container&gt; and CSS</h3>
<p>Examples demonstrating issues with rigid CSS styles.</p>
<button (click)="hero = hero ? null : heroes[0]">Toggle hero</button>
<h4>#1 &lt;ng-container&gt; and &lt;p&gt;</h4>
<!-- #docregion ngif-ngcontainer -->
<p>
I turned the corner
<ng-container *ngIf="hero">
and saw {{hero.name}}. I waved
</ng-container>
and continued on my way.
</p>
<!-- #enddocregion ngif-ngcontainer -->
<!-- #docregion ngif-span -->
<p>
I turned the corner
<span *ngIf="hero">
and saw {{hero.name}}. I waved
</span>
and continued on my way.
</p>
<!-- #enddocregion ngif-span -->
<h4>#2 &lt;ng-container&gt; and &lt;p&gt;</h4>
<div *ngIf="hero">
<!-- #docregion ngif-ngcontainer-2 -->
<p>
{{hero.name}} is
<ng-container *ngFor="let trait of heroTraits; let first=first; let last=last">
<ng-container *ngIf="!first">,</ng-container>
<ng-container *ngIf="last">and</ng-container>
{{trait}}
</ng-container>.
</p>
<!-- #enddocregion ngif-ngcontainer-2 -->
<!-- #docregion ngif-span-2 -->
<p>
{{hero.name}} is
<span *ngFor="let trait of heroTraits; let first=first; let last=last">
<span *ngIf="!first">,</span>
<span *ngIf="last">and</span>
{{trait}}
</span>.
</p>
<!-- #enddocregion ngif-span-2 -->
<br>
<h4>#3 &lt;ng-container&gt; and &lt;p&gt;</h4>
<!-- #docregion ngif-span-3 -->
<p>
<label><input type="checkbox" [checked]="showId" (change)="showId=!showId">Show ID</label>
</p>
<!-- #enddocregion ngif-span-3 -->
<div>
The <code>hero.id</code> in the &lt;span&gt;
is caught by the <span>p-span</span> CSS:
<!-- #docregion ngif-span-3 -->
<p>
<span *ngIf="showId">
Id: ({{hero.id}})
</span>
Name: {{hero.name}}
</p>
<!-- #enddocregion ngif-span-3 -->
</div>
<div>
The <code>hero.id</code> in the &lt;ng-container&gt;
is unaffected by the <span>p-span</span> CSS:
<p>
<ng-container *ngIf="showId">
Id: ({{hero.id}})
</ng-container>
Name: {{hero.name}}
</p>
</div>
<div>
The <code>hero.id</code> in the &lt;ng-template *ngIf&gt; disappears:
<p>
<ng-template *ngIf="showId">
Id: ({{hero.id}})
</ng-template>
Name: {{hero.name}}
</p>
</div>
<div>
The <code>hero.id</code> in the &lt;ng-template [ngIf]&gt;
is unaffected by the <span>p-span</span> CSS:
<p>
<ng-template [ngIf]="showId">
Id: ({{hero.id}})
</ng-template>
Name: {{hero.name}}
</p>
</div>
</div>
<hr>
<h3>&lt;ng-container&gt; and layout-sensitive elements</h3>
<p>
Examples demonstrating issues with layout-sensitive elements
such as &lt;select&gt; and &lt;table&gt;.
</p>
<h4>#1 &lt;ng-container&gt; and &lt;options&gt;</h4>
<p><i>&lt;select&gt; with &lt;span&gt;</i></p>
<div>
Pick your favorite hero
(<label><input type="checkbox" checked (change)="showSad=!showSad">show sad</label>)
</div>
<!-- #docregion select-span -->
<select [(ngModel)]="hero">
<span *ngFor="let h of heroes">
<span *ngIf="showSad || h?.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h?.emotion}})</option>
</span>
</span>
</select>
<!-- #enddocregion select-span -->
<p><i>&lt;select&gt; with &lt;ng-container&gt;</i></p>
<div>
Pick your favorite hero
(<label><input type="checkbox" checked (change)="showSad=!showSad">show sad</label>)
</div>
<!-- #docregion select-ngcontainer -->
<select [(ngModel)]="hero">
<ng-container *ngFor="let h of heroes">
<ng-container *ngIf="showSad || h?.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h?.emotion}})</option>
</ng-container>
</ng-container>
</select>
<!-- #enddocregion select-ngcontainer -->
<br><br><br><br>
<h4>#2 &lt;ng-container&gt; and &lt;options&gt;</h4>
<p>
<label (change)="traitPicker.value=showDefaultTraits ? 'loyal' : heroTraits[0]">
<input type="checkbox"
[checked]="showDefaultTraits"
(change)="showDefaultTraits=!showDefaultTraits">Show default traits
</label>
</p>
<p>Options with &lt;ng-container&gt;</p>
<select #traitPicker>
<!-- #docregion select-ngcontainer-2 -->
<ng-container *ngIf="showDefaultTraits">
<!-- Default traits -->
<option value="loyal">LOYAL</option>
<option value="clean">CLEAN</option>
<option value="reverent">REVERENT</option>
</ng-container>
<option *ngFor="let trait of heroTraits" [value]="trait">
{{ trait | uppercase }}
</option>
<!-- #enddocregion select-ngcontainer-2 -->
</select>
<p>Options with &lt;span&gt;</p>
<!-- #docregion select-span-2 -->
<select>
<!-- Default traits are always excluded because intermediate <span> is illegal -->
<span *ngIf="showDefaultTraits">
<option value="loyal">LOYAL</option>
<option value="clean">CLEAN</option>
<option value="reverent">REVERENT</option>
</span>
<option *ngFor="let trait of heroTraits" [value]="trait">
{{ trait | uppercase }}
</option>
</select>
<!-- #enddocregion select-span-2 -->
<br>
<h4>&lt;ng-container&gt; and &lt;table&gt;</h4>
<p>
<label><input type="checkbox" checked (change)="attrDirs=!attrDirs">Attribute directives</label>
<label><input type="checkbox" checked (change)="strucDirs=!strucDirs">Structural directives</label>
<label><input type="checkbox" (change)="divNgIf=!divNgIf">div with *ngIf</label>
</p>
<table>
<tr>
<th width="20%">Directive</th>
<th width="10%">Type</th>
<th>Description</th>
</tr>
<tr *ngIf="attrDirs">
<td>NgClass</td><td>A</td><td>Add or remove multiple CSS classes.</td>
</tr>
<ng-container *ngIf="divNgIf">
<!-- #docregion ngif-div -->
<div *ngIf="strucDirs">
<tr>
<td>xxx</td><td>S</td><td>div with *ngIf formats crazy.</td>
</tr>
<tr>
<td>yyy</td><td>S</td><td>div with *ngIf formats crazy.</td>
</tr>
</div>
<!-- #enddocregion ngif-div -->
</ng-container>
<!-- #docregion ngif-ngcontainer-4 -->
<ng-container *ngIf="strucDirs">
<tr>
<td>NgFor</td><td>S</td><td>Repeat the template for each item in a list.</td>
</tr>
<tr>
<td>NgIf</td><td>S</td><td>Add or remove DOM elements.</td>
</tr>
</ng-container>
<!-- #enddocregion ngif-ngcontainer-4 -->
<ng-container *ngIf="attrDirs">
<tr>
<td>NgStyle</td><td>A</td><td>Add or remove multiple style attributes.</td>
</tr>
</ng-container>
<!-- #docregion ngif-tr -->
<tr *ngIf="strucDirs">
<td>NgSwitch</td><td>S</td><td>Include in DOM if case matches the switch value.</td>
</tr>
<!-- #enddocregion ngif-tr -->
</table>
<hr>
<h3>Do not confuse &lt;ng-container&gt; with &lt;ng-content&gt;</h3>
<p>&lt;ng-container&gt;Inside ng-container&lt;/ng-container&gt;</p>
<!-- #docregion ngcontainer-bare -->
<ng-container>Inside ng-container</ng-container>
<!-- #enddocregion ngcontainer-bare -->
<p>&lt;ng-content&gt;this is an Angular parse error&lt;/ng-content&gt;</p>
<!-- #docregion ngcontent-bad -->
<!-- <ng-content>this is an Angular parse error</ng-content> -->
<!-- #enddocregion ngcontent-bad -->
<div class="code">Template parse errors:<br>
&lt;ng-content&gt; element cannot have content.</div>
<p>Demo of &lt;/ng-content&gt;</p>
<!-- #docregion content-comp -->
<content-comp>
Projected content
</content-comp>
<!-- #enddocregion content-comp -->