1414
1515 - [What are structural directives?](#definition)
1616 - [*NgIf* case study](#ngIf)
17- - [Group sibling elements with <ng-container>](#ng-container)
1817 - [The asterisk (*) prefix](#asterisk)
1918 - [Inside *NgFor*](#ngFor)
2019 - [microsyntax](#microsyntax)
2322 - [Inside the *NgSwitch* directives](#ngSwitch)
2423 - [Prefer the (*) prefix](#prefer-asterisk)
2524 - [The <template> element](#template)
25+ - [Group sibling elements with <ng-container>](#ng-container)
2626 - [Write a structural directive](#unless)
2727
2828 Try the <live-example></live-example>.
@@ -157,108 +157,6 @@ figure.image-display
157157 Before applying a structural directive, you might want to pause for a moment
158158 to consider the consequences of adding and removing elements and of creating and destroying components.
159159
160- a#ngcontainer
161- a#ng-container
162- .l-main-section
163- :marked
164- ## Group sibling elements with <ng-container>
165-
166- There's often a _root_ element that can and should host the structural directive.
167- The list element (`<li>`) is a typical host element of an `NgFor` repeater.
168-
169- + makeExcerpt('src/app/app.component.html' , 'ngfor-li' , '' )
170-
171- :marked
172- When there isn't a host element, you can usually wrap the content in a native HTML container element,
173- such as a `<div>`, and attach the directive to that wrapper.
174-
175- + makeExcerpt('src/app/app.component.html' , 'ngif' , '' )
176-
177- :marked
178- Introducing another container element—typically a `<span>` or `<div>`—to
179- group the elements under a single _root_ is usually harmless.
180- _Usually_ ... but not _always_.
181-
182- The grouping element may break the template appearance because CSS styles
183- neither expect nor accommodate the new layout.
184- For example, suppose you have the following paragraph layout.
185-
186- + makeExcerpt('src/app/app.component.html' , 'ngif-span' , '' )
187-
188- :marked
189- You also have a CSS style rule that happens to apply to a `<span>` within a `<p>`aragraph.
190-
191- + makeExcerpt('src/app/app.component.css' , 'p-span' , '' )
192-
193- :marked
194- The constructed paragraph renders strangely.
195-
196- figure.image-display
197- img( src ='/resources/images/devguide/structural-directives/bad-paragraph.png' alt ="spanned paragraph with bad style" )
198-
199- :marked
200- The `p span` style, intended for use elsewhere, was inadvertently applied here.
201-
202- Another problem: some HTML elements require all immediate children to be of a specific type.
203- For example, the `<select>` element requires `<option>` children.
204- You can't wrap the _options_ in a conditional `<div>` or a `<span>`.
205-
206- When you try this,
207-
208- + makeExcerpt('src/app/app.component.html' , 'select-span' , '' )
209-
210- :marked
211- the drop down is empty.
212-
213- figure.image-display
214- img( src ='/resources/images/devguide/structural-directives/bad-select.png' alt ="spanned options don't work" )
215-
216- :marked
217- The browser won't display an `<option>` within a `<span>`.
218-
219- ### <ng-container> to the rescue
220-
221- The Angular `<ng-container>` is a grouping element that doesn't interfere with styles or layout
222- because Angular _doesn't put it in the DOM_.
223-
224- Here's the conditional paragraph again, this time using `<ng-container>`.
225-
226- + makeExcerpt('src/app/app.component.html' , 'ngif-ngcontainer' , '' )
227-
228- :marked
229- It renders properly.
230-
231- figure.image-display
232- img( src ='/resources/images/devguide/structural-directives/good-paragraph.png' alt ="ngcontainer paragraph with proper style" )
233-
234- :marked
235- Now conditionally exclude a _select_ `<option>` with `<ng-container>`.
236-
237- + makeExcerpt('src/app/app.component.html' , 'select-ngcontainer' , '' )
238-
239- :marked
240- The drop down works properly.
241-
242- figure.image-display
243- img( src ='/resources/images/devguide/structural-directives/select-ngcontainer-anim.gif' alt ="ngcontainer options work properly" )
244-
245- :marked
246- The `<ng-container>` is a syntax element recognized by the Angular parser.
247- It's not a directive, component, class, or interface.
248- It's more like the curly braces in a JavaScript `if`-block:
249-
250- code-example( language ="javascript" ) .
251- if (someCondition) {
252- statement1;
253- statement2;
254- statement3;
255- }
256-
257- :marked
258- Without those braces, JavaScript would only execute the first statement
259- when you intend to conditionally execute all of them as a single block.
260- The `<ng-container>` satisfies a similar need in Angular templates.
261-
262160a#asterisk
263161.l-main-section
264162:marked
@@ -273,7 +171,7 @@ a#asterisk
273171
274172:marked
275173 The asterisk is "syntactic sugar" for something a bit more complicated.
276- Internally, Angular " desugars" it in two stages.
174+ Internally, Angular desugars it in two stages.
277175 First, it translates the `*ngIf="..."` into a template _attribute_, `template="ngIf ..."`, like this.
278176
279177+ makeExcerpt('src/app/app.component.html' , 'ngif-template-attr' , '' )
@@ -299,7 +197,7 @@ figure.image-display
299197
300198 The [`NgFor`](#ngFor) and [`NgSwitch...`](#ngSwitch) directives follow the same pattern.
301199
302- a#ngfor
200+ a#ngFor
303201.l-main-section
304202:marked
305203 ## Inside _*ngFor_
@@ -400,7 +298,7 @@ a#one-per-element
400298 There's an easy solution for this use case: put the `*ngIf` on a container element that wraps the `*ngFor` element.
401299 One or both elements can be an [`ng-container`](#ngcontainer) so you don't have to introduce extra levels of HTML.
402300
403- a#ngswitch
301+ a#ngSwitch
404302.l-main-section
405303:marked
406304 ## Inside _NgSwitch_ directives
@@ -477,7 +375,109 @@ figure.image-display
477375
478376:marked
479377 A structural directive puts a `<template>` to work
480- as you'll see when you write your own structural directive.
378+ as you'll see when you [write your own structural directive](#unless).
379+
380+ a#ngcontainer
381+ a#ng-container
382+ .l-main-section
383+ :marked
384+ ## Group sibling elements with <ng-container>
385+
386+ There's often a _root_ element that can and should host the structural directive.
387+ The list element (`<li>`) is a typical host element of an `NgFor` repeater.
388+
389+ + makeExcerpt('src/app/app.component.html' , 'ngfor-li' , '' )
390+
391+ :marked
392+ When there isn't a host element, you can usually wrap the content in a native HTML container element,
393+ such as a `<div>`, and attach the directive to that wrapper.
394+
395+ + makeExcerpt('src/app/app.component.html' , 'ngif' , '' )
396+
397+ :marked
398+ Introducing another container element—typically a `<span>` or `<div>`—to
399+ group the elements under a single _root_ is usually harmless.
400+ _Usually_ ... but not _always_.
401+
402+ The grouping element may break the template appearance because CSS styles
403+ neither expect nor accommodate the new layout.
404+ For example, suppose you have the following paragraph layout.
405+
406+ + makeExcerpt('src/app/app.component.html' , 'ngif-span' , '' )
407+
408+ :marked
409+ You also have a CSS style rule that happens to apply to a `<span>` within a `<p>`aragraph.
410+
411+ + makeExcerpt('src/app/app.component.css' , 'p-span' , '' )
412+
413+ :marked
414+ The constructed paragraph renders strangely.
415+
416+ figure.image-display
417+ img( src ='/resources/images/devguide/structural-directives/bad-paragraph.png' alt ="spanned paragraph with bad style" )
418+
419+ :marked
420+ The `p span` style, intended for use elsewhere, was inadvertently applied here.
421+
422+ Another problem: some HTML elements require all immediate children to be of a specific type.
423+ For example, the `<select>` element requires `<option>` children.
424+ You can't wrap the _options_ in a conditional `<div>` or a `<span>`.
425+
426+ When you try this,
427+
428+ + makeExcerpt('src/app/app.component.html' , 'select-span' , '' )
429+
430+ :marked
431+ the drop down is empty.
432+
433+ figure.image-display
434+ img( src ='/resources/images/devguide/structural-directives/bad-select.png' alt ="spanned options don't work" )
435+
436+ :marked
437+ The browser won't display an `<option>` within a `<span>`.
438+
439+ ### <ng-container> to the rescue
440+
441+ The Angular `<ng-container>` is a grouping element that doesn't interfere with styles or layout
442+ because Angular _doesn't put it in the DOM_.
443+
444+ Here's the conditional paragraph again, this time using `<ng-container>`.
445+
446+ + makeExcerpt('src/app/app.component.html' , 'ngif-ngcontainer' , '' )
447+
448+ :marked
449+ It renders properly.
450+
451+ figure.image-display
452+ img( src ='/resources/images/devguide/structural-directives/good-paragraph.png' alt ="ngcontainer paragraph with proper style" )
453+
454+ :marked
455+ Now conditionally exclude a _select_ `<option>` with `<ng-container>`.
456+
457+ + makeExcerpt('src/app/app.component.html' , 'select-ngcontainer' , '' )
458+
459+ :marked
460+ The drop down works properly.
461+
462+ figure.image-display
463+ img( src ='/resources/images/devguide/structural-directives/select-ngcontainer-anim.gif' alt ="ngcontainer options work properly" )
464+
465+ :marked
466+ The `<ng-container>` is a syntax element recognized by the Angular parser.
467+ It's not a directive, component, class, or interface.
468+ It's more like the curly braces in a JavaScript `if`-block:
469+
470+ code-example( language ="javascript" ) .
471+ if (someCondition) {
472+ statement1;
473+ statement2;
474+ statement3;
475+ }
476+
477+ :marked
478+ Without those braces, JavaScript would only execute the first statement
479+ when you intend to conditionally execute all of them as a single block.
480+ The `<ng-container>` satisfies a similar need in Angular templates.
481481
482482a#unless
483483.l-main-section
@@ -583,6 +583,7 @@ a#summary
583583.l-main-section
584584:marked
585585 ## Summary
586+
586587 You can both try and download the source code for this guide in the <live-example></live-example>.
587588
588589 Here is the source from the `src/app/` folder.
@@ -611,7 +612,7 @@ a#summary
611612
612613 * that structural directives manipulate HTML layout.
613614 * to use [`<ng-container>`](#ngcontainer) as a grouping element when there is no suitable host element.
614- * that the Angular " desugars" [asterisk (*) syntax](#asterisk) into a `<template>`.
615+ * that the Angular desugars [asterisk (*) syntax](#asterisk) into a `<template>`.
615616 * how that works for the `NgIf`, `NgFor` and `NgSwitch` built-in directives.
616617 * about the [_microsyntax_](#microsyntax) that expands into a [`<template>`](#template).
617618 * to write a [custom structural directive](#unless), `UnlessDirective`.
0 commit comments