|
14 | 14 |
|
15 | 15 | - [What are structural directives?](#definition)
|
16 | 16 | - [*NgIf* case study](#ngIf)
|
17 |
| - - [Group sibling elements with <ng-container>](#ng-container) |
18 | 17 | - [The asterisk (*) prefix](#asterisk)
|
19 | 18 | - [Inside *NgFor*](#ngFor)
|
20 | 19 | - [microsyntax](#microsyntax)
|
|
23 | 22 | - [Inside the *NgSwitch* directives](#ngSwitch)
|
24 | 23 | - [Prefer the (*) prefix](#prefer-asterisk)
|
25 | 24 | - [The <template> element](#template)
|
| 25 | + - [Group sibling elements with <ng-container>](#ng-container) |
26 | 26 | - [Write a structural directive](#unless)
|
27 | 27 |
|
28 | 28 | Try the <live-example></live-example>.
|
@@ -157,108 +157,6 @@ figure.image-display
|
157 | 157 | Before applying a structural directive, you might want to pause for a moment
|
158 | 158 | to consider the consequences of adding and removing elements and of creating and destroying components.
|
159 | 159 |
|
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 |
| - |
262 | 160 | a#asterisk
|
263 | 161 | .l-main-section
|
264 | 162 | :marked
|
@@ -477,7 +375,109 @@ figure.image-display
|
477 | 375 |
|
478 | 376 | :marked
|
479 | 377 | 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. |
481 | 481 |
|
482 | 482 | a#unless
|
483 | 483 | .l-main-section
|
|
0 commit comments