mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
107 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cc2d32adb9 | |||
| a0cb5011ed | |||
| ad23934a61 | |||
| e21494a333 | |||
| 937e6c5b3d | |||
| 24e5c2a83f | |||
| e0f09ec2b9 | |||
| bb06432948 | |||
| 183dbb7c44 | |||
| 4b7b1aee96 | |||
| f9f414e948 | |||
| 47ed62f6c5 | |||
| 2d7ce00caa | |||
| c9bdf9bab1 | |||
| a61d553d73 | |||
| 80c66a1e57 | |||
| 055b4721b5 | |||
| 403b970e78 | |||
| f4a65b2590 | |||
| 07a4882beb | |||
| a3e1303f04 | |||
| ea6f6eb79d | |||
| 16ba9aaaef | |||
| b75a37491e | |||
| c9666cc8e6 | |||
| 223e27ef57 | |||
| 4002f0121e | |||
| 0e35829580 | |||
| 124a600535 | |||
| 2b503c8da9 | |||
| 6091786696 | |||
| 65d936296d | |||
| f5cfbe00df | |||
| 28d33505fd | |||
| 56304d6b95 | |||
| d8cfb7cbe5 | |||
| f4825c7b9d | |||
| e6b6e89163 | |||
| da7dc4670c | |||
| 1875ce520a | |||
| c0d7ac9ec2 | |||
| 0d337c9ff2 | |||
| b7c1d72a61 | |||
| 844f48ccdb | |||
| 57f13bfe73 | |||
| f11d6ffbb1 | |||
| 798a92db91 | |||
| be5180a6e0 | |||
| 200ddce88f | |||
| 0ba363d5b5 | |||
| 5f065441ca | |||
| 55cc287ad5 | |||
| 0e2d2a576b | |||
| a62f3fab45 | |||
| 577673dcf7 | |||
| 58fd2dccdc | |||
| d10b6f54c7 | |||
| c5d0da9dce | |||
| 3f81b2ac33 | |||
| 24660f6a37 | |||
| 80155e8605 | |||
| 921ab02b3b | |||
| 5d9f93395c | |||
| fd1bfaa823 | |||
| ee8a3a25b8 | |||
| 6ef1d37453 | |||
| 41c845b4a7 | |||
| acfa5cb2db | |||
| 8c6227f186 | |||
| 7b92f214bb | |||
| 626340b2a6 | |||
| af975d5bef | |||
| 4ac5ea3ee8 | |||
| 20e1a2470b | |||
| 59a6fe72a0 | |||
| fed626d4cb | |||
| e9b3d2072b | |||
| c5db867ddc | |||
| f9511bf6e8 | |||
| 40d8821dde | |||
| 9e02af8c7c | |||
| dc29e21b14 | |||
| e05d6db2cd | |||
| 32caa8b669 | |||
| 6790d3ceb1 | |||
| fff8056e7f | |||
| 0dd6102c79 | |||
| 78e72db19c | |||
| e2be52671e | |||
| e717980d77 | |||
| e9ac16ad02 | |||
| b8562eaf01 | |||
| 9aeede60cb | |||
| b96e571897 | |||
| 45a5aa8e01 | |||
| 33f9dba686 | |||
| b9aa77d1d0 | |||
| 7f74e35ffc | |||
| 8e9ab02444 | |||
| e5de9a0722 | |||
| 7c5ede6552 | |||
| d14603fdb5 | |||
| 591068afc7 | |||
| 482b6119c2 | |||
| 1142a1026b | |||
| 3f548610dd | |||
| c83e861a3f |
@@ -24,20 +24,20 @@ version: 2.1
|
||||
# **NOTE 2 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
|
||||
# **NOTE 3 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
|
||||
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
|
||||
var_3: &cache_key v7-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
var_3: &cache_key v8-angular-node-16-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
# We invalidate the cache if the Bazel version changes because otherwise the `bazelisk` cache
|
||||
# folder will contain all previously used versions and ultimately cause the cache restoring to
|
||||
# be slower due to its growing size.
|
||||
var_4: &cache_key_fallback v7-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
var_4: &cache_key_fallback v8-angular-node-16-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Windows needs its own cache key because binaries in node_modules are different.
|
||||
var_3_win: &cache_key_win v9-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}
|
||||
var_4_win: &cache_key_win_fallback v9-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
var_3_win: &cache_key_win v10-angular-win-node-16-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}
|
||||
var_4_win: &cache_key_win_fallback v10-angular-win-node-16-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
||||
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
||||
var_5: &components_repo_unit_tests_cache_key v1-angular-components-{{ checksum "month.txt" }}-7a24e95bafbdeb697f74a48e275c2442bcbefc74
|
||||
var_6: &components_repo_unit_tests_cache_key_fallback v1-angular-components-{{ checksum "month.txt" }}
|
||||
var_5: &components_repo_unit_tests_cache_key v2-angular-components-{{ checksum "month.txt" }}-7a24e95bafbdeb697f74a48e275c2442bcbefc74
|
||||
var_6: &components_repo_unit_tests_cache_key_fallback v2-angular-components-{{ checksum "month.txt" }}
|
||||
|
||||
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages`.
|
||||
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
|
||||
|
||||
@@ -5,38 +5,54 @@ body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
label: Describe the problem that you experienced
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: affected-url
|
||||
attributes:
|
||||
label: What is the affected URL?
|
||||
label: Enter the URL of the topic with the problem
|
||||
|
||||
- type: textarea
|
||||
id: documentation-goal
|
||||
attributes:
|
||||
label: Describe what you were looking for in the documentation
|
||||
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Please provide the steps to reproduce the issue
|
||||
label: Describe the actions that led you to experience the problem
|
||||
|
||||
- type: textarea
|
||||
id: expected-vs-actual-behavior
|
||||
attributes:
|
||||
label: Please provide the expected behavior vs the actual behavior you encountered
|
||||
label: Describe what you want to experience that would fix the problem
|
||||
|
||||
- type: textarea
|
||||
id: screenshot
|
||||
attributes:
|
||||
label: Please provide a screenshot if possible
|
||||
label: Add a screenshot if that helps illustrate the problem
|
||||
|
||||
- type: textarea
|
||||
id: exception-or-error
|
||||
attributes:
|
||||
label: Please provide the exception or error you saw
|
||||
label: If this problem caused an exception or error, please paste it here
|
||||
render: true
|
||||
placeholder: |
|
||||
```
|
||||
Paste the exception or error here inside a markdown code block,
|
||||
which is annotated by three grave \(`\) characters before and after the text block.
|
||||
```
|
||||
|
||||
- type: textarea
|
||||
id: browser-info
|
||||
attributes:
|
||||
label: Is this a browser-specific issue? If so, please specify the device, browser, and version.
|
||||
label: If the problem is browser-specific, please specify the device, OS, browser, and version
|
||||
render: true
|
||||
|
||||
- type: textarea
|
||||
id: additional-info
|
||||
attributes:
|
||||
label: Provide any additional information here in as much as detail as you can
|
||||
render: true
|
||||
|
||||
@@ -45,6 +45,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: 'Upload to code-scanning'
|
||||
uses: github/codeql-action/upload-sarif@2ca79b6fa8d3ec278944088b4aa5f46912db5d63 # tag=v2.1.18
|
||||
uses: github/codeql-action/upload-sarif@b398f525a5587552e573b247ac661067fafa920b # tag=v2.1.22
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
name: Update AIO events
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
schedule:
|
||||
# Run every day at 15:00.
|
||||
- cron: 0 15 * * *
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update_events:
|
||||
name: Update `events.json` (if necessary)
|
||||
if: github.repository == 'angular/angular'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
|
||||
with:
|
||||
# Setting `persist-credentials: false` prevents the github-action account from being the
|
||||
# account that is attempted to be used for authentication, instead the remote is set to
|
||||
# an authenticated URL.
|
||||
persist-credentials: false
|
||||
- name: Install AIO dependencies
|
||||
run: yarn --cwd=aio install
|
||||
- name: Generate `events.json`
|
||||
run: node aio/scripts/generate-events/index.mjs --ignore-invalid-dates
|
||||
- name: Create a PR (if necessary)
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@bf4bb09bb2d32015f71943371c7484cb845f8c33
|
||||
with:
|
||||
branch-prefix: docs-update-events
|
||||
pr-title: 'docs: update events'
|
||||
pr-description: |
|
||||
Generated `events.json` with the latest events retrieved from the Firebase DB.
|
||||
pr-labels: |
|
||||
action: review
|
||||
comp: docs
|
||||
target: patch
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
+3
-1
@@ -266,6 +266,8 @@ groups:
|
||||
'aio/content/images/guide/frequent-ngmodules/**/{*,.*}',
|
||||
'aio/content/guide/hierarchical-dependency-injection.md',
|
||||
'aio/content/examples/hierarchical-dependency-injection/**/{*,.*}',
|
||||
'aio/content/guide/image-directive.md',
|
||||
'aio/content/guide/image-directive-setup.md',
|
||||
'aio/content/examples/providers-viewproviders/**/{*,.*}',
|
||||
'aio/content/examples/resolution-modifiers/**/{*,.*}',
|
||||
'aio/content/guide/lazy-loading-ngmodules.md',
|
||||
@@ -1096,7 +1098,7 @@ groups:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
contains_any_globs(files.exclude('.pullapprove.yml'), [
|
||||
'{*,.*}',
|
||||
'.circleci/**/{*,.*}',
|
||||
'.devcontainer/**/{*,.*}',
|
||||
|
||||
+114
-85
@@ -1,3 +1,101 @@
|
||||
<a name="14.2.2"></a>
|
||||
# 14.2.2 (2022-09-14)
|
||||
### animations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [937e6c5b3d](https://github.com/angular/angular/commit/937e6c5b3d4c4bfc6ba202ee6692bc2fd8a35b89) | fix | make sure that the animation function delay is applied ([#47285](https://github.com/angular/angular/pull/47285)) |
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c9bdf9bab1](https://github.com/angular/angular/commit/c9bdf9bab1bc4cc4da207f6bfc8ebc75eb605486) | fix | rename `rawSrc` -> `ngSrc` in NgOptimizedImage directive ([#47362](https://github.com/angular/angular/pull/47362)) ([#47396](https://github.com/angular/angular/pull/47396)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a3e1303f04](https://github.com/angular/angular/commit/a3e1303f04d4afe456f3728939b3aa54e29f9fb3) | fix | imply @Optional flag when a default value is provided ([#47242](https://github.com/angular/angular/pull/47242)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [80c66a1e57](https://github.com/angular/angular/commit/80c66a1e57af33342ed851a0de886fc17b53f7a3) | fix | don't prevent default behavior for forms with method="dialog" ([#47308](https://github.com/angular/angular/pull/47308)) |
|
||||
## Special Thanks
|
||||
Abhishek Rawat, Andrew Kushnir, Benjamin Chanudet, Bob Watson, George Kalpakas, Ikko Ashimine, Kristiyan Kostadinov, Marc Wrobel, Mariia Subkov, Pawel Kozlowski, Sebastian, abergquist, dario-piotrowicz, onrails and vyom1611
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.1"></a>
|
||||
# 14.2.1 (2022-09-07)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c0d7ac9ec2](https://github.com/angular/angular/commit/c0d7ac9ec2df9af36d80382bc70c4580720f35a3) | fix | improve formatting of image warnings ([#47299](https://github.com/angular/angular/pull/47299)) |
|
||||
| [1875ce520a](https://github.com/angular/angular/commit/1875ce520afe7b5c55680b8c6a938a2331dda599) | fix | use DOCUMENT token to query for preconnect links ([#47353](https://github.com/angular/angular/pull/47353)) |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0e35829580](https://github.com/angular/angular/commit/0e3582958079f798a75240873aebf3c4f5e3df5b) | fix | avoid errors for inputs with Object-builtin names ([#47220](https://github.com/angular/angular/pull/47220)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [6091786696](https://github.com/angular/angular/commit/60917866961b7ab80ec9637c72300f2707aadd09) | fix | include headers in requests for assets ([#47260](https://github.com/angular/angular/pull/47260)) |
|
||||
| [28d33505fd](https://github.com/angular/angular/commit/28d33505fd4be00eaf4bf417cd27e20733ddfb80) | fix | only consider GET requests as navigation requests ([#47263](https://github.com/angular/angular/pull/47263)) |
|
||||
## Special Thanks
|
||||
Aristeidis Bampakos, Asaf M, Bingo's Code, Bob Watson, Daniel Ostrovsky, George Kalpakas, Giovanni Alberto Rivas, Jeremy Elbourn, Jobayer Hossain, Joe Martin (Crowdstaffing), Joey Perrott, JoostK, Kara Erickson, Kristiyan Kostadinov, Maina Wycliffe, Sabareesh Kappagantu, Simona Cotin, Sonu Sindhu, Yann Provoost, abergquist, jaybell and vyom1611
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.0"></a>
|
||||
# 14.2.0 (2022-08-25)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d5f7da2120](https://github.com/angular/angular/commit/d5f7da21207f7808dffb3932fa61d22614e6bd57) | feat | introduce the NgOptimizedImage directive ([#47082](https://github.com/angular/angular/pull/47082)) |
|
||||
| [e2ab99b95e](https://github.com/angular/angular/commit/e2ab99b95efd893c49d15c02cccd72ef82ea1cae) | fix | allow null/undefined to be passed to ngClass input ([#39280](https://github.com/angular/angular/pull/39280)) ([#46906](https://github.com/angular/angular/pull/46906)) |
|
||||
| [bedf537951](https://github.com/angular/angular/commit/bedf537951e64c55dde9b38936e451daa4a4bde9) | fix | allow null/undefined to be passed to ngStyle input ([#47069](https://github.com/angular/angular/pull/47069)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d1e83e1b30](https://github.com/angular/angular/commit/d1e83e1b30f2cea9f2ed16bff2d3b969335072ab) | feat | add `createComponent` function ([#46685](https://github.com/angular/angular/pull/46685)) |
|
||||
| [10becab70e](https://github.com/angular/angular/commit/10becab70e0f2afee29da7b3358eedcc22f655a2) | feat | add `reflectComponentType` function ([#46685](https://github.com/angular/angular/pull/46685)) |
|
||||
| [4b377d3a6d](https://github.com/angular/angular/commit/4b377d3a6d069da23ec577f8deca761b01d4e2f5) | feat | introduce createApplication API ([#46475](https://github.com/angular/angular/pull/46475)) |
|
||||
| [31429eaccc](https://github.com/angular/angular/commit/31429eaccc973672efb4ed98a628cf9842e24b02) | feat | support TypeScript 4.8 ([#47038](https://github.com/angular/angular/pull/47038)) |
|
||||
| [796840209c](https://github.com/angular/angular/commit/796840209cd38aacc5061a31701efe7eda1f6587) | fix | align TestBed interfaces and implementation ([#46635](https://github.com/angular/angular/pull/46635)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [426af91a42](https://github.com/angular/angular/commit/426af91a42104d6ce227ab52c8c4db3e218f5e03) | feat | add `FormBuilder.record()` method ([#46485](https://github.com/angular/angular/pull/46485)) |
|
||||
| [b302797de4](https://github.com/angular/angular/commit/b302797de47409b988ad77e87f766a5f18374ded) | fix | Correctly infer `FormBuilder` types involving `[value, validators]` shorthand in more cases. ([#47034](https://github.com/angular/angular/pull/47034)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [598b72bd05](https://github.com/angular/angular/commit/598b72bd05ea33468c70ac35b8ea5286439f41d9) | feat | support fix the component missing member ([#46764](https://github.com/angular/angular/pull/46764)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [07606e3181](https://github.com/angular/angular/commit/07606e3181fc7aa9f9185eb771fc9c44f01fe344) | feat | add `isEmpty` method to the `TransferState` class ([#46915](https://github.com/angular/angular/pull/46915)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2b4d7f6733](https://github.com/angular/angular/commit/2b4d7f6733e10e45e3ca8a448307bbc2834fc4a1) | feat | support document reference in render functions ([#47032](https://github.com/angular/angular/pull/47032)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0abb67af59](https://github.com/angular/angular/commit/0abb67af59a92a2b29082a259aa9f4ea3fbaab7d) | feat | allow guards and resolvers to be plain functions ([#46684](https://github.com/angular/angular/pull/46684)) |
|
||||
| [75df404467](https://github.com/angular/angular/commit/75df4044675c61d2b646437cfe64fe828a39b3a0) | feat | Create APIs for using Router without RouterModule ([#47010](https://github.com/angular/angular/pull/47010)) |
|
||||
| [10289f1f6e](https://github.com/angular/angular/commit/10289f1f6e3d5935304a38d4300d4dadfea66150) | feat | expose resolved route title ([#46826](https://github.com/angular/angular/pull/46826)) |
|
||||
| [8600732b09](https://github.com/angular/angular/commit/8600732b090a4c253eb89ffde6db3858e4a2021c) | feat | Expose the default matcher for `Routes` used by the `Router` ([#46913](https://github.com/angular/angular/pull/46913)) |
|
||||
| [422323cee0](https://github.com/angular/angular/commit/422323cee00192239d1ab279e6a7c3a808098169) | feat | improve typings for RouterLink boolean inputs ([#47101](https://github.com/angular/angular/pull/47101)) |
|
||||
| [26ea97688c](https://github.com/angular/angular/commit/26ea97688cba5850588d8da83abaf8b539577241) | feat | Make router directives standalone ([#46758](https://github.com/angular/angular/pull/46758)) |
|
||||
| [2a43beec15](https://github.com/angular/angular/commit/2a43beec159990b8c4bafc7f189e2bd85002dc7a) | fix | Fix route recognition behavior with some versions of rxjs ([#47098](https://github.com/angular/angular/pull/47098)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [383090858c](https://github.com/angular/angular/commit/383090858caf04c27ee8b320cceca2da0ae54bb3) | feat | support `sendRequest` as a `notificationclick` action ([#46912](https://github.com/angular/angular/pull/46912)) |
|
||||
| [3f548610dd](https://github.com/angular/angular/commit/3f548610dd05f484cd33fa2cee4e3693ed731126) | fix | export NoNewVersionDetectedEvent ([#47044](https://github.com/angular/angular/pull/47044)) |
|
||||
| [482b6119c2](https://github.com/angular/angular/commit/482b6119c2f3fff5ec0623e101d308a49c416b42) | fix | update golden `index.md` ([#47044](https://github.com/angular/angular/pull/47044)) |
|
||||
## Special Thanks
|
||||
Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Bob Watson, Cédric Exbrayat, Dylan Hunn, Emmanuel Roux, FatalMerlin, George Kalpakas, Ilia Mirkin, Jan Kuehle, Jeremy Elbourn, Jessica Janiuk, JiaLiPassion, Kalbarczyk, Kara Erickson, Katie Hempenius, Kristiyan Kostadinov, Merlin, Paul Gschwendtner, Pawel Kozlowski, Tristan Sprößer, Victor Porof, angular-robot[bot], dario-piotrowicz, ivanwonder and vyom
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.1.3"></a>
|
||||
# 14.1.3 (2022-08-17)
|
||||
### compiler
|
||||
@@ -24,74 +122,6 @@ AlirezaEbrahimkhani, Alma Eyre, Andrew Scott, Bob Watson, George Kalpakas, Kalba
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.0-next.1"></a>
|
||||
# 14.2.0-next.1 (2022-08-10)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [bedf537951](https://github.com/angular/angular/commit/bedf537951e64c55dde9b38936e451daa4a4bde9) | fix | allow null/undefined to be passed to ngStyle input ([#47069](https://github.com/angular/angular/pull/47069)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ea89677c12](https://github.com/angular/angular/commit/ea89677c125c16654e3e521998b575687c2bd20c) | feat | support more recent version of `tsickle` ([#47018](https://github.com/angular/angular/pull/47018)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [dbed2cf079](https://github.com/angular/angular/commit/dbed2cf079c52825ce0aa67fc2a46bc3d38f408f) | fix | check if transplanted views are attached to change detector ([#46974](https://github.com/angular/angular/pull/46974)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2b4d7f6733](https://github.com/angular/angular/commit/2b4d7f6733e10e45e3ca8a448307bbc2834fc4a1) | feat | support document reference in render functions ([#47032](https://github.com/angular/angular/pull/47032)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0abb67af59](https://github.com/angular/angular/commit/0abb67af59a92a2b29082a259aa9f4ea3fbaab7d) | feat | allow guards and resolvers to be plain functions ([#46684](https://github.com/angular/angular/pull/46684)) |
|
||||
| [2a43beec15](https://github.com/angular/angular/commit/2a43beec159990b8c4bafc7f189e2bd85002dc7a) | fix | Fix route recognition behavior with some versions of rxjs ([#47098](https://github.com/angular/angular/pull/47098)) |
|
||||
## Special Thanks
|
||||
4javier, Andrew Kushnir, Andrew Scott, AntonioCardenas, Bob Watson, Bruno Barbosa, Eduardo Speroni, Edward, George Kalpakas, Ilia Mirkin, Jan Melcher, Jessica Janiuk, JiaLiPassion, Kristiyan Kostadinov, Mladen Jakovljević, Paul Gschwendtner, Pawel Kozlowski, Roman Matusevich, Victor Porof, Vovch, ashide2729, ileil and onrails
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.0-next.0"></a>
|
||||
# 14.2.0-next.0 (2022-08-03)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e2ab99b95e](https://github.com/angular/angular/commit/e2ab99b95efd893c49d15c02cccd72ef82ea1cae) | fix | allow null/undefined to be passed to ngClass input ([#39280](https://github.com/angular/angular/pull/39280)) ([#46906](https://github.com/angular/angular/pull/46906)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d1e83e1b30](https://github.com/angular/angular/commit/d1e83e1b30f2cea9f2ed16bff2d3b969335072ab) | feat | add `createComponent` function ([#46685](https://github.com/angular/angular/pull/46685)) |
|
||||
| [10becab70e](https://github.com/angular/angular/commit/10becab70e0f2afee29da7b3358eedcc22f655a2) | feat | add `reflectComponentType` function ([#46685](https://github.com/angular/angular/pull/46685)) |
|
||||
| [4b377d3a6d](https://github.com/angular/angular/commit/4b377d3a6d069da23ec577f8deca761b01d4e2f5) | feat | introduce createApplication API ([#46475](https://github.com/angular/angular/pull/46475)) |
|
||||
| [796840209c](https://github.com/angular/angular/commit/796840209cd38aacc5061a31701efe7eda1f6587) | fix | align TestBed interfaces and implementation ([#46635](https://github.com/angular/angular/pull/46635)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [426af91a42](https://github.com/angular/angular/commit/426af91a42104d6ce227ab52c8c4db3e218f5e03) | feat | add `FormBuilder.record()` method ([#46485](https://github.com/angular/angular/pull/46485)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [598b72bd05](https://github.com/angular/angular/commit/598b72bd05ea33468c70ac35b8ea5286439f41d9) | feat | support fix the component missing member ([#46764](https://github.com/angular/angular/pull/46764)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [07606e3181](https://github.com/angular/angular/commit/07606e3181fc7aa9f9185eb771fc9c44f01fe344) | feat | add `isEmpty` method to the `TransferState` class ([#46915](https://github.com/angular/angular/pull/46915)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [10289f1f6e](https://github.com/angular/angular/commit/10289f1f6e3d5935304a38d4300d4dadfea66150) | feat | expose resolved route title ([#46826](https://github.com/angular/angular/pull/46826)) |
|
||||
| [8600732b09](https://github.com/angular/angular/commit/8600732b090a4c253eb89ffde6db3858e4a2021c) | feat | Expose the default matcher for `Routes` used by the `Router` ([#46913](https://github.com/angular/angular/pull/46913)) |
|
||||
| [26ea97688c](https://github.com/angular/angular/commit/26ea97688cba5850588d8da83abaf8b539577241) | feat | Make router directives standalone ([#46758](https://github.com/angular/angular/pull/46758)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [383090858c](https://github.com/angular/angular/commit/383090858caf04c27ee8b320cceca2da0ae54bb3) | feat | support `sendRequest` as a `notificationclick` action ([#46912](https://github.com/angular/angular/pull/46912)) |
|
||||
## Special Thanks
|
||||
Andrew Kushnir, Andrew Scott, Cédric Exbrayat, Emmanuel Roux, George Kalpakas, Ilia Mirkin, Jessica Janiuk, Paul Gschwendtner, Pawel Kozlowski, Tristan Sprößer, angular-robot[bot], dario-piotrowicz and ivanwonder
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.1.1"></a>
|
||||
# 14.1.1 (2022-08-03)
|
||||
### core
|
||||
@@ -166,7 +196,7 @@ Alan Agius, Andrew Kushnir, Andrew Quinn, Andrew Scott, Aristeidis Bampakos, Asa
|
||||
| [ce20ed067f](https://github.com/angular/angular/commit/ce20ed067f12714ee6488ffe07f1a1c18bb60a15) | fix | Ensure Route injector is created before running CanMatch guards ([#46394](https://github.com/angular/angular/pull/46394)) |
|
||||
| [6a7b818d94](https://github.com/angular/angular/commit/6a7b818d94fdd13d81a01285e3e4be953a29cc06) | fix | Ensure target `RouterStateSnapshot` is defined in `NavigationError` ([#46842](https://github.com/angular/angular/pull/46842)) |
|
||||
| [f94c6f433d](https://github.com/angular/angular/commit/f94c6f433dba3924b79f137cfcc49d2dfd4d679c) | fix | Expose CanMatchFn as public API ([#46394](https://github.com/angular/angular/pull/46394)) |
|
||||
| [e8ae0fe3e9](https://github.com/angular/angular/commit/e8ae0fe3e91e2e805146fad0d2f0976b1f886112) | fix | Fix cancellation code for canLoad rejections ([#46752](https://github.com/angular/angular/pull/46752)) |
|
||||
| [e8ae0fe3e9](https://github.com/angular/angular/commit/e8ae0fe3e91e2e805146fad0d2f0976b1f886112) | fix | Fix cancelation code for canLoad rejections ([#46752](https://github.com/angular/angular/pull/46752)) |
|
||||
### upgrade
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
@@ -380,7 +410,7 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
|
||||
|
||||
This tightens parameter types of `TransferState` usage, and is a minor breaking change which may reveal existing problematic calls.
|
||||
### router
|
||||
- The type of `Route.pathMatch` is now more strict. Places that use
|
||||
- The type of `Route.pathMatch` is now stricter. Places that use
|
||||
`pathMatch` will likely need to be updated to have an explicit
|
||||
`Route`/`Routes` type so that TypeScript does not infer the type as
|
||||
`string`.
|
||||
@@ -620,7 +650,7 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ec0a0e0669](https://github.com/angular/angular/commit/ec0a0e0669ef5d2f524fbf9a540eb2b306b2e24a) | feat | add `cacheOpaqueResponses` option for data-groups ([#44723](https://github.com/angular/angular/pull/44723)) |
|
||||
| [bd04fbc05b](https://github.com/angular/angular/commit/bd04fbc05b0397de966a493a863e1054203c86d9) | feat | emit a notification when the service worker is already up to date after check ([#45216](https://github.com/angular/angular/pull/45216)) |
|
||||
| [bd04fbc05b](https://github.com/angular/angular/commit/bd04fbc05b0397de966a493a863e1054203c86d9) | feat | emit a notification when the service worker is already up-to-date after check ([#45216](https://github.com/angular/angular/pull/45216)) |
|
||||
## Special Thanks
|
||||
Adrian Kunz, Alan Agius, AleksanderBodurri, Alex Rickabaugh, AlirezaEbrahimkhani, Amir Rustamzadeh, Andrew Kushnir, Andrew Scott, Chabbey François, Charles Lyding, Cédric Exbrayat, Daan De Smedt, David Schmidt, Derek Cormier, Dmitrij Kuba, Doug Parker, Dylan Hunn, Emma Twersky, George Kalpakas, George Looshch, Jan Kuehle, Jessica Janiuk, JiaLiPassion, JimMorrison723, Joe Martin (Crowdstaffing), Joey Perrott, JoostK, Kristiyan Kostadinov, Krzysztof Platis, Leosvel Pérez Espinosa, Maddie Klein, Mark Whitfeld, Martin Sikora, Michael-Doner, Michal Materowski, Minko Gechev, Paul Gschwendtner, Pawel Kozlowski, Payam Shahidi, Pusztai Tibor, Ricardo Mattiazzi Baumgartner, Roy Dorombozi, Ruslan Lekhman, Samuel Littley, Sergej Grilborzer, Sumit Arora, Tobias Speicher, Virginia Dooley, Zack Elliott, alirezaghey, ananyahs96, arturovt, cexbrayat, dario-piotrowicz, ivanwonder, kamikopi, markostanimirovic, markwhitfeld, mgechev, renovate[bot], twerske and zverbeta
|
||||
|
||||
@@ -1040,7 +1070,7 @@ Aristeidis Bampakos, Dylan Hunn, George Kalpakas, JoostK, Kristiyan Kostadinov,
|
||||
- The `downgradeModule` function calls with NgModule factories are deprecated. Please use NgModule class based `downgradeModule` calls instead.
|
||||
### common
|
||||
- `TestRequest` from `@angular/common/http/testing` no longer
|
||||
accepts `ErrorEvent` when simulating XHR errors. Instead instances of
|
||||
accepts `ErrorEvent` when simulating XHR errors. Instead, instances of
|
||||
`ProgressEvent` should be passed, matching with the native browser behavior.
|
||||
###
|
||||
| Commit | Type | Description |
|
||||
@@ -1262,11 +1292,11 @@ return type.
|
||||
### core
|
||||
- Angular no longer requires component factories to dynamically create components. The factory-based signature of the `ViewContainerRef.createComponent` function is deprecated in favor of a different signature that allows passing component classes instead.
|
||||
|
||||
- The `getModuleFactory` function is deprecated in favor of the `getNgModuleById` one. With Ivy it's possible to work with NgModule classes directly, without retrieving corresponding factories, so the `getNgModuleById` should be used instead.
|
||||
- The `getModuleFactory` function is deprecated in favor of the `getNgModuleById` one. With Ivy, it's possible to work with NgModule classes directly, without retrieving corresponding factories, so the `getNgModuleById` should be used instead.
|
||||
|
||||
- Ivy made it possible to avoid the need to resolve Component and NgModule factories. Framework APIs allow to use Component and NgModule Types directly. As a result, the `PlatformRef.bootstrapModuleFactory` and a factory-based signature of the `ApplicationRef.bootstrap` method are now obsolete and are now deprecated. The `PlatformRef.bootstrapModuleFactory` calls can be replaced with `PlatformRef.bootstrapModule` ones. The `ApplicationRef.bootstrap` method allows to provide Component Type, so this can be used a replacement for the factory-based calls.
|
||||
|
||||
- In ViewEngine, [JIT compilation](https://angular.io/guide/glossary#jit) required special providers (like `Compiler`, `CompilerFactory`, etc) to be injected in the app and corresponding methods to be invoked. With Ivy, JIT compilation takes place implicitly if the Component, NgModule, etc have not already been [AOT compiled](https://angular.io/guide/glossary#aot). Those special providers were made available in Ivy for backwards-compatibility with ViewEngine to make the transition to Ivy smoother. Since ViewEngine is deprecated and will soon be removed, those symbols are now deprecated as well:
|
||||
- In ViewEngine, [JIT compilation](https://angular.io/guide/glossary#jit) required special providers (like `Compiler`, `CompilerFactory`, etc) to be injected in the app and corresponding methods to be invoked. With Ivy, JIT compilation takes place implicitly if the Component, NgModule, etc. have not already been [AOT compiled](https://angular.io/guide/glossary#aot). Those special providers were made available in Ivy for backwards-compatibility with ViewEngine to make the transition to Ivy smoother. Since ViewEngine is deprecated and will soon be removed, those symbols are now deprecated as well:
|
||||
|
||||
- `ModuleWithComponentFactories`
|
||||
- `Compiler`
|
||||
@@ -2207,7 +2237,7 @@ Alex Rickabaugh, Daniel Díaz, David Shevitz, Dylan Hunn, Front-end developer, G
|
||||
* **router:** update type castings for JSON.parse usage ([#40710](https://github.com/angular/angular/issues/40710)) ([350dada](https://github.com/angular/angular/commit/350dada))
|
||||
* **service-worker:** update supported range of node versions to only include LTS versions ([#41822](https://github.com/angular/angular/issues/41822)) ([6b823d7](https://github.com/angular/angular/commit/6b823d7071d59234ab52bdf7eaa248df6b7d9faa))
|
||||
* **service-worker:** update type castings for JSON.parse usage ([#40710](https://github.com/angular/angular/issues/40710)) ([4f7ff96](https://github.com/angular/angular/commit/4f7ff96))
|
||||
* **upgrade:** preserve $interval.flush when ngMocks is being used ([#30229](https://github.com/angular/angular/issues/30229)) ([87dc851](https://github.com/angular/angular/commit/87dc8511ccb9c75d78866ebd2c250ea96fc91bd0))
|
||||
* **upgrade:** preserve $interval flush when ngMocks is being used ([#30229](https://github.com/angular/angular/issues/30229)) ([87dc851](https://github.com/angular/angular/commit/87dc8511ccb9c75d78866ebd2c250ea96fc91bd0))
|
||||
* **upgrade:** update supported range of node versions to only include LTS versions ([#41822](https://github.com/angular/angular/issues/41822)) ([10c4523](https://github.com/angular/angular/commit/10c45239a68e82ea52c1601fae09953aa7843351))
|
||||
|
||||
|
||||
@@ -2223,7 +2253,7 @@ Alex Rickabaugh, Daniel Díaz, David Shevitz, Dylan Hunn, Front-end developer, G
|
||||
* **bazel:** update supported range of node versions ([#41544](https://github.com/angular/angular/issues/41544)) ([d583d92](https://github.com/angular/angular/commit/d583d926db537cc74f9235cad51189dbe83fbb44))
|
||||
* **common:** update supported range of node versions ([#41544](https://github.com/angular/angular/issues/41544)) ([e0250e5](https://github.com/angular/angular/commit/e0250e567ae47ed7b77e9d88a3289727c056a6f1))
|
||||
* **common:** add `historyGo` method to `Location` service ([#38890](https://github.com/angular/angular/issues/38890)) ([e05a6f3](https://github.com/angular/angular/commit/e05a6f3bb3048e9a94a4b154526221dea290312d))
|
||||
* **common:** support ICU standard "stand alone day of week" with `DatePipe` ([#40766](https://github.com/angular/angular/issues/40766)) ([c56ecab](https://github.com/angular/angular/commit/c56ecab515c28d2ad45c630080bfbf549675528a)), closes [#26922](https://github.com/angular/angular/issues/26922)
|
||||
* **common:** support ICU standard "stand-alone day of week" with `DatePipe` ([#40766](https://github.com/angular/angular/issues/40766)) ([c56ecab](https://github.com/angular/angular/commit/c56ecab515c28d2ad45c630080bfbf549675528a)), closes [#26922](https://github.com/angular/angular/issues/26922)
|
||||
* **common:** implement `appendAll()` method on `HttpParams` ([#20930](https://github.com/angular/angular/issues/20930)) ([575a2d1](https://github.com/angular/angular/commit/575a2d1)), closes [#20798](https://github.com/angular/angular/issues/20798)
|
||||
* **compiler:** support nullish coalescing in templates ([#41437](https://github.com/angular/angular/issues/41437)) ([ec27bd4](https://github.com/angular/angular/commit/ec27bd4ed1cc086d76d8142fadf87354b38aa61a)), closes [#36528](https://github.com/angular/angular/issues/36528)
|
||||
* **compiler:** update supported range of node versions ([#41544](https://github.com/angular/angular/issues/41544)) ([75cc813](https://github.com/angular/angular/commit/75cc8133ad8efd6453694f222e2cc6789c4de7b2))
|
||||
@@ -2307,7 +2337,7 @@ migrate their message ids using the `localize-migrate` command line tool.
|
||||
* **core:** Angular no longer maintains support for node v10
|
||||
* **core:** Previously the `ng.getDirectives` function threw an error in case a
|
||||
given DOM node had no Angular context associated with it (for example
|
||||
if a function was called for a DOM element outside of an Angular app).
|
||||
if a function was called for a DOM element outside an Angular app).
|
||||
This behavior was inconsistent with other debugging utilities under `ng`
|
||||
namespace, which handled this situation without raising an exception.
|
||||
Now calling the `ng.getDirectives` function for such DOM nodes would
|
||||
@@ -2341,8 +2371,7 @@ export class QueryCompWithStrictChangeEmitParent {
|
||||
}
|
||||
```
|
||||
For backward compatibility before v12
|
||||
`emitDistinctChangesOnlyDefaultValue` was set to `false`. This change
|
||||
changes the default to `true`.
|
||||
`emitDistinctChangesOnlyDefaultValue` was set to `false`. This change the default to `true`.
|
||||
* **core:** The type of the `APP_INITIALIZER` token has been changed to more accurately
|
||||
reflect the types of return values that are handled by Angular. Previously,
|
||||
each initializer callback was typed to return `any`, this is now
|
||||
@@ -2353,7 +2382,7 @@ the stricter type.
|
||||
|
||||
Additionally, TypeScript may report the TS2742 error if the `APP_INITIALIZER`
|
||||
token is used in an expression of which its inferred type has to be emitted
|
||||
into a .d.ts file. To workaround this, an explicit type annotation is needed,
|
||||
into a .d.ts file. To work around this, an explicit type annotation is needed,
|
||||
which would typically be `Provider` or `Provider[]`.
|
||||
* **core:** Minimum supported `zone.js` version is `0.11.4`
|
||||
* **forms:** The `emitEvent` option was added to the following `FormArray` and `FormGroup` methods:
|
||||
@@ -2438,7 +2467,7 @@ Alex Rickabaugh, Andrew J Asche, Georgii Dolzhykov, Joey Perrott, Joost Koehoorn
|
||||
* **core:** Angular no longer maintains support for node v10
|
||||
* **core:** Previously the `ng.getDirectives` function threw an error in case a
|
||||
given DOM node had no Angular context associated with it (for example
|
||||
if a function was called for a DOM element outside of an Angular app).
|
||||
if a function was called for a DOM element outside an Angular app).
|
||||
This behavior was inconsistent with other debugging utilities under `ng`
|
||||
namespace, which handled this situation without raising an exception.
|
||||
Now calling the `ng.getDirectives` function for such DOM nodes would
|
||||
@@ -2782,7 +2811,7 @@ This release contains the same set the of changes as 11.2.0-next.1.
|
||||
* **core:** Allow passing AbstractType to the inject function ([#37958](https://github.com/angular/angular/issues/37958)) ([a1b6ad0](https://github.com/angular/angular/commit/a1b6ad0))
|
||||
* **core:** Ensure OnPush ancestors are marked dirty when events occur ([#39833](https://github.com/angular/angular/issues/39833)) ([68d4a74](https://github.com/angular/angular/commit/68d4a74)), closes [#39832](https://github.com/angular/angular/issues/39832)
|
||||
* **core:** meta addTag() adds incorrect attribute for httpEquiv ([#32531](https://github.com/angular/angular/issues/32531)) ([ff0a90e](https://github.com/angular/angular/commit/ff0a90e))
|
||||
* **core:** migration error if program contains files outside of the project ([#39790](https://github.com/angular/angular/issues/39790)) ([1a26f6d](https://github.com/angular/angular/commit/1a26f6d)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** migration error if program contains files outside the project ([#39790](https://github.com/angular/angular/issues/39790)) ([1a26f6d](https://github.com/angular/angular/commit/1a26f6d)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** not invoking object's toString when rendering to the DOM ([#39843](https://github.com/angular/angular/issues/39843)) ([11cd37f](https://github.com/angular/angular/commit/11cd37f)), closes [#38839](https://github.com/angular/angular/issues/38839)
|
||||
* **core:** remove duplicated noop function ([#39761](https://github.com/angular/angular/issues/39761)) ([066126a](https://github.com/angular/angular/commit/066126a))
|
||||
* **core:** support `Attribute` DI decorator in `deps` section of a token ([#37085](https://github.com/angular/angular/issues/37085)) ([f5cbf0b](https://github.com/angular/angular/commit/f5cbf0b)), closes [#36479](https://github.com/angular/angular/issues/36479)
|
||||
@@ -2980,7 +3009,7 @@ This release contains the same set the of changes as 11.2.0-next.1.
|
||||
* **compiler-cli:** report error when a reference target is missing instead of crashing ([#39805](https://github.com/angular/angular/issues/39805)) ([8634611](https://github.com/angular/angular/commit/8634611)), closes [#38618](https://github.com/angular/angular/issues/38618) [#39744](https://github.com/angular/angular/issues/39744)
|
||||
* **core:** Ensure OnPush ancestors are marked dirty when events occur ([#39833](https://github.com/angular/angular/issues/39833)) ([01c1bfd](https://github.com/angular/angular/commit/01c1bfd)), closes [#39832](https://github.com/angular/angular/issues/39832)
|
||||
* **core:** meta addTag() adds incorrect attribute for httpEquiv ([#32531](https://github.com/angular/angular/issues/32531)) ([3114b0a](https://github.com/angular/angular/commit/3114b0a))
|
||||
* **core:** migration error if program contains files outside of the project ([#39790](https://github.com/angular/angular/issues/39790)) ([7dcc212](https://github.com/angular/angular/commit/7dcc212)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** migration error if program contains files outside the project ([#39790](https://github.com/angular/angular/issues/39790)) ([7dcc212](https://github.com/angular/angular/commit/7dcc212)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** not invoking object's toString when rendering to the DOM ([#39843](https://github.com/angular/angular/issues/39843)) ([75e22ab](https://github.com/angular/angular/commit/75e22ab)), closes [#38839](https://github.com/angular/angular/issues/38839)
|
||||
* **core:** remove duplicated noop function ([#39761](https://github.com/angular/angular/issues/39761)) ([26a1337](https://github.com/angular/angular/commit/26a1337))
|
||||
* **core:** support `Attribute` DI decorator in `deps` section of a token ([#37085](https://github.com/angular/angular/issues/37085)) ([aaa3111](https://github.com/angular/angular/commit/aaa3111)), closes [#36479](https://github.com/angular/angular/issues/36479)
|
||||
@@ -3183,7 +3212,7 @@ This release contains the same set the of changes as 11.2.0-next.1.
|
||||
`CollectionChangeRecord` has been removed, use `IterableChangeRecord` instead.
|
||||
- **[c8f056b](https://github.com/angular/angular/commit/c8f056beb696d176530ee4e86f64964c3b834c9a):**
|
||||
If you call `TestBed.overrideProvider` after TestBed initialization, provider overrides are not applied.
|
||||
This behavior is consistent with other override methods (such as `TestBed.overrideDirective`, etc) but they throw an error to indicate that, when the check was missing in the `TestBed.overrideProvider` function.
|
||||
This behavior is consistent with other override methods (such as `TestBed.overrideDirective`, etc.) but they throw an error to indicate that, when the check was missing in the `TestBed.overrideProvider` function.
|
||||
Now calling `TestBed.overrideProvider` after `TestBed` initialization also triggers an error, thus there is a chance that some tests (where `TestBed.overrideProvider` is called after `TestBed` initialization) will start to fail and require updates to move `TestBed.overrideProvider` calls before `TestBed` initialization is completed.
|
||||
- **[4ca1c73](https://github.com/angular/angular/commit/4ca1c736bb020de166b6a1fbfb9fe264602ccd5c):**
|
||||
In v10, IE 9, 10, and IE mobile support was deprecated.
|
||||
@@ -3209,7 +3238,7 @@ This release contains the same set the of changes as 11.2.0-next.1.
|
||||
In an unlikely case your code was testing the parent against `undefined` with strict equality, you'll need to change this to `=== null` instead, since the parent is now explicitly initialized with `null` instead of being left `undefined`.
|
||||
* **platform-server:**
|
||||
- **[b4e8399](https://github.com/angular/angular/commit/b4e8399144ae4b6d4f0da9ff2a8e1fa73643f766):**
|
||||
If you use `useAbsoluteUrl` to setup `platform-server`, you now need to also specify `baseUrl`.
|
||||
If you use `useAbsoluteUrl` to set up `platform-server`, you now need to also specify `baseUrl`.
|
||||
We are intentionally making this a breaking change in a minor release, because if `useAbsoluteUrl` is set to `true` then the behavior of the application could be unpredictable, resulting in issues that are hard to discover but could be affecting production environments.
|
||||
* **platform-webworker:**
|
||||
- **[93c3d8f](https://github.com/angular/angular/commit/93c3d8f9fd79014bf700a1447503f5ee6f170bf9):**
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an safe and welcoming environment, we as
|
||||
In the interest of fostering a safe and welcoming environment, we as
|
||||
the Angular team pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity, gender expression,
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ A minimal reproduction allows us to quickly confirm a bug (or point out a coding
|
||||
|
||||
We require a minimal reproduction to save maintainers' time and ultimately be able to fix more bugs.
|
||||
Often, developers find coding problems themselves while preparing a minimal reproduction.
|
||||
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
|
||||
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase, but we really need to isolate the problem before we can fix it.
|
||||
|
||||
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced.
|
||||
|
||||
|
||||
@@ -158,10 +158,10 @@ cldr_xml_data_repository(
|
||||
# sass rules
|
||||
http_archive(
|
||||
name = "io_bazel_rules_sass",
|
||||
sha256 = "85b34f2e5e227aa586b6e0fd6942262e17b3cface596891eeef5a29a0b7467e3",
|
||||
strip_prefix = "rules_sass-697e5a08bdd39aee49f2c6f4eb621ef59e677e49",
|
||||
sha256 = "a5ff47737667d644dba00af5444b6723fd5ddae2db80ee2f1e202bf0ccfcd4ef",
|
||||
strip_prefix = "rules_sass-f3874ae3ddbdab73a0a0e7bc14909d498c464ad9",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_sass/archive/697e5a08bdd39aee49f2c6f4eb621ef59e677e49.zip",
|
||||
"https://github.com/bazelbuild/rules_sass/archive/f3874ae3ddbdab73a0a0e7bc14909d498c464ad9.zip",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -90,7 +90,6 @@ TEST_DEPS = APPLICATION_DEPS + [
|
||||
"@aio_npm//karma-jasmine",
|
||||
"@aio_npm//karma-jasmine-html-reporter",
|
||||
"@aio_npm//puppeteer",
|
||||
"@aio_npm//timezone-mock",
|
||||
]
|
||||
|
||||
architect(
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ serve the files in `dist/` with `yarn http-server dist -p 4200`.
|
||||
|
||||
There are two types of content in the documentation:
|
||||
|
||||
* **API docs**: descriptions of the modules, classes, interfaces, decorators, etc that make up the Angular platform.
|
||||
* **API docs**: descriptions of all that make up the Angular platform, such as the modules, classes, interfaces or decorators.
|
||||
API docs are generated directly from the source code.
|
||||
The source code is contained in TypeScript files, located in the `angular/packages` folder.
|
||||
Each API item may have a preceding comment, which contains JSDoc style tags and content.
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Update the angular.io app
|
||||
|
||||
The dependencies of the angular.io app (including Angular, Angular Material and Angular CLI) are automatically updated using [Renovate](https://renovatebot.com/).
|
||||
|
||||
However, it is useful to periodically also manually update the app to more closely match (in file layout, configs, etc.) what a new Angular CLI app would look like.
|
||||
This is typically only needed once for each new major Angular version.
|
||||
|
||||
Since angular.io is an Angular CLI app, we can take advantage of `ng update` to apply migrations.
|
||||
|
||||
Follow these steps to align the angular.io app with new CLI apps.
|
||||
|
||||
> **Note:**
|
||||
> The following steps assume that the related Angular dependencies have already been updated in [aio/package.json](./package.json) (for example, automatically by Renovate).
|
||||
|
||||
> **Note:**
|
||||
> All commands shown below are expected to be executed from inside the [aio/](./) directory (unless specified otherwise).
|
||||
|
||||
- Determine (for example, by examining git history) what is the last versions for which this process was performed.
|
||||
These will be referred to as `<FROM_VERSION_*>`.
|
||||
If you can't determine these, use arbitrary versions, such as the previous major version.
|
||||
|
||||
- Run the following commands to automatically apply any available migrations to the project:
|
||||
```sh
|
||||
# Ensure dependencies are installed.
|
||||
yarn install
|
||||
|
||||
# Migrate project to new versions.
|
||||
yarn ng update @angular/cli --allow-dirty --migrate-only --from=<FROM_VERSION_CLI>
|
||||
yarn ng update @angular/core --allow-dirty --migrate-only --from=<FROM_VERSION_ANGULAR>
|
||||
yarn ng update @angular/material --allow-dirty --migrate-only --from=<FROM_VERSION_MATERIAL>
|
||||
```
|
||||
|
||||
> **Note:**
|
||||
> Depending on the number of changes generated from each `ng update` command, it might make sense to create a separate commit for each update.
|
||||
|
||||
- Inspect [package.json](./package.json) to determine what is the current version of Angular CLI (i.e. `@angular/cli`) used in the app.
|
||||
This will be referred to as `<TO_VERSION_CLI>`.
|
||||
|
||||
- Use the [angular-cli-diff](https://github.com/cexbrayat/angular-cli-diff) repository to discover more changes (which are not automatically applied via `ng update` migrations) between Angular CLI apps of different versions.
|
||||
Visit https://github.com/cexbrayat/angular-cli-diff/compare/<FROM_VERSION_CLI>...<TO_VERSION_CLI>, inspect the changes between the two versions and apply the ones that make sense to the angular.io source code.
|
||||
|
||||
- Commit all changes and [submit a pull request](../CONTRIBUTING.md#submit-pr).
|
||||
@@ -40,7 +40,7 @@ ARG AIO_TRUSTED_PR_LABEL="aio: preview"
|
||||
ARG TEST_AIO_TRUSTED_PR_LABEL=$AIO_TRUSTED_PR_LABEL
|
||||
ARG AIO_PREVIEW_SERVER_HOSTNAME=preview.localhost
|
||||
ARG TEST_AIO_PREVIEW_SERVER_HOSTNAME=$AIO_PREVIEW_SERVER_HOSTNAME
|
||||
ARG AIO_ARTIFACT_MAX_SIZE=26214400
|
||||
ARG AIO_ARTIFACT_MAX_SIZE=36700160
|
||||
ARG TEST_AIO_ARTIFACT_MAX_SIZE=200
|
||||
ARG AIO_PREVIEW_SERVER_PORT=3000
|
||||
ARG TEST_AIO_PREVIEW_SERVER_PORT=3001
|
||||
|
||||
@@ -49,6 +49,6 @@
|
||||
"supertest": "^6.0.0",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-jasmine-noSkipOrFocus": "^1.0.9",
|
||||
"typescript": "~4.7.2"
|
||||
"typescript": "~4.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1668,10 +1668,10 @@ type-is@~1.6.18:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
typescript@~4.7.2:
|
||||
version "4.7.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
|
||||
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
|
||||
typescript@~4.8.0:
|
||||
version "4.8.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790"
|
||||
integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==
|
||||
|
||||
unbox-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
|
||||
@@ -30,4 +30,5 @@
|
||||
|
||||
## Miscellaneous
|
||||
- [Debug docker container](misc--debug-docker-container.md)
|
||||
- [Use Let's Encrypt certificates](misc--use-lets-encrypt-certs.md)
|
||||
- [Integrate with CI](misc--integrate-with-ci.md)
|
||||
|
||||
@@ -26,7 +26,7 @@ you don't need to specify values for those.
|
||||
See also `AIO_GITHUB_TEAM_SLUGS`.
|
||||
|
||||
- `AIO_GITHUB_REPO`:
|
||||
The Github repository for which PRs will be hosted.
|
||||
The GitHub repository for which PRs will be hosted.
|
||||
|
||||
- `AIO_GITHUB_TEAM_SLUGS`:
|
||||
A comma-separated list of teams, whose authors are allowed to preview PRs.
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# Miscellaneous - Use Let's Encrypt TLS certificates
|
||||
|
||||
|
||||
[Let's Encrypt](https://letsencrypt.org/) is a free, automated, and open certificate authority (CA),
|
||||
provided by the [Internet Security Research Group (ISRG)](https://www.abetterinternet.org/). It can
|
||||
be used for issuing the certificates needed by the preview server. See the "Create TLS certificates"
|
||||
section in [this doc](vm-setup--create-host-dirs-and-files.md) for more details.
|
||||
|
||||
Let's Encrypt supports issuing
|
||||
[wildcard certificates](https://letsencrypt.org/docs/faq/#does-let-s-encrypt-issue-wildcard-certificates),
|
||||
but they have to be renewed every 3 months using a
|
||||
[DNS-01 challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge).
|
||||
|
||||
Below are instructions for the creation of certificates using Let's Encrypt.
|
||||
|
||||
**Note 1:**
|
||||
It is assumed that the commands are executed on the VM that hosts the preview server. You can run
|
||||
the commands on any machine and adjust accordingly the steps for transfering the generated
|
||||
certificate and private key to the preview server VM.
|
||||
|
||||
**Note 2:**
|
||||
In order to complete the DNS-01 challenge and generate the certificate, one needs to have access
|
||||
to update the DNS records associated with the `ngbuilds.io` domain and subdomains.
|
||||
|
||||
|
||||
## Prerequisites
|
||||
- Install [certbot](https://certbot.eff.org/):
|
||||
- Old method: `sudo apt-get install certbot`
|
||||
- New method: Follow the instructions [here](https://certbot.eff.org/instructions).
|
||||
|
||||
|
||||
## Create new certificate
|
||||
- Run the following command and follow the on-screen instructions:
|
||||
```sh
|
||||
sudo certbot certonly \
|
||||
-d "ngbuilds.io,*.ngbuilds.io" \
|
||||
-m "devops@angular.io" \
|
||||
--agree-tos \
|
||||
--manual \
|
||||
--manual-public-ip-logging-ok \
|
||||
--preferred-challenges="dns"
|
||||
```
|
||||
|
||||
**Hint:**
|
||||
You can use `dig -t txt _acme-challenge.ngbuilds.io` (on Linux/macOS) or something like
|
||||
[DNSChecker.org](https://dnschecker.org/all-dns-records-of-domain.php?query=_acme-challenge.ngbuilds.io&rtype=TXT) to verify that the DNS updates have been successfully deployed and propagated.
|
||||
|
||||
- [Optional] Remove the DNS TXT records added in the previous step.
|
||||
(They are no longer needed, unless you want to create more certificates now.)
|
||||
|
||||
|
||||
## Deploy new certificate
|
||||
- Copy files to the host machine's `/etc/ssl/localcerts` directory, replacing `YYYY-MM` in the file
|
||||
names with the current year and month (for example, `2022-08`):
|
||||
```sh
|
||||
# Copy certificate.
|
||||
sudo cp /etc/letsencrypt/live/ngbuilds.io/fullchain.pem /etc/ssl/localcerts/ngbuilds.io.crt.YYYY-MM
|
||||
sudo cp /etc/letsencrypt/live/ngbuilds.io/fullchain.pem /etc/ssl/localcerts/ngbuilds.io.crt
|
||||
|
||||
# Copy private key.
|
||||
sudo cp /etc/letsencrypt/live/ngbuilds.io/privkey.pem /etc/ssl/localcerts/ngbuilds.io.key.YYYY-MM
|
||||
sudo cp /etc/letsencrypt/live/ngbuilds.io/privkey.pem /etc/ssl/localcerts/ngbuilds.io.key
|
||||
|
||||
# Update permissions.
|
||||
sudo find /etc/ssl/localcerts -type f -exec chmod 400 {} \;
|
||||
```
|
||||
|
||||
**Note:**
|
||||
The `.YYYY-MM`-suffixed copies are not needed/used. They are just kept for reference and backup
|
||||
purposes.
|
||||
|
||||
- Reload `nginx`:
|
||||
```sh
|
||||
# Connect to the Docker container and reload reload `nginx`.
|
||||
sudo docker exec -it aio service nginx reload
|
||||
```
|
||||
|
||||
- [Optional] Verify that the certificate has been successfully deployed by visiting
|
||||
https://ngbuilds.io/ in a browser and inspecting the TLS certificate details. See, for example,
|
||||
[how to view certificate details in Chrome](https://www.howtogeek.com/292076/how-do-you-view-ssl-certificate-details-in-google-chrome/).
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
## Objective
|
||||
Whenever a PR job is run on the CI infrastructure (e.g. CircleCI), we want to build `angular.io`
|
||||
and host the build artifacts on a publicly accessible server so that collaborators (developers,
|
||||
designers, authors, etc) can preview the changes without having to checkout and build the app
|
||||
locally.
|
||||
and host the build artifacts on a publicly accessible server so that collaborators, such as the
|
||||
developers, designers, or authors, can preview the changes without having to check out and build
|
||||
the app locally.
|
||||
|
||||
|
||||
## Source code
|
||||
@@ -57,7 +57,7 @@ More info on how to set things up on CI can be found [here](misc--integrate-with
|
||||
If the PR transitions from "non-public" to "public", the preview-server posts a comment on the
|
||||
corresponding PR on GitHub mentioning the SHAs and the links where the previews can be found.
|
||||
- The preview-server verifies that it is not trying to overwrite an existing build.
|
||||
- The preview-server deploys the artifacts to a sub-directory named after the PR number and the
|
||||
- The preview-server deploys the artifacts to a subdirectory named after the PR number and the
|
||||
first few characters of the SHA: `<PR>/<SHA>/`
|
||||
(Non-publicly accessible PRs will be stored in a different location, but again derived from the PR
|
||||
number and SHA.)
|
||||
@@ -89,7 +89,7 @@ More info on the possible HTTP status codes and their meaning can be found
|
||||
### Serving build artifacts
|
||||
- nginx receives a request for a hosted preview resource on a subdomain corresponding to the PR and SHA.
|
||||
E.g.: `pr<PR>-<SHA>.ngbuilds.io/path/to/resource`
|
||||
- nginx maps the subdomain to the correct sub-directory and serves the resource.
|
||||
- nginx maps the subdomain to the correct subdirectory and serves the resource.
|
||||
E.g.: `/<PR>/<SHA>/path/to/resource`
|
||||
|
||||
More info on the possible HTTP status codes and their meaning can be found
|
||||
|
||||
@@ -19,7 +19,7 @@ along with a brief explanation of what they mean:
|
||||
segment).
|
||||
|
||||
- **403 (Forbidden)**:
|
||||
Trying to access a sub-directory.
|
||||
Trying to access a subdirectory.
|
||||
|
||||
- **404 (Not Found)**:
|
||||
File not found.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
|
||||
Whenever a PR job is run on CircleCI, we want to build `angular.io` and host the build artifacts on
|
||||
a publicly accessible server so that collaborators (developers, designers, authors, etc) can preview
|
||||
the changes without having to checkout and build the app locally.
|
||||
a publicly accessible server so that collaborators, such as the developers, designers, or authors,
|
||||
can preview the changes without having to check out and build the app locally.
|
||||
|
||||
This document discusses the security considerations associated with moving build artifacts as
|
||||
part of the CI process and serving them publicly.
|
||||
@@ -136,7 +136,7 @@ This section describes how each of the aforementioned sub-tasks is accomplished:
|
||||
## Assumptions / Things to keep in mind
|
||||
|
||||
- Other than the initial webhook trigger, which provides a build number, all requests for data come
|
||||
from the preview-server making requests to well defined API endpoints (e.g. CircleCI and Github).
|
||||
from the preview-server making requests to well-defined API endpoints (e.g. CircleCI and Github).
|
||||
This means that any secret access keys need only be stored on the preview-server and not on any of
|
||||
the CI build infrastructure (e.g. CircleCI).
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ persistent disk can be used (as described [here](vm-setup--attach-persistent-dis
|
||||
**Note:** The directories created inside that directory will be owned by user `www-data`.
|
||||
|
||||
|
||||
## Create SSL certificates (Optional for dev)
|
||||
The host VM can attach a directory containing the SSL certificate and key to be used by the nginx
|
||||
## Create TLS certificates (Optional for dev)
|
||||
The host VM can attach a directory containing the TLS certificate and key to be used by the nginx
|
||||
server for serving the hosted previews. More info on how to attach the directory when
|
||||
starting the container can be found [here](vm-setup--start-docker-container.md).
|
||||
|
||||
@@ -32,10 +32,15 @@ specify the domain name see [here](vm-setup--create-docker-image.md).
|
||||
If no directory is attached, nginx will use an internal self-signed certificate. This is convenient
|
||||
during development, but is not suitable for production.
|
||||
|
||||
Certificates from any certificate authority can be used. As an example, see
|
||||
[here](misc--use-lets-encrypt-certs) for instructions on using certificates from
|
||||
[Let's Encrypt](https://letsencrypt.org/).
|
||||
|
||||
**Note:**
|
||||
Since nginx needs to be able to serve requests for both the main domain as well as any subdomain
|
||||
(e.g. `ngbuilds.io/` and `foo-bar.ngbuilds.io/`), the provided certificate needs to be a wildcard
|
||||
certificate covering both the domain and subdomains.
|
||||
(e.g. `ngbuilds.io/` and `foo-bar.ngbuilds.io/`), the provided certificate needs to be a
|
||||
[wildcard certificate](https://en.wikipedia.org/wiki/Wildcard_certificate) covering both the domain
|
||||
and all subdomains.
|
||||
|
||||
|
||||
## Create directory for logs (Optional)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
## The `docker run` command
|
||||
Once everything has been setup and configured, a docker container can be started with the following
|
||||
Once everything has been set up and configured, a docker container can be started with the following
|
||||
command:
|
||||
|
||||
```
|
||||
@@ -48,14 +48,22 @@ sudo docker run \
|
||||
|
||||
# The directory the contains the secrets (e.g. GitHub token, JWT secret, etc).
|
||||
# (See [here](vm-setup--set-up-secrets.md) for more info.)
|
||||
#
|
||||
# NOTE:
|
||||
# Omitting this is OK during development/debugging, when you don't care to interact with real
|
||||
# external services.
|
||||
--volume <host-secrets-dir>:/aio-secrets:ro \
|
||||
|
||||
# The build artifacts and hosted previews will stored to and served from this directory.
|
||||
# (If you are using a persistent disk - as described [here](vm-setup--attach-persistent-disk.md) -
|
||||
# this will be a directory inside the disk.)
|
||||
#
|
||||
# NOTE:
|
||||
# Omitting this is OK during development/debugging, when you don't care to interact with real
|
||||
# external services.
|
||||
--volume <host-builds-dir>:/var/www/aio-builds \
|
||||
|
||||
# The directory the contains the SSL certificates.
|
||||
# The directory the contains the TLS certificates.
|
||||
# (See [here](vm-setup--create-host-dirs-and-files.md) for more info.)
|
||||
# If not provided, the container will use self-signed certificates.
|
||||
[--volume <host-cert-dir>:/etc/ssl/localcerts:ro] \
|
||||
@@ -77,10 +85,13 @@ sudo docker run \
|
||||
|
||||
|
||||
## Example
|
||||
The following command would start a docker container based on the previously created `foobar-builds`
|
||||
docker image, alias it as 'foobar-builds-1' and map predefined directories on the host VM to be used
|
||||
by the container for accessing secrets and SSL certificates and keeping the build artifacts and logs;
|
||||
and will map the source scripts from the host to the container.
|
||||
The following command would do the following:
|
||||
1. Start a docker container based on the previously created `foobar-builds` docker image.
|
||||
2. Alias the docker container as `foobar-builds-1` (so it can be references in subsequent docker
|
||||
commands).
|
||||
3. Map predefined directories on the host VM to be used by the container for accessing secrets and
|
||||
TLS certificates and keeping the build artifacts and logs.
|
||||
4. Map the source scripts from the host to the container (for debugging purposes).
|
||||
|
||||
```
|
||||
sudo docker run \
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
Angular throws an `ExpressionChangedAfterItHasBeenCheckedError` when an expression value has been changed after change detection has completed. Angular only throws this error in development mode.
|
||||
|
||||
In development mode, Angular performs an additional check after each change detection run, to ensure the bindings haven't changed. This catches errors where the view is left in an inconsistent state. This can occur, for example, if a method or getter returns a different value each time it is called, or if a child component changes values on its parent. If either of these occur, this is a sign that change detection is not stabilized. Angular throws the error to ensure data is always reflected correctly in the view, which prevents erratic UI behavior or a possible infinite loop.
|
||||
In development mode, Angular performs an additional check after each change detection run, to ensure the bindings haven't changed. This catches errors where the view is left in an inconsistent state. This can occur, for example, if a method or getter returns a different value each time it is called, or if a child component changes values on its parent. If either of these occurs, this is a sign that change detection is not stabilized. Angular throws the error to ensure data is always reflected correctly in the view, which prevents erratic UI behavior or a possible infinite loop.
|
||||
|
||||
This error commonly occurs when you've added template expressions or have begun to implement lifecycle hooks like `ngAfterViewInit` or `ngOnChanges`. It is also common when dealing with loading status and asynchronous operations, or when a child component changes its parent bindings.
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ NgModules can be declared with an `id`:
|
||||
export class MyModule {}
|
||||
```
|
||||
|
||||
Declaring an `id` makes the NgModule available for lookup via the `getNgModuleById()` operation. This functionality is rarely used, mainly in very specific bundling scenarios when lazily loading NgModules without obtaining direct references to them. In most Angular code, ES dynamic `import()` (`import('./path/to/module')`) should be used instead, as this provides a direct reference to the NgModule being loaded without the need for a global registration side-effect.
|
||||
Declaring an `id` makes the NgModule available for lookup via the `getNgModuleById()` operation. This functionality is rarely used, mainly in very specific bundling scenarios when lazily loading NgModules without obtaining direct references to them. In most Angular code, ES dynamic `import()` (`import('./path/to/module')`) should be used instead, as this provides a direct reference to the NgModule being loaded without the need for a global registration side effect.
|
||||
|
||||
If you are not using `getNgModuleById`, you do not need to provide `id`s for your NgModules. Providing one has a significant drawback: it makes the NgModule non-tree-shakable, which can have an impact on your bundle size.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-manage-hereos',
|
||||
selector: 'app-manage-heroes',
|
||||
templateUrl: './manage-heroes.component.html',
|
||||
styleUrls: ['./manage-heroes.component.css']
|
||||
})
|
||||
|
||||
+8
-1
@@ -13,6 +13,13 @@ export class CheckForUpdateService {
|
||||
const everySixHours$ = interval(6 * 60 * 60 * 1000);
|
||||
const everySixHoursOnceAppIsStable$ = concat(appIsStable$, everySixHours$);
|
||||
|
||||
everySixHoursOnceAppIsStable$.subscribe(() => updates.checkForUpdate());
|
||||
everySixHoursOnceAppIsStable$.subscribe(async () => {
|
||||
try {
|
||||
const updateFound = await updates.checkForUpdate();
|
||||
console.log(updateFound ? 'A new version is available.' : 'Already on the latest version.');
|
||||
} catch (err) {
|
||||
console.error('Failed to check for updates:', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+30
-10
@@ -1,20 +1,40 @@
|
||||
// #docplaster
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SwUpdate, UpdateAvailableEvent } from '@angular/service-worker';
|
||||
// #docregion sw-replicate-available
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
// #enddocregion sw-replicate-available
|
||||
import { SwUpdate, VersionReadyEvent } from '@angular/service-worker';
|
||||
|
||||
function promptUser(event: UpdateAvailableEvent): boolean {
|
||||
function promptUser(event: VersionReadyEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
// #docregion sw-activate
|
||||
// #docregion sw-version-ready
|
||||
@Injectable()
|
||||
export class PromptUpdateService {
|
||||
|
||||
constructor(updates: SwUpdate) {
|
||||
updates.available.subscribe(event => {
|
||||
if (promptUser(event)) {
|
||||
updates.activateUpdate().then(() => document.location.reload());
|
||||
}
|
||||
});
|
||||
constructor(swUpdate: SwUpdate) {
|
||||
swUpdate.versionUpdates
|
||||
.pipe(filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'))
|
||||
.subscribe(evt => {
|
||||
if (promptUser(evt)) {
|
||||
// Reload the page to update to the latest version.
|
||||
document.location.reload();
|
||||
}
|
||||
});
|
||||
// #enddocregion sw-version-ready
|
||||
// #docregion sw-replicate-available
|
||||
// ...
|
||||
const updatesAvailable = swUpdate.versionUpdates.pipe(
|
||||
filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'),
|
||||
map(evt => ({
|
||||
type: 'UPDATE_AVAILABLE',
|
||||
current: evt.currentVersion,
|
||||
available: evt.latestVersion,
|
||||
})));
|
||||
// #enddocregion sw-replicate-available
|
||||
// #docregion sw-version-ready
|
||||
}
|
||||
|
||||
}
|
||||
// #enddocregion sw-activate
|
||||
// #enddocregion sw-version-ready
|
||||
|
||||
@@ -497,7 +497,7 @@ describe('demo (with TestBed):', () => {
|
||||
@Component({ template: '<my-service-comp></my-service-comp>' })
|
||||
class TestComponent { }
|
||||
|
||||
// 3 levels of ValueService provider: module, TestCompomponent, TestProvidersComponent
|
||||
// 3 levels of ValueService provider: module, TestComponent, TestProvidersComponent
|
||||
const fixture = TestBed.configureTestingModule({
|
||||
declarations: [TestComponent, TestProvidersComponent],
|
||||
providers: [ValueService]
|
||||
|
||||
-1
@@ -15,5 +15,4 @@ export class HelloWorldBindingsComponent {
|
||||
alert(this.message);
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ Extended diagnostics should generally:
|
||||
* Detect a common, non-obvious developer mistake with Angular templates
|
||||
* Clearly articulate why this pattern can lead to bugs or unintended behavior
|
||||
* Suggest one or more clear solutions
|
||||
* Have a low \(preferrably zero\) false-positive rate
|
||||
* Have a low, preferably zero, false-positive rate
|
||||
* Apply to the vast majority of Angular applications \(not specific to an unofficial library\)
|
||||
* Improve program correctness or performance \(not style, that responsibility falls to a linter\)
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() =>
|
||||
|
||||
</code-example>
|
||||
|
||||
In a real application, the element that receives focus will depend on your specific application structure and layout.
|
||||
In a real application, the element that receives focus depends on your specific application structure and layout.
|
||||
The focused element should put users in a position to immediately move into the main content that has just been routed into view.
|
||||
You should avoid situations where focus returns to the `body` element after a route change.
|
||||
|
||||
@@ -167,8 +167,12 @@ The following example shows how to apply the `active-page` class to active links
|
||||
|
||||
Books
|
||||
|
||||
* "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery
|
||||
* "Inclusive Design Patterns", Heydon Pickering
|
||||
<!-- vale Angular.Google_Quotes = NO -->
|
||||
|
||||
* "A Web for Everyone: Designing Accessible User Experiences," Sarah Horton and Whitney Quesenbery
|
||||
* "Inclusive Design Patterns," Heydon Pickering
|
||||
|
||||
<!-- vale Angular.Google_Quotes = YES -->
|
||||
|
||||
<!-- links -->
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ One of `static fields` \(the default\) or `decorators`.
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**NOTE**: <br />
|
||||
That the resulting code will not properly tree-shake.
|
||||
That the resulting code cannot tree-shake properly.
|
||||
|
||||
</div>
|
||||
|
||||
@@ -97,11 +97,11 @@ This allows `$localize` messages in application code to use the same ID as ident
|
||||
|
||||
### `enableResourceInlining`
|
||||
|
||||
When `true`, replaces the `templateUrl` and `styleUrls` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
|
||||
When `true`, replaces the `templateUrl` and `styleUrls` properties in all `@Component` decorators with inline content in the `template` and `styles` properties.
|
||||
|
||||
When enabled, the `.js` output of `ngc` does not include any lazy-loaded template or style URLs.
|
||||
|
||||
For library projects generated with the CLI, the development configuration default is `true`.
|
||||
For library projects generated with the Angular CLI, the development configuration default is `true`.
|
||||
|
||||
<a id="enablelegacytemplate"></a>
|
||||
|
||||
@@ -119,12 +119,12 @@ Ignored if `flatModuleOutFile` is `false`.
|
||||
|
||||
### `flatModuleOutFile`
|
||||
|
||||
When `true`, generates a flat module index of the given file name and the corresponding flat module metadata.
|
||||
When `true`, generates a flat module index of the given filename and the corresponding flat module metadata.
|
||||
Use to create flat modules that are packaged similarly to `@angular/core` and `@angular/common`.
|
||||
When this option is used, the `package.json` for the library should refer to the generated flat module index instead of the library index file.
|
||||
|
||||
Produces only one `.metadata.json` file, which contains all the metadata necessary for symbols exported from the library index.
|
||||
In the generated `.ngfactory.js` files, the flat module index is used to import symbols that include both the public API from the library index as well as shrowded internal symbols.
|
||||
In the generated `.ngfactory.js` files, the flat module index is used to import symbols that include both the public API from the library index as well as shrouded internal symbols.
|
||||
|
||||
By default the `.ts` file supplied in the `files` field is assumed to be the library index.
|
||||
If more than one `.ts` file is specified, `libraryIndex` is used to select the file to use.
|
||||
@@ -141,7 +141,7 @@ The `module` field of the library's `package.json` would be `"index.js"` and the
|
||||
When `true` \(recommended\), enables the [binding expression validation](guide/aot-compiler#binding-expression-validation) phase of the template compiler, which uses TypeScript to validate binding expressions.
|
||||
For more information, see [Template type checking](guide/template-typecheck).
|
||||
|
||||
Default is `false`, but when you use the CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
|
||||
Default is `false`, but when you use the Angular CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
@@ -172,7 +172,7 @@ This information includes, for example, the content of annotations \(such as a c
|
||||
You can set to `true` when using factory summaries, because the factory summaries include a copy of the information that is in the `.metadata.json` file.
|
||||
|
||||
Set to `true` if you are using TypeScript's `--outFile` option, because the metadata files are not valid for this style of TypeScript output.
|
||||
However, we do not recommend using `--outFile` with Angular.
|
||||
However, the Angular community does not recommend using `--outFile` with Angular.
|
||||
Use a bundler, such as [webpack](https://webpack.js.org), instead.
|
||||
|
||||
### `skipTemplateCodegen`
|
||||
@@ -182,7 +182,7 @@ This turns off most of the template compiler and disables the reporting of templ
|
||||
|
||||
Can be used to instruct the template compiler to produce `.metadata.json` files for distribution with an `npm` package while avoiding the production of `.ngfactory.js` and `.ngstyle.js` files that cannot be distributed to `npm`.
|
||||
|
||||
For library projects generated with the CLI, the development configuration default is `true`.
|
||||
For library projects generated with the Angular CLI, the development configuration default is `true`.
|
||||
|
||||
### `strictMetadataEmit`
|
||||
|
||||
@@ -202,14 +202,14 @@ The template compiler can then use the error nodes to report an error if these s
|
||||
If the client of a library intends to use a symbol in an annotation, the template compiler does not normally report this until the client uses the symbol.
|
||||
This option allows detection of these errors during the build phase of the library and is used, for example, in producing Angular libraries themselves.
|
||||
|
||||
For library projects generated with the CLI, the development configuration default is `true`.
|
||||
For library projects generated with the Angular CLI, the development configuration default is `true`.
|
||||
|
||||
### `strictInjectionParameters`
|
||||
|
||||
When `true` \(recommended\), reports an error for a supplied parameter whose injection type cannot be determined.
|
||||
When `false` \(currently the default\), constructor parameters of classes marked with `@Injectable` whose type cannot be resolved produce a warning.
|
||||
|
||||
When you use the CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
|
||||
When you use the Angular CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
|
||||
|
||||
### `strictTemplates`
|
||||
|
||||
@@ -218,7 +218,7 @@ When `true`, enables [strict template type checking](guide/template-typecheck#st
|
||||
Additional strictness flags allow you to enable and disable specific types of strict template type checking.
|
||||
See [troubleshooting template errors](guide/template-typecheck#troubleshooting-template-errors).
|
||||
|
||||
When you use the CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
|
||||
When you use the Angular CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
|
||||
|
||||
### `trace`
|
||||
|
||||
@@ -227,7 +227,7 @@ Default is `false`.
|
||||
|
||||
<a id="cli-options"></a>
|
||||
|
||||
## Command Line Options
|
||||
## Command line options
|
||||
|
||||
While most of the time you interact with the Angular Compiler indirectly using Angular CLI, when debugging certain issues, you might find it useful to invoke the Angular Compiler directly.
|
||||
You can use the `ngc` command provided by the `@angular/compiler-cli` npm package to call the compiler from the command line.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Angular Package Format
|
||||
# Angular package format
|
||||
|
||||
This document describes the Angular Package Format \(APF\).
|
||||
APF is an Angular specific specification for the structure and format of npm packages that is used by all first-party Angular packages \(`@angular/core`, `@angular/material`, etc.\) and most third-party Angular libraries.
|
||||
@@ -16,7 +16,7 @@ You can find the versions of the specification prior to v13 in this [google doc]
|
||||
|
||||
## Why specify a package format?
|
||||
|
||||
In today's JavaScript landscape, developers will consume packages in many different ways, using many different toolchains \(Webpack, rollup, esbuild, etc.\).
|
||||
In today's JavaScript landscape, developers consume packages in many different ways, using many different toolchains \(Webpack, rollup, esbuild, etc.\).
|
||||
These tools may understand and require different inputs - some tools may be able to process the latest ES language version, while others may benefit from directly consuming an older ES version.
|
||||
|
||||
The Angular distribution format supports all of the commonly used development tools and workflows, and adds emphasis on optimizations that result either in smaller application payload size or faster development iteration cycle \(build time\).
|
||||
@@ -113,8 +113,8 @@ This table describes the file layout under `node_modules/@angular/core` annotate
|
||||
| `index.d.ts` | Bundled `.d.ts` for the primary entrypoint `@angular/core`. |
|
||||
| `esm2020/` <br /> ─ `core.mjs` <br /> ─ `index.mjs` <br /> ─ `public_api.mjs` | Tree of `@angular/core` sources in unflattened ES2020 format. |
|
||||
| `esm2020/testing/` | Tree of the `@angular/core/testing` entrypoint in unflattened ES2020 format. |
|
||||
| `fesm2015/` <br /> ─ `core.mjs` <br /> ─ `core.mjs.map` <br /> ─ `testing.mjs` <br /> ─ `testing.mjs.map` | Code for all entrypoints in a flattened \(FESM\) ES2015 format, along with sourcemaps. |
|
||||
| `fesm2020/` <br /> ─ `core.mjs` <br /> ─ `core.mjs.map` <br /> ─ `testing.mjs` <br /> ─ `testing.mjs.map` | Code for all entrypoints in flattened \(FESM\) ES2020 format, along with sourcemaps. |
|
||||
| `fesm2015/` <br /> ─ `core.mjs` <br /> ─ `core.mjs.map` <br /> ─ `testing.mjs` <br /> ─ `testing.mjs.map` | Code for all entrypoints in a flattened \(FESM\) ES2015 format, along with source maps. |
|
||||
| `fesm2020/` <br /> ─ `core.mjs` <br /> ─ `core.mjs.map` <br /> ─ `testing.mjs` <br /> ─ `testing.mjs.map` | Code for all entrypoints in flattened \(FESM\) ES2020 format, along with source maps. |
|
||||
| `testing/` | Directory representing the "testing" entrypoint. |
|
||||
| `testing/index.d.ts` | Bundled `.d.ts` for the `@angular/core/testing` entrypoint. |
|
||||
|
||||
@@ -125,9 +125,9 @@ The primary `package.json` contains important package metadata, including the fo
|
||||
* It [declares](#esm-declaration) the package to be in EcmaScript Module \(ESM\) format
|
||||
* It contains an [`"exports"` field](#exports) which defines the available source code formats of all entrypoints
|
||||
* It contains [keys](#legacy-resolution-keys) which define the available source code formats of the primary `@angular/core` entrypoint, for tools which do not understand `"exports"`.
|
||||
These keys are considered deprecated, and will be removed as the support for `"exports"` rolls out across the ecosystem.
|
||||
These keys are considered deprecated, and could be removed as the support for `"exports"` rolls out across the ecosystem.
|
||||
|
||||
* It declares whether the package contains [side-effects](#side-effects)
|
||||
* It declares whether the package contains [side effects](#side-effects)
|
||||
|
||||
### ESM declaration
|
||||
|
||||
@@ -218,7 +218,7 @@ For `@angular/core` these are:
|
||||
|
||||
</code-example>
|
||||
|
||||
As above, a module resolver can use these keys to load a specific code format.
|
||||
As shown in the preceding code snippet, a module resolver can use these keys to load a specific code format.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@@ -230,7 +230,7 @@ As with `"node"`, ES2015 code is selected due to the constraints of ZoneJS.
|
||||
|
||||
### Side effects
|
||||
|
||||
The last function of `package.json` is to declare whether the package has [side-effects](#sideeffects-flag).
|
||||
The last function of `package.json` is to declare whether the package has [side effects](#sideeffects-flag).
|
||||
|
||||
<code-example language="javascript">
|
||||
|
||||
@@ -242,14 +242,14 @@ The last function of `package.json` is to declare whether the package has [side-
|
||||
|
||||
Most Angular packages should not depend on top-level side effects, and thus should include this declaration.
|
||||
|
||||
## Entrypoints and Code Splitting
|
||||
## Entrypoints and code splitting
|
||||
|
||||
Packages in the Angular Package Format contain one primary entrypoint and zero or more secondary entrypoints \(for example, `@angular/common/http`\).
|
||||
Entrypoints serve several functions.
|
||||
|
||||
1. They define the module specifiers from which users import code \(for example, `@angular/core` and `@angular/core/testing`\).
|
||||
|
||||
Users typically perceive these entrypoints as distinct groups of symbols, with different purposes or functionality.
|
||||
Users typically perceive these entrypoints as distinct groups of symbols, with different purposes or capability.
|
||||
|
||||
Specific entrypoints might only be used for special purposes, such as testing.
|
||||
Such APIs can be separated out from the primary entrypoint to reduce the chance of them being used accidentally or incorrectly.
|
||||
@@ -257,7 +257,7 @@ Entrypoints serve several functions.
|
||||
1. They define the granularity at which code can be lazily loaded.
|
||||
|
||||
Many modern build tools are only capable of "code splitting" \(aka lazy loading\) at the ES Module level.
|
||||
Since the Angular Package Format uses primarily a single "flat" ES Module per entrypoint, this means that most build tooling will not be able to split code in a single entrypoint into multiple output chunks.
|
||||
The Angular Package Format uses primarily a single "flat" ES Module per entry point. This means that most build tooling is not able to split code with a single entry point into multiple output chunks.
|
||||
|
||||
The general rule for APF packages is to use entrypoints for the smallest sets of logically connected code possible.
|
||||
For example, the Angular Material package publishes each logical component or set of components as a separate entrypoint - one for Button, one for Tabs, etc.
|
||||
@@ -267,15 +267,15 @@ Not all libraries require such granularity.
|
||||
Most libraries with a single logical purpose should be published as a single entrypoint.
|
||||
`@angular/core` for example uses a single entrypoint for the runtime, because the Angular runtime is generally used as a single entity.
|
||||
|
||||
### Resolution of Secondary Entrypoints
|
||||
### Resolution of secondary entry points
|
||||
|
||||
Secondary entrypoints can be resolved via the `"exports"` field of the `package.json` for the package.
|
||||
|
||||
## README.md
|
||||
|
||||
The readme file in the markdown format that is used to display description of a package on npm and github.
|
||||
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:
|
||||
|
||||
<code-example language="html">
|
||||
|
||||
@@ -288,20 +288,22 @@ License: MIT
|
||||
|
||||
</code-example>
|
||||
|
||||
## Partial Compilation
|
||||
## Partial compilation
|
||||
|
||||
Libraries in the Angular Package Format must be published in "partial compilation" mode.
|
||||
This is a compilation mode for `ngc` which produces compiled Angular code that is not tied to a specific Angular runtime version, in contrast to the full compilation used for applications, where the Angular compiler and runtime versions must match exactly.
|
||||
|
||||
To partially compile Angular code, use the `"compilationMode"` flag in `"angularCompilerOptions"` in your `tsconfig.json`:
|
||||
To partially compile Angular code, use the `compilationMode` flag in the `angularCompilerOptions` property of your `tsconfig.json`:
|
||||
|
||||
<code-example language="javascript">
|
||||
|
||||
{
|
||||
…
|
||||
"angularCompilerOptions": {
|
||||
"compilationMode": "partial",
|
||||
}
|
||||
}
|
||||
|
||||
</code-example>
|
||||
|
||||
Partially compiled library code is then converted to fully compiled code during the application build process by the Angular CLI.
|
||||
@@ -310,20 +312,20 @@ If your build pipeline does not use the Angular CLI then refer to the [Consuming
|
||||
|
||||
## Optimizations
|
||||
|
||||
### Flattening of ES Modules
|
||||
### Flattening of ES modules
|
||||
|
||||
The Angular Package Format specifies that code be published in "flattened" ES module format.
|
||||
This significantly reduces the build time of Angular applications as well as download and parse time of the final application bundle.
|
||||
Please check out the excellent post ["The cost of small modules"](https://nolanlawson.com/2016/08/15/the-cost-of-small-modules) by Nolan Lawson.
|
||||
|
||||
The Angular compiler has support for generating index ES module files that can then be used to generate flattened modules using tools like Rollup, resulting in a file format we call Flattened ES Module or FESM.
|
||||
The Angular compiler can generate index ES module files. Tools like Rollup can use these files to generate flattened modules in a *Flattened ES Module* (FESM) file format.
|
||||
|
||||
FESM is a file format created by flattening all ES Modules accessible from an entrypoint into a single ES Module.
|
||||
It's formed by following all imports from a package and copying that code into a single file while preserving all public ES exports and removing all private imports.
|
||||
|
||||
The shortened name "FESM" \(pronounced "phesom"\) can have a number after it such as "FESM5" or "FESM2015".
|
||||
The abbreviated name, FESM, pronounced *phe-som*, can be followed by a number such as FESM5 or FESM2015.
|
||||
The number refers to the language level of the JavaScript inside the module.
|
||||
So a FESM5 file would be ESM+ES5 \(import/export statements and ES5 source code\).
|
||||
Accordingly a FESM5 file would be ESM+ES5 and include import/export statements and ES5 source code.
|
||||
|
||||
To generate a flattened ES Module index file, use the following configuration options in your tsconfig.json file:
|
||||
|
||||
@@ -349,40 +351,40 @@ Once the index file \(for example, `my-ui-lib.js`\) is generated by ngc, bundler
|
||||
|
||||
#### Note about the defaults in package.json
|
||||
|
||||
As of webpack v4 the flattening of ES modules optimization should not be necessary for webpack users, and in fact theoretically we should be able to get better code-splitting without flattening of modules in webpack.
|
||||
In practice we still see size regressions when using unflattened modules as input for webpack v4.
|
||||
This is why `"module"` and `"es2020"` package.json entries still point to fesm files.
|
||||
We are investigating this issue and expect that we'll switch the `"module"` and `"es2020"` package.json entry points to unflattened files when the size regression issue is resolved.
|
||||
As of webpack v4, the flattening of ES modules optimization should not be necessary for webpack users. It should be possible to get better code-splitting without flattening of modules in webpack.
|
||||
In practice, size regressions can still be seen when using unflattened modules as input for webpack v4.
|
||||
This is why `module` and `es2020` package.json entries still point to FESM files.
|
||||
This issue is being investigated. It is expected to switch the `module` and `es2020` package.json entry points to unflattened files after the size regression issue is resolved.
|
||||
The APF currently includes unflattened ESM2020 code for the purpose of validating such a future change.
|
||||
|
||||
### "sideEffects" flag
|
||||
|
||||
By default, EcmaScript Modules are side-effectful: importing from a module ensures that any code at the top level of that module will execute.
|
||||
By default, EcmaScript Modules are side-effectful: importing from a module ensures that any code at the top level of that module should run.
|
||||
This is often undesirable, as most side-effectful code in typical modules is not truly side-effectful, but instead only affects specific symbols.
|
||||
If those symbols are not imported and used, it's often desirable to remove them in an optimization process known as tree-shaking, and the side-effectful code can prevent this.
|
||||
|
||||
Build tools such as Webpack support a flag which allows packages to declare that they do not depend on side-effectful code at the top level of their modules, giving the tools more freedom to tree-shake code from the package.
|
||||
The end result of these optimizations should be smaller bundle size and better code distribution in bundle chunks after code-splitting.
|
||||
This optimization can break your code if it contains non-local side-effects - this is however not common in Angular applications and it's usually a sign of bad design.
|
||||
Our recommendation is for all packages to claim the side-effect free status by setting the `sideEffects` property to `false`, and that developers follow the [Angular Style Guide](https://angular.io/guide/styleguide) which naturally results in code without non-local side-effects.
|
||||
The recommendation is for all packages to claim the side-effect free status by setting the `sideEffects` property to `false`, and that developers follow the [Angular Style Guide](https://angular.io/guide/styleguide) which naturally results in code without non-local side-effects.
|
||||
|
||||
More info: [webpack docs on side-effects](https://github.com/webpack/webpack/tree/master/examples/side-effects)
|
||||
More info: [webpack docs on side effects](https://github.com/webpack/webpack/tree/master/examples/side-effects)
|
||||
|
||||
### ES2020 Language Level
|
||||
### ES2020 language level
|
||||
|
||||
ES2020 Language level is now the default language level that is consumed by Angular CLI and other tooling.
|
||||
The Angular CLI will downlevel the bundle to a language level that is supported by all targeted browsers at application build time.
|
||||
The Angular CLI down-levels the bundle to a language level that is supported by all targeted browsers at application build time.
|
||||
|
||||
### d.ts bundling / type definition flattening
|
||||
|
||||
As of APF v8 we now prefer to run [API Extractor](https://api-extractor.com), to bundle TypeScript definitions so that the entire API appears in a single file.
|
||||
As of APF v8 it is now preferred to run [API Extractor](https://api-extractor.com), to bundle TypeScript definitions so that the entire API appears in a single file.
|
||||
|
||||
In prior APF versions each entry point would have a `src` directory next to the .d.ts entry point and this directory contained individual d.ts files matching the structure of the original source code.
|
||||
While this distribution format is still allowed and supported, it is highly discouraged because it confuses tools like IDEs that then offer incorrect autocompletion, and allows users to depend on deep-import paths which are typically not considered to be public API of a library or a package.
|
||||
|
||||
### Tslib
|
||||
|
||||
As of APF v10, we recommend adding tslib as a direct dependency of your primary entry-point.
|
||||
As of APF v10, it is recommended to add tslib as a direct dependency of your primary entry-point.
|
||||
This is because the tslib version is tied to the TypeScript version used to compile your library.
|
||||
|
||||
## Examples
|
||||
@@ -390,10 +392,10 @@ This is because the tslib version is tied to the TypeScript version used to comp
|
||||
* [@angular/core package](https://unpkg.com/browse/@angular/core@13.0.0-rc.0)
|
||||
* [@angular/material package](https://unpkg.com/browse/@angular/material@13.0.0-rc.0)
|
||||
|
||||
## Definition of Terms
|
||||
## Definition of terms
|
||||
|
||||
The following terms are used throughout this document very intentionally.
|
||||
In this section we define all of them to provide additional clarity.
|
||||
The following terms are used throughout this document intentionally.
|
||||
In this section are the definitions of all of them to provide additional clarity.
|
||||
|
||||
#### Package
|
||||
|
||||
@@ -403,7 +405,7 @@ The package is installed with `npm install @angular/core`.
|
||||
|
||||
#### Symbol
|
||||
|
||||
A class, function, constant or variable contained in a module and optionally made visible to the external world via a module export.
|
||||
A class, function, constant, or variable contained in a module and optionally made visible to the external world via a module export.
|
||||
|
||||
#### Module
|
||||
|
||||
@@ -424,16 +426,16 @@ Short for Flattened ES Modules and consists of a file format created by flatteni
|
||||
The identifier of a module used in the import statements \(for example, `@angular/core`\).
|
||||
The ID often maps directly to a path on the filesystem, but this is not always the case due to various module resolution strategies.
|
||||
|
||||
#### Module Specifier
|
||||
#### Module specifier
|
||||
|
||||
A module identifier \(see above\).
|
||||
|
||||
#### Module Resolution Strategy
|
||||
#### Module resolution strategy
|
||||
|
||||
Algorithm used to convert Module IDs to paths on the filesystem.
|
||||
Node.js has one that is well specified and widely used, TypeScript supports several module resolution strategies, [Closure Compiler](https://developers.google.com/closure/compiler) has yet another strategy.
|
||||
|
||||
#### Module Format
|
||||
#### Module format
|
||||
|
||||
Specification of the module syntax that covers at minimum the syntax for the importing and exporting from a file.
|
||||
Common module formats are CommonJS \(CJS, typically used for Node.js applications\) or ECMAScript Modules \(ESM\).
|
||||
@@ -447,12 +449,12 @@ Bundles are a browser-specific workaround that reduce network strain that would
|
||||
Node.js typically doesn't use bundles.
|
||||
Common bundle formats are UMD and System.register.
|
||||
|
||||
#### Language Level
|
||||
#### Language level
|
||||
|
||||
The language of the code \(ES2015 or ES2020\).
|
||||
Independent of the module format.
|
||||
|
||||
#### Entry Point
|
||||
#### Entry point
|
||||
|
||||
A module intended to be imported by the user.
|
||||
It is referenced by a unique module ID and exports the public API referenced by that module ID.
|
||||
@@ -460,12 +462,12 @@ An example is `@angular/core` or `@angular/core/testing`.
|
||||
Both entry points exist in the `@angular/core` package, but they export different symbols.
|
||||
A package can have many entry points.
|
||||
|
||||
#### Deep Import
|
||||
#### Deep import
|
||||
|
||||
A process of retrieving symbols from modules that are not Entry Points.
|
||||
These module IDs are usually considered to be private APIs that can change over the lifetime of the project or while the bundle for the given package is being created.
|
||||
|
||||
#### Top-Level Import
|
||||
#### 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`.
|
||||
@@ -475,11 +477,11 @@ The available top-level imports are what define the public API and are exposed i
|
||||
The process of identifying and removing code not used by an application - also known as dead code elimination.
|
||||
This is a global optimization performed at the application level using tools like [Rollup](https://rollupjs.org), [Closure Compiler](https://developers.google.com/closure/compiler), or [Terser](https://github.com/terser/terser).
|
||||
|
||||
#### AOT Compiler
|
||||
#### AOT compiler
|
||||
|
||||
The Ahead of Time Compiler for Angular.
|
||||
|
||||
#### Flattened Type Definitions
|
||||
#### Flattened type definitions
|
||||
|
||||
The bundled TypeScript definitions generated from [API Extractor](https://api-extractor.com).
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Learn more in [The App Shell Model](https://developers.google.com/web/fundamenta
|
||||
|
||||
## Step 1: Prepare the application
|
||||
|
||||
Do this with the following CLI command:
|
||||
Do this with the following Angular CLI command:
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
|
||||
@@ -19,9 +19,9 @@ ng new my-app --routing
|
||||
|
||||
For an existing application, you have to manually add the `RouterModule` and defining a `<router-outlet>` within your application.
|
||||
|
||||
## Step 2: Create the app shell
|
||||
## Step 2: Create the application shell
|
||||
|
||||
Use the CLI to automatically create the application shell.
|
||||
Use the Angular CLI to automatically create the application shell.
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
|
||||
@@ -80,9 +80,9 @@ After running this command you can see that the `angular.json` configuration fil
|
||||
|
||||
</code-example>
|
||||
|
||||
## Step 3: Verify the app is built with the shell content
|
||||
## Step 3: Verify the application is built with the shell content
|
||||
|
||||
Use the CLI to build the `app-shell` target.
|
||||
Use the Angular CLI to build the `app-shell` target.
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ This example shows some of the most useful `@Component` configuration options:
|
||||
| Configuration options | Details |
|
||||
|:--- |:--- |
|
||||
| `selector` | A CSS selector that tells Angular to create and insert an instance of this component wherever it finds the corresponding tag in template HTML. For example, if an application's HTML contains `<app-hero-list></app-hero-list>`, then Angular inserts an instance of the `HeroListComponent` view between those tags. |
|
||||
| `templateUrl` | The module-relative address of this component's HTML template. Alternatively, you can provide the HTML template inline, as the value of the `template` property. This template defines the component's *host view*. |
|
||||
| `templateUrl` | The module-relative address of this component's HTML template. Alternatively, you can provide the HTML template inline, as the value of the `template` property. This template defines the component's *host view*. |
|
||||
| `providers` | An array of [providers](guide/glossary#provider) for services that the component requires. In the example, this tells Angular how to provide the `HeroService` instance that the component's constructor uses to get the list of heroes to display. |
|
||||
|
||||
## Templates and views
|
||||
@@ -86,7 +86,7 @@ For example, here is a template for the Tutorial's `HeroListComponent`.
|
||||
|
||||
<code-example header="src/app/hero-list.component.html" path="architecture/src/app/hero-list.component.html" ></code-example>
|
||||
|
||||
This template uses typical HTML elements like `<h2>` and `<p>`, and also includes Angular template-syntax elements, `*ngFor`, `{{hero.name}}`, `(click)`, `[hero]`, and `<app-hero-detail>`.
|
||||
This template uses typical HTML elements like `<h2>` and `<p>`. It also includes Angular template-syntax elements, `*ngFor`, `{{hero.name}}`, `(click)`, `[hero]`, and `<app-hero-detail>`.
|
||||
The template-syntax elements tell Angular how to render the HTML to the screen, using program logic and data.
|
||||
|
||||
* The `*ngFor` directive tells Angular to iterate over a list
|
||||
@@ -154,7 +154,7 @@ Data binding plays an important role in communication between a template and its
|
||||
Angular pipes let you declare display-value transformations in your template HTML.
|
||||
A class with the `@Pipe` decorator defines a function that transforms input values to output values for display in a view.
|
||||
|
||||
Angular defines various pipes, such as the [date](api/common/DatePipe) pipe and [currency](api/common/CurrencyPipe) pipe; for a complete list, see the [Pipes API list](api?type=pipe).
|
||||
Angular defines various pipes, such as the [date](api/common/DatePipe) pipe and [currency](api/common/CurrencyPipe) pipe. For a complete list, see the [Pipes API list](api?type=pipe).
|
||||
You can also define new pipes.
|
||||
|
||||
To specify a value transformation in an HTML template, use the [pipe operator (`|`)](guide/pipes).
|
||||
@@ -212,8 +212,8 @@ The example template uses two built-in structural directives to add application
|
||||
|
||||
| Directives | Details |
|
||||
|:--- |:--- |
|
||||
| [`*ngFor`](guide/built-in-directives#ngFor) | An iterative; it tells Angular to stamp out one `<li>` per hero in the `heroes` list. |
|
||||
| [`*ngIf`](guide/built-in-directives#ngIf) | A conditional; it includes the `HeroDetail` component only if a selected hero exists. |
|
||||
| [`*ngFor`](guide/built-in-directives#ngFor) | An *iterative*, which tells Angular to create one `<li>` per hero in the `heroes` list. |
|
||||
| [`*ngIf`](guide/built-in-directives#ngIf) | A *conditional*, which includes the `HeroDetail` component only if a selected hero exists. |
|
||||
|
||||
#### Attribute directives
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ The binding punctuation of `[]`, `()`, `[()]`, and the prefix specify the direct
|
||||
|
||||
* Use `[]` to bind from source to view
|
||||
* Use `()` to bind from view to source
|
||||
* Use `[()]` to bind in a two way sequence of view to source to view
|
||||
* Use `[()]` to bind in a two-way sequence of view to source to view
|
||||
|
||||
Place the expression or statement to the right of the equal sign within double quote \(`""`\) characters.
|
||||
For more information see [Interpolation](guide/interpolation) and [Template statements](guide/template-statements).
|
||||
|
||||
@@ -307,7 +307,7 @@ The CLI uses [Autoprefixer](https://github.com/postcss/autoprefixer) to ensure c
|
||||
You might find it necessary to target specific browsers or exclude certain browser versions from your build.
|
||||
|
||||
Internally, Autoprefixer relies on a library called [Browserslist](https://github.com/browserslist/browserslist) to figure out which browsers to support with prefixing.
|
||||
Browserlist looks for configuration options in a `browserslist` property of the package configuration file, or in a configuration file named `.browserslistrc`.
|
||||
Browserslist looks for configuration options in a `browserslist` property of the package configuration file, or in a configuration file named `.browserslistrc`.
|
||||
Autoprefixer looks for the `browserslist` configuration when it prefixes your CSS.
|
||||
|
||||
* Tell Autoprefixer what browsers to target by adding a browserslist property to the package configuration file, `package.json`:
|
||||
|
||||
@@ -179,7 +179,7 @@ To add or remove an element, bind `*ngIf` to a condition expression such as `isA
|
||||
<code-example header="src/app/app.component.html" path="built-in-directives/src/app/app.component.html" region="NgIf-1"></code-example>
|
||||
|
||||
When the `isActive` expression returns a truthy value, `NgIf` adds the `ItemDetailComponent` to the DOM.
|
||||
When the expression is falsy, `NgIf` removes the `ItemDetailComponent` from the DOM and disposes of the component and all of its sub-components.
|
||||
When the expression is falsy, `NgIf` removes the `ItemDetailComponent` from the DOM and disposes of the component and all of its subcomponents.
|
||||
|
||||
For more information on `NgIf` and `NgIfElse`, see the [NgIf API documentation](api/common/NgIf).
|
||||
|
||||
@@ -204,7 +204,7 @@ In this example, Angular does not display the `nullCustomer` because it is `null
|
||||
Use the `NgFor` directive to present a list of items.
|
||||
|
||||
1. Define a block of HTML that determines how Angular renders a single item.
|
||||
1. To list your items, assign the short hand `let item of items` to `*ngFor`.
|
||||
1. To list your items, assign the shorthand `let item of items` to `*ngFor`.
|
||||
|
||||
<code-example header="src/app/app.component.html" path="built-in-directives/src/app/app.component.html" region="NgFor-1"></code-example>
|
||||
|
||||
@@ -239,7 +239,7 @@ For more information about template input variables, see [Structural directive s
|
||||
|
||||
Get the `index` of `*ngFor` in a template input variable and use it in the template.
|
||||
|
||||
In the `*ngFor`, add a semicolon and `let i=index` to the short hand.
|
||||
In the `*ngFor`, add a semicolon and `let i=index` to the shorthand.
|
||||
The following example gets the `index` in a variable named `i` and displays it with the item name.
|
||||
|
||||
<code-example header="src/app/app.component.html" path="built-in-directives/src/app/app.component.html" region="NgFor-3"></code-example>
|
||||
@@ -271,7 +271,7 @@ With the `*ngFor` `trackBy` property, Angular can change and re-render only thos
|
||||
|
||||
<code-example header="src/app/app.component.ts" path="built-in-directives/src/app/app.component.ts" region="trackByItems"></code-example>
|
||||
|
||||
1. In the short hand expression, set `trackBy` to the `trackByItems()` method.
|
||||
1. In the shorthand expression, set `trackBy` to the `trackByItems()` method.
|
||||
|
||||
<code-example header="src/app/app.component.html" path="built-in-directives/src/app/app.component.html" region="trackBy"></code-example>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Angular change detection and runtime optimization
|
||||
|
||||
**Change detection** is the process through which Angular checks to see whether your application state has changed, and if any DOM needs to be updated. At a high level, Angular walks your components from top to bottom, looking for changes. Angular runs its change detection mechanism periodically so that changes to the data model are reflected in an app’s view. Change detection can be triggered either manually or through an asynchronous event (for example, a user interaction or an XHR completion).
|
||||
**Change detection** is the process through which Angular checks to see whether your application state has changed, and if any DOM needs to be updated. At a high level, Angular walks your components from top to bottom, looking for changes. Angular runs its change detection mechanism periodically so that changes to the data model are reflected in an application’s view. Change detection can be triggered either manually or through an asynchronous event (for example, a user interaction or an XMLHttpRequest completion).
|
||||
|
||||
Change detection is a highly optimized performant, but it can still cause slowdowns if the application runs it too frequently.
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@
|
||||
| Class field decorators for directives and components | Details |
|
||||
|:--- |:--- |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> import { Input, … } from '@angular/core'; </code-example> | Import `Input, ...` from `@angular/core`. |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @Input() myProperty; </code-example> | Declares an input property that you can update using property binding \(example: `<my-cmp [myProperty]="someExpression">`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @Output() myEvent = new EventEmitter(); </code-example> | Declares an output property that fires events that you can subscribe to with an event binding \(example: `<my-cmp (myEvent)="doSomething()">`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @Input() myProperty; </code-example> | Declares an input property that you can update using property binding \(example: `<my-cmp [myProperty]="someExpression">`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @Output() myEvent = new EventEmitter(); </code-example> | Declares an output property that fires events that you can subscribe to with an event binding \(example: `<my-cmp (myEvent)="doSomething()">`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @HostBinding('class.valid') isValid; </code-example> | Binds a host element property \(here, the CSS class `valid`\) to a directive/component property \(`isValid`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @HostListener('click', ['$event']) onClick(e) {…} </code-example> | Subscribes to a host element event \(`click`\) with a directive/component method \(`onClick`\), optionally passing an argument \(`$event`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @ContentChild(myPredicate) myChildComponent; </code-example> | Binds the first result of the component content query \(`myPredicate`\) to a property \(`myChildComponent`\) of the class. |
|
||||
|
||||
@@ -30,7 +30,7 @@ With the object format, Angular adds a class only if its associated value is tru
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
With any object-like expression—such as `object`, `Array`, `Map`, or `Set`—the identity of the object must change for Angular to update the class list.
|
||||
With any object-like expression—such as `object`, `Array`, `Map`, or `Set` —the identity of the object must change for Angular to update the class list.
|
||||
Updating the property without changing object identity has no effect.
|
||||
|
||||
</div>
|
||||
@@ -52,7 +52,7 @@ To create a single style binding, use the prefix `style` followed by a dot and t
|
||||
|
||||
For example, to set the `width` style, type the following: `[style.width]="width"`
|
||||
|
||||
Angular sets the property to the value of the bound expression, which is usually a string. Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
|
||||
Angular sets the property to the value of the bound expression, which is usually a string. Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
|
||||
|
||||
1. To write a style in dash-case, type the following:
|
||||
|
||||
|
||||
@@ -445,7 +445,7 @@ Architect can support watch mode, but there are some things to look out for.
|
||||
This prevents Architect from stopping the builder if another run is scheduled.
|
||||
|
||||
When your builder calls `BuilderRun.stop()` to exit watch mode, Architect unsubscribes from the builder's Observable and calls the builder's teardown logic to clean up.
|
||||
\(This behavior also allows for long running builds to be stopped and cleaned up.\)
|
||||
\(This behavior also allows for long-running builds to be stopped and cleaned up.\)
|
||||
|
||||
In general, if your builder is watching an external event, you should separate your run into three phases.
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ If you need to animate the items of an `*ngFor` list and there is a possibility
|
||||
|
||||
## Animations and Component View Encapsulation
|
||||
|
||||
Angular animations are based on the components DOM structure and do not directly take [View Encapsulation](/guide/view-encapsulation) into account, this means that components using `ViewEncapsulation.Emulated` behave exactly as if they where using `ViewEncapsulation.None` (`ViewEncapsulation.ShadowDom` behaves differently as we'll discuss shortly).
|
||||
Angular animations are based on the components DOM structure and do not directly take [View Encapsulation](/guide/view-encapsulation) into account, this means that components using `ViewEncapsulation.Emulated` behave exactly as if they were using `ViewEncapsulation.None` (`ViewEncapsulation.ShadowDom` behaves differently as we'll discuss shortly).
|
||||
|
||||
For example if the `query()` function (which you'll see more of in the rest of the Animations guide) were to be applied at the top of a tree of components using the emulated view encapsulation, such query would be able to identify (and thus animate) DOM elements on any depth of the tree.
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ But it is limited because the parent-child wiring must be done entirely within t
|
||||
The parent component *itself* has no access to the child.
|
||||
|
||||
You can't use the *local variable* technique if the parent component's *class* relies on the child component's *class*.
|
||||
The parent-child relationship of the components is not established within each components respective *class* with the *local variable* technique.
|
||||
The parent-child relationship of the components is not established within each component's respective *class* with the *local variable* technique.
|
||||
Because the *class* instances are not connected to one another, the parent *class* cannot access the child *class* properties and methods.
|
||||
|
||||
When the parent component *class* requires that kind of access, ***inject*** the child component into the parent as a *ViewChild*.
|
||||
@@ -248,7 +248,7 @@ Use [the same countdown timer tests](guide/component-interaction#countdown-tests
|
||||
|
||||
## Parent and children communicate using a service
|
||||
|
||||
A parent component and its children share a service whose interface enables bi-directional communication *within the family*.
|
||||
A parent component and its children share a service whose interface enables bidirectional communication *within the family*.
|
||||
|
||||
The scope of the service instance is the parent component and its children.
|
||||
Components outside this component subtree have no access to the service or their communications.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Angular Components Overview
|
||||
# Angular components overview
|
||||
|
||||
Components are the main building block for Angular applications.
|
||||
Each component consists of:
|
||||
@@ -38,7 +38,7 @@ To create a component using the Angular CLI:
|
||||
|
||||
By default, this command creates the following:
|
||||
|
||||
* A folder named after the component
|
||||
* A directory named after the component
|
||||
* A component file, `<component-name>.component.ts`
|
||||
* A template file, `<component-name>.component.html`
|
||||
* A CSS file, `<component-name>.component.css`
|
||||
|
||||
@@ -49,7 +49,7 @@ While Angular's emulated style encapsulation prevents styles from escaping a com
|
||||
While component consumers should avoid directly overwriting the CSS internals of a component, you can offer a supported customization API via a CSS preprocessor like Sass.
|
||||
|
||||
For example, a component may offer one or more supported mixins to customize various aspects of the component's appearance.
|
||||
While this approach uses global styles in it's implementation, it allows the component author to keep the mixins up to date with changes to the component's private DOM structure and CSS classes.
|
||||
While this approach uses global styles in its implementation, it allows the component author to keep the mixins up to date with changes to the component's private DOM structure and CSS classes.
|
||||
|
||||
#### 3. Customize with CSS `::part`
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ This section describes how to make larger contributions to the documentation.
|
||||
|
||||
The following steps set up your local computer to contribute documentation content.
|
||||
|
||||
1. Sign into your account on GitHub.
|
||||
1. Sign in to your account on GitHub.
|
||||
If you don't have an account on GitHub, [create a new account][GithubJoin] before you continue.
|
||||
2. In your browser, navigate to [https://github.com/angular/angular][GithubAngular].
|
||||
3. In your browser, fork the `angular/angular` repo into your GitHub account.
|
||||
|
||||
@@ -338,9 +338,9 @@ Notice that this form of provider has a third key, `deps`, which specifies depen
|
||||
Use this technique to create a dependency object with a factory function whose inputs are a combination of *injected services* and *local state*.
|
||||
|
||||
The dependency object \(returned by the factory function\) is typically a class instance, but can be other things as well.
|
||||
In this example, the dependency object is a string of the names of the runners up to the "Hero of the Month" contest.
|
||||
In this example, the dependency object is a string of the names of the runners-up to the "Hero of the Month" contest.
|
||||
|
||||
In the example, the local state is the number `2`, the number of runners up that the component should show.
|
||||
In the example, the local state is the number `2`, the number of runners-up that the component should show.
|
||||
The state value is passed as an argument to `runnersUpFactory()`.
|
||||
The `runnersUpFactory()` returns the *provider factory function*, which can use both the passed-in state value and the injected services `Hero` and `HeroService`.
|
||||
|
||||
@@ -465,7 +465,7 @@ That's why you call the `HeroService` from within the `ngOnInit` rather than the
|
||||
</div>
|
||||
|
||||
Users want to see the heroes in alphabetical order.
|
||||
Rather than modify the original component, sub-class it and create a `SortedHeroesComponent` that sorts the heroes before presenting them.
|
||||
Rather than modify the original component, subclass it and create a `SortedHeroesComponent` that sorts the heroes before presenting them.
|
||||
The `SortedHeroesComponent` lets the base class fetch the heroes.
|
||||
|
||||
Unfortunately, Angular cannot inject the `HeroService` directly into the base class.
|
||||
|
||||
@@ -139,7 +139,7 @@ To deploy your Angular application to [GitHub Pages](https://help.github.com/art
|
||||
|
||||
</code-example>
|
||||
|
||||
1. Build your project using the Github project name, with the Angular CLI command [`ng build`](cli/build) and the following options, where `your_project_name` is the name of the project that you gave the GitHub repository in step 1.
|
||||
1. Build your project using the GitHub project name, with the Angular CLI command [`ng build`](cli/build) and the following options, where `your_project_name` is the name of the project that you gave the GitHub repository in step 1.
|
||||
|
||||
Be sure to include the slashes on either side of your project name as in `/your_project_name/`.
|
||||
|
||||
@@ -158,7 +158,7 @@ To deploy your Angular application to [GitHub Pages](https://help.github.com/art
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Check out [angular-cli-ghpages](https://github.com/angular-buch/angular-cli-ghpages), a full featured package that does all this for you and has extra functionality.
|
||||
Check out [angular-cli-ghpages](https://github.com/angular-buch/angular-cli-ghpages), a full-featured package that does all this for you and has extra functionality.
|
||||
|
||||
</div>
|
||||
|
||||
@@ -170,7 +170,7 @@ This section covers changes you may have to make to the server or to files deplo
|
||||
|
||||
<a id="fallback"></a>
|
||||
|
||||
### Routed apps must fallback to `index.html`
|
||||
### Routed apps must fall back to `index.html`
|
||||
|
||||
Angular applications are perfect candidates for serving with a simple static HTML server.
|
||||
You don't need a server-side engine to dynamically compose application pages because
|
||||
|
||||
@@ -384,7 +384,7 @@ These restrictions will be relaxed with the release of Ivy since it'll no longer
|
||||
|
||||
Angular applications, and specifically applications that relied on the JIT compiler, used to require a polyfill for the [reflect-metadata](https://github.com/rbuckton/reflect-metadata) APIs.
|
||||
|
||||
The need for this polyfill was removed in Angular version 8.0 \([see #14473](https://github.com/angular/angular-cli/pull/14473)\), rendering the presence of the poylfill in most Angular applications unnecessary.
|
||||
The need for this polyfill was removed in Angular version 8.0 \([see #14473](https://github.com/angular/angular-cli/pull/14473)\), rendering the presence of the polyfill in most Angular applications unnecessary.
|
||||
Because the polyfill can be depended on by 3rd-party libraries, instead of removing it from all Angular projects, we are deprecating the requirement for this polyfill as of version 8.0.
|
||||
This should give library authors and application developers sufficient time to evaluate if they need the polyfill, and perform any refactoring necessary to remove the dependency on it.
|
||||
|
||||
@@ -549,8 +549,8 @@ Projects that currently have `fullTemplateTypeCheck: true` configured can migrat
|
||||
|
||||
## JIT API changes due to ViewEngine deprecation
|
||||
|
||||
In ViewEngine, [JIT compilation](https://angular.io/guide/glossary#jit) required special providers \(like `Compiler`, `CompilerFactory`, etc.\) to be injected in the app and corresponding methods to be invoked.
|
||||
With Ivy, JIT compilation takes place implicitly if the Component, NgModule, etc have not already been [AOT compiled](https://angular.io/guide/glossary#aot).
|
||||
In ViewEngine, [JIT compilation](https://angular.io/guide/glossary#jit) required special providers \(such as `Compiler` or `CompilerFactory`\) to be injected in the app and corresponding methods to be invoked.
|
||||
With Ivy, JIT compilation takes place implicitly if the Component, NgModule, etc. have not already been [AOT compiled](https://angular.io/guide/glossary#aot).
|
||||
Those special providers were made available in Ivy for backwards-compatibility with ViewEngine to make the transition to Ivy smoother.
|
||||
Since ViewEngine is deprecated and will soon be removed, those symbols are now deprecated as well.
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ Type `$ng0` to get a reference to the instance of the currently selected compone
|
||||
### Select a directive or component
|
||||
|
||||
Similar to browsers' DevTools, you can inspect the page to select a particular component or directive.
|
||||
Click the ***Inspect element*** icon at the top left corner within Angular DevTools and hover over a DOM element on the page.
|
||||
Click the ***Inspect element*** icon in the top left corner within Angular DevTools and hover over a DOM element on the page.
|
||||
The extension recognizes the associated directives and/or components and lets you select the corresponding element in the Component tree.
|
||||
|
||||
<div class="lightbox">
|
||||
@@ -154,7 +154,7 @@ The **Profiler** tab lets you preview the execution of Angular's change detectio
|
||||
</div>
|
||||
|
||||
The Profiler lets you start profiling or import an existing profile.
|
||||
To start profiling your application, hover over the circle at the top-left corner within the **Profiler** tab and click **Start recording**.
|
||||
To start profiling your application, hover over the circle in the top-left corner within the **Profiler** tab and click **Start recording**.
|
||||
|
||||
During profiling, Angular DevTools captures execution events, such as change detection and lifecycle hook execution.
|
||||
To finish recording, click the circle again to **Stop recording**.
|
||||
|
||||
@@ -54,7 +54,7 @@ Style guides and the style tests can change.
|
||||
|
||||
Generally, shorter sentences are easier to read than longer ones.
|
||||
Long sentences can occur when you try to say too much at once.
|
||||
Long sentences, as well as the use of parentheses, semi-colons, or words identified as *too-wordy*, generally require rethinking and rewriting.
|
||||
Long sentences, as well as the use of parentheses, semicolons, or words identified as *too-wordy*, generally require rethinking and rewriting.
|
||||
|
||||
Consider restructuring a long sentence to break its individual ideas into distinct sentences or bullet points.
|
||||
|
||||
@@ -70,7 +70,7 @@ Shorter, more common words are generally easier to read than longer ones.
|
||||
This does not mean you need to write down to the audience. Technical docs should still be precise.
|
||||
Angular docs are read by many people around the world and should use language that the most people can understand.
|
||||
|
||||
If you think a specific term is required even though it is been flagged as uncommon, try to include a short explanation of the term.
|
||||
If you think a specific term is required even though it has been flagged as uncommon, try to include a short explanation of the term.
|
||||
Also, try adding some context around its first mention.
|
||||
|
||||
Linking a term to another section or topic is also an option, but consider the disruption that causes to the reader before you use it.
|
||||
@@ -175,7 +175,7 @@ Sentences that start with the words identified by this message can usually be ma
|
||||
|
||||
Cliches should be replaced by more literal text.
|
||||
|
||||
Cliches make it difficult for people who don't understand English to understand the documentation. When cliches are translated by online tools such as Google translate, they can produce confusing results.
|
||||
Cliches make it difficult for people who don't understand English to understand the documentation. When cliches are translated by online tools such as Google Translate, they can produce confusing results.
|
||||
|
||||
## If all else fails
|
||||
|
||||
|
||||
@@ -577,7 +577,7 @@ Use `#docregion` in source files to mark code for use in `<code-example>` or `<c
|
||||
The `#docregion` comment begins a code snippet region.
|
||||
Every line of code after that comment belongs in the region until the code fragment processor encounters the end of the file or a closing `#enddocregion`.
|
||||
|
||||
The following `src/main.ts` is a an example of a file with a single `#docregion` at the top of the file.
|
||||
The following `src/main.ts` is an example of a file with a single `#docregion` at the top of the file.
|
||||
|
||||
<code-example header="src/main.ts" path="docs-style-guide/src/main.ts"></code-example>
|
||||
|
||||
|
||||
@@ -71,13 +71,13 @@ Combinations of keys can be separated by a `.` (period). For example, `keydown.e
|
||||
<input (keydown.shift.t)="onKeydown($event)" />
|
||||
```
|
||||
|
||||
Depending on the operating system, some key combinations might create special characters instead of the key combination that you expect. MacOS, for example, creates special characters when you use the option and shift keys together. If you bind to `keydown.shift.alt.t`, on MacOS, that combination produces a `ˇ` character instead of a `t`, which doesn't match the binding and won't trigger your event handler. To bind to `keydown.shift.alt.t` on MacOS, use the `code` keyboard event field to get the correct behavior, such as `keydown.code.shiftleft.altleft.keyt` shown in this example.
|
||||
Depending on the operating system, some key combinations might create special characters instead of the key combination that you expect. MacOS, for example, creates special characters when you use the option and shift keys together. If you bind to `keydown.shift.alt.t`, on macOS, that combination produces a `ˇ` character instead of a `t`, which doesn't match the binding and won't trigger your event handler. To bind to `keydown.shift.alt.t` on macOS, use the `code` keyboard event field to get the correct behavior, such as `keydown.code.shiftleft.altleft.keyt` shown in this example.
|
||||
|
||||
```typescript
|
||||
<input (keydown.code.shiftleft.altleft.keyt)="onKeydown($event)" />
|
||||
```
|
||||
|
||||
The `code` field is more specific than the `key` field. The `key` field always reports `shift`, whereas the `code` field will specify `leftshift` or `rightshift`. When using the `code` field, you might need to add separate bindings to catch all the behaviors you want. Using the `code` field avoids the need to handle OS specific behaviors such as the `shift + option` behavior on MacOS.
|
||||
The `code` field is more specific than the `key` field. The `key` field always reports `shift`, whereas the `code` field will specify `leftshift` or `rightshift`. When using the `code` field, you might need to add separate bindings to catch all the behaviors you want. Using the `code` field avoids the need to handle OS specific behaviors such as the `shift + option` behavior on macOS.
|
||||
|
||||
For more information, visit the full reference for [key](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values) and [code](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_code_values) to help build out your event strings.
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ Subfolders contain the application source and application-specific configuration
|
||||
<div class="alert is-helpful">
|
||||
|
||||
New Angular projects use strict mode by default.
|
||||
If this is not desired you can opt-out when creating the project.
|
||||
If this is not desired you can opt out when creating the project.
|
||||
For more information, see [Strict mode](guide/strict-mode).
|
||||
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,7 @@ Each approach offers different advantages.
|
||||
|
||||
| Forms | Details |
|
||||
|:--- |:--- |
|
||||
| Reactive forms | Provide direct, explicit access to the underlying forms object model. Compared to template-driven forms, they are more robust: they're more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms. |
|
||||
| Reactive forms | Provide direct, explicit access to the underlying form's object model. Compared to template-driven forms, they are more robust: they're more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms. |
|
||||
| Template-driven forms | Rely on directives in the template to create and manipulate the underlying object model. They are useful for adding a simple form to an app, such as an email list signup form. They're straightforward to add to an app, but they don't scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, template-driven forms could be a good fit. |
|
||||
|
||||
### Key differences
|
||||
|
||||
@@ -334,7 +334,7 @@ See also [lazy loading][AioGuideGlossaryLazyLoading].
|
||||
The [official JavaScript language specification][WikipediaWikiEcmascript].
|
||||
|
||||
Not all browsers support the latest ECMAScript standard, but you can use a [transpiler][AioGuideGlossaryTranspile] to write code using the latest features, which will then be transpiled to code that runs on versions that are supported by browsers.
|
||||
A example of a [transpiler][AioGuideGlossaryTranspile] is [TypeScript][AioGuideGlossaryTypescript].
|
||||
An example of a [transpiler][AioGuideGlossaryTranspile] is [TypeScript][AioGuideGlossaryTypescript].
|
||||
To learn more, see [Browser Support][AioGuideBrowserSupport].
|
||||
|
||||
## element
|
||||
@@ -357,7 +357,7 @@ For example, the `@angular/core` package has two entry-point modules, which can
|
||||
|
||||
## form control
|
||||
|
||||
A instance of `FormControl`, which is a fundamental building block for Angular forms.
|
||||
An instance of `FormControl`, which is a fundamental building block for Angular forms.
|
||||
Together with `FormGroup` and `FormArray`, tracks the value, validation, and status of a form input element.
|
||||
|
||||
Read more forms in the [Introduction to forms in Angular][AioGuideFormsOverview].
|
||||
@@ -589,7 +589,7 @@ See [Browser Support][AioGuideBrowserSupport] for polyfills that support particu
|
||||
|
||||
## project
|
||||
|
||||
In the Angular CLI, a standalone application or [library][AioGuideGlossaryLibrary] that can be created or modified by a Angular CLI command.
|
||||
In the Angular CLI, a standalone application or [library][AioGuideGlossaryLibrary] that can be created or modified by an Angular CLI command.
|
||||
|
||||
A project, as generated by the [`ng new`][AioCliNew], contains the set of source files, resources, and configuration files that you need to develop and test the application using the Angular CLI.
|
||||
Projects can also be created with the `ng generate application` and `ng generate library` commands.
|
||||
|
||||
@@ -302,7 +302,7 @@ Components are used in your templates, as in the following example:
|
||||
Usually, you declare the components and their templates in separate files.
|
||||
For the purposes of understanding how the injection system works, it is useful to look at them from the point of view of a combined logical tree.
|
||||
The term _logical_ distinguishes it from the render tree, which is your application's DOM tree.
|
||||
To mark the locations of where the component templates are located, this guide uses the `<#VIEW>` pseudo element, which doesn't actually exist in the render tree and is present for mental model purposes only.
|
||||
To mark the locations of where the component templates are located, this guide uses the `<#VIEW>` pseudo-element, which doesn't actually exist in the render tree and is present for mental model purposes only.
|
||||
|
||||
</div>
|
||||
|
||||
@@ -895,7 +895,7 @@ Instead, you can provide the `VillainsService` in the `providers` metadata of th
|
||||
|
||||
<code-example header="src/app/villains-list.component.ts (metadata)" path="hierarchical-dependency-injection/src/app/villains-list.component.ts" region="metadata"></code-example>
|
||||
|
||||
By providing `VillainsService` in the `VillainsListComponent` metadata and nowhere else, the service becomes available only in the `VillainsListComponent` and its sub-component tree.
|
||||
By providing `VillainsService` in the `VillainsListComponent` metadata and nowhere else, the service becomes available only in the `VillainsListComponent` and its subcomponent tree.
|
||||
|
||||
`VillainService` is a singleton with respect to `VillainsListComponent` because that is where it is declared.
|
||||
As long as `VillainsListComponent` does not get destroyed it will be the same instance of `VillainService` but if there are multiple instances of `VillainsListComponent`, then each instance of `VillainsListComponent` will have its own instance of `VillainService`.
|
||||
@@ -971,7 +971,7 @@ The root injector, marked as \(A\), uses *generic* providers for details about `
|
||||
|
||||
2. Child component \(B\). Component \(B\) defines its own, *specialized* providers for `CarService` and `EngineService` that have special capabilities suitable for what's going on in component \(B\).
|
||||
|
||||
3. Child component \(C\) as a childe of Component \(B\). Component \(C\) defines its own, even *more specialized* provider for `CarService`.
|
||||
3. Child component \(C\) as a child of Component \(B\). Component \(C\) defines its own, even *more specialized* provider for `CarService`.
|
||||
|
||||
<div class="lightbox">
|
||||
|
||||
|
||||
@@ -537,7 +537,7 @@ Like other services, you must provide the interceptor class before the app can u
|
||||
Because interceptors are optional dependencies of the `HttpClient` service, you must provide them in the same injector or a parent of the injector that provides `HttpClient`.
|
||||
Interceptors provided *after* DI creates the `HttpClient` are ignored.
|
||||
|
||||
This app provides `HttpClient` in the app's root injector, as a side-effect of importing the `HttpClientModule` in `AppModule`.
|
||||
This app provides `HttpClient` in the app's root injector, as a side effect of importing the `HttpClientModule` in `AppModule`.
|
||||
You should provide interceptors in `AppModule` as well.
|
||||
|
||||
After importing the `HTTP_INTERCEPTORS` injection token from `@angular/common/http`, write the `NoopInterceptor` provider like this:
|
||||
|
||||
@@ -14,7 +14,7 @@ For more information about how to serve each distributable copy of the applicati
|
||||
|
||||
</div>
|
||||
|
||||
For a compile time translation of the application, the build process uses [ahead-of-time (AOT) compilation][AioGuideGlossaryAheadOfTimeAotCompilation] to produce a small, fast, ready-to-run application.
|
||||
For a compile-time translation of the application, the build process uses [ahead-of-time (AOT) compilation][AioGuideGlossaryAheadOfTimeAotCompilation] to produce a small, fast, ready-to-run application.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ Use the following [`extract-i18n`][AioCliExtractI18n] command options to change
|
||||
| Command option | Details |
|
||||
|:--- |:--- |
|
||||
| `--format` | Set the format of the output file |
|
||||
| `--outFile` | Set the name of the output file |
|
||||
| `--out-file` | Set the name of the output file |
|
||||
| `--output-path` | Set the path of the output directory |
|
||||
|
||||
### Change the source language file location
|
||||
@@ -74,7 +74,7 @@ The following example demonstrates several translation formats.
|
||||
|
||||
### Change the source language file name
|
||||
|
||||
To change the name of the source language file generated by the extraction tool, use the `--outFile` command option.
|
||||
To change the name of the source language file generated by the extraction tool, use the `--out-file` command option.
|
||||
|
||||
#### `extract-i18n --out-file` example
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
# Setting up `NgOptimizedImage`
|
||||
|
||||
This tutorial explains how to set up the `NgOptimizedImage`. For information on using `NgOptimizedImage`, see [Getting Started with NgOptimizedImage](/guide/image-directive).
|
||||
|
||||
## Import `NgOptimizedImage`
|
||||
|
||||
You can import `NgOptimizedImage` from the `@angular/common` module. The directive is defined as a [standalone directive](/guide/standalone-components), so components should import it directly.
|
||||
|
||||
## Configure an `ImageLoader`
|
||||
|
||||
A "loader" is a function that generates the [image transformation URL](https://web.dev/image-cdns/#how-image-cdns-use-urls-to-indicate-optimization-options) for a given image file. When appropriate, `NgOptimizedImage` sets the size, format, and image quality transformations for an image.
|
||||
|
||||
`NgOptimizedImage` provides a generic loader as well as loaders for various third-party image services; it also supports writing your own custom loader.
|
||||
|
||||
| Loader type| Behavior |
|
||||
|:--- |:--- |
|
||||
| Generic loader | The URL returned by the generic loader will always match the value of `src`. In other words, this loader applies no transformations. Sites that use Angular to serve images are the primary intended use case for this loader.|
|
||||
| Loaders for third-party image services | The URL returned by the loaders for third-party image services will follow API conventions used by that particular image service. |
|
||||
| Custom loaders | A custom loader's behavior is defined by its developer. You should use a custom loader if your image service isn't supported by the loaders that come preconfigured with `NgOptimizedImage`.|
|
||||
|
||||
Based on the image services commonly used with Angular applications, `NgOptimizedImage` provides loaders preconfigured to work with the following image services:
|
||||
|
||||
| Image Service | Angular API | Documentation |
|
||||
|:--- |:--- |:--- |
|
||||
| Cloudflare Image Resizing | `provideCloudflareLoader` | [Documentation](https://developers.cloudflare.com/images/image-resizing/) |
|
||||
| Cloudinary | `provideCloudinaryLoader` | [Documentation](https://cloudinary.com/documentation/resizing_and_cropping) |
|
||||
| ImageKit | `provideImageKitLoader` | [Documentation](https://docs.imagekit.io/) |
|
||||
| Imgix | `provideImgixLoader` | [Documentation](https://docs.imgix.com/) |
|
||||
|
||||
You must configure an image loader to use `NgOptimizedImage`.
|
||||
|
||||
These instructions explain how to set up an image loader for use with the `NgOptimizedImage`.
|
||||
|
||||
1. Import the `NgOptimizedImage` directive into the application by adding it to the `imports` section of an NgModule or a standalone Component.
|
||||
|
||||
<code-example format="typescript" language="typescript">
|
||||
import { NgOptimizedImage } from '@angular/common';
|
||||
// Include NgOptimizedImage in the appropriate NgModule
|
||||
@NgModule({
|
||||
imports: [
|
||||
// ... other imports
|
||||
NgOptimizedImage,
|
||||
],
|
||||
})
|
||||
|
||||
class AppModule {}
|
||||
</code-example>
|
||||
|
||||
<code-example format="typescript" language="typescript">
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
// ... other imports
|
||||
NgOptimizedImage,
|
||||
],
|
||||
})
|
||||
|
||||
class MyStandaloneComponent {}
|
||||
</code-example>
|
||||
|
||||
2. Configure a loader that you want to use.
|
||||
|
||||
To use the **generic loader**: no additional code changes are necessary.
|
||||
|
||||
To use an existing loader for a **third-party image service**: add the provider factory for your chosen service to the `providers` array. In the example below, the Imgix loader is used:
|
||||
|
||||
<code-example format="typescript" language="typescript">
|
||||
providers: [
|
||||
provideImgixLoader('https://my.base.url/'),
|
||||
],
|
||||
</code-example>
|
||||
|
||||
The base URL for your image assets should be passed to the provider factory as an argument. For most sites, this base URL should match one of the following patterns:
|
||||
|
||||
* https://yoursite.yourcdn.com
|
||||
* https://subdomain.yoursite.com
|
||||
* https://subdomain.yourcdn.com/yoursite
|
||||
|
||||
You can learn more about the base URL structure in the docs of a corresponding CDN provider.
|
||||
|
||||
To use a **custom loader**: provide your loader function as a value for the `IMAGE_LOADER` DI token. In the example below, the custom loader function returns a URL starting with `https://example.com` that includes `src` and `width` as URL parameters.
|
||||
|
||||
<code-example format="typescript" language="typescript">
|
||||
providers: [
|
||||
{
|
||||
provide: IMAGE_LOADER,
|
||||
useValue: (config: ImageLoaderConfig) => {
|
||||
return `https://example.com/images?src=${config.src}&width=${config.width}`;
|
||||
},
|
||||
},
|
||||
],
|
||||
</code-example>
|
||||
|
||||
A loader function for the `NgOptimizedImage` directive takes an object with the `ImageLoaderConfig` type (from `@angular/common`) as its argument and returns the absolute URL of the image asset. The `ImageLoaderConfig` object contains the `src`and `width` properties.
|
||||
|
||||
Note: a custom loader must support requesting images at various widths in order for `ngSrcset` to work properly.
|
||||
@@ -0,0 +1,121 @@
|
||||
# Getting started with NgOptimizedImage
|
||||
|
||||
Note: the `NgOptimizedImage` directive is currently in the ["Developer Preview" mode](https://angular.io/guide/releases#developer-preview). The Angular team will stabilize the APIs based on the feedback and will make an announcement once the APIs are fully stable.
|
||||
|
||||
The `NgOptimizedImage` directive makes it easy to adopt performance best practices for loading images.
|
||||
|
||||
The `NgOptimizedImage` directive ensures that the loading of the [Largest Contentful Paint](http://web.dev/lcp) image is prioritized by:
|
||||
|
||||
* Automatically setting the `fetchpriority` attribute on the `<img>` tag
|
||||
* Lazy loading other images by default
|
||||
* Asserting that there is a corresponding preconnect link tag in the document head
|
||||
|
||||
In addition to optimizing the loading of the LCP image, `NgOptimizedImage` enforces a number of image best practices:
|
||||
|
||||
* Using [image URLs to apply image optimizations](https://web.dev/image-cdns/#how-image-cdns-use-urls-to-indicate-optimization-options)
|
||||
* Requires that `width` and `height` are set
|
||||
* Warns if `width` or `height` have been set incorrectly
|
||||
* Warns if the image will be visually distorted when rendered
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You will need to import the directive into your application. In addition, you will need to set up an image loader. These steps are explained in the [Setting up `NgOptimizedImage`](/guide/image-directive-setup) tutorial.
|
||||
|
||||
## Usage in a template
|
||||
|
||||
### Overview
|
||||
|
||||
To activate the `NgOptimizedImage` directive, replace your image's `src` attribute with `ngSrc`.
|
||||
|
||||
<code-example format="typescript" language="typescript">
|
||||
|
||||
<img ngSrc="cat.jpg" width="400" height="200">
|
||||
|
||||
</code-example>
|
||||
|
||||
The built-in third-party loaders prepend a shared base URL to `src`. If you're using one of these loaders (or any other loader that does this), make sure to omit the shared base URL path from `src` to prevent unnecessary duplication.
|
||||
|
||||
You must also set the `width` and `height` attributes. This is done to prevent [image-related layout shifts](https://web.dev/css-web-vitals/#images-and-layout-shifts). The `width` and `height` attributes should reflect the [intrinsic size](https://developer.mozilla.org/en-US/docs/Glossary/Intrinsic_Size) of the image. During development, the `NgOptimizedImage` warns if it detects that the `width` and `height` attributes have been set incorrectly.
|
||||
|
||||
### Marking images as `priority`
|
||||
|
||||
Always mark the [LCP image](https://web.dev/lcp/#what-elements-are-considered) on your page as `priority` to prioritize its loading.
|
||||
|
||||
<code-example format="typescript" language="typescript">
|
||||
|
||||
<img ngSrc="cat.jpg" width="400" height="200" priority>
|
||||
|
||||
</code-example>
|
||||
|
||||
Marking an image as `priority` applies the following optimizations:
|
||||
|
||||
* Sets `fetchpriority=high` (read more about priority hints [here](https://web.dev/priority-hints))
|
||||
* Sets `loading=eager` (read more about native lazy loading [here](https://web.dev/browser-level-image-lazy-loading))
|
||||
|
||||
Angular displays a warning during development if the LCP element is an image that does not have the `priority` attribute. A page’s LCP element can vary based on a number of factors - such as the dimensions of a user's screen. A page may have multiple images that should be marked `priority`. See [CSS for Web Vitals](https://web.dev/css-web-vitals/#images-and-largest-contentful-paint-lcp) for more details.
|
||||
|
||||
### Adding resource hints
|
||||
|
||||
You can add a [`preconnect` resource hint](https://web.dev/preconnect-and-dns-prefetch) for your image origin to ensure that the LCP image loads as quickly as possible. Always put resource hints in the `<head>` of the document.
|
||||
|
||||
<code-example format="html" language="html">
|
||||
|
||||
<link rel="preconnect" href="https://my.cdn.origin" />
|
||||
|
||||
</code-example>
|
||||
|
||||
By default, if you use a loader for a third-party image service, the `NgOptimizedImage` directive will warn during development if it detects that there is no `preconnect` resource hint for the origin that serves the LCP image.
|
||||
|
||||
To disable these warnings, add `{ensurePreconnect: false}` to the arguments passed to the provider factory for your chosen image service:
|
||||
|
||||
<code-example format="typescript" language="typescript">
|
||||
|
||||
providers: [
|
||||
provideImgixLoader('https://my.base.url', {ensurePreconnect: false})
|
||||
],
|
||||
|
||||
</code-example>
|
||||
|
||||
### Adjusting image styling
|
||||
|
||||
Depending on the image's styling, adding `width` and `height` attributes may cause the image to render differently. `NgOptimizedImage` warns you if your image styling renders the image at a distorted aspect ratio.
|
||||
|
||||
You can typically fix this by adding `height: auto` or `width: auto` to your image styles. For more information, see the [web.dev article on the `<img>` tag](https://web.dev/patterns/web-vitals-patterns/images/img-tag).
|
||||
|
||||
### Handling `srcset` attributes
|
||||
|
||||
If your `<img>` tag defines a `srcset` attribute, replace it with `ngSrcset`.
|
||||
|
||||
<code-example format="html" language="html">
|
||||
|
||||
<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w">
|
||||
|
||||
</code-example>
|
||||
|
||||
If the `ngSrcset` attribute is present, `NgOptimizedImage` generates and sets the [`srcset` attribute](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset) using the configured image loader. Do not include image file names in `ngSrcset` - the directive infers this information from `ngSrc`. The directive supports both width descriptors (e.g. `100w`) and density descriptors (e.g. `1x`) are supported.
|
||||
|
||||
You can also use `ngSrcset` with the standard image [`sizes` attribute](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes).
|
||||
|
||||
<code-example format="html" language="html">
|
||||
|
||||
<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w" sizes="50vw">
|
||||
|
||||
</code-example>
|
||||
|
||||
### Disabling image lazy loading
|
||||
|
||||
By default, `NgOptimizedImage` sets `loading=lazy` for all images that are not marked `priority`. You can disable this behavior for non-priority images by setting the `loading` attribute. This attribute accepts values: `eager`, `auto`, and `lazy`. [See the documentation for the standard image `loading` attribute for details](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/loading#value).
|
||||
|
||||
<code-example format="html" language="html">
|
||||
|
||||
<img ngSrc="cat.jpg" width="400" height="200" loading="eager">
|
||||
|
||||
</code-example>
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!--end links -->
|
||||
|
||||
@reviewed 2022-08-25
|
||||
@@ -148,7 +148,7 @@ When you type into the editor, the editor sends information to the language-serv
|
||||
|
||||
When you trigger a completion list within a template, the editor first parses the template into an HTML [abstract syntax tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
|
||||
The Angular compiler interprets that tree to determine the context: which module the template is part of, the current scope, the component selector, and where your cursor is in the template AST.
|
||||
It can then determine the symbols that could potentially be at that position..
|
||||
It can then determine the symbols that could potentially be at that position.
|
||||
|
||||
It's a little more involved if you are in an interpolation.
|
||||
If you have an interpolation of `{{data.---}}` inside a `div` and need the completion list after `data.---`, the compiler can't use the HTML AST to find the answer.
|
||||
|
||||
@@ -40,7 +40,7 @@ Use them to perform the following kinds of operations.
|
||||
|
||||
| Hook method | Purpose | Timing |
|
||||
|:--- |:--- |:--- |
|
||||
| `ngOnChanges()` | Respond when Angular sets or resets data-bound input properties. The method receives a `SimpleChanges` object of current and previous property values. <br /> <div class="alert is-helpful"> **NOTE**: <br /> This happens very frequently, so any operation you perform here impacts performance significantly. </div> See details in [Using change detection hooks](#onchanges) in this document. | Called before `ngOnInit()` \(if the component has bound inputs\) and whenever one or more data-bound input properties change. <br /> <div class="alert is-helpful"> **NOTE**: <br /> If your component has no inputs or you use it without providing any inputs, the framework will not call `ngOnChanges()`. </div> |
|
||||
| `ngOnChanges()` | Respond when Angular sets or resets data-bound input properties. The method receives a `SimpleChanges` object of current and previous property values. <br /> <div class="alert is-helpful"> **NOTE**: <br /> This happens frequently, so any operation you perform here impacts performance significantly. </div> See details in [Using change detection hooks](#onchanges) in this document. | Called before `ngOnInit()` \(if the component has bound inputs\) and whenever one or more data-bound input properties change. <br /> <div class="alert is-helpful"> **NOTE**: <br /> If your component has no inputs or you use it without providing any inputs, the framework will not call `ngOnChanges()`. </div> |
|
||||
| `ngOnInit()` | Initialize the directive or component after Angular first displays the data-bound properties and sets the directive or component's input properties. See details in [Initializing a component or directive](#oninit) in this document. | Called once, after the first `ngOnChanges()`. `ngOnInit()` is still called even when `ngOnChanges()` is not \(which is the case when there are no template-bound inputs\). |
|
||||
| `ngDoCheck()` | Detect and act upon changes that Angular can't or won't detect on its own. See details and example in [Defining custom change detection](#docheck) in this document. | Called immediately after `ngOnChanges()` on every change detection run, and immediately after `ngOnInit()` on the first run. |
|
||||
| `ngAfterContentInit()` | Respond after Angular projects external content into the component's view, or into the view that a directive is in. <br /> See details and example in [Responding to changes in content](#aftercontent) in this document. | Called *once* after the first `ngDoCheck()`. |
|
||||
@@ -121,12 +121,16 @@ The sequence of log messages follows the prescribed hook calling order:
|
||||
|:--- |:--- |
|
||||
| 1 | `OnChanges` |
|
||||
| 2 | `OnInit` |
|
||||
| 3-5 | `DoCheck` |
|
||||
| 6 | `AfterContentInit` |
|
||||
| 7-9 | `AfterContentChecked` |
|
||||
| 10 | `AfterViewInit` |
|
||||
| 11-13 | `AfterViewChecked` |
|
||||
| 14 | `OnDestroy` |
|
||||
| 3 | `DoCheck` |
|
||||
| 4 | `AfterContentInit` |
|
||||
| 5 | `AfterContentChecked` |
|
||||
| 6 | `AfterViewInit` |
|
||||
| 7 | `AfterViewChecked` |
|
||||
| 8 | `DoCheck` |
|
||||
| 9 | `AfterContentChecked` |
|
||||
| 10 | `AfterViewChecked` |
|
||||
| 11 | `OnDestroy` |
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@@ -151,8 +155,8 @@ The example does not perform any initialization or clean-up.
|
||||
It just tracks the appearance and disappearance of an element in the view by recording when the directive itself is instantiated and destroyed.
|
||||
|
||||
A spy directive like this can provide insight into a DOM object that you cannot change directly.
|
||||
You can't touch the implementation of a built-in `<div>`, or modify a third party component.
|
||||
You can, however watch these elements with a directive.
|
||||
You can't access the implementation of a built-in `<div>`, or modify a third party component.
|
||||
You do have the option to watch these elements with a directive.
|
||||
|
||||
The directive defines `ngOnInit()` and `ngOnDestroy()` hooks
|
||||
that log messages to the parent using an injected `LoggerService`.
|
||||
@@ -253,8 +257,8 @@ The `LoggerService.tick_then()` statement postpones the log update for one turn
|
||||
|
||||
#### Write lean hook methods to avoid performance problems
|
||||
|
||||
When you run the *AfterView* sample, notice how frequently Angular calls `AfterViewChecked()`-often when there are no changes of interest.
|
||||
Be very careful about how much logic or computation you put into one of these methods.
|
||||
When you run the *AfterView* sample, notice how frequently Angular calls `AfterViewChecked()` - often when there are no changes of interest.
|
||||
Be careful about how much logic or computation you put into one of these methods.
|
||||
|
||||
<div class="lightbox">
|
||||
|
||||
@@ -284,7 +288,7 @@ AngularJS developers know this technique as *transclusion*.
|
||||
The *AfterContent* sample explores the `AfterContentInit()` and `AfterContentChecked()` hooks that Angular calls *after* Angular projects external content into the component.
|
||||
|
||||
Consider this variation on the [previous *AfterView*](#afterview) example.
|
||||
This time, instead of including the child view within the template, it imports the content from the `AfterContentComponent`'s parent.
|
||||
This time, instead of including the child view within the template, it imports the content from the `AfterContentComponent` hook's parent.
|
||||
The following is the parent's template.
|
||||
|
||||
<code-example header="AfterContentParentComponent (template excerpt)" path="lifecycle-hooks/src/app/after-content-parent.component.ts" region="parent-template"></code-example>
|
||||
@@ -354,7 +358,7 @@ The results are illuminating.
|
||||
|
||||
</div>
|
||||
|
||||
While the `ngDoCheck()` hook can detect when the hero's `name` has changed, it is very expensive.
|
||||
While the `ngDoCheck()` hook can detect when the hero's `name` has changed, it is an expensive hook.
|
||||
This hook is called with enormous frequency —after *every* change detection cycle no matter where the change occurred.
|
||||
It's called over twenty times in this example before the user can do anything.
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ It also lists `@angular/localize` as a dependency in your app's `package.json` t
|
||||
|
||||
`@angular/localize` is a new package that supports i18n of messages in Ivy applications.
|
||||
This package requires a global `$localize` symbol to exist.
|
||||
The symbol is loaded by importing the `@angular/localize/init` module, which has the side-effect of attaching it to the global scope.
|
||||
The symbol is loaded by importing the `@angular/localize/init` module, which has the side effect of attaching it to the global scope.
|
||||
|
||||
## Why is this migration necessary?
|
||||
|
||||
@@ -41,7 +41,7 @@ Because the application does not need to be built again for each locale, this ma
|
||||
The post-compilation inlining step is optional —for example during development or if the translations will be inlined at runtime.
|
||||
Therefore this global `$localize` must be available on the global scope at runtime.
|
||||
To make `$localize` available on the global scope, each application must now import the `@angular/localize/init` module.
|
||||
This has the side-effect of attaching a minimal implementation of `$localize` to the global scope.
|
||||
This has the side effect of attaching a minimal implementation of `$localize` to the global scope.
|
||||
|
||||
If this import is missing, you will see an error message like this:
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ This section provides guidance on migrating from this deprecated API to the newe
|
||||
|
||||
The deprecated `Renderer` class has been removed in version 9 of Angular, so it's necessary to migrate to a supported API.
|
||||
Using `Renderer2` is the recommended strategy because it supports a similar set of functionality to `Renderer`.
|
||||
The API surface is quite large \(with 19 methods\, but the schematic should simplify this process for your applications.
|
||||
With 19 methods, the API surface is quite large, but the schematic should simplify this process for your applications.
|
||||
|
||||
## Is there action required on my end?
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class BaseMenu {}
|
||||
|
||||
@Component({
|
||||
selector: 'base-menu',
|
||||
template: '<div></div*gt;'
|
||||
template: '<div></div>'
|
||||
})
|
||||
export class SettingsMenu extends BaseMenu {}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ This error often means that you haven't declared the directive "x" or haven't im
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Perhaps you declared "x" in an application sub-module but forgot to export it.
|
||||
Perhaps you declared "x" in an application submodule but forgot to export it.
|
||||
The "x" class isn't visible to other modules until you add it to the `exports` list.
|
||||
|
||||
</div>
|
||||
@@ -384,7 +384,7 @@ The answer is grounded in a fundamental characteristic of the Angular dependency
|
||||
An injector can add providers *until it's first used*.
|
||||
Once an injector starts creating and delivering services, its provider list is frozen; no new providers are allowed.
|
||||
|
||||
When an applications starts, Angular first configures the root injector with the providers of all eagerly loaded NgModules *before* creating its first component and injecting any of the provided services.
|
||||
When an application starts, Angular first configures the root injector with the providers of all eagerly loaded NgModules *before* creating its first component and injecting any of the provided services.
|
||||
Once the application begins, the application root injector is closed to new providers.
|
||||
|
||||
Time passes and application logic triggers lazy loading of an NgModule.
|
||||
|
||||
@@ -34,7 +34,7 @@ import { AppComponent } from './app.component';
|
||||
Each module has its own top-level scope.
|
||||
In other words, top-level variables and functions in a module are not seen in other scripts or modules.
|
||||
Each module provides a namespace for identifiers to prevent them from clashing with identifiers in other modules.
|
||||
With multiple modules, you can prevent accidental global variables by creating a single global namespace and adding sub-modules to it.
|
||||
With multiple modules, you can prevent accidental global variables by creating a single global namespace and adding submodules to it.
|
||||
|
||||
The Angular framework itself is loaded as a set of JavaScript modules.
|
||||
|
||||
|
||||
@@ -318,7 +318,7 @@ Observables can deliver single or multiple values of any type, either synchronou
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For details and examples of observables, see the [Observables Overview](guide/observables#using-observables-to-pass-values "Using observables to pass values"").
|
||||
For details and examples of observables, see the [Observables Overview](guide/observables#using-observables-to-pass-values "Using observables to pass values").
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ To help ensure that you have sufficient time and a clear path to update, this is
|
||||
|
||||
## Public API surface
|
||||
|
||||
Angular is a collection of many packages, sub-projects, and tools.
|
||||
Angular is a collection of many packages, subprojects, and tools.
|
||||
To prevent accidental use of private APIs and so that you can clearly understand what is covered by the practices described here — we document what is and is not considered our public API surface.
|
||||
For details, see [Supported Public API Surface of Angular](https://github.com/angular/angular/blob/main/docs/PUBLIC_API.md "Supported Public API Surface of Angular").
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ We conducted a series of 40 interviews to understand the requirements for micro-
|
||||
### Investigate modern bundles
|
||||
|
||||
To improve development experience by speeding up build times research modern bundles.
|
||||
As part of the project experiment with [esbuild](https://esbuild.github.io) and other open source solutions, compare them with the state of the art tooling in Angular CLI, and report the findings. In Angular v14 we're releasing an [experimental support](https://github.com/angular/angular-cli/pull/22995) for esbuild. Next, the team will focus on validating the new prototype and implementing watch and Sass support.
|
||||
As part of the project experiment with [esbuild](https://esbuild.github.io) and other open source solutions, compare them with the state-of-the-art tooling in Angular CLI, and report the findings. In Angular v14 we're releasing an [experimental support](https://github.com/angular/angular-cli/pull/22995) for esbuild. Next, the team will focus on validating the new prototype and implementing watch and Sass support.
|
||||
|
||||
### Modern CSS
|
||||
|
||||
@@ -177,7 +177,7 @@ Introduce other correctness and conformance checks to further guarantee correctn
|
||||
*Completed Q3 2021*
|
||||
|
||||
To ensure we provide a future-proof e2e testing strategy, we want to evaluate the state of Protractor, community innovations, e2e best practices, and explore novel opportunities.
|
||||
As first steps of the effort, we shared an [RFC](https://github.com/angular/protractor/issues/5502) and worked with partners to ensure smooth integration between the Angular CLI and state of the art tooling for e2e testing.
|
||||
As first steps of the effort, we shared an [RFC](https://github.com/angular/protractor/issues/5502) and worked with partners to ensure smooth integration between the Angular CLI and state-of-the-art tooling for e2e testing.
|
||||
As the next step, we need to finalize the recommendations and compile a list of resources for the transition.
|
||||
|
||||
### Angular libraries use Ivy
|
||||
|
||||
@@ -110,7 +110,7 @@ Click the browser back button or the "Heroes" link to activate a dialog.
|
||||
You can say "OK" and lose your changes or click "Cancel" and continue editing.
|
||||
|
||||
Behind this behavior is the router's `CanDeactivate` guard.
|
||||
The guard gives you a chance to clean-up or ask the user's permission before navigating away from the current view.
|
||||
The guard gives you a chance to clean up or ask the user's permission before navigating away from the current view.
|
||||
|
||||
The `Admin` and `Login` buttons illustrate other router capabilities covered later in the guide.
|
||||
|
||||
@@ -1882,7 +1882,7 @@ The admin feature is now protected by the guard, but the guard requires more cus
|
||||
|
||||
Make the `AuthGuard` mimic authentication.
|
||||
|
||||
The `AuthGuard` should call an application service that can login a user and retain information about the current user.
|
||||
The `AuthGuard` should call an application service that can log in a user and retain information about the current user.
|
||||
Generate a new `AuthService` in the `auth` folder:
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
@@ -2430,7 +2430,7 @@ If the route does not preload, it returns an `Observable` of `null`.
|
||||
|
||||
In this sample, the `preload()` method loads the route if the route's `data.preload` flag is truthy.
|
||||
|
||||
As a side-effect, `SelectivePreloadingStrategyService` logs the `path` of a selected route in its public `preloadedModules` array.
|
||||
As a side effect, `SelectivePreloadingStrategyService` logs the `path` of a selected route in its public `preloadedModules` array.
|
||||
|
||||
Shortly, you'll extend the `AdminDashboardComponent` to inject this service and display its `preloadedModules` array.
|
||||
|
||||
@@ -2457,7 +2457,7 @@ It also logs to the browser's console.
|
||||
|
||||
### Migrating URLs with redirects
|
||||
|
||||
You've setup the routes for navigating around your application and used navigation imperatively and declaratively.
|
||||
You've set up the routes for navigating around your application and used navigation imperatively and declaratively.
|
||||
But like any application, requirements change over time.
|
||||
You've setup links and navigation to `/heroes` and `/hero/:id` from the `HeroListComponent` and `HeroDetailComponent` components.
|
||||
If there were a requirement that links to `heroes` become `superheroes`, you would still want the previous URLs to navigate correctly.
|
||||
|
||||
@@ -134,7 +134,7 @@ These examples use a shorthand form of the prompt syntax, supplying only the tex
|
||||
In most cases, this is all that is required.
|
||||
Notice however, that the two prompts expect different types of input.
|
||||
When using the shorthand form, the most appropriate type is automatically selected based on the property's schema.
|
||||
In the example, the `name` prompt uses the `input` type because it it is a string property.
|
||||
In the example, the `name` prompt uses the `input` type because it is a string property.
|
||||
The `useColor` prompt uses a `confirmation` type because it is a Boolean property.
|
||||
In this case, "yes" corresponds to `true` and "no" corresponds to `false`.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Schematics are packaged into [collections](guide/glossary#collection) and instal
|
||||
|
||||
The schematic collection can be a powerful tool for creating, modifying, and maintaining any software project, but is particularly useful for customizing Angular projects to suit the particular needs of your own organization.
|
||||
You might use schematics, for example, to generate commonly-used UI patterns or specific components, using predefined templates or layouts.
|
||||
Use schematics to enforce architectural rules and conventions, making your projects consistent and inter-operative.
|
||||
Use schematics to enforce architectural rules and conventions, making your projects consistent and interoperative.
|
||||
|
||||
## Schematics for the Angular CLI
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ You can run the <live-example></live-example> in Stackblitz and download the cod
|
||||
|
||||
<header>Reporting vulnerabilities</header>
|
||||
|
||||
To report vulnerabilities in Angular itself, email us at [security@angular.io](mailto:security@angular.io).
|
||||
Angular is part of Google [Open Source Software Vulnerability Reward Program](https://bughunters.google.com/about/rules/6521337925468160/google-open-source-software-vulnerability-reward-program-rules), for vulnerabilities in Angular please submit your report [here](https://bughunters.google.com/report).
|
||||
|
||||
For more information about how Google handles security issues, see [Google's security philosophy](https://www.google.com/about/appsecurity).
|
||||
|
||||
@@ -162,7 +162,7 @@ Content Security Policy \(CSP\) is a defense-in-depth technique to prevent XSS.
|
||||
To enable CSP, configure your web server to return an appropriate `Content-Security-Policy` HTTP header.
|
||||
Read more about content security policy at the [Web Fundamentals guide](https://developers.google.com/web/fundamentals/security/csp) on the Google Developers website.
|
||||
|
||||
The minimal policy required for brand new Angular is:
|
||||
The minimal policy required for brand-new Angular is:
|
||||
|
||||
<code-example format="none" language="none">
|
||||
|
||||
|
||||
@@ -64,16 +64,20 @@ Alternatively, you might want to define a different [registration strategy](api/
|
||||
|
||||
</div>
|
||||
|
||||
### Forcing update activation
|
||||
### Updating to the latest version
|
||||
|
||||
If the current tab needs to be updated to the latest application version immediately, it can ask to do so with the `activateUpdate()` method:
|
||||
You can update an existing tab to the latest version by reloading the page as soon as a new version is ready.
|
||||
To avoid disrupting the user's progress, it is generally a good idea to prompt the user and let them confirm that it is OK to reload the page and update to the latest version:
|
||||
|
||||
<code-example header="prompt-update.service.ts" path="service-worker-getting-started/src/app/prompt-update.service.ts" region="sw-activate"></code-example>
|
||||
<code-example header="prompt-update.service.ts" path="service-worker-getting-started/src/app/prompt-update.service.ts" region="sw-version-ready"></code-example>
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
Calling `activateUpdate()` without reloading the page could break lazy-loading in a currently running app, especially if the lazy-loaded chunks use filenames with hashes, which change every version.
|
||||
Therefore, it is recommended to reload the page once the promise returned by `activateUpdate()` is resolved.
|
||||
Calling {@link SwUpdate#activateUpdate SwUpdate#activateUpdate()} updates a tab to the latest version without reloading the page, but this could break the application.
|
||||
|
||||
Updating without reloading can create a version mismatch between the [application shell](guide/glossary#app-shell) and other page resources, such as [lazy-loaded chunks](guide/glossary#lazy-loading), whose filenames may change between versions.
|
||||
|
||||
You should only use `activateUpdate()`, if you are certain it is safe for your specific use case.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -90,6 +90,12 @@ Usually this is `/index.html`.
|
||||
They can include resources loaded from the page's origin as well as third-party resources loaded from CDNs and other external URLs.
|
||||
As not all such external URLs might be known at build time, URL patterns can be matched.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
For the service worker to handle resources that are loaded from different origins, make sure that [CORS][MozillaDeveloperDocsWebHttpCors] is correctly configured on each origin's server.
|
||||
|
||||
</div>
|
||||
|
||||
This field contains an array of asset groups, each of which defines a set of asset resources and the policy by which they are cached.
|
||||
|
||||
<code-example format="json" language="json">
|
||||
@@ -370,6 +376,7 @@ This optional section enables you to specify a custom list of URLs that will be
|
||||
The ServiceWorker redirects navigation requests that don't match any `asset` or `data` group to the specified [index file](#index-file).
|
||||
A request is considered to be a navigation request if:
|
||||
|
||||
* Its [method](https://developer.mozilla.org/docs/Web/API/Request/method) is `GET`
|
||||
* Its [mode](https://developer.mozilla.org/docs/Web/API/Request/mode) is `navigation`
|
||||
* It accepts a `text/html` response as determined by the value of the `Accept` header
|
||||
* Its URL matches the following criteria:
|
||||
@@ -440,6 +447,8 @@ It is recommended that you use the default performance strategy whenever possibl
|
||||
|
||||
[WhatwgFetchSpecConceptFilteredResponseOpaque]: https://fetch.spec.whatwg.org#concept-filtered-response-opaque
|
||||
|
||||
[MozillaDeveloperDocsWebHttpCors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-02-28
|
||||
|
||||
@@ -290,7 +290,7 @@ Such tools can be powerful when used properly, but there are a few things to kee
|
||||
This can cause behavior with Dev Tools open to differ from behavior a user might experience.
|
||||
|
||||
* If you look in the Cache Storage viewer, the cache is frequently out of date.
|
||||
Right click the Cache Storage title and refresh the caches.
|
||||
Right-click the Cache Storage title and refresh the caches.
|
||||
|
||||
* Stopping and starting the service worker in the Service Worker pane checks for updates
|
||||
|
||||
@@ -336,7 +336,7 @@ You might have already encountered the error `The script resource is behind a re
|
||||
</div>
|
||||
|
||||
This can be a problem if you have to change your application's location.
|
||||
If you setup a redirect from the old location, such as `example.com`, to the new location, `www.example.com` in this example, the worker stops working.
|
||||
If you set up a redirect from the old location, such as `example.com`, to the new location, `www.example.com` in this example, the worker stops working.
|
||||
Also, the redirect won't even trigger for users who are loading the site entirely from Service Worker.
|
||||
The old worker, which was registered at `example.com`, tries to update and sends a request to the old location `example.com`. This request is redirected to the new location `www.example.com` and creates the error: `The script resource is behind a redirect, which is disallowed`.
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ To simulate a network issue, disable network interaction for your application.
|
||||
|
||||
In Chrome:
|
||||
|
||||
1. Select **Tools** > **Developer Tools** \(from the Chrome menu located at 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.
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ The new bootstrap API gives us back the means of configuring “module injectors
|
||||
Environment injectors can be configured using one of the following:
|
||||
|
||||
* `@NgModule.providers` (in applications bootstrapping through an `NgModule`);
|
||||
* `@Injectable({provideIn: "..."})`(in both the NgModule-based as well as “standalone” applications);
|
||||
* `@Injectable({provideIn: "..."})`(in both the NgModule-based and the “standalone” applications);
|
||||
* `providers` option in the `bootstrapApplication` call (in fully “standalone” applications);
|
||||
* `providers` field in a `Route` configuration.
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ Angular version 7 apps will continue to work with libraries that have this flag.
|
||||
However, if you update your library to Angular version 8 and want to take advantage of the new version 8 APIs, or you want more recent dependencies \(such as Typescript or RxJS\) your library will become incompatible with Angular version 7 apps.
|
||||
If your goal is to make your library compatible with Angular versions 7 and 8, you should not update your lib at all —except for `peerDependencies` in `package.json`.
|
||||
|
||||
In general, the most efficient plan is for libraries to adopt a 6 month major version schedule and bump the major version after each Angular update.
|
||||
In general, the most efficient plan is for libraries to adopt a 6-month major version schedule and bump the major version after each Angular update.
|
||||
That way, libraries stay in the same release cadence as Angular.
|
||||
|
||||
<!-- links -->
|
||||
|
||||
@@ -97,7 +97,7 @@ A single component can be the default export for its file which facilitates lazy
|
||||
|
||||
</div>
|
||||
|
||||
The key is to make the code more reusable, easier to read, and less mistake prone.
|
||||
The key is to make the code more reusable, easier to read, and less mistake-prone.
|
||||
|
||||
The following *negative* example defines the `AppComponent`, bootstraps the app,
|
||||
defines the `Hero` model object, and loads heroes from the server all in the same file.
|
||||
@@ -550,7 +550,7 @@ Keeps the names of the properties defined in the directives that are bound to th
|
||||
<div class="s-why-last">
|
||||
|
||||
**Why**? <br />
|
||||
The Angular HTML parser is case sensitive and recognizes lower camel case.
|
||||
The Angular HTML parser is case-sensitive and recognizes lower camel case.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ Some noteworthy observations:
|
||||
|
||||
When you're filtering by CSS selector and only testing properties of a browser's *native element*, the `By.css` approach might be overkill.
|
||||
|
||||
It's often straightforward and more clear to filter with a standard `HTMLElement` method such as `querySelector()` or `querySelectorAll()`.
|
||||
It's often more straightforward and clear to filter with a standard `HTMLElement` method such as `querySelector()` or `querySelectorAll()`.
|
||||
|
||||
<!-- links -->
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ To correct the problem, call `compileComponents()` as explained in the following
|
||||
|
||||
Components often have service dependencies.
|
||||
|
||||
The `WelcomeComponent` displays a welcome message to the logged in user.
|
||||
The `WelcomeComponent` displays a welcome message to the logged-in user.
|
||||
It knows who the user is based on a property of the injected `UserService`:
|
||||
|
||||
<code-example header="app/welcome/welcome.component.ts" path="testing/src/app/welcome/welcome.component.ts"></code-example>
|
||||
@@ -618,7 +618,7 @@ Learn about it on the web, starting with the [official documentation](https://rx
|
||||
## Component with inputs and outputs
|
||||
|
||||
A component with inputs and outputs typically appears inside the view template of a host component.
|
||||
The host uses a property binding to set the input property and an event binding tolisten to events raised by the output property.
|
||||
The host uses a property binding to set the input property and an event binding to listen to events raised by the output property.
|
||||
|
||||
The testing goal is to verify that such bindings work as expected.
|
||||
The tests should set input values and listen for output events.
|
||||
@@ -790,7 +790,7 @@ This testing module configuration shows three important differences:
|
||||
|
||||
The `createComponent` returns a `fixture` that holds an instance of `TestHostComponent` instead of an instance of `DashboardHeroComponent`.
|
||||
|
||||
Creating the `TestHostComponent` has the side-effect of creating a `DashboardHeroComponent` because the latter appears within the template of the former.
|
||||
Creating the `TestHostComponent` has the side effect of creating a `DashboardHeroComponent` because the latter appears within the template of the former.
|
||||
The query for the hero element \(`heroEl`\) still finds it in the test DOM, albeit at greater depth in the element tree than before.
|
||||
|
||||
The tests themselves are almost identical to the stand-alone version:
|
||||
@@ -1070,7 +1070,7 @@ This is a skill you might need to test a more sophisticated component, one that
|
||||
|
||||
#### What good are these tests?
|
||||
|
||||
Stubbed `RouterLink` tests can confirm that a component with links and an outlet is setup properly, that the component has the links it should have, and that they are all pointing in the expected direction.
|
||||
Stubbed `RouterLink` tests can confirm that a component with links and an outlet is set up properly, that the component has the links it should have, and that they are all pointing in the expected direction.
|
||||
These tests do not concern whether the application will succeed in navigating to the target component when the user clicks a link.
|
||||
|
||||
Stubbing the RouterLink and RouterOutlet is the best option for such limited testing goals.
|
||||
@@ -1167,7 +1167,7 @@ So when you call `createComponent()`, the `TestBed` compiles implicitly.
|
||||
That's not a problem when the source code is in memory.
|
||||
But the `BannerComponent` requires external files that the compiler must read from the file system, an inherently *asynchronous* operation.
|
||||
|
||||
If the `TestBed` were allowed to continue, the tests would run and fail mysteriously before the compiler could finished.
|
||||
If the `TestBed` were allowed to continue, the tests would run and fail mysteriously before the compiler could finish.
|
||||
|
||||
The preemptive error message tells you to compile explicitly with `compileComponents()`.
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ This article explains how to configure your project to run Circle CI and Travis
|
||||
|
||||
<code-example format="yaml" language="yaml">
|
||||
|
||||
name: CI Angular app through Github Actions
|
||||
name: CI Angular app through GitHub Actions
|
||||
on: push
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -281,7 +281,7 @@ Use keyframes to create a pulse effect in your animations by defining styles at
|
||||
Here's an example of using keyframes to create a pulse effect:
|
||||
|
||||
* The original `open` and `closed` states, with the original changes in height, color, and opacity, occurring over a timeframe of 1 second
|
||||
* A keyframes sequence inserted in the middle that causes the button to appear to pulsate irregularly over the course of that same 1 second timeframe
|
||||
* A keyframes sequence inserted in the middle that causes the button to appear to pulsate irregularly over the course of that same 1-second timeframe
|
||||
|
||||
<div class="lightbox">
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ addresses.addControl('Andrew', new FormControl('2340 Folsom St'));
|
||||
|
||||
Any control of type `string|null` can be added to this `FormRecord`.
|
||||
|
||||
If you need a `FormGroup` that is both dynamic (open-ended) and heterogenous (the controls are different types), no improved type safety is possible, and you should use `UntypedFormGroup`.
|
||||
If you need a `FormGroup` that is both dynamic (open-ended) and heterogeneous (the controls are different types), no improved type safety is possible, and you should use `UntypedFormGroup`.
|
||||
|
||||
A `FormRecord` can also be built with the `FormBuilder`:
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ For instance, to install typings for `chai` you run `npm install @types/chai --s
|
||||
|
||||
### `target`
|
||||
|
||||
By default, the target is `es2017`, which is supported in modern browsers.
|
||||
By default, the target is `es2020`, which is supported in modern browsers.
|
||||
|
||||
<!-- links -->
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Updating search keywords
|
||||
|
||||
In documentation, being able to find the content you need is equally as important as the content itself.
|
||||
In documentation, being able to find the content you need is as important as the content itself.
|
||||
In [angular.io](https://angular.io), users can discover content in several ways, including:
|
||||
|
||||
* Organic search results, such as through [google.com](https://google.com)
|
||||
|
||||
@@ -128,7 +128,7 @@ You define that recipe by providing a factory function that can create an instan
|
||||
* `NgModuleFactory`
|
||||
* `(extraProviders: StaticProvider[]) => Promise<NgModuleRef>`
|
||||
|
||||
When you pass an `NgModuleFactory`, `downgradeModule()` uses it to instantiate the module using [platformBrowser](api/platform-browser/platformBrowser]'s [bootstrapModuleFactory()](api/core/PlatformRef#bootstrapModuleFactory), which is compatible with ahead-of-time \(AOT\) compilation.
|
||||
When you pass an `NgModuleFactory`, `downgradeModule()` uses it to instantiate the module using [platformBrowser](api/platform-browser/platformBrowser)'s [bootstrapModuleFactory()](api/core/PlatformRef#bootstrapModuleFactory), which is compatible with ahead-of-time \(AOT\) compilation.
|
||||
AOT compilation helps make your applications load faster
|
||||
For more about AOT and how to create an `NgModuleFactory`, see the [Ahead-of-Time Compilation](guide/aot-compiler) guide.
|
||||
|
||||
@@ -177,7 +177,7 @@ As you might have guessed, you don't need to change anything in the way you boot
|
||||
Unlike `UpgradeModule`—which requires some extra steps— `downgradeModule()` is able to take care of bootstrapping the Angular module, as long as you provide the recipe.
|
||||
|
||||
In order to start using any `upgrade/static` APIs, you still need to load the Angular framework as you would in a normal Angular application.
|
||||
You can see how this can be done with SystemJS by following the instructions in the [Upgrade Setup](guide/upgrade-setup "Setup for Upgrading from AngularJS") guide, selectively copying code from the [QuickStart github repository](https://github.com/angular/quickstart).
|
||||
You can see how this can be done with SystemJS by following the instructions in the [Upgrade Setup](guide/upgrade-setup "Setup for Upgrading from AngularJS") guide, selectively copying code from the [QuickStart GitHub repository](https://github.com/angular/quickstart).
|
||||
|
||||
You also need to install the `@angular/upgrade` package using `npm install @angular/upgrade --save` and add a mapping for the `@angular/upgrade/static` package:
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ In particular, the QuickStart live-coding example shows just the AppComponent fi
|
||||
-->
|
||||
|
||||
This guide describes how to develop locally on your own machine.
|
||||
Setting up a new project on your machine is quick and easy with the [QuickStart seed on github](https://github.com/angular/quickstart "Install the github QuickStart repo").
|
||||
Setting up a new project on your machine is quick and easy with the [QuickStart seed on GitHub](https://github.com/angular/quickstart "Install the github QuickStart repo").
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ The `upgrade` module in Angular has been designed to make incremental upgrading
|
||||
## Preparation
|
||||
|
||||
There are many ways to structure AngularJS applications.
|
||||
When you begin to upgrade these applications to Angular, some will turn out to be much more easy to work with than others.
|
||||
There are a few key techniques and patterns that you can apply to future proof applications even before you begin the migration.
|
||||
When you begin to upgrade these applications to Angular, some will turn out to be much easier to work with than others.
|
||||
There are a few key techniques and patterns that you can apply to future-proof applications even before you begin the migration.
|
||||
|
||||
### Follow the AngularJS Style Guide
|
||||
|
||||
@@ -309,7 +309,7 @@ You can remove the `ng-app` and `ng-strict-di` directives from the HTML and inst
|
||||
<code-example header="app.module.ts" path="upgrade-module/src/app/ajs-bootstrap/app.module.ts" region="bootstrap"></code-example>
|
||||
|
||||
To begin converting your AngularJS application to a hybrid, you need to load the Angular framework.
|
||||
You can see how this can be done with SystemJS by following the instructions in [Setup for Upgrading to AngularJS][AioGuideUpgradeSetup] for selectively copying code from the [QuickStart github repository][GithubAngularQuickstart].
|
||||
You can see how this can be done with SystemJS by following the instructions in [Setup for Upgrading to AngularJS][AioGuideUpgradeSetup] for selectively copying code from the [QuickStart GitHub repository][GithubAngularQuickstart].
|
||||
|
||||
You also need to install the `@angular/upgrade` package using `npm install @angular/upgrade --save` and add a mapping for the `@angular/upgrade/static` package:
|
||||
|
||||
@@ -556,7 +556,7 @@ For example, you might have a service called `HeroesService` in AngularJS:
|
||||
|
||||
<code-example header="heroes.service.ts" path="upgrade-module/src/app/ajs-to-a-providers/heroes.service.ts"></code-example>
|
||||
|
||||
You can upgrade the service using a Angular [factory provider][AioGuideDependencyInjectionProvidersFactoryProviders] that requests the service from the AngularJS `$injector`.
|
||||
You can upgrade the service using an Angular [factory provider][AioGuideDependencyInjectionProvidersFactoryProviders] that requests the service from the AngularJS `$injector`.
|
||||
|
||||
Many developers prefer to declare the factory provider in a separate `ajs-upgraded-providers.ts` file so that they are all together, making it easier to reference them, create new ones and delete them once the upgrade is over.
|
||||
|
||||
@@ -634,7 +634,7 @@ This strategy reduces your initial bundle size, defers any potential impact from
|
||||
|
||||
The steps below show you how to do the following:
|
||||
|
||||
* Setup a callback function for your AngularJS bundle.
|
||||
* Set up a callback function for your AngularJS bundle.
|
||||
* Create a service that lazy loads and bootstraps your AngularJS app.
|
||||
* Create a routable component for AngularJS content
|
||||
* Create a custom `matcher` function for AngularJS-specific URLs and configure the Angular `Router` with the custom matcher for AngularJS routes.
|
||||
|
||||
@@ -131,7 +131,7 @@ The following example uses a template reference variable to implement a keystrok
|
||||
The template reference variable named `box`, declared on the `<input>` element, refers to the `<input>` element itself.
|
||||
The code uses the `box` variable to get the input element's `value` and display it with interpolation between `<p>` tags.
|
||||
|
||||
The template is completely self contained.
|
||||
The template is completely self-contained.
|
||||
It doesn't bind to the component, and the component does nothing.
|
||||
|
||||
Type something in the input box, and watch the display update with each keystroke.
|
||||
|
||||
@@ -275,7 +275,7 @@ By default, the `src/assets/` folder and `src/favicon.ico` are copied over.
|
||||
To exclude an asset, you can remove it from the assets configuration.
|
||||
|
||||
You can further configure assets to be copied by specifying assets as objects, rather than as simple paths relative to the workspace root.
|
||||
A asset specification object can have the following fields.
|
||||
An asset specification object can have the following fields.
|
||||
|
||||
| Fields | Details |
|
||||
|:--- |:--- |
|
||||
@@ -344,7 +344,7 @@ An array entry for the `styles` and `scripts` options can be a simple path strin
|
||||
The associated builder will load that file and its dependencies as a separate bundle during the build.
|
||||
With a configuration object, you have the option of naming the bundle for the entry point, using a `bundleName` field.
|
||||
|
||||
The bundle is injected by default, but you can set `inject` to false to exclude the bundle from injection.
|
||||
The bundle is injected by default, but you can set `inject` to `false` to exclude the bundle from injection.
|
||||
For example, the following object values create and name a bundle that contains styles and scripts, and excludes it from injection:
|
||||
|
||||
<code-example language="json">
|
||||
|
||||
@@ -341,7 +341,7 @@ Therefore in those asynchronous APIs, you don't need to trigger change detection
|
||||
|
||||
There are still some third party APIs that Zone does not handle.
|
||||
In those cases, the `NgZone` service provides a [`run()`](api/core/NgZone#run) method that allows you to execute a function inside the Angular zone.
|
||||
This function, and all asynchronous operations in that function, trigger change detection automatically at the correct time.
|
||||
This function, and all asynchronous operations in that function, triggers change detection automatically at the correct time.
|
||||
|
||||
<code-example format="typescript" language="typescript">
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user