Compare commits
366 Commits
creating-l
...
9.0.0-rc.5
Author | SHA1 | Date | |
---|---|---|---|
848018f5d3 | |||
95557318bc | |||
f1737ff578 | |||
4d025562c4 | |||
25462614db | |||
c92c9f7e21 | |||
668692598b | |||
41ea3c214a | |||
eae541b6e2 | |||
b712065726 | |||
00f7372554 | |||
5a98410a7d | |||
65cd811de8 | |||
0044c6621e | |||
91f4b81f79 | |||
383be62afa | |||
6123261ad6 | |||
d2538cab5a | |||
dd6da21068 | |||
d516d5253b | |||
c89017a286 | |||
65755edfa0 | |||
4836fe08b5 | |||
1bab8c2757 | |||
f4d714ca0b | |||
5cf5843be3 | |||
64317c680d | |||
93ac362848 | |||
62d384dbbd | |||
33d3340bac | |||
7414ece2fa | |||
54bfd8a0c1 | |||
cba37734b4 | |||
f11c6b1d42 | |||
60c350cd95 | |||
3516213632 | |||
396779f6e6 | |||
fb22f18694 | |||
db4789bf91 | |||
354f66b904 | |||
716fc845f5 | |||
ce79cacd03 | |||
7504543962 | |||
b640d38fd1 | |||
c3c363fef9 | |||
d5a48b2cc0 | |||
69d27f3a08 | |||
daa403fb61 | |||
572e731b63 | |||
0d102bb918 | |||
bbfca62b66 | |||
08c0e6a002 | |||
9995d87f96 | |||
3224d7e79c | |||
a5fe8501c4 | |||
7a7e999fb5 | |||
29de8d3ab1 | |||
bfeb4d2324 | |||
75f4757173 | |||
12e4aa0bb6 | |||
127baa0d38 | |||
075f01341d | |||
2f8bbec6af | |||
4e766b8e0c | |||
846ff256c3 | |||
325e2665ff | |||
bf16b0e4be | |||
ca88f7d2ef | |||
7385e9d06d | |||
ef8b95abae | |||
fc2db27446 | |||
b05ce85391 | |||
7faa9bbc09 | |||
7402430d06 | |||
5a8d25dfc6 | |||
955a3129f0 | |||
e059df3bad | |||
a7b298a4fd | |||
00f8d6ac64 | |||
1b4fac192a | |||
7e6350ce2e | |||
9e5065a778 | |||
1eddb1ae15 | |||
9255dc3468 | |||
c5584b2dbc | |||
60db3505f6 | |||
6904319847 | |||
dda9b9ea7e | |||
e8ec296fdd | |||
4745aef9e8 | |||
a122311773 | |||
6bf258178d | |||
fec9f7dce5 | |||
d2784c7894 | |||
5cc362fbbf | |||
dee0c33a1d | |||
1d14f85dd6 | |||
5e530e917b | |||
781003fd2f | |||
cbc28f255d | |||
8a565c8814 | |||
d228801af4 | |||
978b500961 | |||
b659aa32c9 | |||
1d513e8978 | |||
d22f3d6f85 | |||
bbc8b0f142 | |||
ebe3229da5 | |||
caf5cffd53 | |||
cf420194ed | |||
420750bd05 | |||
7d8b112a91 | |||
abb8c90df9 | |||
efd626c4bc | |||
8c2ff79d04 | |||
457ac3ac46 | |||
688b188484 | |||
f63fca1e3a | |||
60570d0cb2 | |||
00f1ffbbb4 | |||
9d41b5bdd4 | |||
83989b879b | |||
290739f301 | |||
8ed7b73dc1 | |||
7b77ead88f | |||
27f775a65d | |||
f2bb9cc95e | |||
9248dba8fa | |||
1ffbde14ab | |||
4946be0b35 | |||
274ed2ca74 | |||
21ec7d92dd | |||
85a4a1ac60 | |||
e24ed8d0e2 | |||
229bfd507f | |||
af77e5289d | |||
b4c839ccb9 | |||
99e68d0318 | |||
971228b4f4 | |||
bda3c2245d | |||
63c9123924 | |||
aa4d2b785b | |||
719ca1d23c | |||
18574cfed1 | |||
ad9b9a3534 | |||
a54096ab5b | |||
e456e5833a | |||
4a42be27ee | |||
9719047df8 | |||
f1bf5b26d1 | |||
a528006d7a | |||
c1c04dc8ad | |||
90a9043abb | |||
a172644c6c | |||
d3825c20d5 | |||
c01fa1823f | |||
9a5334c75e | |||
250e6fdd39 | |||
196808eebb | |||
c6695faf47 | |||
3814674f9a | |||
e17f051601 | |||
ca5d7723ff | |||
1394781cef | |||
197f042fb1 | |||
fc6ad19089 | |||
90cd9682d2 | |||
80ecf12b4b | |||
b12fde4ceb | |||
94257ac8d3 | |||
fbd2133610 | |||
a09d60cb50 | |||
61cc7a3437 | |||
4e0eb3627d | |||
05a18cc4cb | |||
6da5230003 | |||
b8ba6b036c | |||
b31afc2aa9 | |||
3b5e1668ed | |||
7c7d432085 | |||
213e3c3e49 | |||
5267c92a93 | |||
595375f7a3 | |||
d92da1335d | |||
30ddadc4d7 | |||
dc8e300029 | |||
a7e2327212 | |||
a7d6829cde | |||
bc97c25efe | |||
49571bf11a | |||
14156bd262 | |||
e42fa81aa9 | |||
c7a3694eb9 | |||
839ac3c0a7 | |||
105616cd2b | |||
edd624b254 | |||
56801c74b9 | |||
01af94ccd7 | |||
456ea5cce4 | |||
1e78fafd37 | |||
83140f7926 | |||
b08bb411b9 | |||
1b4d264ccf | |||
05d5c4fc76 | |||
c126a6e3fc | |||
97ff04a7bd | |||
b744505620 | |||
b707c48817 | |||
2d7b015ed7 | |||
b53a1ac999 | |||
bc28ca7b0c | |||
b7c1a5e45f | |||
f136ddad0d | |||
5be23a309e | |||
6d06d9d3c6 | |||
b7c012f91b | |||
1b7aa05699 | |||
1218ce4f5f | |||
7ffbe54ef0 | |||
2f8c9e1990 | |||
bde55ecc91 | |||
aeaf530de6 | |||
66ecab6e8c | |||
f3d8f6adca | |||
a05e42ad09 | |||
0854dc8688 | |||
5926b2897f | |||
0405ddb521 | |||
1a9904d2f1 | |||
37243ce680 | |||
59a4b76b57 | |||
80cd7d7a40 | |||
e47638ec7c | |||
7567f2b8c8 | |||
ebf3afb7f0 | |||
d562625960 | |||
e57a8350e1 | |||
dafdf9a87b | |||
0e20453273 | |||
5bfcd8231a | |||
e641eaaae0 | |||
3074cdfea9 | |||
c182dea146 | |||
502fa906cd | |||
430293abe2 | |||
cba6b7dd20 | |||
09480d3a9d | |||
ca633535c5 | |||
9761ebe7bd | |||
9882a8215a | |||
0688a28be3 | |||
af2cca0c7a | |||
4a4888b276 | |||
d45bbccb58 | |||
d49c830064 | |||
12d67e0d31 | |||
d39b643553 | |||
84524583e9 | |||
a61fb76d51 | |||
b1d0a4f84d | |||
63c3569e2a | |||
aaa38cf3f3 | |||
a9d834fe69 | |||
987d2bd181 | |||
a16a57e52a | |||
1860a9edbc | |||
5fd0d15d86 | |||
8e5ed203bc | |||
06e36e5972 | |||
21bd8c9a2e | |||
1c1240c21a | |||
4c706086a7 | |||
93ba4c2418 | |||
3f6d9a9870 | |||
ba4f171fac | |||
744a3854f3 | |||
ac9fa2f2eb | |||
de8cf75ff5 | |||
5ad1e5f5ec | |||
b4d7a684f8 | |||
49e517d049 | |||
e1df98be17 | |||
1b489083bc | |||
9f10aa0d8c | |||
ecf38d48cf | |||
5f9a2d1cf8 | |||
8ed32e5e71 | |||
d67a38b7f5 | |||
f750f187d5 | |||
4e027fe3e4 | |||
1b0255c3b0 | |||
29852960c3 | |||
508bbfd92f | |||
e4cb91d373 | |||
71238a95d9 | |||
c22f15812c | |||
da01dbc459 | |||
37ae45e2ec | |||
4ec079f852 | |||
b75a21294f | |||
faaa96c737 | |||
c315881d04 | |||
bb9b8030d0 | |||
20e27a86d4 | |||
7c4366dce8 | |||
f8e9c1e6f1 | |||
4988094e7d | |||
9ab49def61 | |||
66157436f8 | |||
72796b98b1 | |||
ea83125df3 | |||
83626962cf | |||
5b292bf125 | |||
3160193719 | |||
9045e3e495 | |||
c5400616f8 | |||
f67802ddc0 | |||
ffb010d3ab | |||
f45d5dc331 | |||
9396b19631 | |||
343483cae0 | |||
682eaef690 | |||
011ecdf939 | |||
cdceb60bd0 | |||
4613639a02 | |||
f32ce01d93 | |||
3d13a6d318 | |||
46b5e4ae69 | |||
e6f383fe20 | |||
86d656bc67 | |||
c5737f4a19 | |||
0b998844c8 | |||
fc24a69a6b | |||
b789c891bb | |||
eb9ed8cc13 | |||
139b2e4f40 | |||
290ae43db3 | |||
c7f913d1ec | |||
ba68b560bc | |||
69fdcbd71c | |||
a6ddda8834 | |||
2910d1a65f | |||
811275cd15 | |||
c8c51a9879 | |||
33f6cd4799 | |||
c1bd3bc76a | |||
0248d6b8a7 | |||
4f69ff7e85 | |||
9df1178fe7 | |||
76e52c5297 | |||
83b635cb3f | |||
09cf0cd878 | |||
cb55f60c74 | |||
cd8333cf0d | |||
854a377232 | |||
8164d28b6c | |||
59b25da76b | |||
68380e4af2 | |||
4029c98f16 | |||
99ead47bff | |||
d09ad82293 | |||
4924d73b8e | |||
7bccef516f | |||
204620291e | |||
3419b5002f | |||
687582fd99 |
@ -6,4 +6,5 @@ aio/node_modules
|
|||||||
aio/tools/examples/shared/node_modules
|
aio/tools/examples/shared/node_modules
|
||||||
integration/bazel
|
integration/bazel
|
||||||
integration/bazel-schematics/demo
|
integration/bazel-schematics/demo
|
||||||
|
integration/platform-server/node_modules
|
||||||
packages/bazel/node_modules
|
packages/bazel/node_modules
|
||||||
|
33
.bazelrc
33
.bazelrc
@ -64,31 +64,12 @@ test --test_output=errors
|
|||||||
################################
|
################################
|
||||||
# Temporary Settings for Ivy #
|
# Temporary Settings for Ivy #
|
||||||
################################
|
################################
|
||||||
# to determine if the compiler used should be Ivy or ViewEngine one can use `--define=compile=aot` on
|
# To determine if the compiler used should be Ivy instead of ViewEngine, one can use `--config=ivy`
|
||||||
# any bazel target. This is a temporary flag until codebase is permanently switched to Ivy.
|
# on any bazel target. This is a temporary flag until codebase is permanently switched to Ivy.
|
||||||
build --define=compile=legacy
|
build --define=angular_ivy_enabled=False
|
||||||
|
|
||||||
################################
|
build:view-engine --define=angular_ivy_enabled=False
|
||||||
# Settings for rules_nodejs #
|
build:ivy --define=angular_ivy_enabled=True
|
||||||
################################
|
|
||||||
# Temporary define while angular depends on the legacy rollup_bundle rule.
|
|
||||||
# TODO: remove this setting after https://github.com/angular/angular/pull/33201 lands.
|
|
||||||
build --define=enable_legacy_rollup_rule=1
|
|
||||||
|
|
||||||
#######################
|
|
||||||
# Remote HTTP Caching #
|
|
||||||
#######################
|
|
||||||
build --remote_http_cache=https://storage.googleapis.com/angular-team-cache
|
|
||||||
build --remote_accept_cached=true
|
|
||||||
build --remote_upload_local_results=false
|
|
||||||
|
|
||||||
######################################
|
|
||||||
# Remote HTTP Caching writes support #
|
|
||||||
# Turn on these settings with #
|
|
||||||
# --config=-http-caching #
|
|
||||||
######################################
|
|
||||||
build:remote-http-caching --remote_upload_local_results=true
|
|
||||||
build:remote-http-caching --google_default_credentials
|
|
||||||
|
|
||||||
##################################
|
##################################
|
||||||
# Remote Build Execution support #
|
# Remote Build Execution support #
|
||||||
@ -108,6 +89,10 @@ build:remote --remote_timeout=600
|
|||||||
build:remote --jobs=150
|
build:remote --jobs=150
|
||||||
build:remote --google_default_credentials
|
build:remote --google_default_credentials
|
||||||
|
|
||||||
|
# Force remote exeuctions to consider the entire run as linux
|
||||||
|
build:remote --cpu=k8
|
||||||
|
build:remote --host_cpu=k8
|
||||||
|
|
||||||
# Toolchain and platform related flags
|
# Toolchain and platform related flags
|
||||||
build:remote --host_javabase=@rbe_ubuntu1604_angular//java:jdk
|
build:remote --host_javabase=@rbe_ubuntu1604_angular//java:jdk
|
||||||
build:remote --javabase=@rbe_ubuntu1604_angular//java:jdk
|
build:remote --javabase=@rbe_ubuntu1604_angular//java:jdk
|
||||||
|
@ -11,4 +11,7 @@ import %workspace%/.circleci/bazel.common.rc
|
|||||||
build --repository_cache=C:/Users/circleci/bazel_repository_cache
|
build --repository_cache=C:/Users/circleci/bazel_repository_cache
|
||||||
|
|
||||||
# All windows jobs run on master and should use http caching
|
# All windows jobs run on master and should use http caching
|
||||||
build --config=remote-http-caching
|
build --remote_http_cache=https://storage.googleapis.com/angular-team-cache
|
||||||
|
build --remote_accept_cached=true
|
||||||
|
build --remote_upload_local_results=true
|
||||||
|
build --google_default_credentials
|
||||||
|
@ -29,7 +29,7 @@ var_4_win: &cache_key_win_fallback v5-angular-win-node-12.0-
|
|||||||
|
|
||||||
# Cache key for the Material unit tests job. **Note** when updating the SHA in the cache keys,
|
# Cache key for the Material unit tests job. **Note** when updating the SHA in the cache keys,
|
||||||
# also update the SHA for the "MATERIAL_REPO_COMMIT" environment variable.
|
# also update the SHA for the "MATERIAL_REPO_COMMIT" environment variable.
|
||||||
var_5: &material_unit_tests_cache_key v5-angular-material-bc1c454391370e75cf604f94bc2e9131e9aef94e
|
var_5: &material_unit_tests_cache_key v5-angular-material-a5cad10cf9ca5db84c307d38d5594c3f1d89ae2b
|
||||||
var_6: &material_unit_tests_cache_key_fallback v5-angular-material-
|
var_6: &material_unit_tests_cache_key_fallback v5-angular-material-
|
||||||
|
|
||||||
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
|
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
|
||||||
@ -365,7 +365,7 @@ jobs:
|
|||||||
# Compile dependencies to ivy
|
# Compile dependencies to ivy
|
||||||
# Running `ngcc` here (instead of implicitly via `ng build`) allows us to take advantage of
|
# Running `ngcc` here (instead of implicitly via `ng build`) allows us to take advantage of
|
||||||
# the parallel, async mode speed-up (~20-25s on CI).
|
# the parallel, async mode speed-up (~20-25s on CI).
|
||||||
- run: yarn --cwd aio ivy-ngcc --properties es2015
|
- run: yarn --cwd aio ngcc --properties es2015
|
||||||
# Build aio
|
# Build aio
|
||||||
- run: yarn --cwd aio build --progress=false
|
- run: yarn --cwd aio build --progress=false
|
||||||
# Lint the code
|
# Lint the code
|
||||||
@ -502,13 +502,14 @@ jobs:
|
|||||||
- setup_circleci_bazel_config
|
- setup_circleci_bazel_config
|
||||||
- setup_bazel_rbe
|
- setup_bazel_rbe
|
||||||
|
|
||||||
- run: scripts/build-packages-dist.sh
|
- run: node scripts/build-packages-dist.js
|
||||||
|
|
||||||
# Save the npm packages from //packages/... for other workflow jobs to read
|
# Save the npm packages from //packages/... for other workflow jobs to read
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: *workspace_location
|
root: *workspace_location
|
||||||
paths:
|
paths:
|
||||||
- ng/dist/packages-dist
|
- ng/dist/packages-dist
|
||||||
|
- ng/dist/zone.js-dist
|
||||||
|
|
||||||
# Save dependencies and bazel repository cache to use on subsequent runs.
|
# Save dependencies and bazel repository cache to use on subsequent runs.
|
||||||
- save_cache:
|
- save_cache:
|
||||||
@ -529,7 +530,7 @@ jobs:
|
|||||||
- setup_circleci_bazel_config
|
- setup_circleci_bazel_config
|
||||||
- setup_bazel_rbe
|
- setup_bazel_rbe
|
||||||
|
|
||||||
- run: scripts/build-ivy-npm-packages.sh
|
- run: node scripts/build-ivy-npm-packages.js
|
||||||
|
|
||||||
# Save the npm packages from //packages/... for other workflow jobs to read
|
# Save the npm packages from //packages/... for other workflow jobs to read
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
@ -569,15 +570,25 @@ jobs:
|
|||||||
environment:
|
environment:
|
||||||
NG_PACKAGES_DIR: &ng_packages_dir 'dist/packages-dist'
|
NG_PACKAGES_DIR: &ng_packages_dir 'dist/packages-dist'
|
||||||
NG_PACKAGES_ARCHIVES_DIR: &ng_packages_archives_dir 'dist/packages-dist-archives'
|
NG_PACKAGES_ARCHIVES_DIR: &ng_packages_archives_dir 'dist/packages-dist-archives'
|
||||||
|
ZONEJS_PACKAGES_DIR: &zonejs_packages_dir 'dist/zone.js-dist'
|
||||||
|
ZONEJS_PACKAGES_ARCHIVES_DIR: &zonejs_packages_archives_dir 'dist/zone.js-dist-archives'
|
||||||
steps:
|
steps:
|
||||||
- custom_attach_workspace
|
- custom_attach_workspace
|
||||||
- init_environment
|
- init_environment
|
||||||
|
# Publish `@angular/*` packages.
|
||||||
- run:
|
- run:
|
||||||
name: Create artifacts
|
name: Create artifacts for @angular/* packages
|
||||||
command: ./scripts/ci/create-package-archives.sh $CI_PULL_REQUEST $CI_COMMIT $NG_PACKAGES_DIR $NG_PACKAGES_ARCHIVES_DIR
|
command: ./scripts/ci/create-package-archives.sh $CI_BRANCH $CI_COMMIT $NG_PACKAGES_DIR $NG_PACKAGES_ARCHIVES_DIR
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: *ng_packages_archives_dir
|
path: *ng_packages_archives_dir
|
||||||
destination: angular
|
destination: angular
|
||||||
|
# Publish `zone.js` package.
|
||||||
|
- run:
|
||||||
|
name: Create artifacts for zone.js package
|
||||||
|
command: ./scripts/ci/create-package-archives.sh $CI_BRANCH $CI_COMMIT $ZONEJS_PACKAGES_DIR $ZONEJS_PACKAGES_ARCHIVES_DIR
|
||||||
|
- store_artifacts:
|
||||||
|
path: *zonejs_packages_archives_dir
|
||||||
|
destination: zone.js
|
||||||
|
|
||||||
# This job updates the content of repos like github.com/angular/core-builds
|
# This job updates the content of repos like github.com/angular/core-builds
|
||||||
# for every green build on angular/angular.
|
# for every green build on angular/angular.
|
||||||
|
@ -84,7 +84,7 @@ setPublicVar MATERIAL_REPO_TMP_DIR "/tmp/material2"
|
|||||||
setPublicVar MATERIAL_REPO_URL "https://github.com/angular/material2.git"
|
setPublicVar MATERIAL_REPO_URL "https://github.com/angular/material2.git"
|
||||||
setPublicVar MATERIAL_REPO_BRANCH "master"
|
setPublicVar MATERIAL_REPO_BRANCH "master"
|
||||||
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI "config.yml".
|
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI "config.yml".
|
||||||
setPublicVar MATERIAL_REPO_COMMIT "bc1c454391370e75cf604f94bc2e9131e9aef94e"
|
setPublicVar MATERIAL_REPO_COMMIT "a5cad10cf9ca5db84c307d38d5594c3f1d89ae2b"
|
||||||
|
|
||||||
# Source `$BASH_ENV` to make the variables available immediately.
|
# Source `$BASH_ENV` to make the variables available immediately.
|
||||||
source $BASH_ENV;
|
source $BASH_ENV;
|
||||||
|
31
.devcontainer/README.md
Normal file
31
.devcontainer/README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# VSCode Remote Development - Developing inside a Containers
|
||||||
|
|
||||||
|
This folder contains configuration files that can be used to opt into working on this repository in a [Docker container](https://www.docker.com/resources/what-container) via [VSCode](https://code.visualstudio.com/)'s Remote Development feature (see below).
|
||||||
|
|
||||||
|
Info on remote development and developing inside a container with VSCode:
|
||||||
|
- [VSCode: Remote Development](https://code.visualstudio.com/docs/remote/remote-overview)
|
||||||
|
- [VSCode: Developing inside a Container](https://code.visualstudio.com/docs/remote/containers)
|
||||||
|
- [VSCode: Remote Development FAQ](https://code.visualstudio.com/docs/remote/faq)
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
_Prerequisite: [Install Docker](https://docs.docker.com/install) on your local environment._
|
||||||
|
|
||||||
|
To get started, read and follow the instuctions in [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers). The [.devcontainer/](.) directory contains pre-configured `devcontainer.json` and `Dockerfile` files, which you can use to set up remote development with a docker container.
|
||||||
|
|
||||||
|
In a nutshell, you need to:
|
||||||
|
- Install the [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension.
|
||||||
|
- Copy [recommended-Dockerfile](./recommended-Dockerfile) to `Dockerfile` (and optionally tweak to suit your needs).
|
||||||
|
- Copy [recommended-devcontainer.json](./recommended-devcontainer.json) to `devcontainer.json` (and optionally tweak to suit your needs).
|
||||||
|
- Open VSCode and bring up the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette).
|
||||||
|
- Type `Remote-Containers: Open Folder in Container` and choose your local clone of [angular/angular](https://github.com/angular/angular).
|
||||||
|
|
||||||
|
The `.devcontainer/devcontainer.json` and `.devcontainer/Dockerfile` files are ignored by git, so you can have your own local versions. We may occasionally update the template files ([recommended-devcontainer.json](./recommended-devcontainer.json), [recommended-Dockerfile](./recommended-Dockerfile)), in which case you will need to manually update your local copies (if desired).
|
||||||
|
|
||||||
|
|
||||||
|
## Updating `recommended-devcontainer.json` and `recommended-Dockerfile`
|
||||||
|
|
||||||
|
You can update and commit the recommended config files (which people use as basis for their local configs), if you find that something is broken, out-of-date or can be improved.
|
||||||
|
|
||||||
|
Please, keep in mind that any changes you make will potentially be used by many people on different environments. Try to keep these config files cross-platform compatible and free of personal preferences.
|
@ -1,5 +1,5 @@
|
|||||||
# Image metadata and config.
|
# Image metadata and config.
|
||||||
FROM circleci/node:10-browsers
|
FROM circleci/node:10-browsers # This needs to be in sync with what we use on CI.
|
||||||
|
|
||||||
LABEL name="Angular dev environment" \
|
LABEL name="Angular dev environment" \
|
||||||
description="This image can be used to create a dev environment for building Angular." \
|
description="This image can be used to create a dev environment for building Angular." \
|
||||||
@ -15,7 +15,7 @@ USER root
|
|||||||
|
|
||||||
# Configure `Node.js`/`npm` and install utilities.
|
# Configure `Node.js`/`npm` and install utilities.
|
||||||
RUN npm config --global set user root
|
RUN npm config --global set user root
|
||||||
RUN npm install --global yarn@1.13.0 # This needs to be in sync with what we use on CI.
|
RUN npm install --global yarn@1.19.1 # This needs to be in sync with what we use on CI.
|
||||||
|
|
||||||
|
|
||||||
# Go! (And keep going.)
|
# Go! (And keep going.)
|
||||||
|
21
.github/CODEOWNERS
vendored
21
.github/CODEOWNERS
vendored
@ -50,6 +50,7 @@
|
|||||||
# gkalpak - George Kalpakas
|
# gkalpak - George Kalpakas
|
||||||
# IgorMinar - Igor Minar
|
# IgorMinar - Igor Minar
|
||||||
# JiaLiPassion - Jia Li
|
# JiaLiPassion - Jia Li
|
||||||
|
# JoostK - Joost Koehoorn
|
||||||
# josephperrott - Joey Perrott
|
# josephperrott - Joey Perrott
|
||||||
# kapunahelewong - Kapunahele Wong
|
# kapunahelewong - Kapunahele Wong
|
||||||
# kara - Kara Erickson
|
# kara - Kara Erickson
|
||||||
@ -131,6 +132,9 @@
|
|||||||
# ===========================================================
|
# ===========================================================
|
||||||
#
|
#
|
||||||
# - alxhub
|
# - alxhub
|
||||||
|
# - AndrewKushnir
|
||||||
|
# - kara
|
||||||
|
# - JoostK
|
||||||
|
|
||||||
|
|
||||||
# ===========================================================
|
# ===========================================================
|
||||||
@ -344,6 +348,14 @@
|
|||||||
# - josephperrott
|
# - josephperrott
|
||||||
|
|
||||||
|
|
||||||
|
# ===========================================================
|
||||||
|
# @angular/fw-size-tracking
|
||||||
|
# ===========================================================
|
||||||
|
#
|
||||||
|
# - IgorMinar
|
||||||
|
# - kara
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
######################################################################################################
|
######################################################################################################
|
||||||
@ -887,7 +899,6 @@ testing/** @angular/fw-test
|
|||||||
/aio/content/guide/migration-injectable.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/migration-injectable.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/migration-localize.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/migration-localize.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/migration-module-with-providers.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/migration-module-with-providers.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/migration-ngcc.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
|
||||||
/aio/content/guide/updating-to-version-9.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/updating-to-version-9.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/ivy-compatibility.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/ivy-compatibility.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/ivy-compatibility-examples.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/ivy-compatibility-examples.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
@ -946,6 +957,14 @@ testing/** @angular/fw-test
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ================================================
|
||||||
|
# Size tracking
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
/aio/scripts/_payload-limits.json @angular/fw-size-tracking
|
||||||
|
/integration/_payload-limits.json @angular/fw-size-tracking
|
||||||
|
|
||||||
|
|
||||||
# ================================================
|
# ================================================
|
||||||
# Special cases
|
# Special cases
|
||||||
# ================================================
|
# ================================================
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -13,11 +13,13 @@ pubspec.lock
|
|||||||
.c9
|
.c9
|
||||||
.idea/
|
.idea/
|
||||||
.devcontainer/*
|
.devcontainer/*
|
||||||
|
!.devcontainer/README.md
|
||||||
!.devcontainer/recommended-devcontainer.json
|
!.devcontainer/recommended-devcontainer.json
|
||||||
!.devcontainer/recommended-Dockerfile
|
!.devcontainer/recommended-Dockerfile
|
||||||
.settings/
|
.settings/
|
||||||
.vscode/launch.json
|
.vscode/launch.json
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
|
.vscode/tasks.json
|
||||||
*.swo
|
*.swo
|
||||||
modules/.settings
|
modules/.settings
|
||||||
modules/.vscode
|
modules/.vscode
|
||||||
|
18
.vscode/README.md
vendored
18
.vscode/README.md
vendored
@ -1,23 +1,25 @@
|
|||||||
# VSCode Configuration
|
# VSCode Configuration
|
||||||
|
|
||||||
This folder contains opt-in [Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings) and [Extension Recommendations](https://code.visualstudio.com/docs/editor/extension-gallery#_workspace-recommended-extensions) that the Angular team recommends using when working on this repository.
|
This folder contains opt-in [Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings), [Tasks](https://code.visualstudio.com/docs/editor/tasks), [Launch Configurations](https://code.visualstudio.com/Docs/editor/debugging#_launch-configurations) and [Extension Recommendations](https://code.visualstudio.com/docs/editor/extension-gallery#_workspace-recommended-extensions) that the Angular team recommends using when working on this repository.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
To use the recommended settings follow the steps below:
|
To use the recommended configurations follow the steps below:
|
||||||
|
|
||||||
- install <https://marketplace.visualstudio.com/items?itemName=xaver.clang-format>
|
- install the recommneded extensions in `.vscode/extensions.json`
|
||||||
- copy `.vscode/recommended-settings.json` to `.vscode/settings.json`
|
- copy (or link) `.vscode/recommended-settings.json` to `.vscode/settings.json`
|
||||||
|
- copy (or link) `.vscode/recommended-launch.json` to `.vscode/launch.json`
|
||||||
|
- copy (or link) `.vscode/recommended-tasks.json` to `.vscode/tasks.json`
|
||||||
- restart the editor
|
- restart the editor
|
||||||
|
|
||||||
If you already have your custom workspace settings you should instead manually merge the file content.
|
If you already have your custom workspace settings you should instead manually merge the file contents.
|
||||||
|
|
||||||
This isn't an automatic process so you will need to repeat it when settings are updated.
|
This isn't an automatic process so you will need to repeat it when settings are updated.
|
||||||
|
|
||||||
To see the recommended extensions select "Extensions: Show Recommended Extensions" in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette).
|
To see the recommended extensions select "Extensions: Show Recommended Extensions" in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette).
|
||||||
|
|
||||||
## Editing `.vscode/recommended-settings.json`
|
## Editing `.vscode/recommended-*.json` files
|
||||||
|
|
||||||
If you wish to add extra configuration items please keep in mind any settings you add here will be used by many users.
|
If you wish to add extra configuration items please keep in mind any modifications you make here will be used by many users.
|
||||||
|
|
||||||
Try to keep these settings to things that help facilitate the development process and avoid altering the user workflow whenever possible.
|
Try to keep these settings/configuations to things that help facilitate the development process and avoid altering the user workflow whenever possible.
|
||||||
|
85
.vscode/recommended-launch.json
vendored
Normal file
85
.vscode/recommended-launch.json
vendored
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Attach to bazel test ... --config=debug",
|
||||||
|
"type": "node",
|
||||||
|
"request": "attach",
|
||||||
|
"port": 9229,
|
||||||
|
"address": "localhost",
|
||||||
|
"restart": false,
|
||||||
|
"sourceMaps": true,
|
||||||
|
"localRoot": "${workspaceRoot}",
|
||||||
|
"remoteRoot": "${workspaceRoot}",
|
||||||
|
"stopOnEntry": false,
|
||||||
|
"timeout": 600000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Attach to bazel test ... --config=debug (no source maps)",
|
||||||
|
"type": "node",
|
||||||
|
"request": "attach",
|
||||||
|
"port": 9229,
|
||||||
|
"address": "localhost",
|
||||||
|
"restart": false,
|
||||||
|
"sourceMaps": false,
|
||||||
|
"localRoot": "${workspaceRoot}",
|
||||||
|
"remoteRoot": "${workspaceRoot}",
|
||||||
|
"stopOnEntry": false,
|
||||||
|
"timeout": 600000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "IVY:packages/core/test/acceptance",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--config=ivy",
|
||||||
|
"packages/core/test/acceptance",
|
||||||
|
"--config=debug"
|
||||||
|
],
|
||||||
|
"port": 9229,
|
||||||
|
"address": "localhost",
|
||||||
|
"restart": true,
|
||||||
|
"sourceMaps": true,
|
||||||
|
"timeout": 600000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "IVY:packages/core/test/render3",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--config=ivy",
|
||||||
|
"packages/core/test/render3",
|
||||||
|
"--config=debug"
|
||||||
|
],
|
||||||
|
"port": 9229,
|
||||||
|
"address": "localhost",
|
||||||
|
"restart": true,
|
||||||
|
"sourceMaps": true,
|
||||||
|
"timeout": 600000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "IVY:packages/core/test",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--config=ivy",
|
||||||
|
"packages/core/test",
|
||||||
|
"--config=debug"
|
||||||
|
],
|
||||||
|
"port": 9229,
|
||||||
|
"address": "localhost",
|
||||||
|
"restart": true,
|
||||||
|
"sourceMaps": true,
|
||||||
|
"timeout": 600000,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
113
.vscode/recommended-tasks.json
vendored
Normal file
113
.vscode/recommended-tasks.json
vendored
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "IVY:packages/core/test/...",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--config=ivy",
|
||||||
|
"packages/core/test",
|
||||||
|
"packages/core/test/acceptance",
|
||||||
|
"packages/core/test/render3",
|
||||||
|
],
|
||||||
|
"group": "test",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "VE:packages/core/test/...",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"packages/core/test",
|
||||||
|
"packages/core/test/acceptance",
|
||||||
|
"packages/core/test/render3",
|
||||||
|
],
|
||||||
|
"group": "test",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "IVY:packages/core/test/acceptance",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--config=ivy",
|
||||||
|
"packages/core/test/acceptance",
|
||||||
|
],
|
||||||
|
"group": "test",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "VE:packages/core/test/acceptance",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"packages/core/test/acceptance",
|
||||||
|
],
|
||||||
|
"group": "test",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "IVY:packages/core/test",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--config=ivy",
|
||||||
|
"packages/core/test",
|
||||||
|
],
|
||||||
|
"group": "test",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "VE:packages/core/test",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"packages/core/test",
|
||||||
|
],
|
||||||
|
"group": "test",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "IVY:packages/core/test/render3",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "${workspaceFolder}/node_modules/.bin/bazel",
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--config=ivy",
|
||||||
|
"packages/core/test/render3",
|
||||||
|
],
|
||||||
|
"group": "test",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
197
CHANGELOG.md
197
CHANGELOG.md
@ -1,3 +1,198 @@
|
|||||||
|
<a name="9.0.0-rc.5"></a>
|
||||||
|
# [9.0.0-rc.5](https://github.com/angular/angular/compare/9.0.0-rc.4...9.0.0-rc.5) (2019-12-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **bazel:** don't rely on [@angular](https://github.com/angular)/core being as a depedency to install [@angular](https://github.com/angular)/bazel ([#34181](https://github.com/angular/angular/issues/34181)) ([716fc84](https://github.com/angular/angular/commit/716fc84)), closes [#34164](https://github.com/angular/angular/issues/34164)
|
||||||
|
* **bazel:** reenable template type checking in ng_module ([#34144](https://github.com/angular/angular/issues/34144)) ([572e731](https://github.com/angular/angular/commit/572e731)), closes [/github.com/angular/angular/blob/168abc6d6f52713383411b14980e104c99bfeef5/packages/compiler-cli/src/ngtsc/program.ts#L430-L434](https://github.com//github.com/angular/angular/blob/168abc6d6f52713383411b14980e104c99bfeef5/packages/compiler-cli/src/ngtsc/program.ts/issues/L430-L434)
|
||||||
|
* **common:** reflect input type in NgForOf context ([#33997](https://github.com/angular/angular/issues/33997)) ([b640d38](https://github.com/angular/angular/commit/b640d38))
|
||||||
|
* **common:** reflect input type in NgIf context ([#33997](https://github.com/angular/angular/issues/33997)) ([7504543](https://github.com/angular/angular/commit/7504543)), closes [#31556](https://github.com/angular/angular/issues/31556)
|
||||||
|
* **compiler:** i18n - trim whitespace from i18n custom ids ([#34154](https://github.com/angular/angular/issues/34154)) ([64317c6](https://github.com/angular/angular/commit/64317c6)), closes [#34147](https://github.com/angular/angular/issues/34147)
|
||||||
|
* **compiler-cli:** ensure that `ngI18nClosureMode` is guarded in generated code ([#34211](https://github.com/angular/angular/issues/34211)) ([4d02556](https://github.com/angular/angular/commit/4d02556))
|
||||||
|
* **core:** ensure that `ngI18nClosureMode` is guarded ([#34211](https://github.com/angular/angular/issues/34211)) ([2546261](https://github.com/angular/angular/commit/2546261))
|
||||||
|
* **ivy:** allow insertion of views attached to a different container ([#34156](https://github.com/angular/angular/issues/34156)) ([65cd811](https://github.com/angular/angular/commit/65cd811)), closes [#34152](https://github.com/angular/angular/issues/34152)
|
||||||
|
* **ivy:** consistenly return -1 from ViewContainerRef.indexOf for non-inserted view ([#34156](https://github.com/angular/angular/issues/34156)) ([0044c66](https://github.com/angular/angular/commit/0044c66))
|
||||||
|
* **ivy:** correctly support `ngProjectAs` on templates ([#34200](https://github.com/angular/angular/issues/34200)) ([41ea3c2](https://github.com/angular/angular/commit/41ea3c2))
|
||||||
|
* **ivy:** i18n - correctly parse XLIFF placeholders ([#34155](https://github.com/angular/angular/issues/34155)) ([d5a48b2](https://github.com/angular/angular/commit/d5a48b2)), closes [#34151](https://github.com/angular/angular/issues/34151)
|
||||||
|
* **ivy:** i18n - trim whitespace when parsing metadata ([#34154](https://github.com/angular/angular/issues/34154)) ([f4d714c](https://github.com/angular/angular/commit/f4d714c))
|
||||||
|
* **ivy:** incorrectly validating html foreign objects inside svg ([#34178](https://github.com/angular/angular/issues/34178)) ([4836fe0](https://github.com/angular/angular/commit/4836fe0)), closes [#34171](https://github.com/angular/angular/issues/34171)
|
||||||
|
* **ivy:** support ICUs with pipes ([#34198](https://github.com/angular/angular/issues/34198)) ([eae541b](https://github.com/angular/angular/commit/eae541b))
|
||||||
|
* **language-service:** determine correct type for ngFor exported values ([#34089](https://github.com/angular/angular/issues/34089)) ([12e4aa0](https://github.com/angular/angular/commit/12e4aa0))
|
||||||
|
* **language-service:** Do not produce diagnostics if metadata for NgModule not found ([#34113](https://github.com/angular/angular/issues/34113)) ([29de8d3](https://github.com/angular/angular/commit/29de8d3))
|
||||||
|
* implement Symbol.specics of Promise ([#34162](https://github.com/angular/angular/issues/34162)) ([1bab8c2](https://github.com/angular/angular/commit/1bab8c2)), closes [#34105](https://github.com/angular/angular/issues/34105) [#33989](https://github.com/angular/angular/issues/33989)
|
||||||
|
* **language-service:** Insert parentheses for method completion ([#33860](https://github.com/angular/angular/issues/33860)) ([fb22f18](https://github.com/angular/angular/commit/fb22f18))
|
||||||
|
* **language-service:** Make missing module suggestion instead of error ([#34115](https://github.com/angular/angular/issues/34115)) ([#34193](https://github.com/angular/angular/issues/34193)) ([d2538ca](https://github.com/angular/angular/commit/d2538ca))
|
||||||
|
* **language-service:** use host.error() instead of console.error() ([#34114](https://github.com/angular/angular/issues/34114)) ([7a7e999](https://github.com/angular/angular/commit/7a7e999))
|
||||||
|
* **ngcc:** render legacy i18n message ids by default ([#34135](https://github.com/angular/angular/issues/34135)) ([93ac362](https://github.com/angular/angular/commit/93ac362)), closes [#34056](https://github.com/angular/angular/issues/34056)
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* add js-web-frameworks benchmark ([#34034](https://github.com/angular/angular/issues/34034)) ([bf16b0e](https://github.com/angular/angular/commit/bf16b0e))
|
||||||
|
* **ivy:** avoid duplicate state lookup and default function parameters ([#34183](https://github.com/angular/angular/issues/34183)) ([00f7372](https://github.com/angular/angular/commit/00f7372))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="9.0.0-rc.4"></a>
|
||||||
|
# [9.0.0-rc.4](https://github.com/angular/angular/compare/9.0.0-rc.3...9.0.0-rc.4) (2019-11-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **bazel:** ng_module should not emit shim files under bazel and Ivy ([#33765](https://github.com/angular/angular/issues/33765)) ([e24ed8d](https://github.com/angular/angular/commit/e24ed8d))
|
||||||
|
* **bazel:** update to tsickle 0.37.1 to fix peerDep warnings ([#33788](https://github.com/angular/angular/issues/33788)) ([719ca1d](https://github.com/angular/angular/commit/719ca1d))
|
||||||
|
* **core:** allow css custom variables/properties in the style sanitizer ([#33841](https://github.com/angular/angular/issues/33841)) ([61cc7a3](https://github.com/angular/angular/commit/61cc7a3)), closes [#23485](https://github.com/angular/angular/issues/23485) [#23485](https://github.com/angular/angular/issues/23485)
|
||||||
|
* **core:** remove deprecated and defunct wtf* apis ([#33949](https://github.com/angular/angular/issues/33949)) ([cf42019](https://github.com/angular/angular/commit/cf42019))
|
||||||
|
* **ivy:** avoid infinite recursion when evaluation source files ([#33772](https://github.com/angular/angular/issues/33772)) ([b12fde4](https://github.com/angular/angular/commit/b12fde4)), closes [#33734](https://github.com/angular/angular/issues/33734)
|
||||||
|
* **ivy:** avoid using stale cache in TestBed if module overrides are defined ([#33787](https://github.com/angular/angular/issues/33787)) ([fbd2133](https://github.com/angular/angular/commit/fbd2133))
|
||||||
|
* **ivy:** handle non-standard input/output names in template type checking ([#33741](https://github.com/angular/angular/issues/33741)) ([94257ac](https://github.com/angular/angular/commit/94257ac)), closes [#33590](https://github.com/angular/angular/issues/33590)
|
||||||
|
* **ivy:** i18n - ensure that escaped chars are handled in localized strings ([#34065](https://github.com/angular/angular/issues/34065)) ([00f8d6a](https://github.com/angular/angular/commit/00f8d6a))
|
||||||
|
* **ivy:** prevent unknown element check for AOT-compiled components ([#34024](https://github.com/angular/angular/issues/34024)) ([955a312](https://github.com/angular/angular/commit/955a312))
|
||||||
|
* **ivy:** remove TNodeType assertion from `directiveInject` instruction ([#33948](https://github.com/angular/angular/issues/33948)) ([90a9043](https://github.com/angular/angular/commit/90a9043))
|
||||||
|
* **ivy:** reset style property using ngStyle fix ([#33920](https://github.com/angular/angular/issues/33920)) ([b8ba6b0](https://github.com/angular/angular/commit/b8ba6b0))
|
||||||
|
* **ivy:** run pre-order hooks in injection order ([#34026](https://github.com/angular/angular/issues/34026)) ([ebe3229](https://github.com/angular/angular/commit/ebe3229)), closes [#32522](https://github.com/angular/angular/issues/32522)
|
||||||
|
* **ivy:** support ICUs without "other" cases ([#34042](https://github.com/angular/angular/issues/34042)) ([781003f](https://github.com/angular/angular/commit/781003f))
|
||||||
|
* **ivy:** support inserting a `viewRef` that is already present ([#34052](https://github.com/angular/angular/issues/34052)) ([978b500](https://github.com/angular/angular/commit/978b500)), closes [#33924](https://github.com/angular/angular/issues/33924)
|
||||||
|
* **ivy:** take styles extracted from template into account in JIT mode ([#34017](https://github.com/angular/angular/issues/34017)) ([b659aa3](https://github.com/angular/angular/commit/b659aa3))
|
||||||
|
* **ivy:** track changes across failed builds ([#33971](https://github.com/angular/angular/issues/33971)) ([1ffbde1](https://github.com/angular/angular/commit/1ffbde1)), closes [#32214](https://github.com/angular/angular/issues/32214)
|
||||||
|
* **ivy:** wrap functions from "providers" in parentheses in Closure mode ([#33609](https://github.com/angular/angular/issues/33609)) ([fc6ad19](https://github.com/angular/angular/commit/fc6ad19)), closes [/github.com/angular/tsickle/blob/d7974262571c8a17d684e5ba07680e1b1993afdd/src/jsdoc_transformer.ts#L1021](https://github.com//github.com/angular/tsickle/blob/d7974262571c8a17d684e5ba07680e1b1993afdd/src/jsdoc_transformer.ts/issues/L1021)
|
||||||
|
* **language-service:** determine index types accessed using dot notation ([#33884](https://github.com/angular/angular/issues/33884)) ([e8ec296](https://github.com/angular/angular/commit/e8ec296)), closes [#29811](https://github.com/angular/angular/issues/29811) [#29811](https://github.com/angular/angular/issues/29811)
|
||||||
|
* **language-service:** fix error of array-index out of bounds exception ([#33928](https://github.com/angular/angular/issues/33928)) ([b05ce85](https://github.com/angular/angular/commit/b05ce85))
|
||||||
|
* **language-service:** function.bind() should not be an error ([#34041](https://github.com/angular/angular/issues/34041)) ([#34046](https://github.com/angular/angular/issues/34046)) ([d22f3d6](https://github.com/angular/angular/commit/d22f3d6))
|
||||||
|
* **ngcc:** do not crash on packages that specify typings as an array ([#33973](https://github.com/angular/angular/issues/33973)) ([e456e58](https://github.com/angular/angular/commit/e456e58)), closes [#33646](https://github.com/angular/angular/issues/33646)
|
||||||
|
* **ngcc:** do not output duplicate ɵprov properties ([#34085](https://github.com/angular/angular/issues/34085)) ([5a8d25d](https://github.com/angular/angular/commit/5a8d25d))
|
||||||
|
* **ngcc:** render localized strings when in ES5 format ([#33857](https://github.com/angular/angular/issues/33857)) ([c6695fa](https://github.com/angular/angular/commit/c6695fa))
|
||||||
|
* **ngcc:** render UMD global imports correctly ([#34012](https://github.com/angular/angular/issues/34012)) ([83989b8](https://github.com/angular/angular/commit/83989b8))
|
||||||
|
* **ngcc:** report errors from `analyze` and `resolve` processing ([#33964](https://github.com/angular/angular/issues/33964)) ([ca5d772](https://github.com/angular/angular/commit/ca5d772)), closes [/github.com/angular/angular/issues/33685#issuecomment-557091719](https://github.com//github.com/angular/angular/issues/33685/issues/issuecomment-557091719)
|
||||||
|
* **router:** make routerLinkActive work with query params which contain arrays ([#22666](https://github.com/angular/angular/issues/22666)) ([f1bf5b2](https://github.com/angular/angular/commit/f1bf5b2)), closes [#22223](https://github.com/angular/angular/issues/22223)
|
||||||
|
* **service-worker:** allow creating post api requests after cache failure ([#33930](https://github.com/angular/angular/issues/33930)) ([63c9123](https://github.com/angular/angular/commit/63c9123)), closes [#33793](https://github.com/angular/angular/issues/33793)
|
||||||
|
* **service-worker:** throw when using the unsupported `versionedFiles` option in config ([#33903](https://github.com/angular/angular/issues/33903)) ([250e6fd](https://github.com/angular/angular/commit/250e6fd))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **language-service:** completions support for indexed types ([#34047](https://github.com/angular/angular/issues/34047)) ([8a565c8](https://github.com/angular/angular/commit/8a565c8)), closes [angular/vscode-ng-language-service#110](https://github.com/angular/vscode-ng-language-service/issues/110) [angular/vscode-ng-language-service#277](https://github.com/angular/vscode-ng-language-service/issues/277)
|
||||||
|
* **language-service:** completions support for tuple array ([#33928](https://github.com/angular/angular/issues/33928)) ([7faa9bb](https://github.com/angular/angular/commit/7faa9bb))
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **ivy:** do no work if moving a `viewRef` to the same position ([#34052](https://github.com/angular/angular/issues/34052)) ([d228801](https://github.com/angular/angular/commit/d228801))
|
||||||
|
* **ivy:** fix creation time micro-benchmarks ([#34031](https://github.com/angular/angular/issues/34031)) ([457ac3a](https://github.com/angular/angular/commit/457ac3a))
|
||||||
|
* **ivy:** R3TestBed - Do not process NgModuleDefs that have already been processed ([#33863](https://github.com/angular/angular/issues/33863)) ([05a18cc](https://github.com/angular/angular/commit/05a18cc))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="9.0.0-rc.3"></a>
|
||||||
|
# [9.0.0-rc.3](https://github.com/angular/angular/compare/9.0.0-rc.2...9.0.0-rc.3) (2019-11-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **bazel:** add terser as an optional peer dependency ([#33891](https://github.com/angular/angular/issues/33891)) ([2d7b015](https://github.com/angular/angular/commit/2d7b015))
|
||||||
|
* **compiler-cli:** Refactor getTsTypeFromBuiltinType ([#33778](https://github.com/angular/angular/issues/33778)) ([09480d3](https://github.com/angular/angular/commit/09480d3))
|
||||||
|
* **core:** make QueryList implement Iterable in the type system ([#33536](https://github.com/angular/angular/issues/33536)) ([49571bf](https://github.com/angular/angular/commit/49571bf)), closes [#29842](https://github.com/angular/angular/issues/29842)
|
||||||
|
* **ivy:** always re-analyze the program during incremental rebuilds ([#33862](https://github.com/angular/angular/issues/33862)) ([30ddadc](https://github.com/angular/angular/commit/30ddadc)), closes [#32388](https://github.com/angular/angular/issues/32388)
|
||||||
|
* **ivy:** avoid cyclical dependency in imports ([#33831](https://github.com/angular/angular/issues/33831)) ([a61fb76](https://github.com/angular/angular/commit/a61fb76))
|
||||||
|
* **ivy:** constant object literals shared across element and component instances ([#33705](https://github.com/angular/angular/issues/33705)) ([93ba4c2](https://github.com/angular/angular/commit/93ba4c2))
|
||||||
|
* **ivy:** don't infer template context types when in full mode ([#33537](https://github.com/angular/angular/issues/33537)) ([595375f](https://github.com/angular/angular/commit/595375f)), closes [#33527](https://github.com/angular/angular/issues/33527)
|
||||||
|
* **ivy:** emit fs-relative paths when rootDir(s) aren't in effect ([#33828](https://github.com/angular/angular/issues/33828)) ([14156bd](https://github.com/angular/angular/commit/14156bd)), closes [#33659](https://github.com/angular/angular/issues/33659) [#33562](https://github.com/angular/angular/issues/33562)
|
||||||
|
* **ivy:** ExpressionChangedAfterItHasBeenCheckedError for SafeValue ([#33749](https://github.com/angular/angular/issues/33749)) ([cba6b7d](https://github.com/angular/angular/commit/cba6b7d)), closes [#33448](https://github.com/angular/angular/issues/33448)
|
||||||
|
* **ivy:** extend assertion in `directiveInject` function to support IcuContainers ([#33832](https://github.com/angular/angular/issues/33832)) ([8452458](https://github.com/angular/angular/commit/8452458))
|
||||||
|
* **ivy:** i18n - ensure that colons in i18n metadata are not rendered ([#33820](https://github.com/angular/angular/issues/33820)) ([bc28ca7](https://github.com/angular/angular/commit/bc28ca7))
|
||||||
|
* **ivy:** i18n - support "\", "`" and "${" sequences in i18n messages ([#33820](https://github.com/angular/angular/issues/33820)) ([b53a1ac](https://github.com/angular/angular/commit/b53a1ac))
|
||||||
|
* **ivy:** move setClassMetadata calls into a pure iife ([#33337](https://github.com/angular/angular/issues/33337)) ([213e3c3](https://github.com/angular/angular/commit/213e3c3))
|
||||||
|
* **ivy:** properly insert views before ng-container with injected ViewContainerRef ([#33853](https://github.com/angular/angular/issues/33853)) ([c7a3694](https://github.com/angular/angular/commit/c7a3694))
|
||||||
|
* **ivy:** properly insert views into ViewContainerRef injected by querying <ng-container> ([#33816](https://github.com/angular/angular/issues/33816)) ([f136dda](https://github.com/angular/angular/commit/f136dda))
|
||||||
|
* **ivy:** report watch mode diagnostics correctly ([#33862](https://github.com/angular/angular/issues/33862)) ([d92da13](https://github.com/angular/angular/commit/d92da13)), closes [#32213](https://github.com/angular/angular/issues/32213)
|
||||||
|
* **ivy:** reset style property value defined using [style.prop.px] ([#33780](https://github.com/angular/angular/issues/33780)) ([de8cf75](https://github.com/angular/angular/commit/de8cf75))
|
||||||
|
* **ivy:** retain JIT metadata unless JIT mode is explicitly disabled ([#33671](https://github.com/angular/angular/issues/33671)) ([5267c92](https://github.com/angular/angular/commit/5267c92))
|
||||||
|
* **ivy:** shadow all DOM properties in `DebugElement.properties` ([#33781](https://github.com/angular/angular/issues/33781)) ([5be23a3](https://github.com/angular/angular/commit/5be23a3)), closes [#33695](https://github.com/angular/angular/issues/33695)
|
||||||
|
* **ivy:** support for #id bootstrap selectors ([#33784](https://github.com/angular/angular/issues/33784)) ([9761ebe](https://github.com/angular/angular/commit/9761ebe)), closes [#33485](https://github.com/angular/angular/issues/33485)
|
||||||
|
* **language-service:** Function alias should be callable ([#33782](https://github.com/angular/angular/issues/33782)) ([ca63353](https://github.com/angular/angular/commit/ca63353))
|
||||||
|
* **language-service:** Provide completions for attribute values ([#33839](https://github.com/angular/angular/issues/33839)) ([0e20453](https://github.com/angular/angular/commit/0e20453))
|
||||||
|
* **language-service:** Recompute analyzed modules only when source files change ([#33806](https://github.com/angular/angular/issues/33806)) ([9882a82](https://github.com/angular/angular/commit/9882a82))
|
||||||
|
* **language-service:** Remove getTemplateReferences() from LanguageService API ([#33807](https://github.com/angular/angular/issues/33807)) ([0688a28](https://github.com/angular/angular/commit/0688a28))
|
||||||
|
* **ngcc:** always add exports for `ModuleWithProviders` references ([#33875](https://github.com/angular/angular/issues/33875)) ([f3d8f6a](https://github.com/angular/angular/commit/f3d8f6a)), closes [#33701](https://github.com/angular/angular/issues/33701)
|
||||||
|
* **ngcc:** correctly associate decorators with aliased classes ([#33878](https://github.com/angular/angular/issues/33878)) ([59a4b76](https://github.com/angular/angular/commit/59a4b76))
|
||||||
|
* **ngcc:** correctly include internal .d.ts files ([#33875](https://github.com/angular/angular/issues/33875)) ([0854dc8](https://github.com/angular/angular/commit/0854dc8))
|
||||||
|
* **ngcc:** do not emit ES2015 code in ES5 files ([#33514](https://github.com/angular/angular/issues/33514)) ([06e36e5](https://github.com/angular/angular/commit/06e36e5)), closes [#32665](https://github.com/angular/angular/issues/32665)
|
||||||
|
* **ngcc:** generate correct metadata for classes with getter/setter properties ([#33514](https://github.com/angular/angular/issues/33514)) ([21bd8c9](https://github.com/angular/angular/commit/21bd8c9)), closes [#30569](https://github.com/angular/angular/issues/30569)
|
||||||
|
* **ngcc:** properly detect origin of constructor param types ([#33901](https://github.com/angular/angular/issues/33901)) ([05d5c4f](https://github.com/angular/angular/commit/05d5c4f)), closes [#33677](https://github.com/angular/angular/issues/33677)
|
||||||
|
* **router:** make routerLinkActive work with query params which contain arrays ([#22666](https://github.com/angular/angular/issues/22666)) ([8e5ed20](https://github.com/angular/angular/commit/8e5ed20)), closes [#22223](https://github.com/angular/angular/issues/22223)
|
||||||
|
* **zone.js:** fixes typo of zone.js patch vrdisplaydisconnected property ([#33581](https://github.com/angular/angular/issues/33581)) ([1b7aa05](https://github.com/angular/angular/commit/1b7aa05)), closes [#33579](https://github.com/angular/angular/issues/33579)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **bazel:** update ng-add to use bazel v1.1.0 ([#33813](https://github.com/angular/angular/issues/33813)) ([b1d0a4f](https://github.com/angular/angular/commit/b1d0a4f))
|
||||||
|
* **core:** missing-injectable migration should migrate empty object literal providers ([#33709](https://github.com/angular/angular/issues/33709)) ([b7c012f](https://github.com/angular/angular/commit/b7c012f))
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **ivy:** add micro-benchmark focused on directive input update ([#33798](https://github.com/angular/angular/issues/33798)) ([edd624b](https://github.com/angular/angular/commit/edd624b))
|
||||||
|
* **ivy:** don't store public input names in two places ([#33798](https://github.com/angular/angular/issues/33798)) ([105616c](https://github.com/angular/angular/commit/105616c))
|
||||||
|
* **ivy:** extract template's instruction first create pass processing ([#33856](https://github.com/angular/angular/issues/33856)) ([01af94c](https://github.com/angular/angular/commit/01af94c))
|
||||||
|
* **ivy:** Improve performance of transplanted views ([#33702](https://github.com/angular/angular/issues/33702)) ([a16a57e](https://github.com/angular/angular/commit/a16a57e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="9.0.0-rc.2"></a>
|
||||||
|
# [9.0.0-rc.2](https://github.com/angular/angular/compare/9.0.0-rc.1...9.0.0-rc.2) (2019-11-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **common:** rerun cldr to remove <20> characters ([#33699](https://github.com/angular/angular/issues/33699)) ([011ecdf](https://github.com/angular/angular/commit/011ecdf))
|
||||||
|
* **common:** update CLDR generated files after change to npm sources ([#33634](https://github.com/angular/angular/issues/33634)) ([59b25da](https://github.com/angular/angular/commit/59b25da))
|
||||||
|
* **common:** update CLDR generated files to 36.0.0 ([#33584](https://github.com/angular/angular/issues/33584)) ([c1bd3bc](https://github.com/angular/angular/commit/c1bd3bc))
|
||||||
|
* **compiler:** correctly parse attributes with a dot in the name ([#32256](https://github.com/angular/angular/issues/32256)) ([687582f](https://github.com/angular/angular/commit/687582f))
|
||||||
|
* **compiler-cli:** Fix typo $implict ([#33633](https://github.com/angular/angular/issues/33633)) ([7bccef5](https://github.com/angular/angular/commit/7bccef5))
|
||||||
|
* **compiler-cli:** Pass SourceFile to getFullText() ([#33660](https://github.com/angular/angular/issues/33660)) ([33f6cd4](https://github.com/angular/angular/commit/33f6cd4))
|
||||||
|
* **core:** remove ngcc postinstall migration ([#33727](https://github.com/angular/angular/issues/33727)) ([508bbfd](https://github.com/angular/angular/commit/508bbfd))
|
||||||
|
* **core:** support `ngInjectableDef` on types with inherited `ɵprov` ([#33732](https://github.com/angular/angular/issues/33732)) ([4ec079f](https://github.com/angular/angular/commit/4ec079f))
|
||||||
|
* **ivy:** auto register NgModules with ID ([#33663](https://github.com/angular/angular/issues/33663)) ([4988094](https://github.com/angular/angular/commit/4988094))
|
||||||
|
* **ivy:** better support for i18n attributes on <ng-container>s ([#33599](https://github.com/angular/angular/issues/33599)) ([2046202](https://github.com/angular/angular/commit/2046202))
|
||||||
|
* **ivy:** ComponentFactory.create should clear host element content ([#33487](https://github.com/angular/angular/issues/33487)) ([d67a38b](https://github.com/angular/angular/commit/d67a38b))
|
||||||
|
* **ivy:** ensure module scope is rebuilt on dependent change ([#33522](https://github.com/angular/angular/issues/33522)) ([71238a9](https://github.com/angular/angular/commit/71238a9)), closes [#32416](https://github.com/angular/angular/issues/32416)
|
||||||
|
* **ivy:** ensure that the correct `document` is available ([#33712](https://github.com/angular/angular/issues/33712)) ([8362696](https://github.com/angular/angular/commit/8362696)), closes [#33651](https://github.com/angular/angular/issues/33651)
|
||||||
|
* **ivy:** Handle overrides for {providedIn: AModule} in R3TestBed ([#33606](https://github.com/angular/angular/issues/33606)) ([d09ad82](https://github.com/angular/angular/commit/d09ad82))
|
||||||
|
* **ivy:** match directives on namespaced elements ([#33555](https://github.com/angular/angular/issues/33555)) ([99ead47](https://github.com/angular/angular/commit/99ead47)), closes [#32061](https://github.com/angular/angular/issues/32061)
|
||||||
|
* **ivy:** properly determine the first native node of a view ([#33627](https://github.com/angular/angular/issues/33627)) ([811275c](https://github.com/angular/angular/commit/811275c))
|
||||||
|
* **ivy:** properly insert views in front of empty views ([#33647](https://github.com/angular/angular/issues/33647)) ([c5737f4](https://github.com/angular/angular/commit/c5737f4))
|
||||||
|
* **ivy:** properly insert views in front of views with an empty element container ([#33647](https://github.com/angular/angular/issues/33647)) ([0b99884](https://github.com/angular/angular/commit/0b99884))
|
||||||
|
* **ivy:** provider override via TestBed should remove old providers from the list ([#33706](https://github.com/angular/angular/issues/33706)) ([f45d5dc](https://github.com/angular/angular/commit/f45d5dc))
|
||||||
|
* **ivy:** recompile component when template changes in ngc watch mode ([#33551](https://github.com/angular/angular/issues/33551)) ([da01dbc](https://github.com/angular/angular/commit/da01dbc)), closes [#32869](https://github.com/angular/angular/issues/32869)
|
||||||
|
* **ivy:** recompile component when template changes in ngc watch mode ([#33551](https://github.com/angular/angular/issues/33551)) ([cd8333c](https://github.com/angular/angular/commit/cd8333c)), closes [#32869](https://github.com/angular/angular/issues/32869)
|
||||||
|
* **ivy:** Run ChangeDetection on transplanted views ([#33644](https://github.com/angular/angular/issues/33644)) ([37ae45e](https://github.com/angular/angular/commit/37ae45e)), closes [#33393](https://github.com/angular/angular/issues/33393)
|
||||||
|
* **language-service:** Resolve template variable in nested ngFor ([#33676](https://github.com/angular/angular/issues/33676)) ([6615743](https://github.com/angular/angular/commit/6615743))
|
||||||
|
* **ngcc:** add default config for `ng2-dragula` ([#33797](https://github.com/angular/angular/issues/33797)) ([ecf38d4](https://github.com/angular/angular/commit/ecf38d4)), closes [#33718](https://github.com/angular/angular/issues/33718)
|
||||||
|
* **ngcc:** add reexports only once ([#33658](https://github.com/angular/angular/issues/33658)) ([83b635c](https://github.com/angular/angular/commit/83b635c))
|
||||||
|
* **ngcc:** ensure that adjacent statements go after helper calls ([#33689](https://github.com/angular/angular/issues/33689)) ([c540061](https://github.com/angular/angular/commit/c540061))
|
||||||
|
* generate the new locale files ([#33682](https://github.com/angular/angular/issues/33682)) ([72796b9](https://github.com/angular/angular/commit/72796b9))
|
||||||
|
* resolve event listeners not correct when registered outside of ngZone ([#33711](https://github.com/angular/angular/issues/33711)) ([9045e3e](https://github.com/angular/angular/commit/9045e3e)), closes [#33687](https://github.com/angular/angular/issues/33687)
|
||||||
|
* use full cldr data to support all locales ([#33682](https://github.com/angular/angular/issues/33682)) ([ea83125](https://github.com/angular/angular/commit/ea83125)), closes [#33681](https://github.com/angular/angular/issues/33681)
|
||||||
|
* **ngcc:** remove `__decorator` calls even when part of the IIFE return statement ([#33777](https://github.com/angular/angular/issues/33777)) ([e1df98b](https://github.com/angular/angular/commit/e1df98b))
|
||||||
|
* **ngcc:** support minified ES5 scenarios ([#33777](https://github.com/angular/angular/issues/33777)) ([49e517d](https://github.com/angular/angular/commit/49e517d))
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **core:** Avoid unnecessary creating provider factory ([#33742](https://github.com/angular/angular/issues/33742)) ([c315881](https://github.com/angular/angular/commit/c315881))
|
||||||
|
|
||||||
|
|
||||||
|
### Reverts
|
||||||
|
|
||||||
|
* "fix(ivy): recompile component when template changes in ngc watch mode ([#33551](https://github.com/angular/angular/issues/33551))" ([#33661](https://github.com/angular/angular/issues/33661)) ([cb55f60](https://github.com/angular/angular/commit/cb55f60))
|
||||||
|
* fix(ivy): Only restore registered modules if user compiles modules with TestBed ([#32944](https://github.com/angular/angular/issues/32944)) ([#33663](https://github.com/angular/angular/issues/33663)) ([f8e9c1e](https://github.com/angular/angular/commit/f8e9c1e))
|
||||||
|
* fix(ivy): R3TestBed should clean up registered modules after each test ([#32872](https://github.com/angular/angular/issues/32872)) ([#33663](https://github.com/angular/angular/issues/33663)) ([7c4366d](https://github.com/angular/angular/commit/7c4366d))
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* **i18n:** The CLDR data has been updated to v36.0.0, which may cause some localized data strings to change. For example, the space separator used in numbers in the `fr` locales changed from `\xa0` to `\u202f` ([c1bd3bc](https://github.com/angular/angular/commit/c1bd3bc))
|
||||||
|
|
||||||
<a name="9.0.0-rc.1"></a>
|
<a name="9.0.0-rc.1"></a>
|
||||||
# [9.0.0-rc.1](https://github.com/angular/angular/compare/9.0.0-rc.0...9.0.0-rc.1) (2019-11-06)
|
# [9.0.0-rc.1](https://github.com/angular/angular/compare/9.0.0-rc.0...9.0.0-rc.1) (2019-11-06)
|
||||||
|
|
||||||
@ -298,7 +493,7 @@ or
|
|||||||
npm install tslib --save
|
npm install tslib --save
|
||||||
```
|
```
|
||||||
* **forms:** * `<ngForm></ngForm>` can no longer be used as a selector. Use `<ng-form></ng-form>` instead.
|
* **forms:** * `<ngForm></ngForm>` can no longer be used as a selector. Use `<ng-form></ng-form>` instead.
|
||||||
* The `NgFromSelectorWarning` directive has been removed.
|
* The `NgFormSelectorWarning` directive has been removed.
|
||||||
* `FormsModule.withConfig` has been removed. Use the `FormsModule` directly.
|
* `FormsModule.withConfig` has been removed. Use the `FormsModule` directly.
|
||||||
|
|
||||||
|
|
||||||
|
49
WORKSPACE
49
WORKSPACE
@ -5,24 +5,11 @@ workspace(
|
|||||||
|
|
||||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||||
|
|
||||||
# Uncomment for local bazel rules development
|
|
||||||
#local_repository(
|
|
||||||
# name = "build_bazel_rules_nodejs",
|
|
||||||
# path = "../rules_nodejs",
|
|
||||||
#)
|
|
||||||
#local_repository(
|
|
||||||
# name = "npm_bazel_typescript",
|
|
||||||
# path = "../rules_typescript",
|
|
||||||
#)
|
|
||||||
|
|
||||||
# Fetch rules_nodejs so we can install our npm dependencies
|
# Fetch rules_nodejs so we can install our npm dependencies
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "build_bazel_rules_nodejs",
|
name = "build_bazel_rules_nodejs",
|
||||||
patch_args = ["-p1"],
|
sha256 = "c612d6b76eaa17540e8b8c806e02701ed38891460f9ba3303f4424615437887a",
|
||||||
# Patch https://github.com/bazelbuild/rules_nodejs/pull/903
|
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.42.1/rules_nodejs-0.42.1.tar.gz"],
|
||||||
patches = ["//tools:rollup_bundle_commonjs_ignoreGlobal.patch"],
|
|
||||||
sha256 = "3d7296d834208792fa3b2ded8ec04e75068e3de172fae79db217615bd75a6ff7",
|
|
||||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.39.1/rules_nodejs-0.39.1.tar.gz"],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check the bazel version and download npm dependencies
|
# Check the bazel version and download npm dependencies
|
||||||
@ -39,25 +26,10 @@ Try running `yarn bazel` instead.
|
|||||||
(If you did run that, check that you've got a fresh `yarn install`)
|
(If you did run that, check that you've got a fresh `yarn install`)
|
||||||
|
|
||||||
""",
|
""",
|
||||||
minimum_bazel_version = "0.27.0",
|
minimum_bazel_version = "1.1.0",
|
||||||
)
|
)
|
||||||
|
|
||||||
# The NodeJS rules version must be at least the following version because:
|
check_rules_nodejs_version(minimum_version_string = "0.42.1")
|
||||||
# - 0.15.2 Re-introduced the prod_only attribute on yarn_install
|
|
||||||
# - 0.15.3 Includes a fix for the `jasmine_node_test` rule ignoring target tags
|
|
||||||
# - 0.16.8 Supports npm installed bazel workspaces
|
|
||||||
# - 0.26.0 Fix for data files in yarn_install and npm_install
|
|
||||||
# - 0.27.12 Adds NodeModuleSources provider for transtive npm deps support
|
|
||||||
# - 0.30.0 yarn_install now uses symlinked node_modules with new managed directories Bazel 0.26.0 feature
|
|
||||||
# - 0.31.1 entry_point attribute of nodejs_binary & rollup_bundle is now a label
|
|
||||||
# - 0.32.0 yarn_install and npm_install no longer puts build files under symlinked node_modules
|
|
||||||
# - 0.32.1 remove override of @bazel/tsetse & exclude typescript lib declarations in node_module_library transitive_declarations
|
|
||||||
# - 0.32.2 resolves bug in @bazel/hide-bazel-files postinstall step
|
|
||||||
# - 0.34.0 introduces protractor rule
|
|
||||||
# - 0.37.1 windows fixes
|
|
||||||
# - 0.38.2 Adds NpmPackageInfo & JSNamedModuleInfo providers
|
|
||||||
# - 0.38.3 all providers loaded from //:providers.bzl
|
|
||||||
check_rules_nodejs_version(minimum_version_string = "0.38.3")
|
|
||||||
|
|
||||||
# Setup the Node.js toolchain
|
# Setup the Node.js toolchain
|
||||||
node_repositories(
|
node_repositories(
|
||||||
@ -113,12 +85,9 @@ load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories"
|
|||||||
|
|
||||||
web_test_repositories()
|
web_test_repositories()
|
||||||
|
|
||||||
load("@io_bazel_rules_webtesting//web/versioned:browsers-0.3.2.bzl", "browser_repositories")
|
load("//tools/browsers:browser_repositories.bzl", "browser_repositories")
|
||||||
|
|
||||||
browser_repositories(
|
browser_repositories()
|
||||||
chromium = True,
|
|
||||||
firefox = True,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Setup the rules_typescript tooolchain
|
# Setup the rules_typescript tooolchain
|
||||||
load("@npm_bazel_typescript//:index.bzl", "ts_setup_workspace")
|
load("@npm_bazel_typescript//:index.bzl", "ts_setup_workspace")
|
||||||
@ -143,14 +112,14 @@ rbe_autoconfig(
|
|||||||
# Need to specify a base container digest in order to ensure that we can use the checked-in
|
# Need to specify a base container digest in order to ensure that we can use the checked-in
|
||||||
# platform configurations for the "ubuntu16_04" image. Otherwise the autoconfig rule would
|
# platform configurations for the "ubuntu16_04" image. Otherwise the autoconfig rule would
|
||||||
# need to pull the image and run it in order determine the toolchain configuration. See:
|
# need to pull the image and run it in order determine the toolchain configuration. See:
|
||||||
# https://github.com/bazelbuild/bazel-toolchains/blob/0.27.0/configs/ubuntu16_04_clang/versions.bzl
|
# https://github.com/bazelbuild/bazel-toolchains/blob/1.1.2/configs/ubuntu16_04_clang/versions.bzl
|
||||||
base_container_digest = "sha256:94d7d8552902d228c32c8c148cc13f0effc2b4837757a6e95b73fdc5c5e4b07b",
|
base_container_digest = "sha256:1ab40405810effefa0b2f45824d6d608634ccddbf06366760c341ef6fbead011",
|
||||||
# Note that if you change the `digest`, you might also need to update the
|
# Note that if you change the `digest`, you might also need to update the
|
||||||
# `base_container_digest` to make sure marketplace.gcr.io/google/rbe-ubuntu16-04-webtest:<digest>
|
# `base_container_digest` to make sure marketplace.gcr.io/google/rbe-ubuntu16-04-webtest:<digest>
|
||||||
# and marketplace.gcr.io/google/rbe-ubuntu16-04:<base_container_digest> have
|
# and marketplace.gcr.io/google/rbe-ubuntu16-04:<base_container_digest> have
|
||||||
# the same Clang and JDK installed. Clang is needed because of the dependency on
|
# the same Clang and JDK installed. Clang is needed because of the dependency on
|
||||||
# @com_google_protobuf. Java is needed for the Bazel's test executor Java tool.
|
# @com_google_protobuf. Java is needed for the Bazel's test executor Java tool.
|
||||||
digest = "sha256:76e2e4a894f9ffbea0a0cb2fbde741b5d223d40f265dbb9bca78655430173990",
|
digest = "sha256:0b8fa87db4b8e5366717a7164342a029d1348d2feea7ecc4b18c780bc2507059",
|
||||||
env = clang_env(),
|
env = clang_env(),
|
||||||
registry = "marketplace.gcr.io",
|
registry = "marketplace.gcr.io",
|
||||||
# We can't use the default "ubuntu16_04" RBE image provided by the autoconfig because we need
|
# We can't use the default "ubuntu16_04" RBE image provided by the autoconfig because we need
|
||||||
|
@ -104,7 +104,7 @@ You also want to see those changes displayed properly in the doc viewer
|
|||||||
with a quick, edit/view cycle time.
|
with a quick, edit/view cycle time.
|
||||||
|
|
||||||
For this purpose, use the `yarn docs-watch` task, which watches for changes to source files and only
|
For this purpose, use the `yarn docs-watch` task, which watches for changes to source files and only
|
||||||
re-processes the the files necessary to generate the docs that are related to the file that has changed.
|
re-processes the files necessary to generate the docs that are related to the file that has changed.
|
||||||
Since this task takes shortcuts, it is much faster (often less than 1 second) but it won't produce full
|
Since this task takes shortcuts, it is much faster (often less than 1 second) but it won't produce full
|
||||||
fidelity content. For example, links to other docs and code examples may not render correctly. This is
|
fidelity content. For example, links to other docs and code examples may not render correctly. This is
|
||||||
most particularly noticed in links to other docs and in the embedded examples, which may not always render
|
most particularly noticed in links to other docs and in the embedded examples, which may not always render
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { protractor, browser, element, by, ElementFinder } from 'protractor';
|
|||||||
|
|
||||||
const nameSuffix = 'X';
|
const nameSuffix = 'X';
|
||||||
|
|
||||||
class Hero {
|
interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
isSecret = false;
|
isSecret: boolean;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,23 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { QuestionService } from './question.service';
|
import { QuestionService } from './question.service';
|
||||||
|
import { QuestionBase } from './question-base';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
template: `
|
template: `
|
||||||
<div>
|
<div>
|
||||||
<h2>Job Application for Heroes</h2>
|
<h2>Job Application for Heroes</h2>
|
||||||
<app-dynamic-form [questions]="questions"></app-dynamic-form>
|
<app-dynamic-form [questions]="questions$ | async"></app-dynamic-form>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
providers: [QuestionService]
|
providers: [QuestionService]
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
questions: any[];
|
questions$: Observable<QuestionBase<any>[]>;
|
||||||
|
|
||||||
constructor(service: QuestionService) {
|
constructor(service: QuestionService) {
|
||||||
this.questions = service.getQuestions();
|
this.questions$ = service.getQuestions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
|
<option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
|
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,7 +9,7 @@ import { QuestionBase } from './question-base';
|
|||||||
templateUrl: './dynamic-form-question.component.html'
|
templateUrl: './dynamic-form-question.component.html'
|
||||||
})
|
})
|
||||||
export class DynamicFormQuestionComponent {
|
export class DynamicFormQuestionComponent {
|
||||||
@Input() question: QuestionBase<any>;
|
@Input() question: QuestionBase<string>;
|
||||||
@Input() form: FormGroup;
|
@Input() form: FormGroup;
|
||||||
get isValid() { return this.form.controls[this.question.key].valid; }
|
get isValid() { return this.form.controls[this.question.key].valid; }
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import { QuestionControlService } from './question-control.service';
|
|||||||
})
|
})
|
||||||
export class DynamicFormComponent implements OnInit {
|
export class DynamicFormComponent implements OnInit {
|
||||||
|
|
||||||
@Input() questions: QuestionBase<any>[] = [];
|
@Input() questions: QuestionBase<string>[] = [];
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
payLoad = '';
|
payLoad = '';
|
||||||
|
|
||||||
@ -23,6 +23,6 @@ export class DynamicFormComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.payLoad = JSON.stringify(this.form.value);
|
this.payLoad = JSON.stringify(this.form.getRawValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ export class QuestionBase<T> {
|
|||||||
required: boolean;
|
required: boolean;
|
||||||
order: number;
|
order: number;
|
||||||
controlType: string;
|
controlType: string;
|
||||||
|
type: string;
|
||||||
|
options: {key: string, value: string}[];
|
||||||
|
|
||||||
constructor(options: {
|
constructor(options: {
|
||||||
value?: T,
|
value?: T,
|
||||||
@ -13,7 +15,8 @@ export class QuestionBase<T> {
|
|||||||
label?: string,
|
label?: string,
|
||||||
required?: boolean,
|
required?: boolean,
|
||||||
order?: number,
|
order?: number,
|
||||||
controlType?: string
|
controlType?: string,
|
||||||
|
type?: string
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.value = options.value;
|
this.value = options.value;
|
||||||
this.key = options.key || '';
|
this.key = options.key || '';
|
||||||
@ -21,5 +24,6 @@ export class QuestionBase<T> {
|
|||||||
this.required = !!options.required;
|
this.required = !!options.required;
|
||||||
this.order = options.order === undefined ? 1 : options.order;
|
this.order = options.order === undefined ? 1 : options.order;
|
||||||
this.controlType = options.controlType || '';
|
this.controlType = options.controlType || '';
|
||||||
|
this.type = options.type || '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import { QuestionBase } from './question-base';
|
|||||||
export class QuestionControlService {
|
export class QuestionControlService {
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
toFormGroup(questions: QuestionBase<any>[] ) {
|
toFormGroup(questions: QuestionBase<string>[] ) {
|
||||||
let group: any = {};
|
let group: any = {};
|
||||||
|
|
||||||
questions.forEach(question => {
|
questions.forEach(question => {
|
||||||
|
@ -4,15 +4,15 @@ import { Injectable } from '@angular/core';
|
|||||||
import { DropdownQuestion } from './question-dropdown';
|
import { DropdownQuestion } from './question-dropdown';
|
||||||
import { QuestionBase } from './question-base';
|
import { QuestionBase } from './question-base';
|
||||||
import { TextboxQuestion } from './question-textbox';
|
import { TextboxQuestion } from './question-textbox';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QuestionService {
|
export class QuestionService {
|
||||||
|
|
||||||
// TODO: get from a remote source of question metadata
|
// TODO: get from a remote source of question metadata
|
||||||
// TODO: make asynchronous
|
|
||||||
getQuestions() {
|
getQuestions() {
|
||||||
|
|
||||||
let questions: QuestionBase<any>[] = [
|
let questions: QuestionBase<string>[] = [
|
||||||
|
|
||||||
new DropdownQuestion({
|
new DropdownQuestion({
|
||||||
key: 'brave',
|
key: 'brave',
|
||||||
@ -42,6 +42,6 @@ export class QuestionService {
|
|||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
return questions.sort((a, b) => a.order - b.order);
|
return of(questions.sort((a, b) => a.order - b.order));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
|
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
tid: string; // tax id
|
tid: string; // tax id
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"description": "Http Guide Testing",
|
"description": "Http Guide Testing",
|
||||||
"files":[
|
"files":[
|
||||||
|
"src/app/heroes/hero.ts",
|
||||||
"src/app/heroes/heroes.service.ts",
|
"src/app/heroes/heroes.service.ts",
|
||||||
"src/app/heroes/heroes.service.spec.ts",
|
"src/app/heroes/heroes.service.spec.ts",
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@ describe('HeroesService', () => {
|
|||||||
|
|
||||||
// Inject the http, test controller, and service-under-test
|
// Inject the http, test controller, and service-under-test
|
||||||
// as they will be referenced by each test.
|
// as they will be referenced by each test.
|
||||||
httpClient = TestBed.inject(HttpClient);
|
httpClient = TestBed.get(HttpClient);
|
||||||
httpTestingController = TestBed.inject(HttpTestingController);
|
httpTestingController = TestBed.get(HttpTestingController);
|
||||||
heroService = TestBed.inject(HeroesService);
|
heroService = TestBed.get(HeroesService);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -44,7 +44,7 @@ describe('HeroesService', () => {
|
|||||||
let expectedHeroes: Hero[];
|
let expectedHeroes: Hero[];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
heroService = TestBed.inject(HeroesService);
|
heroService = TestBed.get(HeroesService);
|
||||||
expectedHeroes = [
|
expectedHeroes = [
|
||||||
{ id: 1, name: 'A' },
|
{ id: 1, name: 'A' },
|
||||||
{ id: 2, name: 'B' },
|
{ id: 2, name: 'B' },
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
|
import { enableProdMode } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
import { AppModule } from './app/app.module';
|
import { AppModule } from './app/app.module';
|
||||||
|
import { environment } from './environments/environment';
|
||||||
|
|
||||||
|
if (environment.production) {
|
||||||
|
enableProdMode();
|
||||||
|
}
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||||
|
@ -27,8 +27,8 @@ describe('HttpClient testing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Inject the http service and test controller for each test
|
// Inject the http service and test controller for each test
|
||||||
httpClient = TestBed.inject(HttpClient);
|
httpClient = TestBed.get(HttpClient);
|
||||||
httpTestingController = TestBed.inject(HttpTestingController);
|
httpTestingController = TestBed.get(HttpTestingController);
|
||||||
});
|
});
|
||||||
// #enddocregion setup
|
// #enddocregion setup
|
||||||
// #docregion afterEach
|
// #docregion afterEach
|
||||||
@ -67,6 +67,7 @@ describe('HttpClient testing', () => {
|
|||||||
httpTestingController.verify();
|
httpTestingController.verify();
|
||||||
});
|
});
|
||||||
// #enddocregion get-test
|
// #enddocregion get-test
|
||||||
|
|
||||||
it('can test HttpClient.get with matching header', () => {
|
it('can test HttpClient.get with matching header', () => {
|
||||||
const testData: Data = {name: 'Test Data'};
|
const testData: Data = {name: 'Test Data'};
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
"!**/*.js",
|
"!**/*.js",
|
||||||
|
|
||||||
"!src/testing/*.*",
|
"!src/testing/*.*",
|
||||||
"!src/index-specs.html"
|
"!src/index-specs.html",
|
||||||
|
"!src/main-specs.ts"
|
||||||
],
|
],
|
||||||
"tags": ["http"]
|
"tags": ["http"]
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
import { registerLocaleData } from '@angular/common';
|
import { registerLocaleData } from '@angular/common';
|
||||||
import localeFr from '@angular/common/locales/fr';
|
import localeFr from '@angular/common/locales/fr';
|
||||||
|
|
||||||
// the second parameter 'fr' is optional
|
// the second parameter 'fr-FR' is optional
|
||||||
registerLocaleData(localeFr, 'fr');
|
registerLocaleData(localeFr, 'fr-FR');
|
||||||
// #enddocregion import-locale
|
// #enddocregion import-locale
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
emotion?: string;
|
emotion?: string;
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* This example project is special in that it is not a cli app. To run tests appropriate for this
|
||||||
|
* project, the test command is overwritten in `aio/content/examples/observables-in-angular/example-config.json`.
|
||||||
|
*
|
||||||
|
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.js` runs
|
||||||
|
* tests for this project.
|
||||||
|
*
|
||||||
|
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
|
||||||
|
*/
|
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"e2e": [
|
||||||
|
{
|
||||||
|
"cmd": "yarn",
|
||||||
|
"args": [ "tsc", "--project", "./" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
@ -39,9 +39,9 @@ export class ZippyComponent {
|
|||||||
Time: {{ time | async }}</div>`
|
Time: {{ time | async }}</div>`
|
||||||
})
|
})
|
||||||
export class AsyncObservablePipeComponent {
|
export class AsyncObservablePipeComponent {
|
||||||
time = new Observable(observer =>
|
time = new Observable<string>(observer => {
|
||||||
setInterval(() => observer.next(new Date().toString()), 1000)
|
setInterval(() => observer.next(new Date().toString()), 1000);
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// #enddocregion pipe
|
// #enddocregion pipe
|
||||||
|
9
aio/content/examples/observables/e2e/src/app.e2e-spec.ts
Normal file
9
aio/content/examples/observables/e2e/src/app.e2e-spec.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* This example project is special in that it is not a cli app. To run tests appropriate for this
|
||||||
|
* project, the test command is overwritten in `aio/content/examples/observables/example-config.json`.
|
||||||
|
*
|
||||||
|
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.js` runs
|
||||||
|
* tests for this project.
|
||||||
|
*
|
||||||
|
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
|
||||||
|
*/
|
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"e2e": [
|
||||||
|
{
|
||||||
|
"cmd": "yarn",
|
||||||
|
"args": [ "tsc", "--project", "./" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* This example project is special in that it is not a cli app. To run tests appropriate for this
|
||||||
|
* project, the test command is overwritten in `aio/content/examples/practical-observable-usage/example-config.json`.
|
||||||
|
*
|
||||||
|
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.js` runs
|
||||||
|
* tests for this project.
|
||||||
|
*
|
||||||
|
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
|
||||||
|
*/
|
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"e2e": [
|
||||||
|
{
|
||||||
|
"cmd": "yarn",
|
||||||
|
"args": [ "tsc", "--project", "./" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
import { fromEvent } from 'rxjs';
|
import { fromEvent } from 'rxjs';
|
||||||
import { ajax } from 'rxjs/ajax';
|
import { ajax } from 'rxjs/ajax';
|
||||||
import { map, filter, debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
|
import { debounceTime, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
|
|
||||||
const searchBox = document.getElementById('search-box');
|
const searchBox = document.getElementById('search-box');
|
||||||
|
|
||||||
const typeahead = fromEvent(searchBox, 'input').pipe(
|
const typeahead = fromEvent(searchBox, 'input').pipe(
|
||||||
map((e: KeyboardEvent) => e.target.value),
|
map((e: KeyboardEvent) => (e.target as HTMLInputElement).value),
|
||||||
filter(text => text.length > 2),
|
filter(text => text.length > 2),
|
||||||
debounceTime(10),
|
debounceTime(10),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
<div formArrayName="aliases">
|
<div formArrayName="aliases">
|
||||||
<h3>Aliases</h3> <button (click)="addAlias()">Add Alias</button>
|
<h3>Aliases</h3> <button (click)="addAlias()">Add Alias</button>
|
||||||
|
|
||||||
<div *ngFor="let address of aliases.controls; let i=index">
|
<div *ngFor="let alias of aliases.controls; let i=index">
|
||||||
<!-- The repeated alias template -->
|
<!-- The repeated alias template -->
|
||||||
<label>
|
<label>
|
||||||
Alias:
|
Alias:
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
|
// #docplaster
|
||||||
// #docregion
|
// #docregion
|
||||||
|
// #docregion remove-heroes
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
|
// #enddocregion remove-heroes
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
|
// #docregion remove-heroes
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { HeroesModule } from './heroes/heroes.module';
|
import { HeroesModule } from './heroes/heroes.module';
|
||||||
@ -14,6 +19,13 @@ import { PageNotFoundComponent } from './page-not-found/page-not-found.component
|
|||||||
// #docregion module-imports
|
// #docregion module-imports
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
// #enddocregion module-imports
|
||||||
|
// #enddocregion remove-heroes
|
||||||
|
// #docregion animation-import
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
// #enddocregion animation-import
|
||||||
|
// #docregion remove-heroes
|
||||||
|
// #docregion module-imports
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HeroesModule,
|
HeroesModule,
|
||||||
AppRoutingModule
|
AppRoutingModule
|
||||||
@ -27,6 +39,7 @@ import { PageNotFoundComponent } from './page-not-found/page-not-found.component
|
|||||||
bootstrap: [ AppComponent ]
|
bootstrap: [ AppComponent ]
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
|
// #enddocregion remove-heroes
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
9
aio/content/examples/rx-library/e2e/src/app.e2e-spec.ts
Normal file
9
aio/content/examples/rx-library/e2e/src/app.e2e-spec.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* This example project is special in that it is not a cli app. To run tests appropriate for this
|
||||||
|
* project, the test command is overwritten in `aio/content/examples/rx-libary/example-config.json`.
|
||||||
|
*
|
||||||
|
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.js` runs
|
||||||
|
* tests for this project.
|
||||||
|
*
|
||||||
|
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
|
||||||
|
*/
|
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"e2e": [
|
||||||
|
{
|
||||||
|
"cmd": "yarn",
|
||||||
|
"args": [ "tsc", "--project", "./" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
emotion?: string;
|
emotion?: string;
|
||||||
|
@ -4,7 +4,7 @@ import { Component, NgModule, OnInit } from '@angular/core';
|
|||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
class Hero {
|
interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
// #docregion example
|
// #docregion example
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
name: string;
|
name: string;
|
||||||
power: string;
|
power: string;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
// #docregion example
|
// #docregion example
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
name: string;
|
name: string;
|
||||||
power: string;
|
power: string;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,11 @@ import { Component, EventEmitter } from '@angular/core';
|
|||||||
'label'
|
'label'
|
||||||
],
|
],
|
||||||
outputs: [
|
outputs: [
|
||||||
'change'
|
'heroChange'
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class HeroButtonComponent {
|
export class HeroButtonComponent {
|
||||||
change = new EventEmitter<any>();
|
heroChange = new EventEmitter<any>();
|
||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
// #enddocregion example
|
// #enddocregion example
|
||||||
|
@ -7,7 +7,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|||||||
template: `<button>{{label}}</button>`
|
template: `<button>{{label}}</button>`
|
||||||
})
|
})
|
||||||
export class HeroButtonComponent {
|
export class HeroButtonComponent {
|
||||||
@Output() change = new EventEmitter<any>();
|
@Output() heroChange = new EventEmitter<any>();
|
||||||
@Input() label: string;
|
@Input() label: string;
|
||||||
}
|
}
|
||||||
// #enddocregion example
|
// #enddocregion example
|
||||||
|
@ -8,7 +8,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|||||||
})
|
})
|
||||||
export class HeroButtonComponent {
|
export class HeroButtonComponent {
|
||||||
// Pointless aliases
|
// Pointless aliases
|
||||||
@Output('changeEvent') change = new EventEmitter<any>();
|
@Output('heroChangeEvent') heroChange = new EventEmitter<any>();
|
||||||
@Input('labelAttribute') label: string;
|
@Input('labelAttribute') label: string;
|
||||||
}
|
}
|
||||||
// #enddocregion example
|
// #enddocregion example
|
||||||
|
@ -8,7 +8,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|||||||
})
|
})
|
||||||
export class HeroButtonComponent {
|
export class HeroButtonComponent {
|
||||||
// No aliases
|
// No aliases
|
||||||
@Output() change = new EventEmitter<any>();
|
@Output() heroChange = new EventEmitter<any>();
|
||||||
@Input() label: string;
|
@Input() label: string;
|
||||||
}
|
}
|
||||||
// #enddocregion example
|
// #enddocregion example
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import { delay } from 'rxjs/operators';
|
|||||||
|
|
||||||
////////// The App: Services and Components for the tests. //////////////
|
////////// The App: Services and Components for the tests. //////////////
|
||||||
|
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Hero {
|
export interface Hero {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ The following options are available for configuring the AoT template compiler.
|
|||||||
|
|
||||||
### `allowEmptyCodegenFiles`
|
### `allowEmptyCodegenFiles`
|
||||||
|
|
||||||
When true, generate all possible files even if they are empty. Default is false. Used by the Bazel build rules to simplify how Bazel rules track file dependencies. Do not use this option outside of the Bazel rules.
|
When `true`, generate all possible files even if they are empty. Default is `false`. Used by the Bazel build rules to simplify how Bazel rules track file dependencies. Do not use this option outside of the Bazel rules.
|
||||||
|
|
||||||
### `annotationsAs`
|
### `annotationsAs`
|
||||||
|
|
||||||
@ -64,40 +64,48 @@ Modifies how Angular-specific annotations are emitted to improve tree-shaking. N
|
|||||||
|
|
||||||
### `annotateForClosureCompiler`
|
### `annotateForClosureCompiler`
|
||||||
|
|
||||||
When true, use [Tsickle](https://github.com/angular/tsickle) to annotate the emitted JavaScript with [JSDoc](http://usejsdoc.org/) comments needed by the
|
When `true`, use [Tsickle](https://github.com/angular/tsickle) to annotate the emitted JavaScript with [JSDoc](http://usejsdoc.org/) comments needed by the
|
||||||
[Closure Compiler](https://github.com/google/closure-compiler). Default is false.
|
[Closure Compiler](https://github.com/google/closure-compiler). Default is `false`.
|
||||||
|
|
||||||
### `disableExpressionLowering`
|
### `disableExpressionLowering`
|
||||||
|
|
||||||
When true (the default), transforms code that is or could be used in an annotation, to allow it to be imported from template factory modules. See [metadata rewriting](guide/aot-compiler#metadata-rewriting) for more information.
|
When `true` (the default), transforms code that is or could be used in an annotation, to allow it to be imported from template factory modules. See [metadata rewriting](guide/aot-compiler#metadata-rewriting) for more information.
|
||||||
|
|
||||||
When `false`, disables this rewriting, requiring the rewriting to be done manually.
|
When `false`, disables this rewriting, requiring the rewriting to be done manually.
|
||||||
|
|
||||||
### `disableTypeScriptVersionCheck`
|
### `disableTypeScriptVersionCheck`
|
||||||
|
|
||||||
When `true`, the compiler does not check the TypeScript version and does not report an error when an unsupported version of TypeScript is used. Not recommended, as unsupported versions of TypeScript might have undefined behavior. Default is false.
|
When `true`, the compiler does not check the TypeScript version and does not report an error when an unsupported version of TypeScript is used. Not recommended, as unsupported versions of TypeScript might have undefined behavior. Default is `false`.
|
||||||
|
|
||||||
|
### `enableIvy`
|
||||||
|
|
||||||
|
Enables the [Ivy](guide/ivy) compilation and rendering pipeline. Default is `true`, as of version 9. In version 9, you can [opt out of Ivy](guide/ivy#opting-out-of-angular-ivy) to continue using the previous compiler, View Engine.
|
||||||
|
|
||||||
|
For library projects generated with the CLI, the `prod` configuration default is `false` in version 9.
|
||||||
|
|
||||||
### `enableResourceInlining`
|
### `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` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
|
||||||
|
|
||||||
When enabled, the `.js` output of `ngc` does not include any lazy-loaded template or style URLs.
|
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 dev configuration default is `true`.
|
||||||
|
|
||||||
|
|
||||||
{@a enablelegacytemplate}
|
{@a enablelegacytemplate}
|
||||||
|
|
||||||
### `enableLegacyTemplate`
|
### `enableLegacyTemplate`
|
||||||
|
|
||||||
When true, enables use of the `<template>` element, which was deprecated in Angular 4.0, in favor of `<ng-template>` (to avoid colliding with the DOM's element of the same name). Default is false. Might be required by some third-party Angular libraries.
|
When `true`, enables use of the `<template>` element, which was deprecated in Angular 4.0, in favor of `<ng-template>` (to avoid colliding with the DOM's element of the same name). Default is `false`. Might be required by some third-party Angular libraries.
|
||||||
|
|
||||||
### `flatModuleId`
|
### `flatModuleId`
|
||||||
|
|
||||||
The module ID to use for importing a flat module (when `flatModuleOutFile` is true). References generated by the template compiler use this module name when importing symbols
|
The module ID to use for importing a flat module (when `flatModuleOutFile` is `true`). References generated by the template compiler use this module name when importing symbols
|
||||||
from the flat module. Ignored if `flatModuleOutFile` is false.
|
from the flat module. Ignored if `flatModuleOutFile` is `false`.
|
||||||
|
|
||||||
### `flatModuleOutFile`
|
### `flatModuleOutFile`
|
||||||
|
|
||||||
When true, generates a flat module index of the given file name 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
|
When `true`, generates a flat module index of the given file name 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.
|
to the generated flat module index instead of the library index file.
|
||||||
|
|
||||||
Produces only one `.metadata.json` file, which contains all the metadata necessary
|
Produces only one `.metadata.json` file, which contains all the metadata necessary
|
||||||
@ -112,31 +120,31 @@ If more than one `.ts` file is supplied without a `libraryIndex`, an error is pr
|
|||||||
A flat module index `.d.ts` and `.js` is created with the given `flatModuleOutFile` name in the same location as the library index `.d.ts` file.
|
A flat module index `.d.ts` and `.js` is created with the given `flatModuleOutFile` name in the same location as the library index `.d.ts` file.
|
||||||
|
|
||||||
For example, if a library uses the `public_api.ts` file as the library index of the module, the `tsconfig.json` `files` field would be `["public_api.ts"]`.
|
For example, if a library uses the `public_api.ts` file as the library index of the module, the `tsconfig.json` `files` field would be `["public_api.ts"]`.
|
||||||
The `flatModuleOutFile` options could then be set to (for example) `"index.js"`, which produces `index.d.ts` and `index.metadata.json` files.
|
The `flatModuleOutFile` option could then be set to (for example) `"index.js"`, which produces `index.d.ts` and `index.metadata.json` files.
|
||||||
The `module` field of the library's `package.json` would be `"index.js"` and the `typings` field
|
The `module` field of the library's `package.json` would be `"index.js"` and the `typings` field
|
||||||
would be `"index.d.ts"`.
|
would be `"index.d.ts"`.
|
||||||
|
|
||||||
### `fullTemplateTypeCheck`
|
### `fullTemplateTypeCheck`
|
||||||
|
|
||||||
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.
|
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 currently false.
|
Default is `false`, but when you use the CLI command `ng new`, it is set to `true` by default in the generated project's configuration.
|
||||||
|
|
||||||
### `generateCodeForLibraries`
|
### `generateCodeForLibraries`
|
||||||
|
|
||||||
When true (the default), generates factory files (`.ngfactory.js` and `.ngstyle.js`)
|
When `true` (the default), generates factory files (`.ngfactory.js` and `.ngstyle.js`)
|
||||||
for `.d.ts` files with a corresponding `.metadata.json` file.
|
for `.d.ts` files with a corresponding `.metadata.json` file.
|
||||||
|
|
||||||
When false, factory files are generated only for `.ts` files. Do this when using factory summaries.
|
When `false`, factory files are generated only for `.ts` files. Do this when using factory summaries.
|
||||||
|
|
||||||
|
|
||||||
### `preserveWhitespaces`
|
### `preserveWhitespaces`
|
||||||
|
|
||||||
When false (the default), removes blank text nodes from compiled templates, which results in smaller emitted template factory modules. Set to true to preserve blank text nodes.
|
When `false` (the default), removes blank text nodes from compiled templates, which results in smaller emitted template factory modules. Set to `true` to preserve blank text nodes.
|
||||||
|
|
||||||
### `skipMetadataEmit`
|
### `skipMetadataEmit`
|
||||||
|
|
||||||
When true, does not to produce `.metadata.json` files. Default is `false`.
|
When `true`, does not produce `.metadata.json` files. Default is `false`.
|
||||||
|
|
||||||
The `.metadata.json` files contain information needed by the template compiler from a `.ts`
|
The `.metadata.json` files contain information needed by the template compiler from a `.ts`
|
||||||
file that is not included in the `.d.ts` file produced by the TypeScript compiler.
|
file that is not included in the `.d.ts` file produced by the TypeScript compiler.
|
||||||
@ -150,14 +158,16 @@ are not valid for this style of TypeScript output. However, we do not recommend
|
|||||||
|
|
||||||
### `skipTemplateCodegen`
|
### `skipTemplateCodegen`
|
||||||
|
|
||||||
When true, does not emit `.ngfactory.js` and `.ngstyle.js` files. This turns off most of the template compiler and disables the reporting of template diagnostics.
|
When `true`, does not emit `.ngfactory.js` and `.ngstyle.js` files. This turns off most of the template compiler and disables the reporting of template diagnostics.
|
||||||
|
|
||||||
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`.
|
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 dev configuration default is `true`.
|
||||||
|
|
||||||
### `strictMetadataEmit`
|
### `strictMetadataEmit`
|
||||||
|
|
||||||
When true, reports an error to the `.metadata.json` file if `"skipMetadataEmit"` is `false`.
|
When `true`, reports an error to the `.metadata.json` file if `"skipMetadataEmit"` is `false`.
|
||||||
Default is false. Use only when `"skipMetadataEmit"` is false and `"skipTemplateCodeGen"` is true.
|
Default is `false`. Use only when `"skipMetadataEmit"` is `false` and `"skipTemplateCodeGen"` is `true`.
|
||||||
|
|
||||||
This option is intended to validate the `.metadata.json` files emitted for bundling with an `npm` package. The validation is strict and can emit errors for metadata that would never produce an error when used by the template compiler. You can choose to suppress the error emitted by this option for an exported symbol by including `@dynamic` in the comment documenting the symbol.
|
This option is intended to validate the `.metadata.json` files emitted for bundling with an `npm` package. The validation is strict and can emit errors for metadata that would never produce an error when used by the template compiler. You can choose to suppress the error emitted by this option for an exported symbol by including `@dynamic` in the comment documenting the symbol.
|
||||||
|
|
||||||
@ -170,10 +180,21 @@ If the client of a library intends to use a symbol in an annotation, the templat
|
|||||||
This option allows detection of these errors during the build phase of
|
This option allows detection of these errors during the build phase of
|
||||||
the library and is used, for example, in producing Angular libraries themselves.
|
the library and is used, for example, in producing Angular libraries themselves.
|
||||||
|
|
||||||
|
For library projects generated with the CLI, the dev configuration default is `true`.
|
||||||
|
|
||||||
### `strictInjectionParameters`
|
### `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 `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`, it is set to `true` by default in the generated project's configuration.
|
||||||
|
|
||||||
|
### `strictTemplates`
|
||||||
|
|
||||||
|
When `true`, enables [strict template type checking](guide/template-typecheck#strict-mode) in Angular version 9. Strict mode is only available when using [Ivy](guide/ivy).
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
|
||||||
### `trace`
|
### `trace`
|
||||||
|
|
||||||
When true, prints extra information while compiling templates. Default is false.
|
When `true`, prints extra information while compiling templates. Default is `false`.
|
||||||
|
@ -69,11 +69,9 @@ Let's animate a simple transition that changes a single HTML element from one st
|
|||||||
|
|
||||||
In HTML, these attributes are set using ordinary CSS styles such as color and opacity. In Angular, use the `style()` function to specify a set of CSS styles for use with animations. You can collect a set of styles in an animation state, and give the state a name, such as `open` or `closed`.
|
In HTML, these attributes are set using ordinary CSS styles such as color and opacity. In Angular, use the `style()` function to specify a set of CSS styles for use with animations. You can collect a set of styles in an animation state, and give the state a name, such as `open` or `closed`.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/animations/open-closed.png" alt="open and closed states">
|
||||||
<img src="generated/images/guide/animations/open-closed.png" alt="open and closed states">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
### Animation state and styles
|
### Animation state and styles
|
||||||
|
|
||||||
@ -168,11 +166,9 @@ The `trigger()` function describes the property name to watch for changes. When
|
|||||||
|
|
||||||
In this example, we'll name the trigger `openClose`, and attach it to the `button` element. The trigger describes the open and closed states, and the timings for the two transitions.
|
In this example, we'll name the trigger `openClose`, and attach it to the `button` element. The trigger describes the open and closed states, and the timings for the two transitions.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/animations/triggering-the-animation.png" alt="triggering the animation">
|
||||||
<img src="generated/images/guide/animations/triggering-the-animation.png" alt="triggering the animation">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
|
@ -51,11 +51,9 @@ You define a component's view with its companion template. A template is a form
|
|||||||
|
|
||||||
Views are typically arranged hierarchically, allowing you to modify or show and hide entire UI sections or pages as a unit. The template immediately associated with a component defines that component's *host view*. The component can also define a *view hierarchy*, which contains *embedded views*, hosted by other components.
|
Views are typically arranged hierarchically, allowing you to modify or show and hide entire UI sections or pages as a unit. The template immediately associated with a component defines that component's *host view*. The component can also define a *view hierarchy*, which contains *embedded views*, hosted by other components.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/architecture/component-tree.png" alt="Component tree" class="left">
|
||||||
<img src="generated/images/guide/architecture/component-tree.png" alt="Component tree" class="left">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
A view hierarchy can include views from components in the same NgModule, but it also can (and often does) include views from components that are defined in different NgModules.
|
A view hierarchy can include views from components in the same NgModule, but it also can (and often does) include views from components that are defined in different NgModules.
|
||||||
|
|
||||||
@ -83,11 +81,9 @@ Angular supports *two-way data binding*, a mechanism for coordinating the parts
|
|||||||
|
|
||||||
The following diagram shows the four forms of data binding markup. Each form has a direction: to the DOM, from the DOM, or both.
|
The following diagram shows the four forms of data binding markup. Each form has a direction: to the DOM, from the DOM, or both.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/architecture/databinding.png" alt="Data Binding" class="left">
|
||||||
<img src="generated/images/guide/architecture/databinding.png" alt="Data Binding" class="left">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
This example from the `HeroListComponent` template uses three of these forms.
|
This example from the `HeroListComponent` template uses three of these forms.
|
||||||
|
|
||||||
@ -114,19 +110,15 @@ as with event binding.
|
|||||||
Angular processes *all* data bindings once for each JavaScript event cycle,
|
Angular processes *all* data bindings once for each JavaScript event cycle,
|
||||||
from the root of the application component tree through all child components.
|
from the root of the application component tree through all child components.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/architecture/component-databinding.png" alt="Data Binding" class="left">
|
||||||
<img src="generated/images/guide/architecture/component-databinding.png" alt="Data Binding" class="left">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
Data binding plays an important role in communication between a template and its component, and is also important for communication between parent and child components.
|
Data binding plays an important role in communication between a template and its component, and is also important for communication between parent and child components.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/architecture/parent-child-binding.png" alt="Parent/Child binding" class="left">
|
||||||
<img src="generated/images/guide/architecture/parent-child-binding.png" alt="Parent/Child binding" class="left">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
### Pipes
|
### Pipes
|
||||||
|
|
||||||
|
@ -35,21 +35,17 @@ Here's a simple root NgModule definition.
|
|||||||
|
|
||||||
NgModules provide a *compilation context* for their components. A root NgModule always has a root component that is created during bootstrap, but any NgModule can include any number of additional components, which can be loaded through the router or created through the template. The components that belong to an NgModule share a compilation context.
|
NgModules provide a *compilation context* for their components. A root NgModule always has a root component that is created during bootstrap, but any NgModule can include any number of additional components, which can be loaded through the router or created through the template. The components that belong to an NgModule share a compilation context.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/architecture/compilation-context.png" alt="Component compilation context" class="left">
|
||||||
<img src="generated/images/guide/architecture/compilation-context.png" alt="Component compilation context" class="left">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<br class="clear">
|
<br class="clear">
|
||||||
|
|
||||||
A component and its template together define a *view*. A component can contain a *view hierarchy*, which allows you to define arbitrarily complex areas of the screen that can be created, modified, and destroyed as a unit. A view hierarchy can mix views defined in components that belong to different NgModules. This is often the case, especially for UI libraries.
|
A component and its template together define a *view*. A component can contain a *view hierarchy*, which allows you to define arbitrarily complex areas of the screen that can be created, modified, and destroyed as a unit. A view hierarchy can mix views defined in components that belong to different NgModules. This is often the case, especially for UI libraries.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/architecture/view-hierarchy.png" alt="View hierarchy" class="left">
|
||||||
<img src="generated/images/guide/architecture/view-hierarchy.png" alt="View hierarchy" class="left">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<br class="clear">
|
<br class="clear">
|
||||||
|
|
||||||
|
@ -70,11 +70,9 @@ When all requested services have been resolved and returned, Angular can call th
|
|||||||
|
|
||||||
The process of `HeroService` injection looks something like this.
|
The process of `HeroService` injection looks something like this.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/architecture/injector-injects.png" alt="Service" class="left">
|
||||||
<img src="generated/images/guide/architecture/injector-injects.png" alt="Service" class="left">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
### Providing services
|
### Providing services
|
||||||
|
|
||||||
|
@ -113,11 +113,9 @@ To define navigation rules, you associate *navigation paths* with your component
|
|||||||
|
|
||||||
You've learned the basics about the main building blocks of an Angular application. The following diagram shows how these basic pieces are related.
|
You've learned the basics about the main building blocks of an Angular application. The following diagram shows how these basic pieces are related.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/architecture/overview2.png" alt="overview">
|
||||||
<img src="generated/images/guide/architecture/overview2.png" alt="overview">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
* Together, a component and template define an Angular view.
|
* Together, a component and template define an Angular view.
|
||||||
* A decorator on a component class adds the metadata, including a pointer to the associated template.
|
* A decorator on a component class adds the metadata, including a pointer to the associated template.
|
||||||
|
@ -175,11 +175,9 @@ Here's the updated directive in full:
|
|||||||
Run the app and confirm that the background color appears when
|
Run the app and confirm that the background color appears when
|
||||||
the mouse hovers over the `p` and disappears as it moves out.
|
the mouse hovers over the `p` and disappears as it moves out.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/attribute-directives/highlight-directive-anim.gif" alt="Second Highlight">
|
||||||
<img src="generated/images/guide/attribute-directives/highlight-directive-anim.gif" alt="Second Highlight">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
{@a bindings}
|
{@a bindings}
|
||||||
|
|
||||||
@ -273,11 +271,9 @@ Revise the `AppComponent.color` so that it has no initial value.
|
|||||||
|
|
||||||
Here are the harness and directive in action.
|
Here are the harness and directive in action.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/attribute-directives/highlight-directive-v2-anim.gif" alt="Highlight v.2">
|
||||||
<img src="generated/images/guide/attribute-directives/highlight-directive-v2-anim.gif" alt="Highlight v.2">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
{@a second-property}
|
{@a second-property}
|
||||||
|
|
||||||
@ -311,11 +307,9 @@ because you made it _public_ with the `@Input` decorator.
|
|||||||
|
|
||||||
Here's how the harness should work when you're done coding.
|
Here's how the harness should work when you're done coding.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight">
|
||||||
<img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
|
@ -50,11 +50,9 @@ and each iteration's `hero` instance to the child's `hero` property.
|
|||||||
The running application displays three heroes:
|
The running application displays three heroes:
|
||||||
|
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/component-interaction/parent-to-child.png" alt="Parent-to-child">
|
||||||
<img src="generated/images/guide/component-interaction/parent-to-child.png" alt="Parent-to-child">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -96,11 +94,9 @@ Here's the `NameParentComponent` demonstrating name variations including a name
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/component-interaction/setter.png" alt="Parent-to-child-setter">
|
||||||
<img src="generated/images/guide/component-interaction/setter.png" alt="Parent-to-child-setter">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -156,11 +152,9 @@ The `VersionParentComponent` supplies the `minor` and `major` values and binds b
|
|||||||
Here's the output of a button-pushing sequence:
|
Here's the output of a button-pushing sequence:
|
||||||
|
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/component-interaction/parent-to-child-on-changes.gif" alt="Parent-to-child-onchanges">
|
||||||
<img src="generated/images/guide/component-interaction/parent-to-child-on-changes.gif" alt="Parent-to-child-onchanges">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -212,11 +206,9 @@ The framework passes the event argument—represented by `$event`—to t
|
|||||||
and the method processes it:
|
and the method processes it:
|
||||||
|
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/component-interaction/child-to-parent.gif" alt="Child-to-parent">
|
||||||
<img src="generated/images/guide/component-interaction/child-to-parent.gif" alt="Child-to-parent">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -276,11 +268,9 @@ uses interpolation to display the child's `seconds` property.
|
|||||||
Here we see the parent and child working together.
|
Here we see the parent and child working together.
|
||||||
|
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/component-interaction/countdown-timer-anim.gif" alt="countdown timer">
|
||||||
<img src="generated/images/guide/component-interaction/countdown-timer-anim.gif" alt="countdown timer">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -431,11 +421,9 @@ the parent `MissionControlComponent` and the `AstronautComponent` children,
|
|||||||
facilitated by the service:
|
facilitated by the service:
|
||||||
|
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/component-interaction/bidirectional-service.gif" alt="bidirectional-service">
|
||||||
<img src="generated/images/guide/component-interaction/bidirectional-service.gif" alt="bidirectional-service">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,11 +109,10 @@ To learn more, see [Schematics Overview](guide/schematics) and [Schematics for
|
|||||||
|
|
||||||
## Publishing your library
|
## Publishing your library
|
||||||
|
|
||||||
Use the Angular CLI and the npm package manager to build and publish your library as an npm package.
|
Use the Angular CLI and the npm package manager to build and publish your library as an npm package. It is not recommended to publish Ivy libraries to NPM repositories. Before publishing a library to NPM, build it using the `--prod` flag which will use the older compiler and runtime known as View Engine instead of Ivy.
|
||||||
Libraries are built in [AoT mode](guide/aot-compiler) by default, so you do not need to specify the `-prod` flag when building for publication.
|
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng build my-lib
|
ng build my-lib --prod
|
||||||
cd dist/my-lib
|
cd dist/my-lib
|
||||||
npm publish
|
npm publish
|
||||||
</code-example>
|
</code-example>
|
||||||
|
@ -40,11 +40,9 @@ and the framework resolves the nested dependencies.
|
|||||||
|
|
||||||
When all dependencies are in place, `AppComponent` displays the user information.
|
When all dependencies are in place, `AppComponent` displays the user information.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/logged-in-user.png" alt="Logged In User">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/logged-in-user.png" alt="Logged In User">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
{@a service-scope}
|
{@a service-scope}
|
||||||
|
|
||||||
@ -133,11 +131,9 @@ The template displays this data-bound property.
|
|||||||
Find this example in <live-example name="dependency-injection-in-action">live code</live-example>
|
Find this example in <live-example name="dependency-injection-in-action">live code</live-example>
|
||||||
and confirm that the three `HeroBioComponent` instances have their own cached hero data.
|
and confirm that the three `HeroBioComponent` instances have their own cached hero data.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/hero-bios.png" alt="Bios">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bios.png" alt="Bios">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
{@a qualify-dependency-lookup}
|
{@a qualify-dependency-lookup}
|
||||||
|
|
||||||
@ -195,11 +191,9 @@ placing it in the `<ng-content>` slot of the `HeroBioComponent` template.
|
|||||||
|
|
||||||
The result is shown below, with the hero's telephone number from `HeroContactComponent` projected above the hero description.
|
The result is shown below, with the hero's telephone number from `HeroContactComponent` projected above the hero description.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/hero-bio-and-content.png" alt="bio and contact">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bio-and-content.png" alt="bio and contact">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
Here's `HeroContactComponent`, which demonstrates the qualifying decorators.
|
Here's `HeroContactComponent`, which demonstrates the qualifying decorators.
|
||||||
@ -227,11 +221,9 @@ When the property is marked as optional, Angular sets `loggerService` to null an
|
|||||||
|
|
||||||
Here's `HeroBiosAndContactsComponent` in action.
|
Here's `HeroBiosAndContactsComponent` in action.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/hero-bios-and-contacts.png" alt="Bios with contact into">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bios-and-contacts.png" alt="Bios with contact into">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -240,11 +232,9 @@ until it finds the logger at the `AppComponent` level.
|
|||||||
The logger logic kicks in and the hero display updates
|
The logger logic kicks in and the hero display updates
|
||||||
with the "!!!" marker to indicate that the logger was found.
|
with the "!!!" marker to indicate that the logger was found.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/hero-bio-contact-no-host.png" alt="Without @Host">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bio-contact-no-host.png" alt="Without @Host">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
If you restore the `@Host()` decorator and comment out `@Optional`,
|
If you restore the `@Host()` decorator and comment out `@Optional`,
|
||||||
@ -304,11 +294,9 @@ first without a value (yielding the default color) and then with an assigned col
|
|||||||
|
|
||||||
The following image shows the effect of mousing over the `<hero-bios-and-contacts>` tag.
|
The following image shows the effect of mousing over the `<hero-bios-and-contacts>` tag.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/highlight.png" alt="Highlighted bios">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/highlight.png" alt="Highlighted bios">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
{@a providers}
|
{@a providers}
|
||||||
|
|
||||||
@ -359,11 +347,9 @@ You learned about some other methods in [Dependency Providers](guide/dependency-
|
|||||||
The following `HeroOfTheMonthComponent` example demonstrates many of the alternatives and why you need them.
|
The following `HeroOfTheMonthComponent` example demonstrates many of the alternatives and why you need them.
|
||||||
It's visually simple: a few properties and the logs produced by a logger.
|
It's visually simple: a few properties and the logs produced by a logger.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/hero-of-month.png" alt="Hero of the month">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/hero-of-month.png" alt="Hero of the month">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The code behind it customizes how and where the DI framework provides dependencies.
|
The code behind it customizes how and where the DI framework provides dependencies.
|
||||||
The use cases illustrate different ways to use the [*provide* object literal](guide/dependency-injection-providers#provide) to associate a definition object with a DI token.
|
The use cases illustrate different ways to use the [*provide* object literal](guide/dependency-injection-providers#provide) to associate a definition object with a DI token.
|
||||||
@ -474,11 +460,9 @@ The following example puts `MinimalLogger` to use in a simplified version of `He
|
|||||||
|
|
||||||
The `HeroOfTheMonthComponent` constructor's `logger` parameter is typed as `MinimalLogger`, so only the `logs` and `logInfo` members are visible in a TypeScript-aware editor.
|
The `HeroOfTheMonthComponent` constructor's `logger` parameter is typed as `MinimalLogger`, so only the `logs` and `logInfo` members are visible in a TypeScript-aware editor.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/minimal-logger-intellisense.png" alt="MinimalLogger restricted API">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/minimal-logger-intellisense.png" alt="MinimalLogger restricted API">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
Behind the scenes, Angular sets the `logger` parameter to the full service registered under the `LoggingService` token, which happens to be the `DateLoggerService` instance that was [provided above](guide/dependency-injection-in-action#useclass).
|
Behind the scenes, Angular sets the `logger` parameter to the full service registered under the `LoggingService` token, which happens to be the `DateLoggerService` instance that was [provided above](guide/dependency-injection-in-action#useclass).
|
||||||
@ -488,11 +472,9 @@ Behind the scenes, Angular sets the `logger` parameter to the full service regis
|
|||||||
|
|
||||||
This is illustrated in the following image, which displays the logging date.
|
This is illustrated in the following image, which displays the logging date.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/date-logger-entry.png" alt="DateLoggerService entry">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/date-logger-entry.png" alt="DateLoggerService entry">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -645,11 +627,9 @@ and then pass them down to the base class through the constructor.
|
|||||||
In this contrived example, `SortedHeroesComponent` inherits from `HeroesBaseComponent`
|
In this contrived example, `SortedHeroesComponent` inherits from `HeroesBaseComponent`
|
||||||
to display a *sorted* list of heroes.
|
to display a *sorted* list of heroes.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/sorted-heroes.png" alt="Sorted Heroes">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/sorted-heroes.png" alt="Sorted Heroes">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The `HeroesBaseComponent` can stand on its own.
|
The `HeroesBaseComponent` can stand on its own.
|
||||||
It demands its own instance of `HeroService` to get heroes
|
It demands its own instance of `HeroService` to get heroes
|
||||||
|
@ -145,11 +145,9 @@ the same way you've done it before.
|
|||||||
|
|
||||||
Here's *Alex* and family in action.
|
Here's *Alex* and family in action.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/alex.png" alt="Alex in action">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/alex.png" alt="Alex in action">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -203,13 +201,9 @@ which *is* what parent means.
|
|||||||
Here's *Alice*, *Barry*, and family in action.
|
Here's *Alice*, *Barry*, and family in action.
|
||||||
|
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection-in-action/alice.png" alt="Alice in action">
|
||||||
<img src="generated/images/guide/dependency-injection-in-action/alice.png" alt="Alice in action">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a parent-token}
|
{@a parent-token}
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ Check out [angular-cli-ghpages](https://github.com/angular-buch/angular-cli-ghpa
|
|||||||
|
|
||||||
## Server configuration
|
## Server configuration
|
||||||
|
|
||||||
This section covers changes you may have make to the server or to files deployed to the server.
|
This section covers changes you may have to make to the server or to files deployed on the server.
|
||||||
|
|
||||||
{@a fallback}
|
{@a fallback}
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ modified to serve `index.html`:
|
|||||||
http.ListenAndServe(":"+httpPort, nil)
|
http.ListenAndServe(":"+httpPort, nil)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
* [Ruby](https://www.ruby-lang.org/): create a Ruby server using ([sinatra](http://sinatrarb.com/)) with a basic Ruby file that configures the server `server.rb`:
|
* [Ruby](https://www.ruby-lang.org/): create a Ruby server using ([sinatra](http://sinatrarb.com/)) with a basic Ruby file that configures the server `server.rb`:
|
||||||
|
|
||||||
``` ruby
|
``` ruby
|
||||||
@ -434,11 +434,9 @@ showing exactly which classes are included in the bundle.
|
|||||||
|
|
||||||
Here's the output for the _main_ bundle of an example app called `cli-quickstart`.
|
Here's the output for the _main_ bundle of an example app called `cli-quickstart`.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/deployment/quickstart-sourcemap-explorer.png" alt="quickstart sourcemap explorer">
|
||||||
<img src="generated/images/guide/deployment/quickstart-sourcemap-explorer.png" alt="quickstart sourcemap explorer">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
{@a base-tag}
|
{@a base-tag}
|
||||||
|
|
||||||
@ -470,7 +468,7 @@ for the missing files. Look at where it _tried_ to find those files and adjust t
|
|||||||
|
|
||||||
## Differential Loading
|
## Differential Loading
|
||||||
|
|
||||||
When building web applications, making sure your application is compatible with the majority of browsers is a goal.
|
When building web applications, you want to make sure your application is compatible with the majority of browsers.
|
||||||
Even as JavaScript continues to evolve, with new features being introduced, not all browsers are updated with support for these new features at the same pace.
|
Even as JavaScript continues to evolve, with new features being introduced, not all browsers are updated with support for these new features at the same pace.
|
||||||
|
|
||||||
The code you write in development using TypeScript is compiled and bundled into ES2015, the JavaScript syntax that is compatible with most browsers.
|
The code you write in development using TypeScript is compiled and bundled into ES2015, the JavaScript syntax that is compatible with most browsers.
|
||||||
@ -481,42 +479,40 @@ To maximize compatibility, you could ship a single bundle that includes all your
|
|||||||
Users with modern browsers, however, shouldn't have to pay the price of increased bundle size that comes with polyfills they don't need.
|
Users with modern browsers, however, shouldn't have to pay the price of increased bundle size that comes with polyfills they don't need.
|
||||||
Differential loading, which is supported by default in Angular CLI version 8 and higher, solves this problem.
|
Differential loading, which is supported by default in Angular CLI version 8 and higher, solves this problem.
|
||||||
|
|
||||||
Differential loading is a strategy where the CLI builds two separate bundles as part of your deployed application.
|
Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled (which is the default) the CLI builds two separate bundles as part of your deployed application.
|
||||||
|
|
||||||
* The first bundle contains modern ES2015 syntax, takes advantage of built-in support in modern browsers, ships less polyfills, and results in a smaller bundle size.
|
* The first bundle contains modern ES2015 syntax, takes advantage of built-in support in modern browsers, ships fewer polyfills, and results in a smaller bundle size.
|
||||||
|
|
||||||
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This results in a larger bundle size, but supports older browsers.
|
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This results in a larger bundle size, but supports older browsers.
|
||||||
|
|
||||||
This strategy allows you to continue to build your web application to support multiple browsers, but only load the necessary code that the browser needs.
|
|
||||||
|
|
||||||
### Differential builds
|
### Differential builds
|
||||||
|
|
||||||
The Angular CLI handles differential loading for you as part of the _build_ process for deployment.
|
When you deploy using the Angular CLI build process, you can choose how and when to support differential loading.
|
||||||
The `ng build` command produces the necessary bundles used for differential loading, based on your browser support requirements and compilation target.
|
The [`ng build` CLI command](cli/build) queries the browser configuration and the configured build target to determine if support for legacy browsers is required, and whether the build should produce the necessary bundles used for differential loading.
|
||||||
|
|
||||||
The Angular CLI uses two configurations for differential loading:
|
The following configurations determine your requirements.
|
||||||
|
|
||||||
* Browsers list
|
* Browsers list
|
||||||
|
|
||||||
The `browserslist` configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options.
|
The `browserslist` configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options.
|
||||||
|
|
||||||
* TypeScript configuration
|
* TypeScript configuration
|
||||||
In the TypeScript configuration file, `tsconfig.json`, the `target` in the `compilerOptions` section determines the ECMAScript target version that the code is compiled to.
|
|
||||||
|
In the TypeScript configuration file, `tsconfig.json`, the "target" option in the `compilerOptions` section determines the ECMAScript target version that the code is compiled to.
|
||||||
Modern browsers support ES2015 natively, while ES5 is more commonly used to support legacy browsers.
|
Modern browsers support ES2015 natively, while ES5 is more commonly used to support legacy browsers.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Differential loading is currently only supported when using `es2015` as a compilation `target`. When used with targets higher than `es2015`, a warning is emitted during build time.
|
Differential loading is currently only supported when using `es2015` as a compilation target. When used with targets higher than `es2015`, the build process emits a warning.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
The CLI queries the Browserslist configuration, and checks the `target` to determine if support for legacy browsers is required.
|
For a development build, the output produced by `ng build` is simpler and easier to debug, allowing you to rely less on sourcemaps of compiled code.
|
||||||
The combination of these two configurations determines whether multiple bundles are produced when you create a _build_.
|
|
||||||
When you create a development build using [`ng build`](cli/build) and differential loading is enabled, the output produced is simpler and easier to debug, allowing you to rely less on sourcemaps of compiled code.
|
|
||||||
When you create a production build using [`ng build --prod`](cli/build), the CLI uses the defined configurations above to determine the bundles to build for deployment of your application.
|
|
||||||
|
|
||||||
The `index.html` file is also modified during the build process to include script tags that enable differential loading. See the sample output below from the `index.html` file produced during a build using `ng build`.
|
For a production build, your configuration determines which bundles are created for deployment of your application.
|
||||||
|
When needed, the `index.html` file is also modified during the build process to include script tags that enable differential loading, as shown in the following example.
|
||||||
|
|
||||||
<code-example language="html">
|
<code-example language="html" header="index.html">
|
||||||
<body>
|
<body>
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
<script src="runtime-es2015.js" type="module"></script>
|
<script src="runtime-es2015.js" type="module"></script>
|
||||||
@ -540,26 +536,22 @@ Each script tag has a `type="module"` or `nomodule` attribute. Browsers with nat
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
See the [configuration table](#configuration-table) below for the configurations for enabling differential loading.
|
|
||||||
|
|
||||||
### Configuring differential loading
|
### Configuring differential loading
|
||||||
|
|
||||||
Differential loading is supported by default with version 8 and later of the Angular CLI.
|
Differential loading is supported by default with version 8 and later of the Angular CLI.
|
||||||
For each application project in your workspace, you can configure how builds are produced based on the `browserslist` and `tsconfig.json` files in your application project.
|
For each application project in your workspace, you can configure how builds are produced based on the `browserslist` and `tsconfig.json` configuration files in your application project.
|
||||||
|
|
||||||
For a newly created Angular application, the default `browserslist` looks like this:
|
For a newly created Angular application, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015.
|
||||||
|
|
||||||
```
|
<code-example language="none" header="browserslist">
|
||||||
> 0.5%
|
> 0.5%
|
||||||
last 2 versions
|
last 2 versions
|
||||||
Firefox ESR
|
Firefox ESR
|
||||||
not dead
|
not dead
|
||||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
||||||
```
|
</code-example>
|
||||||
|
|
||||||
The `tsconfig.json` looks like this:
|
<code-example language="json" header="tsconfig.json">
|
||||||
|
|
||||||
<code-example language="json">
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
@ -586,33 +578,35 @@ The `tsconfig.json` looks like this:
|
|||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
By default, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015. As a result, this produces two builds, and differential loading is enabled. If you ignore browsers without ES2015 support, a single build is produced. To see the build result for differential loading based on different configurations, refer to the table below.
|
The default configuration creates two builds, with differential loading enabled.
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
To see which browsers are supported with the above configuration, see which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
|
To see which browsers are supported with the default configuration and determine which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
The `browserslist` configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced.
|
||||||
|
|
||||||
|
If your `browserslist` configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading.
|
||||||
|
|
||||||
{@a configuration-table }
|
{@a configuration-table }
|
||||||
|
|
||||||
| ES5 Browserslist Result | ES Target | Build Result |
|
| browserslist | ES target | Build result |
|
||||||
| -------- | -------- | -------- |
|
| -------- | -------- | -------- |
|
||||||
| disabled | es5 | Single build |
|
| ES5 support disabled | es2015 | Single build, ES5 not required |
|
||||||
| enabled | es5 | Single build w/Conditional Polyfills |
|
| ES5 support enabled | es5 | Single build w/conditional polyfills for ES5 only |
|
||||||
| disabled | es2015 | Single build |
|
| ES5 support enabled | es2015 | Differential loading (two builds w/conditional polyfills) |
|
||||||
| enabled | es2015 | Differential Loading (Two builds w/Conditional Polyfills |
|
|
||||||
|
|
||||||
When the ES5 Browserslist result is `disabled`, then ES5 browser support is not required. Otherwise, ES5 browser support is required.
|
|
||||||
|
|
||||||
### Opting out of differential loading
|
### Opting out of differential loading
|
||||||
|
|
||||||
Differential loading can be explicitly disabled if it causes unexpected issues or you need to target ES5 specifically for legacy browser support.
|
Differential loading can be explicitly disabled if it causes unexpected issues, or if you need to target ES5 specifically for legacy browser support.
|
||||||
|
|
||||||
To explicitly disable differential loading:
|
To explicitly disable differential loading and create an ES5 build:
|
||||||
|
|
||||||
- Enable the `dead` or `IE` browsers in the `browserslist` config file by removing the `not` keyword in front of them.
|
- Enable the `dead` or `IE` browsers in the `browserslist` configuration file by removing the `not` keyword in front of them.
|
||||||
- Set the `target` in the `compilerOptions` to `es5`.
|
- To create a single ES5 build, set the target in the `compilerOptions` to `es5`.
|
||||||
|
|
||||||
{@a test-and-serve}
|
{@a test-and-serve}
|
||||||
|
|
||||||
@ -669,7 +663,7 @@ In `angular.json` add two new configuration sections under the `build` and `serv
|
|||||||
...
|
...
|
||||||
},
|
},
|
||||||
"es5": {
|
"es5": {
|
||||||
"browserTarget": "<app-name>:build:es5"
|
"browserTarget": "<app-name>:build:es5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -741,7 +735,7 @@ Create an [ES5 serve configuration](guide/deployment#configuring-serve-for-es5)
|
|||||||
...
|
...
|
||||||
},
|
},
|
||||||
"es5": {
|
"es5": {
|
||||||
"devServerTarget": "<app-name>:serve:es5"
|
"devServerTarget": "<app-name>:serve:es5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -41,11 +41,6 @@ v9 - v12
|
|||||||
| `@angular/core` | [`ReflectiveKey`](#core) | <!--v8--> v10 |
|
| `@angular/core` | [`ReflectiveKey`](#core) | <!--v8--> v10 |
|
||||||
| `@angular/core` | [`RenderComponentType`](#core) | <!--v7--> v10 |
|
| `@angular/core` | [`RenderComponentType`](#core) | <!--v7--> v10 |
|
||||||
| `@angular/core` | [`ViewEncapsulation.Native`](#core) | <!--v6--> v10 |
|
| `@angular/core` | [`ViewEncapsulation.Native`](#core) | <!--v6--> v10 |
|
||||||
| `@angular/core` | [`WtfScopeFn`](api/core/WtfScopeFn) | <!--v8--> v10 |
|
|
||||||
| `@angular/core` | [`wtfCreateScope`](api/core/wtfCreateScope) | <!--v8--> v10 |
|
|
||||||
| `@angular/core` | [`wtfStartTimeRange`](api/core/wtfStartTimeRange) | <!--v8--> v10 |
|
|
||||||
| `@angular/core` | [`wtfEndTimeRange`](api/core/wtfEndTimeRange) | <!--v8--> v10 |
|
|
||||||
| `@angular/core` | [`wtfLeave`](api/core/wtfLeave) | <!--v8--> v10 |
|
|
||||||
| `@angular/core` | [`ModuleWithProviders` without a generic](#moduleWithProviders) | <!--v9--> v10 |
|
| `@angular/core` | [`ModuleWithProviders` without a generic](#moduleWithProviders) | <!--v9--> v10 |
|
||||||
| `@angular/forms` | [`ngModel` with reactive forms](#ngmodel-reactive) | <!--v6--> v10 |
|
| `@angular/forms` | [`ngModel` with reactive forms](#ngmodel-reactive) | <!--v6--> v10 |
|
||||||
| `@angular/router` | [`preserveQueryParams`](#router) | <!--v7--> v10 |
|
| `@angular/router` | [`preserveQueryParams`](#router) | <!--v7--> v10 |
|
||||||
@ -89,11 +84,6 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i
|
|||||||
| [`ReflectiveKey`](api/core/ReflectiveKey) | none | v5 | none |
|
| [`ReflectiveKey`](api/core/ReflectiveKey) | none | v5 | none |
|
||||||
| [`ViewEncapsulation.Native`](api/core/ViewEncapsulation#Native) | [`ViewEncapsulation.ShadowDom`](api/core/ViewEncapsulation#ShadowDom) | v6 | Use the native encapsulation mechanism of the renderer. See [view.ts](https://github.com/angular/angular/blob/3e992e18ebf51d6036818f26c3d77b52d3ec48eb/packages/core/src/metadata/view.ts#L32).
|
| [`ViewEncapsulation.Native`](api/core/ViewEncapsulation#Native) | [`ViewEncapsulation.ShadowDom`](api/core/ViewEncapsulation#ShadowDom) | v6 | Use the native encapsulation mechanism of the renderer. See [view.ts](https://github.com/angular/angular/blob/3e992e18ebf51d6036818f26c3d77b52d3ec48eb/packages/core/src/metadata/view.ts#L32).
|
||||||
| [`defineInjectable`](api/core/defineInjectable) | `ɵɵdefineInjectable` | v8 | Used only in generated code. No source code should depend on this API. |
|
| [`defineInjectable`](api/core/defineInjectable) | `ɵɵdefineInjectable` | v8 | Used only in generated code. No source code should depend on this API. |
|
||||||
| [`WtfScopeFn`](api/core/WtfScopeFn) | none | v8 | See [Web Tracing Framework](#wtf) |
|
|
||||||
| [`wtfCreateScope`](api/core/wtfCreateScope) | none | v8 | See [Web Tracing Framework](#wtf) |
|
|
||||||
| [`wtfStartTimeRange`](api/core/wtfStartTimeRange) | none | v8 | See [Web Tracing Framework](#wtf) |
|
|
||||||
| [`wtfEndTimeRange`](api/core/wtfEndTimeRange) | none | v8 | See [Web Tracing Framework](#wtf) |
|
|
||||||
| [`wtfLeave`](api/core/wtfLeave) | none | v8 | See [Web Tracing Framework](#wtf) |
|
|
||||||
| [`entryComponents`](api/core/NgModule#entryComponents) | none | v9 | See [`entryComponents`](#entryComponents) |
|
| [`entryComponents`](api/core/NgModule#entryComponents) | none | v9 | See [`entryComponents`](#entryComponents) |
|
||||||
| [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | none | v9 | See [`ANALYZE_FOR_ENTRY_COMPONENTS`](#entryComponents) |
|
| [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | none | v9 | See [`ANALYZE_FOR_ENTRY_COMPONENTS`](#entryComponents) |
|
||||||
| `ModuleWithProviders` without a generic | `ModuleWithProviders` with a generic | v9 | See [`ModuleWithProviders` section](#moduleWithProviders) |
|
| `ModuleWithProviders` without a generic | `ModuleWithProviders` with a generic | v9 | See [`ModuleWithProviders` section](#moduleWithProviders) |
|
||||||
@ -166,7 +156,7 @@ This section lists all of the currently-deprecated features, which includes temp
|
|||||||
{@a wtf}
|
{@a wtf}
|
||||||
### Web Tracing Framework integration
|
### Web Tracing Framework integration
|
||||||
|
|
||||||
Angular previously has supported an integration with the Web Tracing Framework (WTF) for performance testing of Angular applications. This integration has not been maintained and likely does not work for the majority of Angular applications today. As a result, we are deprecating the integration in Angular version 8.
|
Angular previously has supported an integration with the [Web Tracing Framework (WTF)](https://google.github.io/tracing-framework/) for performance testing of Angular applications. This integration has not been maintained and defunct. As a result, the integration was deprecated in Angular version 8 and due to no evidence of any existing usage removed in version 9.
|
||||||
|
|
||||||
|
|
||||||
{@a deep-component-style-selector}
|
{@a deep-component-style-selector}
|
||||||
@ -454,6 +444,11 @@ The following APIs have been removed starting with version 9.0.0*:
|
|||||||
| `@angular/core` | [`Renderer`](https://v8.angular.io/api/core/Renderer) | [`Renderer2`](https://angular.io/api/core/Renderer2) | [Migration guide](guide/migration-renderer) |
|
| `@angular/core` | [`Renderer`](https://v8.angular.io/api/core/Renderer) | [`Renderer2`](https://angular.io/api/core/Renderer2) | [Migration guide](guide/migration-renderer) |
|
||||||
| `@angular/core` | [`RootRenderer`](https://v8.angular.io/api/core/RootRenderer) | [`RendererFactory2`](https://angular.io/api/core/RendererFactory2) | none |
|
| `@angular/core` | [`RootRenderer`](https://v8.angular.io/api/core/RootRenderer) | [`RendererFactory2`](https://angular.io/api/core/RendererFactory2) | none |
|
||||||
| `@angular/core` | [`RenderComponentType`](https://v8.angular.io/api/core/RenderComponentType) | [`RendererType2`](https://angular.io/api/core/RendererType2) | none |
|
| `@angular/core` | [`RenderComponentType`](https://v8.angular.io/api/core/RenderComponentType) | [`RendererType2`](https://angular.io/api/core/RendererType2) | none |
|
||||||
|
| `@angular/core` | [`WtfScopeFn`](https://v8.angular.io/api/core/WtfScopeFn) | none | v8 | See [Web Tracing Framework](#wtf) |
|
||||||
|
| `@angular/core` | [`wtfCreateScope`](https://v8.angular.io/api/core/wtfCreateScope) | none | v8 | See [Web Tracing Framework](#wtf) |
|
||||||
|
| `@angular/core` | [`wtfStartTimeRange`](https://v8.angular.io/api/core/wtfStartTimeRange) | none | v8 | See [Web Tracing Framework](#wtf) |
|
||||||
|
| `@angular/core` | [`wtfEndTimeRange`](https://v8.angular.io/api/core/wtfEndTimeRange) | none | v8 | See [Web Tracing Framework](#wtf) |
|
||||||
|
| `@angular/core` | [`wtfLeave`](https://v8.angular.io/api/core/wtfLeave) | none | v8 | See [Web Tracing Framework](#wtf) |
|
||||||
| `@angular/common` | `DeprecatedI18NPipesModule` | [`CommonModule`](api/common/CommonModule#pipes) | none |
|
| `@angular/common` | `DeprecatedI18NPipesModule` | [`CommonModule`](api/common/CommonModule#pipes) | none |
|
||||||
| `@angular/common` | `DeprecatedCurrencyPipe` | [`CurrencyPipe`](api/common/CurrencyPipe) | none |
|
| `@angular/common` | `DeprecatedCurrencyPipe` | [`CurrencyPipe`](api/common/CurrencyPipe) | none |
|
||||||
| `@angular/common` | `DeprecatedDatePipe` | [`DatePipe`](api/common/DatePipe) | none |
|
| `@angular/common` | `DeprecatedDatePipe` | [`DatePipe`](api/common/DatePipe) | none |
|
||||||
|
@ -8,12 +8,9 @@ conditionally show a message below the list.
|
|||||||
|
|
||||||
The final UI looks like this:
|
The final UI looks like this:
|
||||||
|
|
||||||
|
<div class="lightbox">
|
||||||
<figure class="lightbox">
|
<img src="generated/images/guide/displaying-data/final.png" alt="Final UI">
|
||||||
<div class="card">
|
</div>
|
||||||
<img src="generated/images/guide/displaying-data/final.png" alt="Final UI">
|
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
@ -105,13 +102,9 @@ inside the `<app-root>` tag.
|
|||||||
|
|
||||||
Now run the app. It should display the title and hero name:
|
Now run the app. It should display the title and hero name:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/displaying-data/title-and-hero.png" alt="Title and Hero">
|
||||||
<img src="generated/images/guide/displaying-data/title-and-hero.png" alt="Title and Hero">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The next few sections review some of the coding choices in the app.
|
The next few sections review some of the coding choices in the app.
|
||||||
|
|
||||||
@ -215,14 +208,9 @@ repeat items for any [iterable](https://developer.mozilla.org/en-US/docs/Web/Jav
|
|||||||
|
|
||||||
Now the heroes appear in an unordered list.
|
Now the heroes appear in an unordered list.
|
||||||
|
|
||||||
|
<div class="lightbox">
|
||||||
<figure class="lightbox">
|
<img src="generated/images/guide/displaying-data/hero-names-list.png" alt="After ngfor">
|
||||||
<div class="card">
|
</div>
|
||||||
<img src="generated/images/guide/displaying-data/hero-names-list.png" alt="After ngfor">
|
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Creating a class for the data
|
## Creating a class for the data
|
||||||
|
@ -1244,19 +1244,20 @@ Images should be specified in an `<img>` tag.
|
|||||||
|
|
||||||
For accessibility, always set the `alt` attribute with a meaningful description of the image.
|
For accessibility, always set the `alt` attribute with a meaningful description of the image.
|
||||||
|
|
||||||
You should nest the `<img>` tag within a `<figure>` tag, which styles the image within a drop-shadow frame. You'll need the editor's permission to skip the `<figure>` tag.
|
You should nest the `<img>` tag within a `<div class="lightbox">` tag, which styles the image within a drop-shadow frame. You'll need the editor's permission to skip the `lightbox` class on its `div` encapsulation.
|
||||||
|
|
||||||
Here's a conforming example
|
Here's a conforming example
|
||||||
|
|
||||||
<figure>
|
<div class="lightbox">
|
||||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png" alt="flying hero">
|
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
||||||
</figure>
|
alt="flying hero">
|
||||||
|
</div>
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<figure>
|
<div class="lightbox">
|
||||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
||||||
alt="flying hero">
|
alt="flying hero">
|
||||||
</figure>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
_Note that the HTML image element does not have a closing tag._
|
_Note that the HTML image element does not have a closing tag._
|
||||||
@ -1267,17 +1268,19 @@ The doc generator reads the image dimensions from the file and adds width and he
|
|||||||
|
|
||||||
Here's the "flying hero" at a more reasonable scale.
|
Here's the "flying hero" at a more reasonable scale.
|
||||||
|
|
||||||
<figure>
|
<div class="lightbox">
|
||||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png" alt="flying Angular hero" width="200">
|
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
||||||
</figure>
|
alt="flying Angular hero"
|
||||||
|
width="200">
|
||||||
|
</div>
|
||||||
|
|
||||||
```html
|
```html
|
||||||
|
|
||||||
<figure>
|
<div class="lightbox">
|
||||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
||||||
alt="flying Angular hero"
|
alt="flying Angular hero"
|
||||||
width="200">
|
width="200">
|
||||||
</figure>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
Wide images can be a problem. Most browsers try to rescale the image but wide images may overflow the document in certain viewports.
|
Wide images can be a problem. Most browsers try to rescale the image but wide images may overflow the document in certain viewports.
|
||||||
@ -1285,9 +1288,9 @@ Wide images can be a problem. Most browsers try to rescale the image but wide im
|
|||||||
**Do not set a width greater than 700px**. If you wish to display a larger image, provide a link to the actual image that the user can click on to see the full size image separately as in this example of `source-map-explorer` output from the "Ahead-of-time Compilation" guide:
|
**Do not set a width greater than 700px**. If you wish to display a larger image, provide a link to the actual image that the user can click on to see the full size image separately as in this example of `source-map-explorer` output from the "Ahead-of-time Compilation" guide:
|
||||||
|
|
||||||
<a href="generated/images/guide/docs-style-guide/toh-pt6-bundle.png" title="Click to view larger image">
|
<a href="generated/images/guide/docs-style-guide/toh-pt6-bundle.png" title="Click to view larger image">
|
||||||
<figure>
|
<div class="lightbox">
|
||||||
<img src="generated/images/guide/docs-style-guide/toh-pt6-bundle-700w.png" alt="toh-pt6-bundle" width="300px">
|
<img src="generated/images/guide/docs-style-guide/toh-pt6-bundle-700w.png" alt="toh-pt6-bundle" width="300px">
|
||||||
</figure>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<h3 class="no-toc">Image compression</h3>
|
<h3 class="no-toc">Image compression</h3>
|
||||||
|
@ -183,12 +183,8 @@ Here are two sample components and the `AdComponent` interface for reference:
|
|||||||
## Final ad banner
|
## Final ad banner
|
||||||
The final ad banner looks like this:
|
The final ad banner looks like this:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dynamic-component-loader/ads-example.gif" alt="Ads">
|
||||||
<img src="generated/images/guide/dynamic-component-loader/ads-example.gif" alt="Ads">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
See the <live-example name="dynamic-component-loader"></live-example>.
|
See the <live-example name="dynamic-component-loader"></live-example>.
|
||||||
|
@ -197,12 +197,9 @@ Saving and retrieving the data is an exercise for another time.
|
|||||||
|
|
||||||
The final form looks like this:
|
The final form looks like this:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dynamic-form/dynamic-form.png" alt="Dynamic-Form">
|
||||||
<img src="generated/images/guide/dynamic-form/dynamic-form.png" alt="Dynamic-Form">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Back to top](guide/dynamic-form#top)
|
[Back to top](guide/dynamic-form#top)
|
||||||
|
@ -42,11 +42,9 @@ After you register your configured class with the browser's custom-element regis
|
|||||||
|
|
||||||
When your custom element is placed on a page, the browser creates an instance of the registered class and adds it to the DOM. The content is provided by the component's template, which uses Angular template syntax, and is rendered using the component and DOM data. Input properties in the component correspond to input attributes for the element.
|
When your custom element is placed on a page, the browser creates an instance of the registered class and adds it to the DOM. The content is provided by the component's template, which uses Angular template syntax, and is rendered using the component and DOM data. Input properties in the component correspond to input attributes for the element.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/elements/customElement1.png" alt="Custom element in browser" class="left">
|
||||||
<img src="generated/images/guide/elements/customElement1.png" alt="Custom element in browser" class="left">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<hr class="clear">
|
<hr class="clear">
|
||||||
|
|
||||||
@ -64,11 +62,9 @@ Use a JavaScript function, `customElements.define()`, to register the configure
|
|||||||
and its associated custom-element tag with the browser's `CustomElementRegistry`.
|
and its associated custom-element tag with the browser's `CustomElementRegistry`.
|
||||||
When the browser encounters the tag for the registered element, it uses the constructor to create a custom-element instance.
|
When the browser encounters the tag for the registered element, it uses the constructor to create a custom-element instance.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/elements/createElement.png" alt="Transform a component to a custom element" class="left">
|
||||||
<img src="generated/images/guide/elements/createElement.png" alt="Transform a component to a custom element" class="left">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
### Mapping
|
### Mapping
|
||||||
|
|
||||||
@ -107,7 +103,7 @@ The recently-developed [custom elements](https://developer.mozilla.org/en-US/doc
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Firefox</td>
|
<td>Firefox</td>
|
||||||
<td>Supported natively as of version 63. In older versions: Set the <code>dom.webcomponents.enabled</code> and <code>dom.webcomponents.customelements.enabled</code> preferences to true.</td>
|
<td>Supported natively.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Edge</td>
|
<td>Edge</td>
|
||||||
|
@ -102,12 +102,9 @@ Next, in the `AppComponent`, `app.component.html`, add the tag `<app-customer-da
|
|||||||
|
|
||||||
Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too:
|
Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too:
|
||||||
|
|
||||||
|
<div class="lightbox">
|
||||||
<figure class="lightbox">
|
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
|
||||||
<div class="card">
|
</div>
|
||||||
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
|
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ Project-specific [TypeScript](https://www.typescriptlang.org/) configuration fil
|
|||||||
| :--------------------- | :------------------------------------------|
|
| :--------------------- | :------------------------------------------|
|
||||||
| `browserslist` | Configures sharing of target browsers and Node.js versions among various front-end tools. See [Browserslist on GitHub](https://github.com/browserslist/browserslist) for more information. |
|
| `browserslist` | Configures sharing of target browsers and Node.js versions among various front-end tools. See [Browserslist on GitHub](https://github.com/browserslist/browserslist) for more information. |
|
||||||
| `karma.conf.js` | Application-specific [Karma](https://karma-runner.github.io/2.0/config/configuration-file.html) configuration. |
|
| `karma.conf.js` | Application-specific [Karma](https://karma-runner.github.io/2.0/config/configuration-file.html) configuration. |
|
||||||
| `tsconfig.app.json` | Application-specific [TypeScript](https://www.typescriptlang.org/) configuration, including TypeScript and Angular template compiler options. See [TypeScript Configuration](guide/typescript-configuration). |
|
| `tsconfig.app.json` | Application-specific [TypeScript](https://www.typescriptlang.org/) configuration, including TypeScript and Angular template compiler options. See [TypeScript Configuration](guide/typescript-configuration) and [Angular Compiler Options](guide/angular-compiler-options). |
|
||||||
| `tsconfig.spec.json` | [TypeScript](https://www.typescriptlang.org/) configuration for the application tests. See [TypeScript Configuration](guide/typescript-configuration). |
|
| `tsconfig.spec.json` | [TypeScript](https://www.typescriptlang.org/) configuration for the application tests. See [TypeScript Configuration](guide/typescript-configuration). |
|
||||||
| `tslint.json` | Application-specific [TSLint](https://palantir.github.io/tslint/) configuration. |
|
| `tslint.json` | Application-specific [TSLint](https://palantir.github.io/tslint/) configuration. |
|
||||||
|
|
||||||
|
@ -67,11 +67,9 @@ Here's a component with an input field for a single control implemented using re
|
|||||||
|
|
||||||
The source of truth provides the value and status of the form element at a given point in time. In reactive forms, the form model is the source of truth. In the example above, the form model is the `FormControl` instance.
|
The source of truth provides the value and status of the form element at a given point in time. In reactive forms, the form model is the source of truth. In the example above, the form model is the `FormControl` instance.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms-overview/key-diff-reactive-forms.png" alt="Reactive forms key differences">
|
||||||
<img src="generated/images/guide/forms-overview/key-diff-reactive-forms.png" alt="Reactive forms key differences">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
With reactive forms, the form model is explicitly defined in the component class. The reactive form directive (in this case, `FormControlDirective`) then links the existing `FormControl` instance to a specific form element in the view using a value accessor (`ControlValueAccessor` instance).
|
With reactive forms, the form model is explicitly defined in the component class. The reactive form directive (in this case, `FormControlDirective`) then links the existing `FormControl` instance to a specific form element in the view using a value accessor (`ControlValueAccessor` instance).
|
||||||
|
|
||||||
@ -84,11 +82,9 @@ Here's the same component with an input field for a single control implemented u
|
|||||||
|
|
||||||
In template-driven forms, the source of truth is the template.
|
In template-driven forms, the source of truth is the template.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms-overview/key-diff-td-forms.png" alt="Template-driven forms key differences">
|
||||||
<img src="generated/images/guide/forms-overview/key-diff-td-forms.png" alt="Template-driven forms key differences">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The abstraction of the form model promotes simplicity over structure. The template-driven form directive `NgModel` is responsible for creating and managing the `FormControl` instance for a given form element. It's less explicit, but you no longer have direct control over the form model.
|
The abstraction of the form model promotes simplicity over structure. The template-driven form directive `NgModel` is responsible for creating and managing the `FormControl` instance for a given form element. It's less explicit, but you no longer have direct control over the form model.
|
||||||
|
|
||||||
@ -102,11 +98,9 @@ When building forms in Angular, it's important to understand how the framework h
|
|||||||
|
|
||||||
As described above, in reactive forms each form element in the view is directly linked to a form model (`FormControl` instance). Updates from the view to the model and from the model to the view are synchronous and aren't dependent on the UI rendered. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
|
As described above, in reactive forms each form element in the view is directly linked to a form model (`FormControl` instance). Updates from the view to the model and from the model to the view are synchronous and aren't dependent on the UI rendered. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-vtm.png" alt="Reactive forms data flow - view to model" width="100%">
|
||||||
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-vtm.png" alt="Reactive forms data flow - view to model" width="100%">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The steps below outline the data flow from view to model.
|
The steps below outline the data flow from view to model.
|
||||||
|
|
||||||
@ -116,11 +110,9 @@ The steps below outline the data flow from view to model.
|
|||||||
1. The `FormControl` instance emits the new value through the `valueChanges` observable.
|
1. The `FormControl` instance emits the new value through the `valueChanges` observable.
|
||||||
1. Any subscribers to the `valueChanges` observable receive the new value.
|
1. Any subscribers to the `valueChanges` observable receive the new value.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-mtv.png" alt="Reactive forms data flow - model to view" width="100%">
|
||||||
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-mtv.png" alt="Reactive forms data flow - model to view" width="100%">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The steps below outline the data flow from model to view.
|
The steps below outline the data flow from model to view.
|
||||||
|
|
||||||
@ -133,11 +125,9 @@ The steps below outline the data flow from model to view.
|
|||||||
|
|
||||||
In template-driven forms, each form element is linked to a directive that manages the form model internally. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
|
In template-driven forms, each form element is linked to a directive that manages the form model internally. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms-overview/dataflow-td-forms-vtm.png" alt="Template-driven forms data flow - view to model" width="100%">
|
||||||
<img src="generated/images/guide/forms-overview/dataflow-td-forms-vtm.png" alt="Template-driven forms data flow - view to model" width="100%">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The steps below outline the data flow from view to model when the input value changes from *Red* to *Blue*.
|
The steps below outline the data flow from view to model when the input value changes from *Red* to *Blue*.
|
||||||
|
|
||||||
@ -150,11 +140,9 @@ The steps below outline the data flow from view to model when the input value ch
|
|||||||
1. Because the component template uses two-way data binding for the `favoriteColor` property, the `favoriteColor` property in the component
|
1. Because the component template uses two-way data binding for the `favoriteColor` property, the `favoriteColor` property in the component
|
||||||
is updated to the value emitted by the `ngModelChange` event (*Blue*).
|
is updated to the value emitted by the `ngModelChange` event (*Blue*).
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms-overview/dataflow-td-forms-mtv.png" alt="Template-driven forms data flow - model to view" width="100%">
|
||||||
<img src="generated/images/guide/forms-overview/dataflow-td-forms-mtv.png" alt="Template-driven forms data flow - model to view" width="100%">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The steps below outline the data flow from model to view when the `favoriteColor` changes from *Blue* to *Red*.
|
The steps below outline the data flow from model to view when the `favoriteColor` changes from *Blue* to *Red*.
|
||||||
|
|
||||||
|
@ -45,11 +45,9 @@ otherwise wrestle with yourself.
|
|||||||
|
|
||||||
You'll learn to build a template-driven form that looks like this:
|
You'll learn to build a template-driven form that looks like this:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms/hero-form-1.png" alt="Clean Form">
|
||||||
<img src="generated/images/guide/forms/hero-form-1.png" alt="Clean Form">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The *Hero Employment Agency* uses this form to maintain personal information about heroes.
|
The *Hero Employment Agency* uses this form to maintain personal information about heroes.
|
||||||
Every hero needs a job. It's the company mission to match the right hero with the right crisis.
|
Every hero needs a job. It's the company mission to match the right hero with the right crisis.
|
||||||
@ -58,11 +56,9 @@ Two of the three fields on this form are required. Required fields have a green
|
|||||||
|
|
||||||
If you delete the hero name, the form displays a validation error in an attention-grabbing style:
|
If you delete the hero name, the form displays a validation error in an attention-grabbing style:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms/hero-form-2.png" alt="Invalid, Name Required">
|
||||||
<img src="generated/images/guide/forms/hero-form-2.png" alt="Invalid, Name Required">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
Note that the *Submit* button is disabled, and the "required" bar to the left of the input control changes from green to red.
|
Note that the *Submit* button is disabled, and the "required" bar to the left of the input control changes from green to red.
|
||||||
|
|
||||||
@ -276,11 +272,9 @@ you display its name using the interpolation syntax.
|
|||||||
|
|
||||||
Running the app right now would be disappointing.
|
Running the app right now would be disappointing.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms/hero-form-3.png" alt="Early form with no binding">
|
||||||
<img src="generated/images/guide/forms/hero-form-3.png" alt="Early form with no binding">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
You don't see hero data because you're not binding to the `Hero` yet.
|
You don't see hero data because you're not binding to the `Hero` yet.
|
||||||
@ -341,11 +335,9 @@ adding and deleting characters, you'd see them appear and disappear
|
|||||||
from the interpolated text.
|
from the interpolated text.
|
||||||
At some point it might look like this:
|
At some point it might look like this:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms/ng-model-in-action.png" alt="ngModel in action">
|
||||||
<img src="generated/images/guide/forms/ng-model-in-action.png" alt="ngModel in action">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The diagnostic is evidence that values really are flowing from the input box to the model and
|
The diagnostic is evidence that values really are flowing from the input box to the model and
|
||||||
back again.
|
back again.
|
||||||
@ -391,11 +383,9 @@ After revision, the core of the form should look like this:
|
|||||||
|
|
||||||
If you run the app now and change every hero model property, the form might display like this:
|
If you run the app now and change every hero model property, the form might display like this:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms/ng-model-in-action-2.png" alt="ngModel in action">
|
||||||
<img src="generated/images/guide/forms/ng-model-in-action-2.png" alt="ngModel in action">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The diagnostic near the top of the form
|
The diagnostic near the top of the form
|
||||||
confirms that all of your changes are reflected in the model.
|
confirms that all of your changes are reflected in the model.
|
||||||
@ -493,19 +483,15 @@ Follow these steps *precisely*:
|
|||||||
|
|
||||||
The actions and effects are as follows:
|
The actions and effects are as follows:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms/control-state-transitions-anim.gif" alt="Control State Transition">
|
||||||
<img src="generated/images/guide/forms/control-state-transitions-anim.gif" alt="Control State Transition">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
You should see the following transitions and class names:
|
You should see the following transitions and class names:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms/ng-control-class-changes.png" alt="Control state transitions">
|
||||||
<img src="generated/images/guide/forms/ng-control-class-changes.png" alt="Control state transitions">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The `ng-valid`/`ng-invalid` pair is the most interesting, because you want to send a
|
The `ng-valid`/`ng-invalid` pair is the most interesting, because you want to send a
|
||||||
strong visual signal when the values are invalid. You also want to mark required fields.
|
strong visual signal when the values are invalid. You also want to mark required fields.
|
||||||
@ -518,11 +504,9 @@ To create such visual feedback, add definitions for the `ng-*` CSS classes.
|
|||||||
You can mark required fields and invalid data at the same time with a colored bar
|
You can mark required fields and invalid data at the same time with a colored bar
|
||||||
on the left of the input box:
|
on the left of the input box:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms/validity-required-indicator.png" alt="Invalid Form">
|
||||||
<img src="generated/images/guide/forms/validity-required-indicator.png" alt="Invalid Form">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
You achieve this effect by adding these class definitions to a new `forms.css` file
|
You achieve this effect by adding these class definitions to a new `forms.css` file
|
||||||
that you add to the project as a sibling to `index.html`:
|
that you add to the project as a sibling to `index.html`:
|
||||||
@ -541,11 +525,9 @@ Leverage the control's state to reveal a helpful message.
|
|||||||
|
|
||||||
When the user deletes the name, the form should look like this:
|
When the user deletes the name, the form should look like this:
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/forms/name-required-error.png" alt="Name required">
|
||||||
<img src="generated/images/guide/forms/name-required-error.png" alt="Name required">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
To achieve this effect, extend the `<input>` tag with the following:
|
To achieve this effect, extend the `<input>` tag with the following:
|
||||||
|
|
||||||
|
@ -111,11 +111,9 @@ directives in `CommonModule`; they don’t need to re-install app-wide providers
|
|||||||
If you do import `BrowserModule` into a lazy loaded feature module,
|
If you do import `BrowserModule` into a lazy loaded feature module,
|
||||||
Angular returns an error telling you to use `CommonModule` instead.
|
Angular returns an error telling you to use `CommonModule` instead.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/frequent-ngmodules/browser-module-error.gif" width=750 alt="BrowserModule error">
|
||||||
<img src="generated/images/guide/frequent-ngmodules/browser-module-error.gif" width=750 alt="BrowserModule error">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
@ -108,11 +108,9 @@ The following diagram represents the relationship between the
|
|||||||
`root` `ModuleInjector` and its parent injectors as the
|
`root` `ModuleInjector` and its parent injectors as the
|
||||||
previous paragraphs describe.
|
previous paragraphs describe.
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection/injectors.svg" alt="NullInjector, ModuleInjector, root injector">
|
||||||
<img src="generated/images/guide/dependency-injection/injectors.svg" alt="NullInjector, ModuleInjector, root injector">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
While the name `root` is a special alias, other `ModuleInjector`s
|
While the name `root` is a special alias, other `ModuleInjector`s
|
||||||
don't have aliases. You have the option to create `ModuleInjector`s
|
don't have aliases. You have the option to create `ModuleInjector`s
|
||||||
@ -245,7 +243,7 @@ By default, Angular always starts at the current `Injector` and keeps
|
|||||||
searching all the way up. Modifiers allow you to change the starting
|
searching all the way up. Modifiers allow you to change the starting
|
||||||
(self) or ending location.
|
(self) or ending location.
|
||||||
|
|
||||||
Additionally, you can combine all of the modifiers except `@Host()` and `@Self()` and of course `@Skipself()` and `@Self()`.
|
Additionally, you can combine all of the modifiers except `@Host()` and `@Self()` and of course `@SkipSelf()` and `@Self()`.
|
||||||
|
|
||||||
{@a optional}
|
{@a optional}
|
||||||
|
|
||||||
@ -1098,12 +1096,9 @@ Each tax return component has the following characteristics:
|
|||||||
* Can change a tax return without affecting a return in another component.
|
* Can change a tax return without affecting a return in another component.
|
||||||
* Has the ability to save the changes to its tax return or cancel them.
|
* Has the ability to save the changes to its tax return or cancel them.
|
||||||
|
|
||||||
|
<div class="lightbox">
|
||||||
<figure class="lightbox">
|
<img src="generated/images/guide/dependency-injection/hid-heroes-anim.gif" alt="Heroes in action">
|
||||||
<div class="card">
|
</div>
|
||||||
<img src="generated/images/guide/dependency-injection/hid-heroes-anim.gif" alt="Heroes in action">
|
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
Suppose that the `HeroTaxReturnComponent` had logic to manage and restore changes.
|
Suppose that the `HeroTaxReturnComponent` had logic to manage and restore changes.
|
||||||
That would be a pretty easy task for a simple hero tax return.
|
That would be a pretty easy task for a simple hero tax return.
|
||||||
@ -1172,11 +1167,9 @@ that have special capabilities suitable for whatever is going on in component (B
|
|||||||
Component (B) is the parent of another component (C) that defines its own, even _more specialized_ provider for `CarService`.
|
Component (B) is the parent of another component (C) that defines its own, even _more specialized_ provider for `CarService`.
|
||||||
|
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection/car-components.png" alt="car components">
|
||||||
<img src="generated/images/guide/dependency-injection/car-components.png" alt="car components">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
Behind the scenes, each component sets up its own injector with zero, one, or more providers defined for that component itself.
|
Behind the scenes, each component sets up its own injector with zero, one, or more providers defined for that component itself.
|
||||||
|
|
||||||
@ -1185,11 +1178,9 @@ its injector produces an instance of `Car` resolved by injector (C) with an `Eng
|
|||||||
`Tires` resolved by the root injector (A).
|
`Tires` resolved by the root injector (A).
|
||||||
|
|
||||||
|
|
||||||
<figure class="lightbox">
|
<div class="lightbox">
|
||||||
<div class="card">
|
<img src="generated/images/guide/dependency-injection/injector-tree.png" alt="car injector tree">
|
||||||
<img src="generated/images/guide/dependency-injection/injector-tree.png" alt="car injector tree">
|
</div>
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -170,7 +170,7 @@ As you can see, the response object has a `body` property of the correct type.
|
|||||||
|
|
||||||
### Making a JSONP request
|
### Making a JSONP request
|
||||||
|
|
||||||
Apps can use the the `HttpClient` to make [JSONP](https://en.wikipedia.org/wiki/JSONP) requests across domains when the server doesn't support [CORS protocol](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
|
Apps can use the `HttpClient` to make [JSONP](https://en.wikipedia.org/wiki/JSONP) requests across domains when the server doesn't support [CORS protocol](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
|
||||||
|
|
||||||
Angular JSONP requests return an `Observable`.
|
Angular JSONP requests return an `Observable`.
|
||||||
Follow the pattern for subscribing to observables and use the RxJS `map` operator to transform the response before using the [async pipe](api/common/AsyncPipe) to manage the results.
|
Follow the pattern for subscribing to observables and use the RxJS `map` operator to transform the response before using the [async pipe](api/common/AsyncPipe) to manage the results.
|
||||||
@ -951,7 +951,7 @@ by returning an observable of simulated events.
|
|||||||
|
|
||||||
## Security: XSRF protection
|
## Security: XSRF protection
|
||||||
|
|
||||||
[Cross-Site Request Forgery (XSRF)](https://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by which the attacker can trick an authenticated user into unknowingly executing actions on your website.
|
[Cross-Site Request Forgery (XSRF or CSRF)](https://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by which the attacker can trick an authenticated user into unknowingly executing actions on your website.
|
||||||
`HttpClient` supports a [common mechanism](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-Header_Token) used to prevent XSRF attacks.
|
`HttpClient` supports a [common mechanism](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-Header_Token) used to prevent XSRF attacks.
|
||||||
When performing HTTP requests, an interceptor reads a token from a cookie, by default `XSRF-TOKEN`, and sets it as an HTTP header, `X-XSRF-TOKEN`.
|
When performing HTTP requests, an interceptor reads a token from a cookie, by default `XSRF-TOKEN`, and sets it as an HTTP header, `X-XSRF-TOKEN`.
|
||||||
Since only code that runs on your domain could read the cookie, the backend can be certain that the HTTP request came from your client application and not an attacker.
|
Since only code that runs on your domain could read the cookie, the backend can be certain that the HTTP request came from your client application and not an attacker.
|
||||||
|
@ -25,6 +25,16 @@ After you have set up your app to use i18n, the CLI can help you with the follow
|
|||||||
* Building and serving the app for a given locale, using the translated text.
|
* Building and serving the app for a given locale, using the translated text.
|
||||||
* Creating multiple language versions of your app.
|
* Creating multiple language versions of your app.
|
||||||
|
|
||||||
|
{@a setting-up-cli}
|
||||||
|
## Setting up localization with the Angular CLI
|
||||||
|
|
||||||
|
The first step to setting up localization when using the Angular CLI is to add the `@angular/localize` package to the project. This will install the package within your project as well as
|
||||||
|
initialize the project to take advantage of Angular's localization features.
|
||||||
|
|
||||||
|
<code-example language="sh" class="code-shell">
|
||||||
|
ng add @angular/localize
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
{@a setting-up-locale}
|
{@a setting-up-locale}
|
||||||
## Setting up the locale of your app
|
## Setting up the locale of your app
|
||||||
@ -76,12 +86,12 @@ time of writing:
|
|||||||
## i18n pipes
|
## i18n pipes
|
||||||
|
|
||||||
Angular pipes can help you with internationalization: the `DatePipe`, `CurrencyPipe`, `DecimalPipe`
|
Angular pipes can help you with internationalization: the `DatePipe`, `CurrencyPipe`, `DecimalPipe`
|
||||||
and `PercentPipe` use locale data to format data based on the `LOCALE_ID`.
|
and `PercentPipe` use locale data to format data based on the `LOCALE_ID` dependency injection token.
|
||||||
|
|
||||||
By default, Angular only contains locale data for `en-US`. If you set the value of
|
By default, Angular only contains locale data for `en-US`.
|
||||||
`LOCALE_ID` to another locale, you must import locale data for that new locale.
|
The CLI automatically includes the locale data and sets the `LOCALE_ID` value for you when you use the
|
||||||
The CLI imports the locale data for you when you use the parameter `--configuration` with `ng serve` and
|
parameter `--i18nLocale` or option `i18nLocale` with `ng serve` and `ng build`.
|
||||||
`ng build`.
|
However, if you manually set the value of `LOCALE_ID` to another locale, you must import locale data for that new locale.
|
||||||
|
|
||||||
If you want to import locale data for other languages, you can do it manually:
|
If you want to import locale data for other languages, you can do it manually:
|
||||||
|
|
||||||
@ -98,6 +108,7 @@ locale id "fr-FR" instead of "fr".
|
|||||||
The files in `@angular/common/locales` contain most of the locale data that you
|
The files in `@angular/common/locales` contain most of the locale data that you
|
||||||
need, but some advanced formatting options might only be available in the extra dataset that you can
|
need, but some advanced formatting options might only be available in the extra dataset that you can
|
||||||
import from `@angular/common/locales/extra`. An error message informs you when this is the case.
|
import from `@angular/common/locales/extra`. An error message informs you when this is the case.
|
||||||
|
Ivy will automatically include the extra locale data if the locale was configured via `i18nLocale`.
|
||||||
|
|
||||||
<code-example path="i18n/doc-files/app.locale_data_extra.ts" region="import-locale-extra" header="src/app/app.module.ts"></code-example>
|
<code-example path="i18n/doc-files/app.locale_data_extra.ts" region="import-locale-extra" header="src/app/app.module.ts"></code-example>
|
||||||
|
|
||||||
@ -126,15 +137,12 @@ The i18n template translation process has four phases:
|
|||||||
|
|
||||||
3. Edit the generated translation file: Translate the extracted text into the target language.
|
3. Edit the generated translation file: Translate the extracted text into the target language.
|
||||||
|
|
||||||
4. Merge the completed translation file into the app. To do this, use the Angular CLI `build` command to compile the app, choosing a [locale-specific configuration](#merge-aot), or specifying the following command options.
|
4. Add the target locale and language translation to the application's configuration.
|
||||||
|
|
||||||
* `--i18nFile`=*path to the translation file*
|
5. Merge the completed translation file into the application. To do this, use the Angular CLI `build` command to compile the app, choosing a [locale-specific configuration](#merge), or specifying the `--localize` [option](#localize-config). The command replaces the original messages with translated text, and generates a new version of the app in the target language.
|
||||||
* `--i18nFormat`=*format of the translation file*
|
* When using individual configurations per locale, you need to build and deploy a separate version of the app for each supported language.
|
||||||
* `--i18nLocale`= *locale id*
|
* When using the `--localize` option, the CLI will automatically build a separate version of the application
|
||||||
|
for each supported language. This option shortens the build process by removing the requirement to perform a full application build for each supported language. You still need to deploy each language-specific version separately.
|
||||||
The command replaces the original messages with translated text, and generates a new version of the app in the target language.
|
|
||||||
|
|
||||||
You need to build and deploy a separate version of the app for each supported language.
|
|
||||||
|
|
||||||
{@a i18n-attribute}
|
{@a i18n-attribute}
|
||||||
### Mark text with the i18n attribute
|
### Mark text with the i18n attribute
|
||||||
@ -381,17 +389,6 @@ Open a terminal window at the root of the app project and run the CLI command `x
|
|||||||
|
|
||||||
By default, the command creates a file named `messages.xlf` in your project's root directory.
|
By default, the command creates a file named `messages.xlf` in your project's root directory.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
If you don't use the CLI, you have two options:
|
|
||||||
* You can use the `ng-xi18n` tool directly from the `@angular/compiler-cli` package.
|
|
||||||
For more information, see the [`ng xi18n` command documentation](cli/xi18n).
|
|
||||||
* You can use the CLI Webpack plugin `AngularCompilerPlugin` from the `@ngtools/webpack` package.
|
|
||||||
Set the parameters `i18nOutFile` and `i18nOutFormat` to trigger the extraction.
|
|
||||||
For more information, see the [Angular Ahead-of-Time Webpack Plugin documentation](https://github.com/angular/angular-cli/tree/master/packages/ngtools/webpack).
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{@a other-formats}
|
{@a other-formats}
|
||||||
### Output options
|
### Output options
|
||||||
|
|
||||||
@ -412,13 +409,13 @@ The command can read and write files in three translation formats:
|
|||||||
* <a href="http://cldr.unicode.org/development/development-process/design-proposals/xmb" >XML Message
|
* <a href="http://cldr.unicode.org/development/development-process/design-proposals/xmb" >XML Message
|
||||||
Bundle (XMB)</a>
|
Bundle (XMB)</a>
|
||||||
|
|
||||||
You can specify the translation format explicitly with the `--i18nFormat` command option, as illustrated in
|
You can specify the translation format explicitly with the `--format` command option, as illustrated in
|
||||||
these example commands:
|
these example commands:
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
ng xi18n --i18n-format=xlf
|
ng xi18n --format=xlf
|
||||||
ng xi18n --i18n-format=xlf2
|
ng xi18n --format=xlf2
|
||||||
ng xi18n --i18n-format=xmb
|
ng xi18n --format=xmb
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
The sample in this guide uses the default XLIFF 1.2 format.
|
The sample in this guide uses the default XLIFF 1.2 format.
|
||||||
@ -454,8 +451,7 @@ file. This information is not used by Angular, but external translation tools ma
|
|||||||
{@a translate}
|
{@a translate}
|
||||||
## Translate the source text
|
## Translate the source text
|
||||||
|
|
||||||
The `ng xi18n` command generates a translation source file named `messages.xlf` in the project `src`
|
By default, the `ng xi18n` command generates a translation source file named `messages.xlf` in the project `src` folder.
|
||||||
folder.
|
|
||||||
The next step is to translate the display strings in this source file into language-specific
|
The next step is to translate the display strings in this source file into language-specific
|
||||||
translation files. The example in this guide creates a French translation file.
|
translation files. The example in this guide creates a French translation file.
|
||||||
|
|
||||||
@ -619,53 +615,80 @@ The sample app and its translation file are now as follows:
|
|||||||
## Merge the completed translation file into the app
|
## Merge the completed translation file into the app
|
||||||
|
|
||||||
To merge the translated text into component templates, compile the app with the completed
|
To merge the translated text into component templates, compile the app with the completed
|
||||||
translation file.
|
translation file. You will need to provide the path to the translation file, and the supported locale or locales for which you have provided translations. You can do this on the command line, or through a build configuration in the project's `angular.json` file.
|
||||||
|
|
||||||
Provide the Angular compiler with three translation-specific pieces of information:
|
|
||||||
|
|
||||||
* The translation file.
|
|
||||||
* The translation file format.
|
|
||||||
* The locale (`fr` or `en-US` for instance).
|
|
||||||
|
|
||||||
The compilation process is the same whether the translation file is in `.xlf` format or in another
|
The compilation process is the same whether the translation file is in `.xlf` format or in another
|
||||||
format that Angular understands, such as `.xtb`.
|
format that Angular understands, such as `.xtb`.
|
||||||
|
|
||||||
How you provide this information depends upon whether you compile with
|
|
||||||
the JIT compiler or the AOT compiler.
|
|
||||||
|
|
||||||
* With [AOT](guide/i18n#merge-aot), you pass the information as configuration settings.
|
|
||||||
* With [JIT](guide/i18n#merge-jit), you provide the information at bootstrap time.
|
|
||||||
|
|
||||||
|
|
||||||
{@a merge-aot}
|
{@a merge-aot}
|
||||||
### Merge with the AOT compiler
|
|
||||||
|
|
||||||
The [AOT compiler](guide/glossary#aot) is part of a build process that produces a small, fast,
|
The [AOT compiler](guide/glossary#aot) is part of a build process that produces a small, fast,
|
||||||
ready-to-run application package, typically for production.
|
ready-to-run application package. With Ivy in Angular version 9, AOT is used by default for both
|
||||||
|
development and production builds.
|
||||||
|
|
||||||
When you internationalize with the AOT compiler, you must pre-build a separate application
|
<div class="alert is-important">
|
||||||
|
|
||||||
|
Ivy does not support merging i18n translations when using JIT mode.
|
||||||
|
If you [disable Ivy](guide/ivy#opting-out-of-ivy-in-version-9) and are using JIT mode,
|
||||||
|
additional information regarding translation merging can be found [here](https://v8.angular.io/guide/i18n#merge-with-the-jit-compiler).
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
When you internationalize with the AOT compiler, you must build a separate application
|
||||||
package for each language and serve the appropriate package based on either server-side language
|
package for each language and serve the appropriate package based on either server-side language
|
||||||
detection or URL parameters.
|
detection or URL parameters. The CLI can be configured to automatically build separate locale-specific versions
|
||||||
|
for each defined locale.
|
||||||
|
|
||||||
To instruct the AOT compiler to use your translation configuration, set the three "i18n" build configuration options in your CLI configuration file, `angular.json`.
|
{@a localize-config}
|
||||||
|
The `i18n` project option in your CLI configuration file is used to define locales for a project. The sub-options identify the source language and tell the compiler where to find supported translations for the project.
|
||||||
|
|
||||||
* `i18nFile`: the path to the translation file.
|
* `sourceLocale` - The locale used within the source code for the application. Defaults to `en-US`.
|
||||||
* `i18nFormat`: the format of the translation file.
|
* `locales` - A map of locale identifiers to translation files
|
||||||
* `i18nLocale`: the locale id.
|
|
||||||
|
|
||||||
You should also direct the output to a locale-specific folder to keep it separate from other locale versions of your app, by setting the `outputPath` configuration option.
|
<code-example language="json" header="angular.json">
|
||||||
|
"projects": {
|
||||||
|
...
|
||||||
|
"angular.io-example": {
|
||||||
|
...
|
||||||
|
"i18n": {
|
||||||
|
"sourceLocale": "en-US",
|
||||||
|
"locales": {
|
||||||
|
"fr": "src/locale/messages.fr.xlf"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
"targets": {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code-example>
|
||||||
|
|
||||||
```
|
To instruct the AOT compiler to use your translation configuration, set the `localize` build configuration option in your CLI configuration file, `angular.json`. The option supports the following values:
|
||||||
|
|
||||||
|
* `true` - Build and generate locale-specific versions for all defined locales including the source locale.
|
||||||
|
* `false` - (default) Disable localization and do not generate locale-specific versions.
|
||||||
|
* Array of locale identifiers - Build and generate locale-specific versions for one or more specified locales.
|
||||||
|
|
||||||
|
When using the `localize` option, the CLI places the output in a locale-specific directory to keep it separate from other locale versions of your application. The directories are placed within the configured `outputPath` for the project.
|
||||||
|
The CLI also adjusts the HTML base HREF for each version of the application by adding the locale to the configured `baseHref`.
|
||||||
|
|
||||||
|
You can also provide the `--localize` option to the `ng build` command with your existing `production` configuration.
|
||||||
|
In this case, the CLI builds all locales defined under i18n in the project configuration.
|
||||||
|
|
||||||
|
<code-example language="sh" class="code-shell">
|
||||||
|
ng build --prod --localize
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
To apply specific build options to only one locale, you can create a custom locale-specific configuration. In this case, the localize option specifies the single locale, as shown here.
|
||||||
|
|
||||||
|
<code-example language="json" header="angular.json">
|
||||||
"build": {
|
"build": {
|
||||||
...
|
...
|
||||||
"configurations": {
|
"configurations": {
|
||||||
...
|
...
|
||||||
"fr": {
|
"fr": {
|
||||||
"aot": true,
|
"localize": ["fr"],
|
||||||
"outputPath": "dist/my-project-fr/",
|
"main": "src/main.fr.ts",
|
||||||
"i18nFile": "src/locale/messages.fr.xlf",
|
|
||||||
"i18nFormat": "xlf",
|
|
||||||
"i18nLocale": "fr",
|
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -679,7 +702,7 @@ You should also direct the output to a locale-specific folder to keep it separat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
</code-example>
|
||||||
|
|
||||||
You can then pass this configuration to the `ng serve` or `ng build` commands.
|
You can then pass this configuration to the `ng serve` or `ng build` commands.
|
||||||
The example below shows how to serve the French language file created in previous
|
The example below shows how to serve the French language file created in previous
|
||||||
@ -689,10 +712,19 @@ sections of this guide:
|
|||||||
ng serve --configuration=fr
|
ng serve --configuration=fr
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
For production builds, you define a separate `production-fr` build configuration in
|
<div class="alert is-important">
|
||||||
the CLI configuration file, `angular.json`.
|
|
||||||
|
|
||||||
```
|
The CLI development server (`ng serve`) can only be used with a single locale.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
For production builds, you can use configuration composition to execute both configurations:
|
||||||
|
|
||||||
|
<code-example language="sh" class="code-shell">
|
||||||
|
ng build --configuration=production,fr
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
<code-example language="json" header="angular.json">
|
||||||
...
|
...
|
||||||
"architect": {
|
"architect": {
|
||||||
"build": {
|
"build": {
|
||||||
@ -700,12 +732,7 @@ the CLI configuration file, `angular.json`.
|
|||||||
"options": { ... },
|
"options": { ... },
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"fr": {
|
"fr": {
|
||||||
"aot": true,
|
"localize": ["fr"],
|
||||||
"outputPath": "dist/my-project-fr/",
|
|
||||||
"i18nFile": "src/locale/messages.fr.xlf",
|
|
||||||
"i18nFormat": "xlf",
|
|
||||||
"i18nLocale": "fr",
|
|
||||||
"i18nMissingTranslation": "error",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -725,42 +752,8 @@ the CLI configuration file, `angular.json`.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
The same configuration options can also be provided through the CLI with your existing `production` configuration.
|
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
|
||||||
ng build --prod --i18n-file src/locale/messages.fr.xlf --i18n-format xlf --i18n-locale fr
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
{@a merge-jit}
|
|
||||||
### Merge with the JIT compiler
|
|
||||||
|
|
||||||
The [JITcompiler](guide/glossary#jit) compiles your app in the browser as the app loads.
|
|
||||||
To support translation with the JIT compiler, you must do the following:
|
|
||||||
|
|
||||||
1. Import the appropriate language translation file as a string constant.
|
|
||||||
2. Create corresponding translation providers for the JIT compiler.
|
|
||||||
3. Bootstrap the app with those providers.
|
|
||||||
|
|
||||||
Three providers tell the JIT compiler how to translate the template texts for a particular language
|
|
||||||
while compiling the app:
|
|
||||||
|
|
||||||
* `TRANSLATIONS` is a string containing the content of the translation file.
|
|
||||||
* `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlf2`, or `xtb`.
|
|
||||||
* `LOCALE_ID` is the locale of the target language.
|
|
||||||
|
|
||||||
The Angular `bootstrapModule` method has a second `compilerOptions` parameter that can influence the
|
|
||||||
behavior of the compiler. You can use it to specify the translation providers:
|
|
||||||
|
|
||||||
<code-example path="i18n/doc-files/main.2.ts" header="src/main.ts">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
Then provide the `LOCALE_ID` in the main module:
|
|
||||||
|
|
||||||
<code-example path="i18n/doc-files/app.module.ts" header="src/app/app.module.ts"></code-example>
|
|
||||||
|
|
||||||
|
|
||||||
{@a missing-translation}
|
{@a missing-translation}
|
||||||
### Report missing translations
|
### Report missing translations
|
||||||
|
|
||||||
@ -773,43 +766,15 @@ compilation, the app will fail to load.
|
|||||||
* Warning (default): show a 'Missing translation' warning in the console or shell.
|
* Warning (default): show a 'Missing translation' warning in the console or shell.
|
||||||
* Ignore: do nothing.
|
* Ignore: do nothing.
|
||||||
|
|
||||||
You specify the warning level in the `configurations` section of your Angular CLI configuration file, `angular.json`. The example below shows how to set the warning level to error.
|
You specify the warning level in the `options` section for the `build` target of your Angular CLI configuration file, `angular.json`. The example below shows how to set the warning level to error.
|
||||||
|
|
||||||
```
|
<code-example language="json" header="angular.json">
|
||||||
"configurations": {
|
"options": {
|
||||||
...
|
...
|
||||||
"fr": {
|
"i18nMissingTranslation": "error"
|
||||||
...
|
|
||||||
"i18nMissingTranslation": "error"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
If you use the JIT compiler, specify the warning level in the compiler config at bootstrap by adding
|
|
||||||
the 'MissingTranslationStrategy' property. The example below shows how to set the warning level to
|
|
||||||
error.
|
|
||||||
|
|
||||||
<code-example path="i18n/doc-files/main.3.ts" header="src/main.ts">
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
### Build for multiple locales
|
### Deployment for multiple locales
|
||||||
|
|
||||||
When you use the CLI `build` or `serve` command to build your application for different locales, change the output path using the `--outputPath` command option (along with the i18n-specific command options), so that the translation files are saved to different locations.
|
|
||||||
When you are serving a locale-specific version from a subdirectory, you can also change the base URL used by your app by specifying the `--baseHref` option.
|
|
||||||
|
|
||||||
For example, if the French version of your application is served from https://example.com/fr/, configure the build for the French version as follows.
|
|
||||||
|
|
||||||
```
|
|
||||||
"configurations": {
|
|
||||||
"fr": {
|
|
||||||
"aot": true,
|
|
||||||
"outputPath": "dist/my-project-fr/",
|
|
||||||
"baseHref": "/fr/",
|
|
||||||
"i18nFile": "src/locale/messages.fr.xlf",
|
|
||||||
"i18nFormat": "xlf",
|
|
||||||
"i18nLocale": "fr",
|
|
||||||
"i18nMissingTranslation": "error",
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For more details about how to create scripts to generate an app in multiple languages and how to set up Apache 2 and NGINX to serve them from different subdirectories, read [this tutorial by Philippe Martin](https://dev.to/angular/deploying-an-i18n-angular-app-with-angular-cli-2fb9).
|
For more details about how to create scripts to generate an app in multiple languages and how to set up Apache 2 and NGINX to serve them from different subdirectories, read [this tutorial by Philippe Martin](https://dev.to/angular/deploying-an-i18n-angular-app-with-angular-cli-2fb9).
|
||||||
|
@ -111,4 +111,106 @@ Option 2:
|
|||||||
<comp>
|
<comp>
|
||||||
<div #foo></div> <!-- matches in both old runtime and new runtime -->
|
<div #foo></div> <!-- matches in both old runtime and new runtime -->
|
||||||
</comp>
|
</comp>
|
||||||
|
```
|
||||||
|
|
||||||
|
{@a undecorated-classes}
|
||||||
|
## All Classes That Use Angular DI Must Have An Angular Class-level Decorator
|
||||||
|
|
||||||
|
|
||||||
|
### Basic example of change:
|
||||||
|
|
||||||
|
In the previous rendering engine, the following would work:
|
||||||
|
|
||||||
|
```
|
||||||
|
export class DataService {
|
||||||
|
constructor(@Inject('CONFIG') public config: DataConfig) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AppService extends DataService {...}
|
||||||
|
```
|
||||||
|
|
||||||
|
In Ivy, it will throw an error because `DataService` is using Angular dependency injection, but is missing an `@Injectable` decorator.
|
||||||
|
|
||||||
|
The following would also work in the previous rendering engine, but in Ivy would require a `@Directive` decorator because it uses DI:
|
||||||
|
|
||||||
|
```
|
||||||
|
export class BaseMenu {
|
||||||
|
constructor(private vcr: ViewContainerRef) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Directive({selector: '[settingsMenu]'})
|
||||||
|
export class SettingsMenu extends BaseMenu {}
|
||||||
|
```
|
||||||
|
|
||||||
|
The same is true if your directive class extends a decorated directive, but does not have a decorator of its own.
|
||||||
|
|
||||||
|
If you're using the CLI, there are two automated migrations that should transition your code for you ([this one](guide/migration-injectable) and [this one](guide/migration-undecorated-classes)).
|
||||||
|
However, as you're adding new code in version 9, you may run into this difference.
|
||||||
|
|
||||||
|
### Background
|
||||||
|
|
||||||
|
When a class has an Angular decorator like `@Injectable` or `@Directive`, the Angular compiler generates extra code to support injecting dependencies into the constructor of your class.
|
||||||
|
When using inheritance, Ivy needs both the parent class and the child class to apply a decorator to generate the correct code.
|
||||||
|
Otherwise, when the decorator is missing from the parent class, the subclass will inherit a constructor from a class for which the compiler did not generate special constructor info, and Angular won't have the dependency info it needs to create it properly.
|
||||||
|
|
||||||
|
In the previous rendering engine, the compiler had global knowledge, so in some cases (such as AOT mode or the presence of certain injection flags), it could look up the missing data.
|
||||||
|
However, the Ivy compiler only processes each class in isolation.
|
||||||
|
This means that compilation has the potential to be faster (and opens the framework up for optimizations and features going forward), but the compiler can't automatically infer the same information as before.
|
||||||
|
|
||||||
|
Adding the proper decorator explicitly provides this information.
|
||||||
|
|
||||||
|
### Example of error
|
||||||
|
|
||||||
|
In JIT mode, the framework will throw the following error:
|
||||||
|
|
||||||
|
```
|
||||||
|
ERROR: This constructor is not compatible with Angular Dependency Injection because dependency at index 'X' is invalid.
|
||||||
|
This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
|
||||||
|
|
||||||
|
Please check that 1) the type for dependency X is correct and 2) the correct Angular decorators are defined for this class and its ancestors.
|
||||||
|
```
|
||||||
|
|
||||||
|
In AOT mode, you'll see something like:
|
||||||
|
|
||||||
|
```
|
||||||
|
X inherits its constructor from Y, but the latter does not have an Angular decorator of its own.
|
||||||
|
Dependency injection will not be able to resolve the parameters of Y's constructor. Either add a
|
||||||
|
@Directive decorator to Y, or add an explicit constructor to X.
|
||||||
|
```
|
||||||
|
|
||||||
|
In some cases, the framework may not be able to detect the missing decorator.
|
||||||
|
In these cases, you'll generally see a runtime error thrown when there is a property access attempted on the missing dependency.
|
||||||
|
If dependency was `foo`, you'd see an error when accessing something like `foo.bar`:
|
||||||
|
|
||||||
|
```
|
||||||
|
Uncaught TypeError: Cannot read property 'bar' of undefined
|
||||||
|
```
|
||||||
|
|
||||||
|
If you see an error like this, and the `undefined` value refers to something that should have been injected, it may be this change.
|
||||||
|
|
||||||
|
### Recommended fix
|
||||||
|
|
||||||
|
- Add an `@Injectable` decorator to anything you plan to provide or inject.
|
||||||
|
|
||||||
|
```
|
||||||
|
@Injectable()
|
||||||
|
export class DataService {
|
||||||
|
constructor(@Inject('CONFIG') public config: DataConfig) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AppService extends DataService {...}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Add a [selectorless `@Directive` decorator](guide/migration-undecorated-classes#what-does-it-mean-to-have-a-directive-decorator-with-no-metadata-inside-of-it) to any class that extends a directive or any class from which a directive inherits.
|
||||||
|
|
||||||
|
```
|
||||||
|
@Directive() // selectorless, so it's not usable directly
|
||||||
|
export class BaseMenu {
|
||||||
|
constructor(private vcr: ViewContainerRef) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Directive({selector: '[settingsMenu]'})
|
||||||
|
export class SettingsMenu extends BaseMenu {}
|
||||||
```
|
```
|
@ -11,9 +11,9 @@ That said, some applications will likely need to apply some manual updates.
|
|||||||
In version 9, [a few deprecated APIs have been removed](guide/updating-to-version-9#removals) and there are a [few breaking changes](guide/updating-to-version-9#breaking-changes) unrelated to Ivy.
|
In version 9, [a few deprecated APIs have been removed](guide/updating-to-version-9#removals) and there are a [few breaking changes](guide/updating-to-version-9#breaking-changes) unrelated to Ivy.
|
||||||
If you're seeing errors after updating to version 9, you'll first want to rule those changes out.
|
If you're seeing errors after updating to version 9, you'll first want to rule those changes out.
|
||||||
|
|
||||||
To do so, temporarily [turn off Ivy in your `tsconfig.json`](guide/ivy#opting-out-of-angular-ivy) and re-start your app.
|
To do so, temporarily [turn off Ivy](guide/ivy#opting-out-of-angular-ivy) in your `tsconfig.json` and re-start your app.
|
||||||
|
|
||||||
If you're still seeing the errors, they are not specific to Ivy. In this case, you may want to consult the [general version 9 guide](guide/updating-to-version-9).
|
If you're still seeing the errors, they are not specific to Ivy. In this case, you may want to consult the [general version 9 guide](guide/updating-to-version-9). If you've opted into any of the stricter type-checking settings that are new with v9, you may also want to check out the [template type-checking guide](guide/template-typecheck).
|
||||||
|
|
||||||
If the errors are gone, switch back to Ivy by removing the changes to the `tsconfig.json` and review the list of expected changes below.
|
If the errors are gone, switch back to Ivy by removing the changes to the `tsconfig.json` and review the list of expected changes below.
|
||||||
|
|
||||||
@ -21,40 +21,39 @@ If the errors are gone, switch back to Ivy by removing the changes to the `tscon
|
|||||||
{@a common-changes}
|
{@a common-changes}
|
||||||
### Changes You May See
|
### Changes You May See
|
||||||
|
|
||||||
- By default, `@ContentChildren` queries will only search direct child nodes in the DOM hierarchy (previously, they would search any nesting level in the DOM as long as another directive wasn't matched above it). ([details](guide/ivy-compatibility-examples#content-children-descendants))
|
* By default, `@ContentChildren` queries will only search direct child nodes in the DOM hierarchy (previously, they would search any nesting level in the DOM as long as another directive wasn't matched above it). [details](guide/ivy-compatibility-examples#content-children-descendants)
|
||||||
|
|
||||||
- All classes that use Angular DI must have an Angular decorator like `@Directive()` or `@Injectable` (previously, undecorated classes were allowed if an ancestor class or subclass had a decorator).
|
* All classes that use Angular DI must have an Angular decorator like `@Directive()` or `@Injectable` (previously, undecorated classes were allowed in AOT mode only or if injection flags were used). [details](guide/ivy-compatibility-examples#undecorated-classes)
|
||||||
|
|
||||||
- Unbound inputs for directives (e.g. name in `<my-comp name="">`) are now set upon creation of the view, before change detection runs (previously, all inputs were set during change detection).
|
|
||||||
|
|
||||||
|
* Unbound inputs for directives (e.g. name in `<my-comp name="">`) are now set upon creation of the view, before change detection runs (previously, all inputs were set during change detection).
|
||||||
|
|
||||||
{@a less-common-changes}
|
{@a less-common-changes}
|
||||||
### Less Common Changes
|
### Less Common Changes
|
||||||
|
|
||||||
- Properties like `host` inside `@Component` and `@Directive` decorators can be inherited (previously, only properties with explicit field decorators like `@HostBinding` would be inherited).
|
* Properties like `host` inside `@Component` and `@Directive` decorators can be inherited (previously, only properties with explicit field decorators like `@HostBinding` would be inherited).
|
||||||
|
|
||||||
- HammerJS support is opt-in through importing the `HammerModule` (previously, it was always included in production bundles regardless of whether the app used HammerJS).
|
* HammerJS support is opt-in through importing the `HammerModule` (previously, it was always included in production bundles regardless of whether the app used HammerJS).
|
||||||
|
|
||||||
- `@ContentChild` and `@ContentChildren` queries will no longer be able to match their directive's own host node (previously, these queries would match the host node in addition to its content children).
|
* `@ContentChild` and `@ContentChildren` queries will no longer be able to match their directive's own host node (previously, these queries would match the host node in addition to its content children).
|
||||||
|
|
||||||
- If a token is injected with the `@Host` or `@Self` flag, the module injector is not searched for that token (previously, tokens marked with these flags would still search at the module level).
|
* If a token is injected with the `@Host` or `@Self` flag, the module injector is not searched for that token (previously, tokens marked with these flags would still search at the module level).
|
||||||
|
|
||||||
- If a template is declared in one view but inserted into a different view, change detection will occur for that template only when its insertion point is checked (previously, change detection would also run when its declaration point was checked).
|
* When accessing multiple local refs with the same name in template bindings, the first is matched (previously, the last instance was matched).
|
||||||
|
|
||||||
- When accessing multiple local refs with the same name in template bindings, the first is matched (previously, the last instance was matched).
|
* Directives that are used in an exported module (but not exported themselves) are exported publicly (previously, the compiler would automatically write a private, aliased export that it could use its global knowledge to resolve downstream).
|
||||||
|
|
||||||
- Directives that are used in an exported module (but not exported themselves) are exported publicly (previously, the compiler would automatically write a private, aliased export that it could use its global knowledge to resolve downstream).
|
* Foreign functions or foreign constants in decorator metadata aren't statically resolvable (previously, you could import a constant or function from another compilation unit, like a library, and use that constant/function in your `@NgModule` definition).
|
||||||
|
|
||||||
- Foreign functions or foreign constants in decorator metadata aren't statically resolvable (previously, you could import a constant or function from another compilation unit, like a library, and use that constant/function in your `@NgModule` definition).
|
* Forward references to directive inputs accessed through local refs are no longer supported by default.
|
||||||
|
|
||||||
- Forward references to directive inputs accessed through local refs are no longer supported by default.
|
* If there is both an unbound class attribute and a `[class]` binding, the classes in the unbound attribute will also be added (previously, the class binding would overwrite classes in the unbound attribute).
|
||||||
|
|
||||||
- If there is both an unbound class attribute and a `[class]` binding, the classes in the unbound attribute will also be added (previously, the class binding would overwrite classes in the unbound attribute).
|
* It is now an error to assign values to template-only variables like `item` in `ngFor="let item of items"` (previously, the compiler would ignore these assignments).
|
||||||
|
|
||||||
- It is now an error to assign values to template-only variables like `item` in `ngFor="let item of items"` (previously, the compiler would ignore these assignments).
|
* It's no longer possible to overwrite lifecycle hooks with mocks on directive instances for testing (instead, modify the lifecycle hook on the directive type itself).
|
||||||
|
|
||||||
- It's no longer possible to overwrite lifecycle hooks with mocks on directive instances for testing (instead, modify the lifecycle hook on the directive type itself).
|
* Special injection tokens (such as `TemplateRef` or `ViewContainerRef`) return a new instance whenever they are requested (previously, instances of special tokens were shared if requested on the same node). This primarily affects tests that do identity comparison of these objects.
|
||||||
|
|
||||||
- Special injection tokens (e.g. `TemplateRef` or `ViewContainerRef`) return a new instance whenever they are requested (previously, instances of special tokens were shared if requested on the same node). This primarily affects tests that do identity comparison of these objects.
|
* ICU parsing happens at runtime, so only text, HTML tags and text bindings are allowed inside ICU cases (previously, directives were also permitted inside ICUs).
|
||||||
|
|
||||||
- ICU parsing happens at runtime, so only text, HTML tags and text bindings are allowed inside ICU cases (previously, directives were also permitted inside ICUs).
|
* Providers formatted as `{provide: X}` without a `useValue`, `useFactory`, `useExisting`, or `useClass` property are treated like `{provide: X, useClass: X}` (previously, it defaulted to `{provide: X, useValue: undefined}`).
|
@ -15,6 +15,7 @@ Learn more about the [Compiler](https://www.youtube.com/watch?v=anphffaCZrQ) and
|
|||||||
|
|
||||||
AOT compilation with Ivy is faster and should be used by default.
|
AOT compilation with Ivy is faster and should be used by default.
|
||||||
In the `angular.json` workspace configuration file, set the default build options for your project to always use AOT compilation.
|
In the `angular.json` workspace configuration file, set the default build options for your project to always use AOT compilation.
|
||||||
|
When using application internationalization (i18n) with Ivy, [translation merging](guide/i18n#merge) also requires the use of AOT compilation.
|
||||||
|
|
||||||
<code-example language="json" header="angular.json">
|
<code-example language="json" header="angular.json">
|
||||||
|
|
||||||
@ -38,7 +39,33 @@ In the `angular.json` workspace configuration file, set the default build option
|
|||||||
|
|
||||||
Ivy applications can be built with libraries that were created with the View Engine compiler.
|
Ivy applications can be built with libraries that were created with the View Engine compiler.
|
||||||
This compatibility is provided by a tool known as the Angular compatibility compiler (`ngcc`).
|
This compatibility is provided by a tool known as the Angular compatibility compiler (`ngcc`).
|
||||||
CLI commands run `ngcc` as needed, either after npm installation of dependencies or when performing an Angular build.
|
CLI commands run `ngcc` as needed performing an Angular build.
|
||||||
|
|
||||||
|
{@a speeding-up-ngcc-compilation}
|
||||||
|
### Speeding up ngcc compilation
|
||||||
|
|
||||||
|
The standalone `ngcc` program can run in parallel over your third party modules, making it more efficient than letting Angular CLI run it as needed.
|
||||||
|
|
||||||
|
You can run `ngcc` after each installation of node_modules by adding a `postinstall` [npm script](https://docs.npmjs.com/misc/scripts):
|
||||||
|
|
||||||
|
<code-example language="json" header="package.json">
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
<div class="alert is-important">
|
||||||
|
|
||||||
|
The `postinstall` script will run on every installation of `node_modules`, including those performed by `ng update` and `ng add`.
|
||||||
|
|
||||||
|
If you perform multiple installs in a row, this can end up being slower than letting Angular CLI run `ngcc` on builds.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{@a maintaining-library-compatibility}
|
||||||
|
### Maintaining library compatibility
|
||||||
|
|
||||||
If you are a library author, you should keep using the View Engine compiler as of version 9.
|
If you are a library author, you should keep using the View Engine compiler as of version 9.
|
||||||
By having all libraries continue to use View Engine, you will maintain compatibility with default v9 applications that use Ivy, as well as with applications that have opted to continue using View Engine.
|
By having all libraries continue to use View Engine, you will maintain compatibility with default v9 applications that use Ivy, as well as with applications that have opted to continue using View Engine.
|
||||||
@ -60,7 +87,8 @@ Before disabling Ivy, check out the debugging recommendations in the [Ivy Compat
|
|||||||
|
|
||||||
To opt out of Ivy, change the `angularCompilerOptions` in your project's TypeScript configuration, most commonly located at `tsconfig.app.json` at the root of the workspace.
|
To opt out of Ivy, change the `angularCompilerOptions` in your project's TypeScript configuration, most commonly located at `tsconfig.app.json` at the root of the workspace.
|
||||||
|
|
||||||
The value of the `enableIvy` flag is set to `true` by default, as of version 9.
|
The value of the `enableIvy` flag is set to `true` by default, as of version 9.
|
||||||
|
|
||||||
The following example shows how to set the `enableIvy` option to `false` in order to opt out of Ivy.
|
The following example shows how to set the `enableIvy` option to `false` in order to opt out of Ivy.
|
||||||
|
|
||||||
<code-example language="json" header="tsconfig.app.json">
|
<code-example language="json" header="tsconfig.app.json">
|
||||||
@ -70,17 +98,105 @@ The following example shows how to set the `enableIvy` option to `false` in orde
|
|||||||
"outDir": "./out-tsc/app",
|
"outDir": "./out-tsc/app",
|
||||||
"types": []
|
"types": []
|
||||||
},
|
},
|
||||||
|
"files": [
|
||||||
|
"src/main.ts",
|
||||||
|
"src/polyfills.ts"
|
||||||
|
],
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"src/**/*.d.ts"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"angularCompilerOptions": {
|
||||||
"src/test.ts",
|
"enableIvy": false
|
||||||
"src/**/*.spec.ts"
|
}
|
||||||
],
|
|
||||||
"angularCompilerOptions": {
|
|
||||||
"enableIvy": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
If you disable Ivy, you might also want to reconsider whether to make AOT compilation the default for your application development, as described [above](#aot-and-ivy). To revert the compiler default, set the build option `aot: false` in the `angular.json` configuration file.
|
<div class="alert is-important">
|
||||||
|
|
||||||
|
If you disable Ivy, you might also want to reconsider whether to make AOT compilation the default for your application development, as described [above](#aot-and-ivy).
|
||||||
|
|
||||||
|
To revert the compiler default, set the build option `aot: false` in the `angular.json` configuration file.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
If you disable Ivy and the project uses internationalization, you can also remove the `@angular/localize` runtime component from the project's polyfills file located be default at `src/polyfills.ts`.
|
||||||
|
|
||||||
|
To remove, delete the `import '@angular/localize/init';` line from the polyfills file.
|
||||||
|
|
||||||
|
<code-example language="typescript" header="polyfills.ts">
|
||||||
|
/***************************************************************************************************
|
||||||
|
* Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
|
||||||
|
*/
|
||||||
|
import '@angular/localize/init';
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
{@a using-ssr-without-angular-ivy}
|
||||||
|
### Using SSR without Ivy
|
||||||
|
|
||||||
|
If you opt out of Ivy and your application uses [Angular Universal](guide/universal) to render Angular applications on the server, you must also change the way the server performs bootstrapping.
|
||||||
|
|
||||||
|
The following example shows how you modify the `server.ts` file to provide the `AppServerModuleNgFactory` as the bootstrap module.
|
||||||
|
|
||||||
|
* Import `AppServerModuleNgFactory` from the `app.server.module.ngfactory` virtual file.
|
||||||
|
* Set `bootstrap: AppServerModuleNgFactory` in the `ngExpressEngine` call.
|
||||||
|
|
||||||
|
<code-example language="typescript" header="server.ts">
|
||||||
|
import 'zone.js/dist/zone-node';
|
||||||
|
|
||||||
|
import { ngExpressEngine } from '@nguniversal/express-engine';
|
||||||
|
import * as express from 'express';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
|
import { APP_BASE_HREF } from '@angular/common';
|
||||||
|
|
||||||
|
import { AppServerModuleNgFactory } from './src/app/app.server.module.ngfactory';
|
||||||
|
|
||||||
|
// The Express app is exported so that it can be used by serverless Functions.
|
||||||
|
export function app() {
|
||||||
|
const server = express();
|
||||||
|
const distFolder = join(process.cwd(), 'dist/ivy-test/browser');
|
||||||
|
|
||||||
|
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
|
||||||
|
server.engine('html', ngExpressEngine({
|
||||||
|
bootstrap: AppServerModuleNgFactory,
|
||||||
|
}));
|
||||||
|
|
||||||
|
server.set('view engine', 'html');
|
||||||
|
server.set('views', distFolder);
|
||||||
|
|
||||||
|
// Example Express Rest API endpoints
|
||||||
|
// app.get('/api/**', (req, res) => { });
|
||||||
|
// Serve static files from /browser
|
||||||
|
server.get('*.*', express.static(distFolder, {
|
||||||
|
maxAge: '1y'
|
||||||
|
}));
|
||||||
|
|
||||||
|
// All regular routes use the Universal engine
|
||||||
|
server.get('*', (req, res) => {
|
||||||
|
res.render('index', { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
|
||||||
|
});
|
||||||
|
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
const port = process.env.PORT || 4000;
|
||||||
|
|
||||||
|
// Start up the Node server
|
||||||
|
const server = app();
|
||||||
|
server.listen(port, () => {
|
||||||
|
console.log(`Node Express server listening on http://localhost:${port}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Webpack will replace 'require' with '__webpack_require__'
|
||||||
|
// '__non_webpack_require__' is a proxy to Node 'require'
|
||||||
|
// The below code is to ensure that the server is run only when not requiring the bundle.
|
||||||
|
declare const __non_webpack_require__: NodeRequire;
|
||||||
|
const mainModule = __non_webpack_require__.main;
|
||||||
|
if (mainModule && mainModule.filename === __filename) {
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
|
||||||
|
export * from './src/main.server';
|
||||||
|
</code-example>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user