From ce0eb43f015e340b7729bb99830d93ba3199b05e Mon Sep 17 00:00:00 2001 From: Matthieu Riegler Date: Sat, 23 Mar 2024 23:30:54 -0700 Subject: [PATCH] docs: unescape html entities (#55016) adev supports regular characters in place of entity. Let's use them to make the ease the work for the editors. PR Close #55016 --- adev/src/content/best-practices/a11y.md | 12 +- .../src/content/best-practices/style-guide.md | 76 ++--- adev/src/content/best-practices/update.md | 2 +- .../ecosystem/service-workers/app-shell.md | 4 +- .../service-workers/communications.md | 2 +- .../ecosystem/service-workers/config.md | 16 +- .../ecosystem/service-workers/devops.md | 4 +- .../service-workers/getting-started.md | 4 +- .../service-workers/push-notifications.md | 2 +- adev/src/content/ecosystem/web-workers.md | 10 +- adev/src/content/guide/animations/overview.md | 4 +- .../guide/animations/route-animations.md | 2 +- .../animations/transition-and-triggers.md | 4 +- .../di/hierarchical-dependency-injection.md | 264 +++++++++--------- .../guide/di/lightweight-injection-tokens.md | 14 +- .../guide/directives/structural-directives.md | 2 +- adev/src/content/guide/elements.md | 28 +- adev/src/content/guide/forms/dynamic-forms.md | 2 +- .../content/guide/forms/form-validation.md | 10 +- adev/src/content/guide/forms/overview.md | 10 +- .../guide/forms/template-driven-forms.md | 6 +- .../content/guide/i18n/format-data-locale.md | 4 +- .../content/guide/i18n/manage-marked-text.md | 6 +- adev/src/content/guide/i18n/prepare.md | 20 +- .../content/guide/i18n/translation-files.md | 22 +- adev/src/content/guide/image-optimization.md | 28 +- adev/src/content/guide/ngmodules/api.md | 4 +- adev/src/content/guide/ngmodules/faq.md | 8 +- .../content/guide/ngmodules/lazy-loading.md | 14 +- .../content/guide/ngmodules/module-types.md | 2 +- .../content/guide/ngmodules/vs-jsmodule.md | 2 +- .../content/guide/pipes/change-detection.md | 2 +- .../guide/routing/common-router-tasks.md | 2 +- .../content/guide/routing/router-reference.md | 6 +- adev/src/content/guide/security.md | 8 +- .../guide/templates/attribute-binding.md | 2 +- adev/src/content/guide/templates/binding.md | 4 +- .../content/guide/templates/class-binding.md | 22 +- .../content/guide/templates/event-binding.md | 2 +- .../guide/templates/template-statements.md | 2 +- .../content/guide/testing/code-coverage.md | 2 +- .../guide/testing/components-scenarios.md | 16 +- .../src/content/guide/testing/utility-apis.md | 10 +- .../reference/configs/workspace-config.md | 12 +- adev/src/content/reference/errors/NG0300.md | 2 +- adev/src/content/reference/errors/NG0301.md | 4 +- adev/src/content/reference/errors/NG1001.md | 4 +- adev/src/content/reference/errors/NG2009.md | 4 +- adev/src/content/reference/errors/NG3003.md | 6 +- adev/src/content/reference/errors/NG8002.md | 2 +- adev/src/content/reference/errors/NG8003.md | 4 +- .../migrations/module-with-providers.md | 6 +- adev/src/content/reference/releases.md | 2 +- adev/src/content/reference/versions.md | 24 +- adev/src/content/tools/cli/aot-compiler.md | 76 ++--- .../content/tools/cli/aot-metadata-errors.md | 110 ++++---- adev/src/content/tools/cli/build.md | 16 +- adev/src/content/tools/cli/cli-builder.md | 14 +- adev/src/content/tools/cli/environments.md | 10 +- .../content/tools/cli/schematics-authoring.md | 16 +- .../tools/cli/schematics-for-libraries.md | 8 +- adev/src/content/tools/cli/schematics.md | 14 +- .../content/tools/cli/template-typecheck.md | 56 ++-- adev/src/content/tools/language-service.md | 8 +- .../tools/libraries/angular-package-format.md | 12 +- .../tools/libraries/creating-libraries.md | 6 +- .../tools/libraries/using-libraries.md | 6 +- .../first-app/steps/11-details-page/README.md | 2 +- .../first-app/steps/13-search/README.md | 6 +- 69 files changed, 548 insertions(+), 548 deletions(-) diff --git a/adev/src/content/best-practices/a11y.md b/adev/src/content/best-practices/a11y.md index 7ab27c7195084e..7d030c250c39b4 100644 --- a/adev/src/content/best-practices/a11y.md +++ b/adev/src/content/best-practices/a11y.md @@ -17,16 +17,16 @@ Use attribute binding template syntax to control the values of accessibility-rel When binding to ARIA attributes in Angular, you must use the `attr.` prefix. The ARIA specification depends specifically on HTML attributes rather than properties of DOM elements. -<!-- Use attr. when binding to an ARIA attribute --> -<button [attr.aria-label]="myActionLabel">…</button> + + Note: This syntax is only necessary for attribute *bindings*. Static ARIA attributes require no extra syntax. -<!-- Static ARIA attributes require no extra syntax --> -<button aria-label="Save document">…</button> + + HELPFUL: By convention, HTML attributes use lowercase names \(`tabindex`\), while properties use camelCase names \(`tabIndex`\). @@ -103,8 +103,8 @@ The following example shows how to find and focus the main content header in the -router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => { - const mainHeader = document.querySelector('#main-content-header') +router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => { + const mainHeader = document.querySelector('#main-content-header') if (mainHeader) { mainHeader.focus(); } diff --git a/adev/src/content/best-practices/style-guide.md b/adev/src/content/best-practices/style-guide.md index 736fe4e7a829cd..ce209b4df3e365 100644 --- a/adev/src/content/best-practices/style-guide.md +++ b/adev/src/content/best-practices/style-guide.md @@ -151,14 +151,14 @@ Consistent conventions make it easy to quickly identify and reference assets of | Symbol name | File name | |:--- |:--- | -| @Component({ … }) export class AppComponent { } | app.component.ts | -| @Component({ … }) export class HeroesComponent { } | heroes.component.ts | -| @Component({ … }) export class HeroListComponent { } | hero-list.component.ts | -| @Component({ … }) export class HeroDetailComponent { } | hero-detail.component.ts | -| @Directive({ … }) export class ValidationDirective { } | validation.directive.ts | -| @NgModule({ … }) export class AppModule | app.module.ts | -| @Pipe({ name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { } | init-caps.pipe.ts | -| @Injectable() export class UserProfileService { } | user-profile.service.ts | +| @Component({ … })
export class AppComponent { }
| app.component.ts | +| @Component({ … })
export class HeroesComponent { }
| heroes.component.ts | +| @Component({ … })
export class HeroListComponent { }
| hero-list.component.ts | +| @Component({ … })
export class HeroDetailComponent { }
| hero-detail.component.ts | +| @Directive({ … })
export class ValidationDirective { }
| validation.directive.ts | +| @NgModule({ … })
export class AppModule
| app.module.ts | +| @Pipe({ name: 'initCaps' })
export class InitCapsPipe implements PipeTransform { }
| init-caps.pipe.ts | +| @Injectable()
export class UserProfileService { }
| user-profile.service.ts | ### Service names @@ -186,9 +186,9 @@ Service names such as `Credit` are nouns and require a suffix and should be name | Symbol name | File name | |:--- |:--- | -| @Injectable() export class HeroDataService { } | hero-data.service.ts | -| @Injectable() export class CreditService { } | credit.service.ts | -| @Injectable() export class Logger { } | logger.service.ts | +| @Injectable()
export class HeroDataService { }
| hero-data.service.ts | +| @Injectable()
export class CreditService { }
| credit.service.ts | +| @Injectable()
export class Logger { }
| logger.service.ts | ### Bootstrapping @@ -293,8 +293,8 @@ Provides a consistent way to quickly identify and reference pipes. | Symbol name | File name | |:--- |:--- | -| @Pipe({ standalone: true, name: 'ellipsis' }) export class EllipsisPipe implements PipeTransform { } | ellipsis.pipe.ts | -| @Pipe({ standalone: true, name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { } | init-caps.pipe.ts | +| @Pipe({ standalone: true, name: 'ellipsis' })
export class EllipsisPipe implements PipeTransform { }
| ellipsis.pipe.ts | +| @Pipe({ standalone: true, name: 'initCaps' })
export class InitCapsPipe implements PipeTransform { }
| init-caps.pipe.ts | ### Unit test file names @@ -354,40 +354,40 @@ project root ├── src │ ├── app │ │ ├── core -│ │ │ └── exception.service.ts|spec.ts -│ │ │ └── user-profile.service.ts|spec.ts +│ │ │ └── exception.service.ts|spec.ts +│ │ │ └── user-profile.service.ts|spec.ts │ │ ├── heroes │ │ │ ├── hero -│ │ │ │ └── hero.component.ts|html|css|spec.ts +│ │ │ │ └── hero.component.ts|html|css|spec.ts │ │ │ ├── hero-list -│ │ │ │ └── hero-list.component.ts|html|css|spec.ts +│ │ │ │ └── hero-list.component.ts|html|css|spec.ts │ │ │ ├── shared -│ │ │ │ └── hero-button.component.ts|html|css|spec.ts +│ │ │ │ └── hero-button.component.ts|html|css|spec.ts │ │ │ │ └── hero.model.ts -│ │ │ │ └── hero.service.ts|spec.ts -│ │ │ └── heroes.component.ts|html|css|spec.ts +│ │ │ │ └── hero.service.ts|spec.ts +│ │ │ └── heroes.component.ts|html|css|spec.ts │ │ │ └── heroes.routes.ts │ │ ├── shared -│ │ │ └── init-caps.pipe.ts|spec.ts -│ │ │ └── filter-text.component.ts|spec.ts -│ │ │ └── filter-text.service.ts|spec.ts +│ │ │ └── init-caps.pipe.ts|spec.ts +│ │ │ └── filter-text.component.ts|spec.ts +│ │ │ └── filter-text.service.ts|spec.ts │ │ ├── villains │ │ │ ├── villain -│ │ │ │ └── … +│ │ │ │ └── … │ │ │ ├── villain-list -│ │ │ │ └── … +│ │ │ │ └── … │ │ │ ├── shared -│ │ │ │ └── … -│ │ │ └── villains.component.ts|html|css|spec.ts +│ │ │ │ └── … +│ │ │ └── villains.component.ts|html|css|spec.ts │ │ │ └── villains.module.ts │ │ │ └── villains-routing.module.ts -│ │ └── app.component.ts|html|css|spec.ts +│ │ └── app.component.ts|html|css|spec.ts │ │ └── app.routes.ts │ └── main.ts │ └── index.html -│ └── … -└── node_modules/… -└── … +│ └── … +└── node_modules/… +└── … ``` HELPFUL: While components in dedicated folders are widely preferred, another option for small applications is to keep components flat \(not in a dedicated folder\). @@ -506,15 +506,15 @@ project root ├──├──app ├──├──├── shared ├──├──├──└── shared.module.ts -├──├──├──└── init-caps.pipe.ts|spec.ts -├──├──├──└── filter-text.component.ts|spec.ts -├──├──├──└── filter-text.service.ts|spec.ts -├──├──└── app.component.ts|html|css|spec.ts +├──├──├──└── init-caps.pipe.ts|spec.ts +├──├──├──└── filter-text.component.ts|spec.ts +├──├──├──└── filter-text.service.ts|spec.ts +├──├──└── app.component.ts|html|css|spec.ts ├──├──└── app.module.ts ├──├──└── app-routing.module.ts ├──└── main.ts ├──└── index.html -└── … +└── … ``` @@ -761,7 +761,7 @@ An element may have more than one attribute directive applied. **Do** be consistent in your choice. **Why**?
-The property associated with `@HostBinding` or the method associated with `@HostListener` can be modified only in a single place —in the directive's class. +The property associated with `@HostBinding` or the method associated with `@HostListener` can be modified only in a single place —in the directive's class. If you use the `host` metadata property, you must modify both the property/method declaration in the directive's class and the metadata in the decorator associated with the directive. @@ -811,7 +811,7 @@ In this scenario it would be better to provide the service at the component leve -### Use the @Injectable() class decorator +### Use the @Injectable() class decorator #### Style 07-04 diff --git a/adev/src/content/best-practices/update.md b/adev/src/content/best-practices/update.md index ea9f460472348d..55db2f1fee6edf 100644 --- a/adev/src/content/best-practices/update.md +++ b/adev/src/content/best-practices/update.md @@ -6,7 +6,7 @@ Keeping your Angular application up-to-date enables you to take advantage of lea This document contains information and resources to help you keep your Angular applications and libraries up-to-date. -For information about our versioning policy and practices —including support and deprecation practices, as well as the release schedule— see [Angular versioning and releases](reference/releases "Angular versioning and releases"). +For information about our versioning policy and practices —including support and deprecation practices, as well as the release schedule— see [Angular versioning and releases](reference/releases "Angular versioning and releases"). HELPFUL: If you are currently using AngularJS, see [Upgrading from AngularJS](https://angular.io/guide/upgrade "Upgrading from Angular JS"). *AngularJS* is the name for all v1.x versions of Angular. diff --git a/adev/src/content/ecosystem/service-workers/app-shell.md b/adev/src/content/ecosystem/service-workers/app-shell.md index f96ad0a6cc4952..20c23843cd157c 100644 --- a/adev/src/content/ecosystem/service-workers/app-shell.md +++ b/adev/src/content/ecosystem/service-workers/app-shell.md @@ -33,7 +33,7 @@ After running this command you can see that the `angular.json` configuration fil "server": { - "builder": "@angular-devkit/build-angular:server", + "builder": "@angular-devkit/build-angular:server", "defaultConfiguration": "production", "options": { "outputPath": "dist/my-app/server", @@ -58,7 +58,7 @@ After running this command you can see that the `angular.json` configuration fil } }, "app-shell": { - "builder": "@angular-devkit/build-angular:app-shell", + "builder": "@angular-devkit/build-angular:app-shell", "defaultConfiguration": "production", "options": { "route": "shell" diff --git a/adev/src/content/ecosystem/service-workers/communications.md b/adev/src/content/ecosystem/service-workers/communications.md index a0e265a344139c..ea08f24a932d36 100644 --- a/adev/src/content/ecosystem/service-workers/communications.md +++ b/adev/src/content/ecosystem/service-workers/communications.md @@ -28,7 +28,7 @@ The `versionUpdates` is an `Observable` property of `SwUpdate` and emits four ev ### Checking for updates It's possible to ask the service worker to check if any updates have been deployed to the server. -The service worker checks for updates during initialization and on each navigation request —that is, when the user navigates from a different address to your application. +The service worker checks for updates during initialization and on each navigation request —that is, when the user navigates from a different address to your application. However, you might choose to manually check for updates if you have a site that changes frequently or want updates to happen on a schedule. Do this with the `checkForUpdate()` method: diff --git a/adev/src/content/ecosystem/service-workers/config.md b/adev/src/content/ecosystem/service-workers/config.md index a18333b402700a..bc650f4a7b08f5 100644 --- a/adev/src/content/ecosystem/service-workers/config.md +++ b/adev/src/content/ecosystem/service-workers/config.md @@ -7,7 +7,7 @@ This topic describes the properties of the service worker configuration file. The `ngsw-config.json` JSON configuration file specifies which files and data URLs the Angular service worker should cache and how it should update the cached files and data. The [Angular CLI](tools/cli) processes this configuration file during `ng build`. -All file paths must begin with `/`, which corresponds to the deployment directory — usually `dist/` in CLI projects. +All file paths must begin with `/`, which corresponds to the deployment directory — usually `dist/` in CLI projects. Unless otherwise commented, patterns use a **limited*** glob format that internally will be converted into regex: @@ -68,10 +68,10 @@ This field contains an array of asset groups, each of which defines a set of ass { "assetGroups": [ { - … + … }, { - … + … } ] } @@ -169,10 +169,10 @@ This field contains an array of data groups, each of which defines a set of data { "dataGroups": [ { - … + … }, { - … + … } ] } @@ -197,7 +197,7 @@ export interface DataGroup { maxSize: number; maxAge: string; timeout?: string; - strategy?: 'freshness' | 'performance'; + strategy?: 'freshness' | 'performance'; }; cacheQueryOptions?: { ignoreSearch?: boolean; @@ -226,7 +226,7 @@ Only non-mutating requests (GET and HEAD) are cached. Occasionally APIs change formats in a way that is not backward-compatible. A new version of the application might not be compatible with the old API format and thus might not be compatible with existing cached resources from that API. -`version` provides a mechanism to indicate that the resources being cached have been updated in a backwards-incompatible way, and that the old cache entries —those from previous versions— should be discarded. +`version` provides a mechanism to indicate that the resources being cached have been updated in a backwards-incompatible way, and that the old cache entries —those from previous versions— should be discarded. `version` is an integer field and defaults to `1`. @@ -306,7 +306,7 @@ In case you are not familiar, an [opaque response][https://fetch.spec.whatwg.org One of the characteristics of an opaque response is that the service worker is not allowed to read its status, meaning it can't check if the request was successful or not. See [Introduction to fetch()][https://developers.google.com/web/updates/2015/03/introduction-to-fetch#response_types] for more details. -If you are not able to implement CORS — for example, if you don't control the origin — prefer using the `freshness` strategy for resources that result in opaque responses. +If you are not able to implement CORS — for example, if you don't control the origin — prefer using the `freshness` strategy for resources that result in opaque responses. diff --git a/adev/src/content/ecosystem/service-workers/devops.md b/adev/src/content/ecosystem/service-workers/devops.md index d42d12449c7e24..4bde02234d7391 100644 --- a/adev/src/content/ecosystem/service-workers/devops.md +++ b/adev/src/content/ecosystem/service-workers/devops.md @@ -155,7 +155,7 @@ Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100 Last update tick: 1s496u Last update run: never Task queue: - * init post-load (update, cleanup) + * init post-load (update, cleanup) Debug log: @@ -232,7 +232,7 @@ HELPFUL: This version hash is the "latest manifest hash" listed above. Both clie Last update tick: 1s496u Last update run: never Task queue: - * init post-load (update, cleanup) + * init post-load (update, cleanup) diff --git a/adev/src/content/ecosystem/service-workers/getting-started.md b/adev/src/content/ecosystem/service-workers/getting-started.md index 73a4843603b5de..bd83949286775f 100644 --- a/adev/src/content/ecosystem/service-workers/getting-started.md +++ b/adev/src/content/ecosystem/service-workers/getting-started.md @@ -54,7 +54,7 @@ To simulate a network issue, disable network interaction for your application. In Chrome: -1. Select **Tools** > **Developer Tools** (from the Chrome menu located in the top right corner). +1. Select **Tools** > **Developer Tools** (from the Chrome menu located in the top right corner). 1. Go to the **Network tab**. 1. Select **Offline** in the **Throttling** dropdown menu. @@ -110,7 +110,7 @@ Make a change to the application, and watch the service worker install the updat ng build - npx http-server -p 8080 -c-1 dist/<project-name>/browser + npx http-server -p 8080 -c-1 dist//browser diff --git a/adev/src/content/ecosystem/service-workers/push-notifications.md b/adev/src/content/ecosystem/service-workers/push-notifications.md index d217e8aed18dc7..116d18c0784cb9 100644 --- a/adev/src/content/ecosystem/service-workers/push-notifications.md +++ b/adev/src/content/ecosystem/service-workers/push-notifications.md @@ -14,7 +14,7 @@ Invoke push notifications by pushing a message with a valid payload. See `SwPush` for guidance. HELPFUL: In Chrome, you can test push notifications without a backend. -Open Devtools -> Application -> Service Workers and use the `Push` input to send a JSON notification payload. +Open Devtools -> Application -> Service Workers and use the `Push` input to send a JSON notification payload. ## Notification click handling diff --git a/adev/src/content/ecosystem/web-workers.md b/adev/src/content/ecosystem/web-workers.md index cf90ad810bb56a..c832564b4e1978 100644 --- a/adev/src/content/ecosystem/web-workers.md +++ b/adev/src/content/ecosystem/web-workers.md @@ -11,7 +11,7 @@ To add a web worker to an existing project, use the Angular CLI `ng generate` co -ng generate web-worker <location> +ng generate web-worker @@ -31,8 +31,8 @@ The command performs the following actions. - addEventListener('message', ({ data }) => { - const response = `worker response to ${data}`; + addEventListener('message', ({ data }) => { + const response = `worker response to ${data}`; postMessage(response); }); @@ -45,8 +45,8 @@ The command performs the following actions. if (typeof Worker !== 'undefined') { // Create a new const worker = new Worker(new URL('./app.worker', import.meta.url)); - worker.onmessage = ({ data }) => { - console.log(`page got message: ${data}`); + worker.onmessage = ({ data }) => { + console.log(`page got message: ${data}`); }; worker.postMessage('hello'); } else { diff --git a/adev/src/content/guide/animations/overview.md b/adev/src/content/guide/animations/overview.md index c0476066a13349..70cc93af0f2a34 100644 --- a/adev/src/content/guide/animations/overview.md +++ b/adev/src/content/guide/animations/overview.md @@ -196,7 +196,7 @@ HELPFUL: Some additional notes on using styles within [`state`](api/animations/s - transition( 'on => off, off => void' ) + transition( 'on => off, off => void' ) @@ -227,7 +227,7 @@ Then, you can bind the trigger to a template expression using standard Angular p -<div [@triggerName]="expression">…</div>; +
;
diff --git a/adev/src/content/guide/animations/route-animations.md b/adev/src/content/guide/animations/route-animations.md index 5e7abb374632d3..60361898c76549 100644 --- a/adev/src/content/guide/animations/route-animations.md +++ b/adev/src/content/guide/animations/route-animations.md @@ -113,7 +113,7 @@ Adding these styles to the views animates the containers in place and prevents o Use the `query()` method to find and animate elements within the current host component. The `query(":enter")` statement returns the view that is being inserted, and `query(":leave")` returns the view that is being removed. -Assume that you are routing from the *Home => About*. +Assume that you are routing from the *Home => About*. diff --git a/adev/src/content/guide/animations/transition-and-triggers.md b/adev/src/content/guide/animations/transition-and-triggers.md index 711cff9f8f83e3..e150410e360ba1 100644 --- a/adev/src/content/guide/animations/transition-and-triggers.md +++ b/adev/src/content/guide/animations/transition-and-triggers.md @@ -85,8 +85,8 @@ These aliases are used by several animation functions. -transition ( ':enter', [ … ] ); // alias for void => * -transition ( ':leave', [ … ] ); // alias for * => void +transition ( ':enter', [ … ] ); // alias for void => * +transition ( ':leave', [ … ] ); // alias for * => void diff --git a/adev/src/content/guide/di/hierarchical-dependency-injection.md b/adev/src/content/guide/di/hierarchical-dependency-injection.md index 6d46da3106812e..e8cd1eafcfccdd 100644 --- a/adev/src/content/guide/di/hierarchical-dependency-injection.md +++ b/adev/src/content/guide/di/hierarchical-dependency-injection.md @@ -30,7 +30,7 @@ The `EnvironmentInjector` can be configured in one of two ways by using: * The `@Injectable()` `providedIn` property to refer to `root` or `platform` * The `ApplicationConfig` `providers` array - + Using the `@Injectable()` `providedIn` property is preferable to using the `ApplicationConfig` `providers` array. With `@Injectable()` `providedIn`, optimization tools can perform tree-shaking, which removes services that your application isn't using. This results in smaller bundle sizes. @@ -46,7 +46,7 @@ Provide services using `providedIn` of `@Injectable()` as follows: import { Injectable } from '@angular/core'; @Injectable({ - providedIn: 'root' // <--provides this service in the root EnvironmentInjector + providedIn: 'root' // <--provides this service in the root EnvironmentInjector }) export class ItemService { name = 'telephone'; @@ -134,7 +134,7 @@ For example, the following `TestComponent` configures the `ElementInjector` by p @Component({ - … + … providers: [{ provide: ItemService, useValue: { name: 'lamp' } }] }) export class TestComponent @@ -335,7 +335,7 @@ The following is an example of how the `` and `` view trees <#VIEW> <#VIEW> - …content goes here… + …content goes here… <#VIEW> @@ -387,24 +387,24 @@ The most basic rendered view would look like nested HTML elements such as the fo -<app-root> <!-- AppComponent selector --> - <app-child> <!-- ChildComponent selector --> - </app-child> -</app-root> + + + + However, behind the scenes, Angular uses a logical view representation as follows when resolving injection requests: -<app-root> <!-- AppComponent selector --> - <#VIEW> - <app-child> <!-- ChildComponent selector --> - <#VIEW> - </#VIEW> - </app-child> - </#VIEW> -</app-root> + + <#VIEW> + + <#VIEW> + + + + The `<#VIEW>` here represents an instance of a template. @@ -435,16 +435,16 @@ Emoji from FlowerService: 🌺 In the logical tree, this would be represented as follows: -<app-root @ApplicationConfig - @Inject(FlowerService) flower=>"🌺"> - <#VIEW> - <p>Emoji from FlowerService: {{flower.emoji}} (🌺)</p> - <app-child> - <#VIEW> - </#VIEW> - </app-child> - </#VIEW> -</app-root> +"🌺"> + <#VIEW> +

Emoji from FlowerService: {{flower.emoji}} (🌺)

+ + <#VIEW> + + + +
@@ -507,19 +507,19 @@ In the logical tree, this is represented as follows: -<app-root @ApplicationConfig - @Inject(FlowerService) flower=>"🌺"> - <#VIEW> - <p>Emoji from FlowerService: {{flower.emoji}} (🌺)</p> - <app-child @Provide(FlowerService="🌻") - @Inject(FlowerService)=>"🌻"> <!-- search ends here --> - <#VIEW> <!-- search starts here --> - <h2>Child Component</h2> - <p>Emoji from FlowerService: {{flower.emoji}} (🌻)</p> - </#VIEW> - </app-child> - </#VIEW> -</app-root> +"🌺"> + <#VIEW> +

Emoji from FlowerService: {{flower.emoji}} (🌺)

+ "🌻"> + <#VIEW> +

Child Component

+

Emoji from FlowerService: {{flower.emoji}} (🌻)

+ +
+ +
@@ -613,18 +613,18 @@ The logic tree for this example of `viewProviders` is as follows: -<app-root @ApplicationConfig - @Inject(AnimalService) animal=>"🐳"> - <#VIEW> - <app-child> - <#VIEW @Provide(AnimalService="🐶") - @Inject(AnimalService=>"🐶")> - <!-- ^^using viewProviders means AnimalService is available in <#VIEW>--> - <p>Emoji from AnimalService: {{animal.emoji}} (🐶)</p> - </#VIEW> - </app-child> - </#VIEW> -</app-root> +"🐳"> + <#VIEW> + + <#VIEW @Provide(AnimalService="🐶") + @Inject(AnimalService=>"🐶")> + +

Emoji from AnimalService: {{animal.emoji}} (🐶)

+ +
+ +
@@ -715,31 +715,31 @@ The `AnimalService` in the logical tree would look like this: -<app-root @ApplicationConfig - @Inject(AnimalService) animal=>"🐳"> - <#VIEW> - <app-child> - <#VIEW @Provide(AnimalService="🐶") - @Inject(AnimalService=>"🐶")> - <!-- ^^using viewProviders means AnimalService is available in <#VIEW>--> - <p>Emoji from AnimalService: {{animal.emoji}} (🐶)</p> - - <div class="container"> - <h3>Content projection</h3> - <app-inspector @Inject(AnimalService) animal=>"🐳"> - <p>Emoji from AnimalService: {{animal.emoji}} (🐳)</p> - </app-inspector> - </div> - - <app-inspector> - <#VIEW @Inject(AnimalService) animal=>"🐶"> - <p>Emoji from AnimalService: {{animal.emoji}} (🐶)</p> - </#VIEW> - </app-inspector> - </#VIEW> - </app-child> - </#VIEW> -</app-root> +"🐳"> + <#VIEW> + + <#VIEW @Provide(AnimalService="🐶") + @Inject(AnimalService=>"🐶")> + +

Emoji from AnimalService: {{animal.emoji}} (🐶)

+ +
+

Content projection

+ "🐳"> +

Emoji from AnimalService: {{animal.emoji}} (🐳)

+
+
+ + + <#VIEW @Inject(AnimalService) animal=>"🐶"> +

Emoji from AnimalService: {{animal.emoji}} (🐶)

+ +
+ +
+ +
@@ -773,16 +773,16 @@ In a logical tree, this same idea might look like this: -<app-root @ApplicationConfig - @Inject(FlowerService) flower=>"🌺"> - <#VIEW> - <app-child @Provide(FlowerService="🌻")> - <#VIEW @Inject(FlowerService, SkipSelf)=>"🌺"> - <!-- With SkipSelf, the injector looks to the next injector up the tree (app-root) --> - </#VIEW> - </app-child> - </#VIEW> -</app-root> +"🌺"> + <#VIEW> + + <#VIEW @Inject(FlowerService, SkipSelf)=>"🌺"> + + + + + @@ -794,15 +794,15 @@ Here's the idea in the logical tree: -<app-root @ApplicationConfig - @Inject(FlowerService) flower=>"🌺"> - <#VIEW> <!-- end search here with null--> - <app-child @Provide(FlowerService="🌻")> <!-- start search here --> - <#VIEW @Inject(FlowerService, @SkipSelf, @Host, @Optional)=>null> - </#VIEW> - </app-parent> - </#VIEW> -</app-root> +"🌺"> + <#VIEW> + + <#VIEW @Inject(FlowerService, @SkipSelf, @Host, @Optional)=>null> + + + + @@ -820,7 +820,7 @@ Instead, the injector will begin at the `` `ElementInjector`. @Component({ standalone: true, selector: 'app-child', - … + … viewProviders: [ { provide: AnimalService, useValue: { emoji: '🐶' } }, ], @@ -831,17 +831,17 @@ The logical tree looks like this with `@SkipSelf()` in ``: -<app-root @ApplicationConfig - @Inject(AnimalService=>"🐳")> - <#VIEW><!-- search begins here --> - <app-child> - <#VIEW @Provide(AnimalService="🐶") - @Inject(AnimalService, SkipSelf=>"🐳")> - <!--Add @SkipSelf --> - </#VIEW> - </app-child> - </#VIEW> -</app-root> +"🐳")> + <#VIEW> + + <#VIEW @Provide(AnimalService="🐶") + @Inject(AnimalService, SkipSelf=>"🐳")> + + + + + @@ -857,7 +857,7 @@ You can also see `@Host()` in the constructor: @Component({ standalone: true selector: 'app-child', - … + … viewProviders: [ { provide: AnimalService, useValue: { emoji: '🐶' } }, ] @@ -871,16 +871,16 @@ export class ChildComponent { -<app-root @ApplicationConfig - @Inject(AnimalService=>"🐳")> - <#VIEW> - <app-child> - <#VIEW @Provide(AnimalService="🐶") - @Inject(AnimalService, @Host=>"🐶")> <!-- @Host stops search here --> - </#VIEW> - </app-child> - </#VIEW> -</app-root> +"🐳")> + <#VIEW> + + <#VIEW @Provide(AnimalService="🐶") + @Inject(AnimalService, @Host=>"🐶")> + + + + @@ -915,7 +915,7 @@ export class ChildComponent { and how `@Host()` works. --> -When `@Host()` and `@SkipSelf()` were applied to the `FlowerService`, which is in the `providers` array, the result was `null` because `@SkipSelf()` starts its search in the `` injector, but `@Host()` stops searching at `<#VIEW>` —where there is no `FlowerService` +When `@Host()` and `@SkipSelf()` were applied to the `FlowerService`, which is in the `providers` array, the result was `null` because `@SkipSelf()` starts its search in the `` injector, but `@Host()` stops searching at `<#VIEW>` —where there is no `FlowerService` In the logical tree, you can see that the `FlowerService` is visible in ``, not its `<#VIEW>`. However, the `AnimalService`, which is provided in the `AppComponent` `viewProviders` array, is visible. @@ -924,19 +924,19 @@ The logical tree representation shows why this is: -<app-root @ApplicationConfig - @Inject(AnimalService=>"🐳")> - <#VIEW @Provide(AnimalService="🦔") - @Inject(AnimalService, @Optional)=>"🦔"> - <!-- ^^@SkipSelf() starts here, @Host() stops here^^ --> - <app-child> - <#VIEW @Provide(AnimalService="🐶") - @Inject(AnimalService, @SkipSelf, @Host, @Optional)=>"🦔"> - <!-- Add @SkipSelf ^^--> - </#VIEW> - </app-child> - </#VIEW> -</app-root> +"🐳")> + <#VIEW @Provide(AnimalService="🦔") + @Inject(AnimalService, @Optional)=>"🦔"> + + + <#VIEW @Provide(AnimalService="🐶") + @Inject(AnimalService, @SkipSelf, @Host, @Optional)=>"🦔"> + + + + + diff --git a/adev/src/content/guide/di/lightweight-injection-tokens.md b/adev/src/content/guide/di/lightweight-injection-tokens.md index 9ee8307ae3a07c..3d65e9abbc1ba9 100644 --- a/adev/src/content/guide/di/lightweight-injection-tokens.md +++ b/adev/src/content/guide/di/lightweight-injection-tokens.md @@ -25,7 +25,7 @@ This component contains a body and can contain an optional header. ; - ; + ; ; @@ -35,13 +35,13 @@ In a likely implementation, the `` component uses `@ContentChild()` or @Component({ selector: 'lib-header', - …, + …, }) class LibHeaderComponent {} @Component({ selector: 'lib-card', - …, + …, }) class LibCardComponent { @ContentChild(LibHeaderComponent) header: LibHeaderComponent|null = null; @@ -108,13 +108,13 @@ abstract class LibHeaderToken {} providers: [ {provide: LibHeaderToken, useExisting: LibHeaderComponent} ] - …, + …, }) class LibHeaderComponent extends LibHeaderToken {} @Component({ selector: 'lib-card', - …, + …, }) class LibCardComponent { @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null; @@ -156,7 +156,7 @@ abstract class LibHeaderToken { providers: [ {provide: LibHeaderToken, useExisting: LibHeaderComponent} ] - …, + …, }) class LibHeaderComponent extends LibHeaderToken { doSomething(): void { @@ -166,7 +166,7 @@ class LibHeaderComponent extends LibHeaderToken { @Component({ selector: 'lib-card', - …, + …, }) class LibCardComponent implement AfterContentInit { @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null; diff --git a/adev/src/content/guide/directives/structural-directives.md b/adev/src/content/guide/directives/structural-directives.md index 1d081afe553157..8a0bdf14d63d98 100644 --- a/adev/src/content/guide/directives/structural-directives.md +++ b/adev/src/content/guide/directives/structural-directives.md @@ -130,7 +130,7 @@ When you write your own structural directives, use the following syntax: -*:prefix="( :let | :expression ) (';' | ',')? ( :let | :as | :keyExp )*" +*:prefix="( :let | :expression ) (';' | ',')? ( :let | :as | :keyExp )*" diff --git a/adev/src/content/guide/elements.md b/adev/src/content/guide/elements.md index 8532222c5ebb4b..373dab820dbd87 100644 --- a/adev/src/content/guide/elements.md +++ b/adev/src/content/guide/elements.md @@ -31,7 +31,7 @@ After you register your configured class with the browser's custom-element regis -<my-popup message="Use Angular!"></my-popup> + @@ -73,7 +73,7 @@ For more information, see Web Component documentation for [Creating custom event Previously, when you wanted to add a component to an application at runtime, you had to define a _dynamic component_, and then you would have to load it, attach it to an element in the DOM, and wire up all of the dependencies, change detection, and event handling. -Using an Angular custom element makes the process simpler and more transparent, by providing all the infrastructure and framework automatically —all you have to do is define the kind of event handling you want. +Using an Angular custom element makes the process simpler and more transparent, by providing all the infrastructure and framework automatically —all you have to do is define the kind of event handling you want. \(You do still have to exclude the component from compilation, if you are not going to use it in your application.\) The following Popup Service example application defines a component that you can either load dynamically or convert to a custom element. @@ -111,9 +111,9 @@ Assume you create a `my-dialog` custom element based on the following component: -@Component(…) +@Component(…) class MyDialog { - @Input() content: string; + @Input() content: string; } @@ -123,10 +123,10 @@ For that, use the `NgElement` and `WithProperties` types \(both exported from `@ -const aDialog = document.createElement('my-dialog') as NgElement & WithProperties<{content: string}>; +const aDialog = document.createElement('my-dialog') as NgElement & WithProperties<{content: string}>; aDialog.content = 'Hello, world!'; -aDialog.content = 123; // <-- ERROR: TypeScript knows this should be a string. -aDialog.body = 'News'; // <-- ERROR: TypeScript knows there is no `body` property on `aDialog`. +aDialog.content = 123; // <-- ERROR: TypeScript knows this should be a string. +aDialog.body = 'News'; // <-- ERROR: TypeScript knows there is no `body` property on `aDialog`. @@ -139,9 +139,9 @@ An alternative way, that only requires defining each custom element's type once, declare global { interface HTMLElementTagNameMap { - 'my-dialog': NgElement & WithProperties<{content: string}>; - 'my-other-element': NgElement & WithProperties<{foo: 'bar'}>; - … + 'my-dialog': NgElement & WithProperties<{content: string}>; + 'my-other-element': NgElement & WithProperties<{foo: 'bar'}>; + … } } @@ -151,9 +151,9 @@ Now, TypeScript can infer the correct type the same way it does for built-in ele -document.createElement('div') //--> HTMLDivElement (built-in element) -document.querySelector('foo') //--> Element (unknown element) -document.createElement('my-dialog') //--> NgElement & WithProperties<{content: string}> (custom element) -document.querySelector('my-other-element') //--> NgElement & WithProperties<{foo: 'bar'}> (custom element) +document.createElement('div') //--> HTMLDivElement (built-in element) +document.querySelector('foo') //--> Element (unknown element) +document.createElement('my-dialog') //--> NgElement & WithProperties<{content: string}> (custom element) +document.querySelector('my-other-element') //--> NgElement & WithProperties<{foo: 'bar'}> (custom element) diff --git a/adev/src/content/guide/forms/dynamic-forms.md b/adev/src/content/guide/forms/dynamic-forms.md index 692a3836208fe0..60d0de0af3629d 100644 --- a/adev/src/content/guide/forms/dynamic-forms.md +++ b/adev/src/content/guide/forms/dynamic-forms.md @@ -42,7 +42,7 @@ The following code from the example shows the setup in the root module. ## Create a form object model A dynamic form requires an object model that can describe all scenarios needed by the form functionality. -The example hero-application form is a set of questions — that is, each control in the form must ask a question and accept an answer. +The example hero-application form is a set of questions — that is, each control in the form must ask a question and accept an answer. The data model for this type of form must represent a question. The example includes the `DynamicFormQuestionComponent`, which defines a question as the fundamental object in the model. diff --git a/adev/src/content/guide/forms/form-validation.md b/adev/src/content/guide/forms/form-validation.md index b7eb723b7fd3e9..f72fca26eb9a58 100644 --- a/adev/src/content/guide/forms/form-validation.md +++ b/adev/src/content/guide/forms/form-validation.md @@ -61,11 +61,11 @@ The same built-in validators that are available as attributes in template-driven For a full list of built-in validators, see the [Validators](api/forms/Validators) API reference. To update the actor form to be a reactive form, use some of the same -built-in validators —this time, in function form, as in the following example. +built-in validators —this time, in function form, as in the following example. -In this example, the `name` control sets up two built-in validators —`Validators.required` and `Validators.minLength(4)`— and one custom validator, `forbiddenNameValidator`. +In this example, the `name` control sets up two built-in validators —`Validators.required` and `Validators.minLength(4)`— and one custom validator, `forbiddenNameValidator`. All of these validators are synchronous, so they are passed as the second argument. Notice that you can support multiple validators by passing the functions in as an array. @@ -129,7 +129,7 @@ For example: HELPFUL: Notice that the custom validation directive is instantiated with `useExisting` rather than `useClass`. -The registered validator must be *this instance* of the `ForbiddenValidatorDirective` —the instance in the form with its `forbiddenName` property bound to "bob". +The registered validator must be *this instance* of the `ForbiddenValidatorDirective` —the instance in the form with its `forbiddenName` property bound to "bob". If you were to replace `useExisting` with `useClass`, then you'd be registering a new class instance, one that doesn't have a `forbiddenName`. @@ -253,8 +253,8 @@ The following example shows how to achieve this in a template-driven form. -<input [(ngModel)]="name" #model="ngModel" appSomeAsyncValidator> -<app-spinner *ngIf="model.pending"></app-spinner> + + diff --git a/adev/src/content/guide/forms/overview.md b/adev/src/content/guide/forms/overview.md index e53b36f1bc544d..60a3ea327d3d8b 100644 --- a/adev/src/content/guide/forms/overview.md +++ b/adev/src/content/guide/forms/overview.md @@ -110,7 +110,7 @@ The view-to-model diagram shows how data flows when an input field's value is ch ```mermaid flowchart TB U{User} - I("<input>") + I("") CVA(ControlValueAccessor) FC(FormControl) O(Observers) @@ -130,14 +130,14 @@ The model-to-view diagram shows how a programmatic change to the model is propag ```mermaid flowchart TB U{User} - I(<input>) + I() CVA(ControlValueAccessor) FC(FormControl) O(Observers) U-->|"Calls setValue() on the FormControl"|FC FC-->|Notifies the ControlValueAccessor|CVA FC-.->|Fires a 'valueChanges' event to observers|O - CVA-->|"Updates the value of the <input>"|I + CVA-->|"Updates the value of the "|I ``` ### Data flow in template-driven forms @@ -157,7 +157,7 @@ The view-to-model diagram shows how data flows when an input field's value is ch ```mermaid flowchart TB U{User} - I(<input>) + I() CVA(ControlValueAccessor) FC(FormControl) M(NgModel) @@ -207,7 +207,7 @@ flowchart TB FC2(FormControl) O(Observers) CVA(ControlValueAccessor) - I("<input>") + I("") FC2-.->|Fires a 'valueChanges' event to observers|O O-->|ControlValueAccessor receives valueChanges event|CVA CVA-->|Sets the value in the control|I diff --git a/adev/src/content/guide/forms/template-driven-forms.md b/adev/src/content/guide/forms/template-driven-forms.md index cbf0860be0bf75..bfa422cfde4038 100644 --- a/adev/src/content/guide/forms/template-driven-forms.md +++ b/adev/src/content/guide/forms/template-driven-forms.md @@ -10,7 +10,7 @@ Angular supports two design approaches for interactive forms. Template-driven fo Template-driven forms are a great choice for small or simple forms, while reactive forms are more scalable and suitable for complex forms. For a comparison of the two approaches, see [Choosing an approach](guide/forms#choosing-an-approach)
-You can build almost any kind of form with an Angular template —login forms, contact forms, and pretty much any business form. +You can build almost any kind of form with an Angular template —login forms, contact forms, and pretty much any business form. You can lay out the controls creatively and bind them to the data in your object model. You can specify validation rules and display validation errors, conditionally allow input from specific controls, trigger built-in visual feedback, and much more. @@ -339,11 +339,11 @@ You will bind the form property that indicates its overall validity to the **Sub -Notice that the button is enabled —although it doesn't do anything useful yet. +Notice that the button is enabled —although it doesn't do anything useful yet. -This violates the "required" rule, so it displays the error message —and notice that it also disables the **Submit** button. +This violates the "required" rule, so it displays the error message —and notice that it also disables the **Submit** button. You didn't have to explicitly wire the button's enabled state to the form's validity. The `FormsModule` did this automatically when you defined a template reference variable on the enhanced form element, then referred to that variable in the button control. diff --git a/adev/src/content/guide/i18n/format-data-locale.md b/adev/src/content/guide/i18n/format-data-locale.md index 140e977a95d9b4..74819de24b00b4 100644 --- a/adev/src/content/guide/i18n/format-data-locale.md +++ b/adev/src/content/guide/i18n/format-data-locale.md @@ -18,7 +18,7 @@ To display the current date in the format for the current locale, use the follow -{{ today | date }} +{{ today | date }} @@ -32,7 +32,7 @@ To force the currency to use American English \(`en-US`\), use the following for -{{ amount | currency : 'en-US' }} +{{ amount | currency : 'en-US' }} diff --git a/adev/src/content/guide/i18n/manage-marked-text.md b/adev/src/content/guide/i18n/manage-marked-text.md index 7de4e6dbae31f2..23e168ffea0f31 100644 --- a/adev/src/content/guide/i18n/manage-marked-text.md +++ b/adev/src/content/guide/i18n/manage-marked-text.md @@ -32,7 +32,7 @@ The following example defines the `introductionHeader` custom ID for a variable. -variableText1 = $localize `:@@introductionHeader:Hello i18n!`; +variableText1 = $localize `:@@introductionHeader:Hello i18n!`; @@ -58,7 +58,7 @@ The following example defines the `introductionHeader` custom ID and description -variableText2 = $localize `:An introduction header for this sample@@introductionHeader:Hello i18n!`; +variableText2 = $localize `:An introduction header for this sample@@introductionHeader:Hello i18n!`; @@ -72,7 +72,7 @@ The following example defines the `introductionHeader` custom ID for a variable. -variableText3 = $localize `:site header|An introduction header for this sample@@introductionHeader:Hello i18n!`; +variableText3 = $localize `:site header|An introduction header for this sample@@introductionHeader:Hello i18n!`; diff --git a/adev/src/content/guide/i18n/prepare.md b/adev/src/content/guide/i18n/prepare.md index 9597db3f1abef6..9bd1f225125910 100644 --- a/adev/src/content/guide/i18n/prepare.md +++ b/adev/src/content/guide/i18n/prepare.md @@ -11,7 +11,7 @@ To prepare your project for translation, complete the following actions. In a component template, the i18n metadata is the value of the `i18n` attribute. -<element i18n="{i18n_metadata}">{string_to_translate}</element> +{string_to_translate} Use the `i18n` attribute to mark a static text message in your component templates for translation. @@ -44,7 +44,7 @@ The following example shows the `` element transformed into a non- In a component template, the i18n metadata is the value of the `i18n-{attribute_name}` attribute. -<element i18n-{attribute_name}="{i18n_metadata}" {attribute_name}="{attribute_value}" /> + The attributes of HTML elements include text that should be translated along with the rest of the displayed text in the component template. @@ -55,7 +55,7 @@ Use the following syntax to assign a meaning, description, and custom ID. -i18n-{attribute_name}="{meaning}|{description}@@{id}" +i18n-{attribute_name}="{meaning}|{description}@@{id}" ### `i18n-title` example @@ -82,7 +82,7 @@ Use the [`$localize`][ApiLocalizeInitLocalize] tagged message string to mark a s -$localize `string_to_translate`; +$localize `string_to_translate`; The i18n metadata is surrounded by colon \(`:`\) characters and prepends the translation source text. @@ -90,7 +90,7 @@ The i18n metadata is surrounded by colon \(`:`\) characters and prepends the tra -$localize `:{i18n_metadata}:string_to_translate` +$localize `:{i18n_metadata}:string_to_translate` ### Include interpolated text @@ -100,13 +100,13 @@ Include [interpolations](guide/templates/interpolation) in a [`$localize`][ApiLo -$localize `string_to_translate ${variable_name}`; +$localize `string_to_translate ${variable_name}`; ### Name the interpolation placeholder -$localize `string_to_translate ${variable_name}:placeholder_name:`; +$localize `string_to_translate ${variable_name}:placeholder_name:`; ## i18n metadata for translation @@ -114,7 +114,7 @@ Include [interpolations](guide/templates/interpolation) in a [`$localize`][ApiLo -{meaning}|{description}@@{custom_id} +{meaning}|{description}@@{custom_id} The following parameters provide context and additional information to reduce confusion for your translator. @@ -143,7 +143,7 @@ The following example shows the value of the [`$localize`][ApiLocalizeInitLocali -$localize `:An introduction header for this sample:Hello i18n!`; +$localize `:An introduction header for this sample:Hello i18n!`; @@ -166,7 +166,7 @@ The following code example shows the value of the [`$localize`][ApiLocalizeInitL -$localize `:site header|An introduction header for this sample:Hello i18n!`; +$localize `:site header|An introduction header for this sample:Hello i18n!`; diff --git a/adev/src/content/guide/i18n/translation-files.md b/adev/src/content/guide/i18n/translation-files.md index 311b5d801fa962..6ee0a2559a700f 100644 --- a/adev/src/content/guide/i18n/translation-files.md +++ b/adev/src/content/guide/i18n/translation-files.md @@ -88,7 +88,7 @@ To create a translation file for a locale or language, complete the following ac - messages.xlf --> messages.{locale}.xlf + messages.xlf --> messages.{locale}.xlf @@ -132,20 +132,20 @@ The following actions describe the translation process for French. 1. Open `messages.fr.xlf` and find the first `` element. This is a *translation unit*, also known as a *text node*, that represents the translation of the `

` greeting tag that was previously marked with the `i18n` attribute. - + The `id="introductionHeader"` is a [custom ID][GuideI18nOptionalManageMarkedText], but without the `@@` prefix required in the source HTML. 1. Duplicate the `... ` element in the text node, rename it to `target`, and then replace the content with the French text. - + In a more complex translation, the information and context in the [description and meaning elements][GuideI18nCommonPrepareAddHelpfulDescriptionsAndMeanings] help you choose the right words for translation. 1. Translate the other text nodes. The following example displays the way to translate. - + IMPORTANT: Don't change the IDs for translation units. Each `id` attribute is generated by Angular and depends on the content of the component text and the assigned meaning. @@ -169,7 +169,7 @@ To translate a `plural`, translate the ICU format match values. The following example displays the way to translate. - + ## Translate alternate expressions @@ -184,18 +184,18 @@ The following example displays a `select` ICU expression in the component templa In this example, Angular extracts the expression into two translation units. The first contains the text outside of the `select` clause, and uses a placeholder for `select` \(``\): - + IMPORTANT: When you translate the text, move the placeholder if necessary, but don't remove it. If you remove the placeholder, the ICU expression is removed from your translated application. The following example displays the second translation unit that contains the `select` clause. - + The following example displays both translation units after translation is complete. - + ## Translate nested expressions @@ -206,15 +206,15 @@ Angular extracts the expression into two translation units. The following example displays the first translation unit that contains the text outside of the nested expression. - + The following example displays the second translation unit that contains the complete nested expression. - + The following example displays both translation units after translating. - + ## What's next diff --git a/adev/src/content/guide/image-optimization.md b/adev/src/content/guide/image-optimization.md index 902cf7e84cfc13..3dcad1b169be19 100644 --- a/adev/src/content/guide/image-optimization.md +++ b/adev/src/content/guide/image-optimization.md @@ -52,7 +52,7 @@ To activate the `NgOptimizedImage` directive, replace your image's `src` attribu -<img ngSrc="cat.jpg"> + @@ -63,7 +63,7 @@ Always mark the [LCP image](https://web.dev/lcp/#what-elements-are-considered) o -<img ngSrc="cat.jpg" width="400" height="200" priority> + @@ -80,7 +80,7 @@ In order to prevent [image-related layout shifts](https://web.dev/css-web-vitals -<img ngSrc="cat.jpg" width="400" height="200"> + @@ -100,7 +100,7 @@ When you add the `fill` attribute to your image, you do not need and should not -<img ngSrc="cat.jpg" fill> + @@ -120,7 +120,7 @@ NgOptimizedImage can display an automatic low-resolution placeholder for your im -<img ngSrc="cat.jpg" width="400" height="200" placeholder> + @@ -147,7 +147,7 @@ You can also specify a placeholder using a base64 [data URL](https://developer.m -<img ngSrc="cat.jpg" width="400" height="200" placeholder="data:image/png;base64,iVBORw0K..."> + @@ -159,7 +159,7 @@ By default, NgOptimizedImage applies a CSS blur effect to image placeholders. To -<img ngSrc="cat.jpg" width="400" height="200" placeholder [placeholderConfig]="{blur: false}"> + @@ -181,7 +181,7 @@ You can add a [`preconnect` resource hint](https://web.dev/preconnect-and-dns-pr -<link rel="preconnect" href="https://my.cdn.origin" /> + @@ -236,7 +236,7 @@ If you would like to manually define a `srcset` attribute, you can provide your -<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w"> + @@ -244,7 +244,7 @@ If the `ngSrcset` attribute is present, `NgOptimizedImage` generates and sets th -<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w" sizes="50vw"> + @@ -254,7 +254,7 @@ To disable srcset generation for a single image, you can add the `disableOptimiz -<img ngSrc="about.jpg" disableOptimizedSrcset> + @@ -264,7 +264,7 @@ By default, `NgOptimizedImage` sets `loading=lazy` for all images that are not m -<img ngSrc="cat.jpg" width="400" height="200" loading="eager"> + @@ -274,7 +274,7 @@ You may want to have images displayed at varying widths on differently-sized scr -<img ngSrc="cat.jpg" width="400" height="200" sizes="(max-width: 768px) 100vw, 50vw"> + @@ -371,7 +371,7 @@ Note that in the above example, we've invented the 'roundedCorners' property nam -<img ngSrc="profile.jpg" width="300" height="300" [loaderParams]="{roundedCorners: true}"> + diff --git a/adev/src/content/guide/ngmodules/api.md b/adev/src/content/guide/ngmodules/api.md index 338c3d2f325594..11c1b52917937a 100644 --- a/adev/src/content/guide/ngmodules/api.md +++ b/adev/src/content/guide/ngmodules/api.md @@ -31,10 +31,10 @@ The following table summarizes the `@NgModule` metadata properties. | Property | Details | |:--- |:--- | -| `declarations` | A list of [declarable](/guide/ngmodules/faq#what-is-a-declarable?) classes (*components*, *directives*, and *pipes*) that *belong to this module*.
  1. When compiling a template, you need to determine a set of selectors which should be used for triggering their corresponding directives.
  2. The template is compiled within the context of an NgModule —the NgModule within which the template's component is declared— which determines the set of selectors using the following rules:
    • All selectors of directives listed in `declarations`.
    • All selectors of directives exported from imported NgModules.
Components, directives, and pipes must belong to *exactly* one module. The compiler emits an error if you try to declare the same class in more than one module. Be careful not to re-declare a class that is imported directly or indirectly from another module. | +| `declarations` | A list of [declarable](/guide/ngmodules/faq#what-is-a-declarable?) classes (*components*, *directives*, and *pipes*) that *belong to this module*.
  1. When compiling a template, you need to determine a set of selectors which should be used for triggering their corresponding directives.
  2. The template is compiled within the context of an NgModule —the NgModule within which the template's component is declared— which determines the set of selectors using the following rules:
    • All selectors of directives listed in `declarations`.
    • All selectors of directives exported from imported NgModules.
Components, directives, and pipes must belong to *exactly* one module. The compiler emits an error if you try to declare the same class in more than one module. Be careful not to re-declare a class that is imported directly or indirectly from another module. | | `providers` | A list of dependency-injection providers.
Angular registers these providers with the NgModule's injector. If it is the NgModule used for bootstrapping then it is the root injector.
These services become available for injection into any component, directive, pipe or service which is a child of this injector.
A lazy-loaded module has its own injector which is typically a child of the application root injector.
Lazy-loaded services are scoped to the lazy module's injector. If a lazy-loaded module also provides the `UserService`, any component created within that module's context (such as by router navigation) gets the local instance of the service, not the instance in the root application injector.
Components in external modules continue to receive the instance provided by their injectors.
For more information on injector hierarchy and scoping, see [Providers](/guide/ngmodules/providers) and the [DI Guide](/guide/di). | | `imports` | A list of modules which should be folded into this module. Folded means it is as if all the imported NgModule's exported properties were declared here.
Specifically, it is as if the list of modules whose exported components, directives, or pipes are referenced by the component templates were declared in this module.
A component template can [reference](/guide/ngmodules/faq#how-does-angular-find-components,-directives,-and-pipes-in-a-template?-what-is-a-template-reference?) another component, directive, or pipe when the reference is declared in this module or if the imported module has exported it. For example, a component can use the `NgIf` and `NgFor` directives only if the module has imported the Angular `CommonModule` (perhaps indirectly by importing `BrowserModule`).
You can import many standard directives from the `CommonModule` but some familiar directives belong to other modules. For example, you can use `[(ngModel)]` only after importing the Angular `FormsModule`. | -| `exports` | A list of declarations —*component*, *directive*, and *pipe* classes— that an importing module can use.
Exported declarations are the module's *public API*. A component in another module can use *this* module's `UserComponent` if it imports this module and this module exports `UserComponent`.
Declarations are private by default. If this module does *not* export `UserComponent`, then only the components within *this* module can use `UserComponent`.
Importing a module does *not* automatically re-export the imported module's imports. Module 'B' can't use `ngIf` just because it imported module 'A' which imported `CommonModule`. Module 'B' must import `CommonModule` itself.
A module can list another module among its `exports`, in which case all of that module's public components, directives, and pipes are exported.
[Re-export](/guide/ngmodules/faq#what-should-i-export?) makes module transitivity explicit. If Module 'A' re-exports `CommonModule` and Module 'B' imports Module 'A', Module 'B' components can use `ngIf` even though 'B' itself didn't import `CommonModule`. | +| `exports` | A list of declarations —*component*, *directive*, and *pipe* classes— that an importing module can use.
Exported declarations are the module's *public API*. A component in another module can use *this* module's `UserComponent` if it imports this module and this module exports `UserComponent`.
Declarations are private by default. If this module does *not* export `UserComponent`, then only the components within *this* module can use `UserComponent`.
Importing a module does *not* automatically re-export the imported module's imports. Module 'B' can't use `ngIf` just because it imported module 'A' which imported `CommonModule`. Module 'B' must import `CommonModule` itself.
A module can list another module among its `exports`, in which case all of that module's public components, directives, and pipes are exported.
[Re-export](/guide/ngmodules/faq#what-should-i-export?) makes module transitivity explicit. If Module 'A' re-exports `CommonModule` and Module 'B' imports Module 'A', Module 'B' components can use `ngIf` even though 'B' itself didn't import `CommonModule`. | | `bootstrap` | A list of components that are automatically bootstrapped.
Usually there's only one component in this list, the *root component* of the application.
Angular can launch with multiple bootstrap components, each with its own location in the host web page. | ## More on NgModules diff --git a/adev/src/content/guide/ngmodules/faq.md b/adev/src/content/guide/ngmodules/faq.md index 8cd55faf5b7b82..ad8d22b12ea24e 100644 --- a/adev/src/content/guide/ngmodules/faq.md +++ b/adev/src/content/guide/ngmodules/faq.md @@ -6,14 +6,14 @@ This page answers the questions many developers ask about NgModule design and im ## What classes should I add to the `declarations` array? -Add [declarable](/guide/ngmodules/bootstrapping#the-declarations-array) classes —components, directives, and pipes— to a `declarations` list. +Add [declarable](/guide/ngmodules/bootstrapping#the-declarations-array) classes —components, directives, and pipes— to a `declarations` list. Declare these classes in *exactly one* module of the application. Declare them in a module if they belong to that particular module. ## What is a `declarable`? -Declarables are the class types —components, directives, and pipes— that you can add to a module's `declarations` list. +Declarables are the class types —components, directives, and pipes— that you can add to a module's `declarations` list. They're the only classes that you can add to `declarations`. ## What classes should I *not* add to `declarations`? @@ -97,7 +97,7 @@ Export [declarable](/guide/ngmodules/bootstrapping#the-declarations-array) class These are your *public* classes. If you don't export a declarable class, it stays *private*, visible only to other components declared in this NgModule. -You *can* export any declarable class —components, directives, and pipes— whether +You *can* export any declarable class —components, directives, and pipes— whether it's declared in this NgModule or in an imported NgModule. You *can* re-export entire imported NgModules, which effectively re-export all of their exported classes. @@ -389,7 +389,7 @@ In an Angular app, NgModules and JavaScript modules work together. In modern JavaScript, every file is a module (see the [Modules](https://exploringjs.com/es6/ch_modules.html) page of the Exploring ES6 website). Within each file you write an `export` statement to make parts of the module public. -An Angular NgModule is a class with the `@NgModule` decorator —JavaScript modules don't have to have the `@NgModule` decorator. +An Angular NgModule is a class with the `@NgModule` decorator —JavaScript modules don't have to have the `@NgModule` decorator. Angular's `NgModule` has `imports` and `exports` and they serve a similar purpose. You *import* other NgModules so you can use their exported classes in component templates. diff --git a/adev/src/content/guide/ngmodules/lazy-loading.md b/adev/src/content/guide/ngmodules/lazy-loading.md index 1687433c9cbaf9..70b0eb735e9cad 100644 --- a/adev/src/content/guide/ngmodules/lazy-loading.md +++ b/adev/src/content/guide/ngmodules/lazy-loading.md @@ -1,7 +1,7 @@ # Lazy-loading feature modules By default, NgModules are eagerly loaded. This means that as soon as the application loads, so do all the NgModules, whether they are immediately necessary or not. -For large applications with lots of routes, consider lazy loading —a design pattern that loads NgModules as needed. +For large applications with lots of routes, consider lazy loading —a design pattern that loads NgModules as needed. Lazy loading helps keep initial bundle sizes smaller, which in turn helps decrease load times. @@ -363,7 +363,7 @@ In the newly created service, implement the `Resolve` interface provided by the import { Resolve } from '@angular/router'; -… +… /*An interface that represents your data model*/ export interface Crisis { @@ -371,8 +371,8 @@ export interface Crisis { name: string; } -export class CrisisDetailResolverService implements Resolve<Crisis> { - resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Crisis> { +export class CrisisDetailResolverService implements Resolve { + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { // your logic goes here } } @@ -405,7 +405,7 @@ In the component's constructor, inject an instance of the `ActivatedRoute` class import { ActivatedRoute } from '@angular/router'; -@Component({ … }) +@Component({ … }) class YourComponent { constructor(private route: ActivatedRoute) {} } @@ -417,7 +417,7 @@ Use the injected instance of the `ActivatedRoute` class to access `data` associa highlight="[1,5,8]"> import { ActivatedRoute } from '@angular/router'; -@Component({ … }) +@Component({ … }) class YourComponent { constructor(private route: ActivatedRoute) {} @@ -425,7 +425,7 @@ class YourComponent { this.route.data .subscribe(data => { const crisis: Crisis = data.crisis; - // … + // … }); } } diff --git a/adev/src/content/guide/ngmodules/module-types.md b/adev/src/content/guide/ngmodules/module-types.md index 50d0d23b7aaf60..9f7f05e0e91a05 100644 --- a/adev/src/content/guide/ngmodules/module-types.md +++ b/adev/src/content/guide/ngmodules/module-types.md @@ -1,7 +1,7 @@ # Guidelines for creating NgModules This topic provides a conceptual overview of the different categories of NgModules you can create in order to organize your code in a modular structure. -These categories are not cast in stone —they are suggestions. +These categories are not cast in stone —they are suggestions. You may want to create NgModules for other purposes, or combine the characteristics of some of these categories. NgModules are a great way to organize an application and keep code related to a specific functionality or feature separate from other code. diff --git a/adev/src/content/guide/ngmodules/vs-jsmodule.md b/adev/src/content/guide/ngmodules/vs-jsmodule.md index 9a47c02acd85a9..b524109a96e49b 100644 --- a/adev/src/content/guide/ngmodules/vs-jsmodule.md +++ b/adev/src/content/guide/ngmodules/vs-jsmodule.md @@ -14,7 +14,7 @@ For the module specification, see the [6th Edition of the ECMAScript standard](h To make the code in a JavaScript module available to other modules, use an `export` statement at the end of the relevant code in the module, such as the following: -export class AppComponent { … } +export class AppComponent { … } When you need that module's code in another module, use an `import` statement as follows: diff --git a/adev/src/content/guide/pipes/change-detection.md b/adev/src/content/guide/pipes/change-detection.md index dd393d4a064ed6..28b5b842537ce7 100644 --- a/adev/src/content/guide/pipes/change-detection.md +++ b/adev/src/content/guide/pipes/change-detection.md @@ -97,7 +97,7 @@ Make a pipe impure by setting its `pure` flag to `false`: visibleRegion="pipe-decorator" highlight="[19]"/> The following code shows the complete implementation of `FlyingHeroesImpurePipe`, which extends `FlyingHeroesPipe` to inherit its characteristics. -The example shows that you don't have to change anything else—the only difference is setting the `pure` flag as `false` in the pipe metadata. +The example shows that you don't have to change anything else—the only difference is setting the `pure` flag as `false` in the pipe metadata. diff --git a/adev/src/content/guide/routing/common-router-tasks.md b/adev/src/content/guide/routing/common-router-tasks.md index 78c4189d9aa41c..0d6b23c37b5ae9 100644 --- a/adev/src/content/guide/routing/common-router-tasks.md +++ b/adev/src/content/guide/routing/common-router-tasks.md @@ -380,7 +380,7 @@ The router uses an `id` to show the correct hero's details. First, import the following members in the component you want to navigate from. ```ts -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators'; ``` diff --git a/adev/src/content/guide/routing/router-reference.md b/adev/src/content/guide/routing/router-reference.md index 269386896298df..e3d71dbedaec1b 100644 --- a/adev/src/content/guide/routing/router-reference.md +++ b/adev/src/content/guide/routing/router-reference.md @@ -59,7 +59,7 @@ The data property is accessible within each activated route. Use it to store items such as page titles, breadcrumb text, and other read-only, static data. Use the resolve guard to retrieve dynamic data. -The empty path in the fourth route represents the default path for the application —the place to go when the path in the URL is empty, as it typically is at the start. +The empty path in the fourth route represents the default path for the application —the place to go when the path in the URL is empty, as it typically is at the start. This default route redirects to the route for the `/heroes` URL and, therefore, displays the `HeroesListComponent`. If you need to see what events are happening during the navigation lifecycle, there is the `withDebugTracing` feature. @@ -74,8 +74,8 @@ It acts as a placeholder that marks the spot in the template where the router sh -<router-outlet></router-outlet> -<!-- Routed components go here --> + + diff --git a/adev/src/content/guide/security.md b/adev/src/content/guide/security.md index 539c32804ba870..6c4889967528df 100644 --- a/adev/src/content/guide/security.md +++ b/adev/src/content/guide/security.md @@ -29,7 +29,7 @@ This is one of the most common attacks on the web. To block XSS attacks, you must prevent malicious code from entering the Document Object Model (DOM). For example, if attackers can trick you into inserting a ` + + + + diff --git a/adev/src/content/tools/cli/aot-compiler.md b/adev/src/content/tools/cli/aot-compiler.md index 9f32cd537c1889..c88539ca235101 100644 --- a/adev/src/content/tools/cli/aot-compiler.md +++ b/adev/src/content/tools/cli/aot-compiler.md @@ -44,13 +44,13 @@ In the following example, the `@Component()` metadata object and the class const -@Component({ +@Component({ selector: 'app-typical', - template: '<div>A typical component for {{data.name}}</div>' + template: '
A typical component for {{data.name}}
' }) export class TypicalComponent { - @Input() data: TypicalData; - constructor(private someService: SomeService) { … } + @Input() data: TypicalData; + constructor(private someService: SomeService) { … } }
@@ -104,13 +104,13 @@ Define metadata objects with the following limited syntax: |:--- |:--- | | Literal object | `{cherry: true, apple: true, mincemeat: false}` | | Literal array | `['cherries', 'flour', 'sugar']` | -| Spread in literal array | `['apples', 'flour', ...]` | +| Spread in literal array | `['apples', 'flour', …]` | | Calls | `bake(ingredients)` | | New | `new Oven()` | | Property access | `pie.slice` | | Array index | `ingredients[0]` | | Identity reference | `Component` | -| A template string | `pie is ${multiplier} times better than cake` | +| A template string | `pie is ${multiplier} times better than cake` | | Literal string | `'pi'` | | Literal number | `3.14153265` | | Literal boolean | `true` | @@ -128,7 +128,7 @@ HELPFUL: If you want `ngc` to report syntax errors immediately rather than produ "angularCompilerOptions": { - … + … "strictMetadataEmit" : true } @@ -145,9 +145,9 @@ Consider the following component decorator: -@Component({ - … - providers: [{provide: server, useFactory: () => new Server()}] +@Component({ + … + providers: [{provide: server, useFactory: () => new Server()}] }) @@ -164,8 +164,8 @@ export function serverFactory() { return new Server(); } -@Component({ - … +@Component({ + … providers: [{provide: server, useFactory: serverFactory}] }) @@ -189,14 +189,14 @@ Consider the following component definition: -const template = '<div>{{hero.name}}</div>'; +const template = '
{{hero.name}}
'; -@Component({ +@Component({ selector: 'app-hero', template: template }) export class HeroComponent { - @Input() hero: Hero; + @Input() hero: Hero; }
@@ -207,12 +207,12 @@ The effect is the same as if you had written: -@Component({ +@Component({ selector: 'app-hero', - template: '<div>{{hero.name}}</div>' + template: '
{{hero.name}}
' }) export class HeroComponent { - @Input() hero: Hero; + @Input() hero: Hero; }
@@ -223,14 +223,14 @@ You can take this example a step further by including the `template` constant in -const template = '<div>{{hero.name}}</div>'; +const template = '
{{hero.name}}
'; -@Component({ +@Component({ selector: 'app-hero', - template: template + '<div>{{hero.title}}</div>' + template: template + '
{{hero.title}}
' }) export class HeroComponent { - @Input() hero: Hero; + @Input() hero: Hero; }
@@ -239,7 +239,7 @@ The collector reduces this expression to its equivalent *folded* string: -'<div>{{hero.name}}</div><div>{{hero.title}}</div>' +'
{{hero.name}}
{{hero.title}}
'
@@ -309,7 +309,7 @@ For example, consider the following function: -export function wrapInArray<T>(value: T): T[] { +export function wrapInArray(value: T): T[] { return [value]; } @@ -321,7 +321,7 @@ You might use `wrapInArray()` like this: -@NgModule({ +@NgModule({ declarations: wrapInArray(TypicalComponent) }) export class TypicalModule {} @@ -332,7 +332,7 @@ The compiler treats this usage as if you had written: -@NgModule({ +@NgModule({ declarations: [TypicalComponent] }) export class TypicalModule {} @@ -347,7 +347,7 @@ for these methods to see how macros can simplify configuration of complex [NgMod The compiler treats object literals containing the fields `useClass`, `useValue`, `useFactory`, and `data` specially, converting the expression initializing one of these fields into an exported variable that replaces the expression. This process of rewriting these expressions removes all the restrictions on what can be in them because -the compiler doesn't need to know the expression's value —it just needs to be able to generate a reference to the value. +the compiler doesn't need to know the expression's value — it just needs to be able to generate a reference to the value. You might write something like: @@ -357,8 +357,8 @@ class TypicalServer { } -@NgModule({ - providers: [{provide: SERVER, useFactory: () => TypicalServer}] +@NgModule({ + providers: [{provide: SERVER, useFactory: () => TypicalServer}] }) export class TypicalModule {} @@ -373,10 +373,10 @@ class TypicalServer { } -export const θ0 = () => new TypicalServer(); +export const θ0 = () => new TypicalServer(); -@NgModule({ - providers: [{provide: SERVER, useFactory: θ0}] +@NgModule({ + providers: [{provide: SERVER, useFactory: θ0}] }) export class TypicalModule {} @@ -404,7 +404,7 @@ For example, consider the following component: -@Component({ +@Component({ selector: 'my-component', template: '{{person.addresss.street}}' }) @@ -451,7 +451,7 @@ For example, to avoid `Object is possibly 'undefined'` error in the template abo -@Component({ +@Component({ selector: 'my-component', template: ' {{person.address.street}} ' }) @@ -474,9 +474,9 @@ There is no convenient way to describe this constraint to TypeScript and the tem -@Component({ +@Component({ selector: 'my-component', - template: '<span *ngIf="person"> {{person.name}} lives on {{address!.street}} </span>' + template: ' {{person.name}} lives on {{address!.street}} ' }) class MyComponent { person?: Person; @@ -496,9 +496,9 @@ In this example it is recommended to include the checking of `address` in the `* -@Component({ +@Component({ selector: 'my-component', - template: '<span *ngIf="person && address"> {{person.name}} lives on {{address.street}} </span>' + template: ' {{person.name}} lives on {{address.street}} ' }) class MyComponent { person?: Person; diff --git a/adev/src/content/tools/cli/aot-metadata-errors.md b/adev/src/content/tools/cli/aot-metadata-errors.md index 140126f5a53910..3d9e31a96da632 100644 --- a/adev/src/content/tools/cli/aot-metadata-errors.md +++ b/adev/src/content/tools/cli/aot-metadata-errors.md @@ -11,13 +11,13 @@ can produce this error, as seen in the following example: // ERROR -export class Fooish { … } -… +export class Fooish { … } +… const prop = typeof Fooish; // typeof is not valid in metadata - … + … // bracket notation is not valid in metadata { provide: 'token', useValue: { [prop]: 'value' } }; - … + … You can use `typeof` and bracket notation in normal application code. @@ -40,9 +40,9 @@ Here's a `provider` example of the problem. // ERROR let foo: number; // neither exported nor initialized -@Component({ +@Component({ selector: 'my-component', - template: … , + template: … , providers: [ { provide: Foo, useValue: foo } ] @@ -73,9 +73,9 @@ Alternatively, you can fix it by exporting `foo` with the expectation that `foo` // CORRECTED export let foo: number; // exported -@Component({ +@Component({ selector: 'my-component', - template: … , + template: … , providers: [ { provide: Foo, useValue: foo } ] @@ -94,7 +94,7 @@ For example, it doesn't work for the `template` property. // ERROR export let someTemplate: string; // exported but not initialized -@Component({ +@Component({ selector: 'my-component', template: someTemplate }) @@ -120,7 +120,7 @@ The following example tries to set the component's `template` property to the va // ERROR export let someTemplate: string; -@Component({ +@Component({ selector: 'my-component', template: someTemplate }) @@ -135,7 +135,7 @@ You'd also get this error if you imported `someTemplate` from some other module // ERROR - not initialized there either import { someTemplate } from './config'; -@Component({ +@Component({ selector: 'my-component', template: someTemplate }) @@ -151,9 +151,9 @@ To correct this error, provide the initial value of the variable in an initializ // CORRECTED -export let someTemplate = '<h1>Greetings from Angular</h1>'; +export let someTemplate = '

Greetings from Angular

'; -@Component({ +@Component({ selector: 'my-component', template: someTemplate }) @@ -175,11 +175,11 @@ For example, you may have defined a class and used it as an injection token in a // ERROR abstract class MyStrategy { } - … + … providers: [ - { provide: MyStrategy, useValue: … } + { provide: MyStrategy, useValue: … } ] - … + …
@@ -191,11 +191,11 @@ To correct this error, export the referenced class. // CORRECTED export abstract class MyStrategy { } - … + … providers: [ - { provide: MyStrategy, useValue: … } + { provide: MyStrategy, useValue: … } ] - … + …
@@ -208,13 +208,13 @@ For example, you may have set a providers `useFactory` property to a locally def // ERROR -function myStrategy() { … } +function myStrategy() { … } - … + … providers: [ { provide: MyStrategy, useFactory: myStrategy } ] - … + … @@ -224,13 +224,13 @@ To correct this error, export the function. // CORRECTED -export function myStrategy() { … } +export function myStrategy() { … } - … + … providers: [ { provide: MyStrategy, useFactory: myStrategy } ] - … + … @@ -244,12 +244,12 @@ For example, you cannot set a provider's `useFactory` to an anonymous function o // ERROR - … + … providers: [ - { provide: MyStrategy, useFactory: function() { … } }, - { provide: OtherStrategy, useFactory: () => { … } } + { provide: MyStrategy, useFactory: function() { … } }, + { provide: OtherStrategy, useFactory: () => { … } } ] - … + … @@ -260,11 +260,11 @@ You also get this error if you call a function or method in a provider's `useVal // ERROR import { calculateValue } from './utilities'; - … + … providers: [ { provide: SomeValue, useValue: calculateValue() } ] - … + …
@@ -275,18 +275,18 @@ To correct this error, export a function from the module and refer to the functi // CORRECTED import { calculateValue } from './utilities'; -export function myStrategy() { … } -export function otherStrategy() { … } +export function myStrategy() { … } +export function otherStrategy() { … } export function someValueFactory() { return calculateValue(); } - … + … providers: [ { provide: MyStrategy, useFactory: myStrategy }, { provide: OtherStrategy, useFactory: otherStrategy }, { provide: SomeValue, useFactory: someValueFactory } ] - … + …
@@ -305,12 +305,12 @@ import { configuration } from './configuration'; // destructured assignment to foo and bar const {foo, bar} = configuration; - … + … providers: [ {provide: Foo, useValue: foo}, {provide: Bar, useValue: bar}, ] - … + …
@@ -320,12 +320,12 @@ To correct this error, refer to non-destructured values. // CORRECTED import { configuration } from './configuration'; - … + … providers: [ {provide: Foo, useValue: configuration.foo}, {provide: Bar, useValue: configuration.bar}, ] - … + …
@@ -341,9 +341,9 @@ You'll get an error if you reference it in the component constructor, which the // ERROR -@Component({ }) +@Component({ }) export class MyComponent { - constructor (private win: Window) { … } + constructor (private win: Window) { … } } @@ -368,19 +368,19 @@ Here's an illustrative example. // CORRECTED -import { Inject } from '@angular/core'; +import { Inject } from '@angular/core'; export const WINDOW = new InjectionToken('Window'); export function _window() { return window; } -@Component({ - … +@Component({ + … providers: [ { provide: WINDOW, useFactory: _window } ] }) export class MyComponent { - constructor (@Inject(WINDOW) private win: Window) { … } + constructor (@Inject(WINDOW) private win: Window) { … } } @@ -392,12 +392,12 @@ Angular does something similar with the `DOCUMENT` token so you can inject the b -import { Inject } from '@angular/core'; -import { DOCUMENT } from '@angular/common'; +import { Inject } from '@angular/core'; +import { DOCUMENT } from '@angular/common'; -@Component({ … }) +@Component({ … }) export class MyComponent { - constructor (@Inject(DOCUMENT) private doc: Document) { … } + constructor (@Inject(DOCUMENT) private doc: Document) { … } } @@ -439,13 +439,13 @@ enum Colors { Blue = "Blue".length // computed } - … + … providers: [ { provide: BaseColor, useValue: Colors.White } // ok { provide: DangerColor, useValue: Colors.Red } // ok { provide: StrongColor, useValue: Colors.Blue } // bad ] - … + …
@@ -461,10 +461,10 @@ The compiler encountered a JavaScript ES2015 [tagged template expression](https: // ERROR const expression = 'funky'; -const raw = String.raw`A tagged template ${expression} string`; - … - template: '<div>' + raw + '</div>' - … +const raw = String.raw`A tagged template ${expression} string`; + … + template: '
' + raw + '
' + …
diff --git a/adev/src/content/tools/cli/build.md b/adev/src/content/tools/cli/build.md index bea0c7c42003eb..d708aea65516dc 100644 --- a/adev/src/content/tools/cli/build.md +++ b/adev/src/content/tools/cli/build.md @@ -27,11 +27,11 @@ You can determine which builder is being used for a particular project by lookin // `ng build` invokes the Architect target named `build`. "build": { "builder": "@angular-devkit/build-angular:application", - … + … }, - "serve": { … } - "test": { … } - … + "serve": { … } + "test": { … } + … } } } @@ -55,10 +55,10 @@ Define your size boundaries in the CLI configuration file, `angular.json`, in a { - … + … "configurations": { "production": { - … + … "budgets": [ { "type": "initial", @@ -120,9 +120,9 @@ If the best option is to use a CommonJS dependency, you can disable these warnin "allowedCommonJsDependencies": [ "lodash" ] - … + … } - … + … }, diff --git a/adev/src/content/tools/cli/cli-builder.md b/adev/src/content/tools/cli/cli-builder.md index ffd6d678f6d9fa..33e18ef0219782 100644 --- a/adev/src/content/tools/cli/cli-builder.md +++ b/adev/src/content/tools/cli/cli-builder.md @@ -179,17 +179,17 @@ By default, for example, the `ng build` command runs the builder `@angular-devki -… +… "myApp": { - … + … "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/myApp", "index": "src/index.html", - … + … }, "configurations": { "production": { @@ -201,15 +201,15 @@ By default, for example, the `ng build` command runs the builder `@angular-devki ], "optimization": true, "outputHashing": "all", - … + … } } }, - … + … } } -… +… @@ -265,7 +265,7 @@ You can publish the builder to npm (see [Publishing your Library](tools/librarie -npm install @example/copy-file +npm install @example/copy-file diff --git a/adev/src/content/tools/cli/environments.md b/adev/src/content/tools/cli/environments.md index a76922390344cc..8f50ba372cd7e3 100644 --- a/adev/src/content/tools/cli/environments.md +++ b/adev/src/content/tools/cli/environments.md @@ -28,7 +28,7 @@ Angular CLI builders support a `configurations` object, which allows overwriting } } }, - … + … } } } @@ -154,7 +154,7 @@ You can change or add file replacements for specific build targets by editing th "with": "src/environments/environment.development.ts" } ], - … + …
@@ -165,8 +165,8 @@ To add a staging environment, create a copy of `src/environments/environment.ts` "configurations": { - "development": { … }, - "production": { … }, + "development": { … }, + "production": { … }, "staging": { "fileReplacements": [ { @@ -197,7 +197,7 @@ You can also configure `ng serve` to use the targeted build configuration if you "serve": { "builder": "@angular-devkit/build-angular:dev-server", - "options": { … }, + "options": { … }, "configurations": { "development": { // Use the `development` configuration of the `build` target. diff --git a/adev/src/content/tools/cli/schematics-authoring.md b/adev/src/content/tools/cli/schematics-authoring.md index e1942d08bfb9c3..19300906f2279b 100644 --- a/adev/src/content/tools/cli/schematics-authoring.md +++ b/adev/src/content/tools/cli/schematics-authoring.md @@ -38,12 +38,12 @@ A `RuleFactory` object defines a higher-order function that creates a `Rule`. -import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; +import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; // You don't have to export the function as default. // You can also have more than one rule factory per file. export function helloWorld(_options: any): Rule { - return (tree: Tree,_context: SchematicContext) => { + return (tree: Tree,_context: SchematicContext) => { return tree; }; } @@ -66,7 +66,7 @@ import { normalize, parseJsonAst, strings, -} from '@angular-devkit/core'; +} from '@angular-devkit/core'; @@ -154,7 +154,7 @@ In the short form, the type is inferred from the property's type and constraints | "type": "string" | input | | "type": "number" | input \(only valid numbers accepted\) | | "type": "integer" | input \(only valid numbers accepted\) | -| "enum": […] | list \(enum members become list selections\) | +| "enum": […] | list \(enum members become list selections\) | In the following example, the property takes an enumerated value, so the schematic automatically chooses the list type, and creates a menu from the possible values. @@ -268,7 +268,7 @@ Using Node 6.9 or later, install the Schematics command line tool globally: -npm install -g @angular-devkit/schematics-cli +npm install -g @angular-devkit/schematics-cli @@ -316,7 +316,7 @@ Provide the path to the project folder, the schematic name, and any mandatory op -schematics <path-to-schematics-project>:<schematics-name> --<required-option>=<value> +schematics : --= @@ -352,8 +352,8 @@ Each schematic is created with a name, description, and factory function. { - "$schema": - "../node_modules/@angular-devkit/schematics/collection-schema.json", + "$schema": + "../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "hello-world": { "description": "A blank schematic.", diff --git a/adev/src/content/tools/cli/schematics-for-libraries.md b/adev/src/content/tools/cli/schematics-for-libraries.md index b32e39227eb620..79fac147818bab 100644 --- a/adev/src/content/tools/cli/schematics-for-libraries.md +++ b/adev/src/content/tools/cli/schematics-for-libraries.md @@ -147,13 +147,13 @@ Schematic templates support special syntax to execute code and variable substitu - import { Injectable } from '@angular/core'; - import { HttpClient } from '@angular/common/http'; + import { Injectable } from '@angular/core'; + import { HttpClient } from '@angular/common/http'; - @Injectable({ + @Injectable({ providedIn: 'root' }) - export class <%= classify(name) %>Service { + export class <%= classify(name) %>Service { constructor(private http: HttpClient) { } } diff --git a/adev/src/content/tools/cli/schematics.md b/adev/src/content/tools/cli/schematics.md index 596b722f19bab0..33778b0df59989 100644 --- a/adev/src/content/tools/cli/schematics.md +++ b/adev/src/content/tools/cli/schematics.md @@ -81,7 +81,7 @@ The following command uses one of these schematics to render an Angular Material -ng generate @angular/material:table <component-name> +ng generate @angular/material:table @@ -97,11 +97,11 @@ We analyzed your package.json, there are some packages to update: Name Version Command to update ‐------------------------------------------------------------------------------- - @angular/cdk 7.2.2 -> 7.3.1 ng update @angular/cdk - @angular/cli 7.2.3 -> 7.3.0 ng update @angular/cli - @angular/core 7.2.2 -> 7.2.3 ng update @angular/core - @angular/material 7.2.2 -> 7.3.1 ng update @angular/material - rxjs 6.3.3 -> 6.4.0 ng update rxjs + @angular/cdk 7.2.2 -> 7.3.1 ng update @angular/cdk + @angular/cli 7.2.3 -> 7.3.0 ng update @angular/cli + @angular/core 7.2.2 -> 7.2.3 ng update @angular/core + @angular/material 7.2.2 -> 7.3.1 ng update @angular/material + rxjs 6.3.3 -> 6.4.0 ng update rxjs There might be additional packages that are outdated. Run "ng update --all" to try to update all at the same time. @@ -122,7 +122,7 @@ If you create a new version of your library that introduces potential breaking c For example, suppose you want to update the Angular Material library. -ng update @angular/material +ng update @angular/material This command updates both `@angular/material` and its dependency `@angular/cdk` in your workspace's `package.json`. diff --git a/adev/src/content/tools/cli/template-typecheck.md b/adev/src/content/tools/cli/template-typecheck.md index 58694871f3126d..f2476811a06d74 100644 --- a/adev/src/content/tools/cli/template-typecheck.md +++ b/adev/src/content/tools/cli/template-typecheck.md @@ -76,10 +76,10 @@ interface User { -<div *ngFor="let user of users"> - <h2>{{config.title}}</h2> - <span>City: {{user.address.city}}</span> -</div> +
+

{{config.title}}

+ City: {{user.address.city}} +
@@ -116,7 +116,7 @@ Unless otherwise commented, each following option is set to the value for `stric | `strictInputTypes` | Whether the assignability of a binding expression to the `@Input()` field is checked. Also affects the inference of directive generic types. | | `strictInputAccessModifiers` | Whether access modifiers such as `private`/`protected`/`readonly` are honored when assigning a binding expression to an `@Input()`. If disabled, the access modifiers of the `@Input` are ignored; only the type is checked. This option is `false` by default, even with `strictTemplates` set to `true`. | | `strictNullInputTypes` | Whether `strictNullChecks` is honored when checking `@Input()` bindings \(per `strictInputTypes`\). Turning this off can be useful when using a library that was not built with `strictNullChecks` in mind. | -| `strictAttributeTypes` | Whether to check `@Input()` bindings that are made using text attributes. For example, <input matInput disabled="true"> \(setting the `disabled` property to the string `'true'`\) vs <input matInput [disabled]="true"> \(setting the `disabled` property to the boolean `true`\). | +| `strictAttributeTypes` | Whether to check `@Input()` bindings that are made using text attributes. For example, \(setting the `disabled` property to the string `'true'`\) vs \(setting the `disabled` property to the boolean `true`\). | | `strictSafeNavigationTypes` | Whether the return type of safe navigation operations \(for example, `user?.name` will be correctly inferred based on the type of `user`\). If disabled, `user?.name` will be of type `any`. | | `strictDomLocalRefTypes` | Whether local references to DOM elements will have the correct type. If disabled `ref` will be of type `any` for ``. | | `strictOutputEventTypes` | Whether `$event` will have the correct type for event bindings to component/directive an `@Output()`, or to animation events. If disabled, it will be `any`. | @@ -143,12 +143,12 @@ export interface User { name: string; } -@Component({ +@Component({ selector: 'user-detail', template: '{{ user.name }}', }) export class UserDetailComponent { - @Input() user: User; + @Input() user: User; }
@@ -157,12 +157,12 @@ The `AppComponent` template uses this component as follows: -@Component({ +@Component({ selector: 'app-root', - template: '<user-detail [user]="selectedUser"></user-detail>', + template: '', }) export class AppComponent { - selectedUser: User | null = null; + selectedUser: User | null = null; } @@ -189,7 +189,7 @@ For example: * Using the `async` pipe with an Observable which you know will emit synchronously. The `async` pipe currently assumes that the Observable it subscribes to can be asynchronous, which means that it's possible that there is no value available yet. - In that case, it still has to return something —which is `null`. + In that case, it still has to return something —which is `null`. In other words, the return type of the `async` pipe includes `null`, which might result in errors in situations where the Observable is known to emit a non-nullable value synchronously. There are two potential workarounds to the preceding issues: @@ -198,7 +198,7 @@ There are two potential workarounds to the preceding issues: - <user-detail [user]="user!"></user-detail> + @@ -207,7 +207,7 @@ There are two potential workarounds to the preceding issues: - <user-detail [user]="(user$ | async)!"></user-detail> + @@ -233,18 +233,18 @@ Consider the following directive: -@Component({ +@Component({ selector: 'submit-button', - template: ` - <div class="wrapper"> - <button [disabled]="disabled">Submit</button> - </div> - `, + template: ` +
+ +
+ `, }) class SubmitButton { private _disabled: boolean; - @Input() + @Input() get disabled(): boolean { return this._disabled; } @@ -262,7 +262,7 @@ But, suppose a consumer uses this input in the template as an attribute: -<submit-button disabled></submit-button> + @@ -270,7 +270,7 @@ This has the same effect as the binding: -<submit-button [disabled]="''"></submit-button> + @@ -280,7 +280,7 @@ Angular component libraries that deal with this problem often "coerce" the value set disabled(value: boolean) { - this._disabled = (value === '') || value; + this._disabled = (value === '') || value; } @@ -298,16 +298,16 @@ Enable this by adding a static property with the `ngAcceptInputType_` prefix to class SubmitButton { private _disabled: boolean; - @Input() + @Input() get disabled(): boolean { return this._disabled; } set disabled(value: boolean) { - this._disabled = (value === '') || value; + this._disabled = (value === '') || value; } - static ngAcceptInputType_disabled: boolean|''; + static ngAcceptInputType_disabled: boolean|''; }
@@ -330,9 +330,9 @@ In the following example, casting `person` to the `any` type suppresses the erro -@Component({ +@Component({ selector: 'my-component', - template: '{{$any(person).address.street}}' + template: '{{$any(person).address.street}}' }) class MyComponent { person?: Person; diff --git a/adev/src/content/tools/language-service.md b/adev/src/content/tools/language-service.md index aa1c89a034b922..f2a3a39a286181 100644 --- a/adev/src/content/tools/language-service.md +++ b/adev/src/content/tools/language-service.md @@ -101,7 +101,7 @@ Starting with TypeScript 2.3, TypeScript has a plug-in model that the language s - npm install --save-dev @angular/language-service + npm install --save-dev @angular/language-service @@ -110,7 +110,7 @@ Starting with TypeScript 2.3, TypeScript has a plug-in model that the language s "plugins": [ - {"name": "@angular/language-service"} + {"name": "@angular/language-service"} ] @@ -119,7 +119,7 @@ Starting with TypeScript 2.3, TypeScript has a plug-in model that the language s - "typescript-tsdk": "<path to your folder>/node_modules/typescript/lib" + "typescript-tsdk": "/node_modules/typescript/lib" @@ -127,7 +127,7 @@ This lets the Angular Language Service provide diagnostics and completions in `. ### Eclipse IDE -Either directly install the "Eclipse IDE for Web and JavaScript developers" package which comes with the Angular Language Server included, or from other Eclipse IDE packages, use Help > Eclipse Marketplace to find and install [Eclipse Wild Web Developer](https://marketplace.eclipse.org/content/wild-web-developer-html-css-javascript-typescript-nodejs-angular-json-yaml-kubernetes-xml). +Either directly install the "Eclipse IDE for Web and JavaScript developers" package which comes with the Angular Language Server included, or from other Eclipse IDE packages, use Help > Eclipse Marketplace to find and install [Eclipse Wild Web Developer](https://marketplace.eclipse.org/content/wild-web-developer-html-css-javascript-typescript-nodejs-angular-json-yaml-kubernetes-xml). ## How the Language Service works diff --git a/adev/src/content/tools/libraries/angular-package-format.md b/adev/src/content/tools/libraries/angular-package-format.md index c81db79997a406..7ee9d46997a6de 100644 --- a/adev/src/content/tools/libraries/angular-package-format.md +++ b/adev/src/content/tools/libraries/angular-package-format.md @@ -189,7 +189,7 @@ Secondary entrypoints can be resolved via the `"exports"` field of the `package. The README file in the Markdown format that is used to display description of a package on npm and GitHub. -Example README content of @angular/core package: +Example README content of @angular/core package: @@ -212,7 +212,7 @@ To partially compile Angular code, use the `compilationMode` flag in the `angula { - … + … "angularCompilerOptions": { "compilationMode": "partial", } @@ -247,13 +247,13 @@ To generate a flattened ES Module index file, use the following configuration op { "compilerOptions": { - … + … "module": "esnext", "target": "es2022", - … + … }, "angularCompilerOptions": { - … + … "flatModuleOutFile": "my-ui-lib.js", "flatModuleId": "my-ui-lib" } @@ -386,7 +386,7 @@ These module IDs are usually considered to be private APIs that can change over ### Top-Level import An import coming from an entry point. -The available top-level imports are what define the public API and are exposed in "@angular/name" modules, such as `@angular/core` or `@angular/common`. +The available top-level imports are what define the public API and are exposed in "@angular/name" modules, such as `@angular/core` or `@angular/common`. ### Tree-shaking diff --git a/adev/src/content/tools/libraries/creating-libraries.md b/adev/src/content/tools/libraries/creating-libraries.md index e9598f8947e0a6..2a4a1a13a04c31 100644 --- a/adev/src/content/tools/libraries/creating-libraries.md +++ b/adev/src/content/tools/libraries/creating-libraries.md @@ -41,7 +41,7 @@ When you generate a new library, the workspace configuration file, `angular.json "projects": { - … + … "my-lib": { "root": "projects/my-lib", "sourceRoot": "projects/my-lib/src", @@ -49,8 +49,8 @@ When you generate a new library, the workspace configuration file, `angular.json "prefix": "lib", "architect": { "build": { - "builder": "@angular-devkit/build-angular:ng-packagr", - … + "builder": "@angular-devkit/build-angular:ng-packagr", + … diff --git a/adev/src/content/tools/libraries/using-libraries.md b/adev/src/content/tools/libraries/using-libraries.md index 7c31f1116f15ba..86c6597cc0bd15 100644 --- a/adev/src/content/tools/libraries/using-libraries.md +++ b/adev/src/content/tools/libraries/using-libraries.md @@ -27,7 +27,7 @@ For example, suppose you have a library named `d3`: npm install d3 --save -npm install @types/d3 --save-dev +npm install @types/d3 --save-dev @@ -128,7 +128,7 @@ The following code snippet is an example import statement. -import * as $ from 'jquery'; +import * as $ from 'jquery'; @@ -154,7 +154,7 @@ Some scripts extend other libraries; for instance with JQuery plugins: -$('.test').myPlugin(); +$('.test').myPlugin(); diff --git a/adev/src/content/tutorials/first-app/steps/11-details-page/README.md b/adev/src/content/tutorials/first-app/steps/11-details-page/README.md index 30f8168da43d3b..a337654def5b38 100644 --- a/adev/src/content/tutorials/first-app/steps/11-details-page/README.md +++ b/adev/src/content/tutorials/first-app/steps/11-details-page/README.md @@ -50,7 +50,7 @@ In this step, you will get the route parameter in the `DetailsComponent`. Curren 1. Update the `template` property of the `@Component` decorator to display the value `housingLocationId`: - template: `<p>details works! {{ housingLocationId }}</p>`, + template: `

details works! {{ housingLocationId }}

`,
1. Update the body of the `DetailsComponent` with the following code: diff --git a/adev/src/content/tutorials/first-app/steps/13-search/README.md b/adev/src/content/tutorials/first-app/steps/13-search/README.md index f776bac14196c1..51f3bdb8ac2559 100644 --- a/adev/src/content/tutorials/first-app/steps/13-search/README.md +++ b/adev/src/content/tutorials/first-app/steps/13-search/README.md @@ -36,7 +36,7 @@ The `HomeComponent` already contains an input field that you will use to capture 1. Update the `HomeComponent` template to include a template variable in the `input` element called `#filter`. - <input type="text" placeholder="Filter by city" #filter> + This example uses a [template reference variable](/guide/templates) to get access to the `input` element as its value. @@ -44,7 +44,7 @@ The `HomeComponent` already contains an input field that you will use to capture 1. Next, update the component template to attach an event handler to the "Search" button. - <button class="primary" type="button" (click)="filterResults(filter.value)">Search</button> + By binding to the `click` event on the `button` element, you are able to call the `filterResults` function. The argument to the function is the `value` property of the `filter` template variable. Specifically, the `.value` property from the `input` HTML element. @@ -52,7 +52,7 @@ The `HomeComponent` already contains an input field that you will use to capture 1. The last template update is to the `ngFor` directive. Update the `ngFor` value to iterate over values from the `filteredLocationList` array. - <app-housing-location *ngFor="let housingLocation of filteredLocationList" [housingLocation]="housingLocation"></app-housing-location> +