Compare commits
187 Commits
10.0.10
...
9.0.0-rc.3
Author | SHA1 | Date | |
---|---|---|---|
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 |
11
.bazelrc
11
.bazelrc
@ -68,13 +68,6 @@ test --test_output=errors
|
||||
# any bazel target. This is a temporary flag until codebase is permanently switched to Ivy.
|
||||
build --define=compile=legacy
|
||||
|
||||
################################
|
||||
# Settings for rules_nodejs #
|
||||
################################
|
||||
# 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 #
|
||||
#######################
|
||||
@ -108,6 +101,10 @@ build:remote --remote_timeout=600
|
||||
build:remote --jobs=150
|
||||
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
|
||||
build:remote --host_javabase=@rbe_ubuntu1604_angular//java:jdk
|
||||
build:remote --javabase=@rbe_ubuntu1604_angular//java:jdk
|
||||
|
@ -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,
|
||||
# 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-
|
||||
|
||||
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
|
||||
@ -365,7 +365,7 @@ jobs:
|
||||
# Compile dependencies to ivy
|
||||
# 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).
|
||||
- run: yarn --cwd aio ivy-ngcc --properties es2015
|
||||
- run: yarn --cwd aio ngcc --properties es2015
|
||||
# Build aio
|
||||
- run: yarn --cwd aio build --progress=false
|
||||
# Lint the code
|
||||
@ -502,13 +502,14 @@ jobs:
|
||||
- setup_circleci_bazel_config
|
||||
- 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
|
||||
- persist_to_workspace:
|
||||
root: *workspace_location
|
||||
paths:
|
||||
- ng/dist/packages-dist
|
||||
- ng/dist/zone.js-dist
|
||||
|
||||
# Save dependencies and bazel repository cache to use on subsequent runs.
|
||||
- save_cache:
|
||||
@ -529,7 +530,7 @@ jobs:
|
||||
- setup_circleci_bazel_config
|
||||
- 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
|
||||
- persist_to_workspace:
|
||||
@ -569,15 +570,25 @@ jobs:
|
||||
environment:
|
||||
NG_PACKAGES_DIR: &ng_packages_dir 'dist/packages-dist'
|
||||
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:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Publish `@angular/*` packages.
|
||||
- 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
|
||||
- store_artifacts:
|
||||
path: *ng_packages_archives_dir
|
||||
destination: angular
|
||||
# Publish `zone.js` package.
|
||||
- run:
|
||||
name: Create artifacts for zone.js package
|
||||
command: ./scripts/ci/create-package-archives.sh $CI_PULL_REQUEST $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
|
||||
# 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_BRANCH "master"
|
||||
# **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;
|
||||
|
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.
|
||||
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" \
|
||||
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.
|
||||
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.)
|
||||
|
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -887,7 +887,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-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-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/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
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -13,11 +13,13 @@ pubspec.lock
|
||||
.c9
|
||||
.idea/
|
||||
.devcontainer/*
|
||||
!.devcontainer/README.md
|
||||
!.devcontainer/recommended-devcontainer.json
|
||||
!.devcontainer/recommended-Dockerfile
|
||||
.settings/
|
||||
.vscode/launch.json
|
||||
.vscode/settings.json
|
||||
.vscode/tasks.json
|
||||
*.swo
|
||||
modules/.settings
|
||||
modules/.vscode
|
||||
|
18
.vscode/README.md
vendored
18
.vscode/README.md
vendored
@ -1,23 +1,25 @@
|
||||
# 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
|
||||
|
||||
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>
|
||||
- copy `.vscode/recommended-settings.json` to `.vscode/settings.json`
|
||||
- install the recommneded extensions in `.vscode/extensions.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
|
||||
|
||||
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.
|
||||
|
||||
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",
|
||||
"--define=compile=aot",
|
||||
"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",
|
||||
"--define=compile=aot",
|
||||
"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",
|
||||
"--define=compile=aot",
|
||||
"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",
|
||||
"--define=compile=aot",
|
||||
"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",
|
||||
"--define=compile=aot",
|
||||
"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",
|
||||
"--define=compile=aot",
|
||||
"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",
|
||||
"--define=compile=aot",
|
||||
"packages/core/test/render3",
|
||||
],
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "dedicated",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
111
CHANGELOG.md
111
CHANGELOG.md
@ -1,3 +1,112 @@
|
||||
<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>
|
||||
# [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 +407,7 @@ or
|
||||
npm install tslib --save
|
||||
```
|
||||
* **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.
|
||||
|
||||
|
||||
|
30
WORKSPACE
30
WORKSPACE
@ -5,24 +5,11 @@ workspace(
|
||||
|
||||
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
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
patch_args = ["-p1"],
|
||||
# Patch https://github.com/bazelbuild/rules_nodejs/pull/903
|
||||
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"],
|
||||
sha256 = "9901bc17138a79135048fb0c107ee7a56e91815ec6594c08cb9a17b80276d62b",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.40.0/rules_nodejs-0.40.0.tar.gz"],
|
||||
)
|
||||
|
||||
# Check the bazel version and download npm dependencies
|
||||
@ -113,12 +100,9 @@ load("@io_bazel_rules_webtesting//web:repositories.bzl", "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(
|
||||
chromium = True,
|
||||
firefox = True,
|
||||
)
|
||||
browser_repositories()
|
||||
|
||||
# Setup the rules_typescript tooolchain
|
||||
load("@npm_bazel_typescript//:index.bzl", "ts_setup_workspace")
|
||||
@ -143,14 +127,14 @@ rbe_autoconfig(
|
||||
# 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
|
||||
# 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
|
||||
base_container_digest = "sha256:94d7d8552902d228c32c8c148cc13f0effc2b4837757a6e95b73fdc5c5e4b07b",
|
||||
# https://github.com/bazelbuild/bazel-toolchains/blob/1.1.2/configs/ubuntu16_04_clang/versions.bzl
|
||||
base_container_digest = "sha256:1ab40405810effefa0b2f45824d6d608634ccddbf06366760c341ef6fbead011",
|
||||
# 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>
|
||||
# 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
|
||||
# @com_google_protobuf. Java is needed for the Bazel's test executor Java tool.
|
||||
digest = "sha256:76e2e4a894f9ffbea0a0cb2fbde741b5d223d40f265dbb9bca78655430173990",
|
||||
digest = "sha256:0b8fa87db4b8e5366717a7164342a029d1348d2feea7ecc4b18c780bc2507059",
|
||||
env = clang_env(),
|
||||
registry = "marketplace.gcr.io",
|
||||
# We can't use the default "ubuntu16_04" RBE image provided by the autoconfig because we need
|
||||
|
@ -2,21 +2,23 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { QuestionService } from './question.service';
|
||||
import { QuestionBase } from './question-base';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<div>
|
||||
<h2>Job Application for Heroes</h2>
|
||||
<app-dynamic-form [questions]="questions"></app-dynamic-form>
|
||||
<app-dynamic-form [questions]="questions$ | async"></app-dynamic-form>
|
||||
</div>
|
||||
`,
|
||||
providers: [QuestionService]
|
||||
})
|
||||
export class AppComponent {
|
||||
questions: any[];
|
||||
questions$: Observable<QuestionBase<any>[]>;
|
||||
|
||||
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>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@ import { QuestionBase } from './question-base';
|
||||
templateUrl: './dynamic-form-question.component.html'
|
||||
})
|
||||
export class DynamicFormQuestionComponent {
|
||||
@Input() question: QuestionBase<any>;
|
||||
@Input() question: QuestionBase<string>;
|
||||
@Input() form: FormGroup;
|
||||
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 {
|
||||
|
||||
@Input() questions: QuestionBase<any>[] = [];
|
||||
@Input() questions: QuestionBase<string>[] = [];
|
||||
form: FormGroup;
|
||||
payLoad = '';
|
||||
|
||||
@ -23,6 +23,6 @@ export class DynamicFormComponent implements OnInit {
|
||||
}
|
||||
|
||||
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;
|
||||
order: number;
|
||||
controlType: string;
|
||||
type: string;
|
||||
options: {key: string, value: string}[];
|
||||
|
||||
constructor(options: {
|
||||
value?: T,
|
||||
@ -13,7 +15,8 @@ export class QuestionBase<T> {
|
||||
label?: string,
|
||||
required?: boolean,
|
||||
order?: number,
|
||||
controlType?: string
|
||||
controlType?: string,
|
||||
type?: string
|
||||
} = {}) {
|
||||
this.value = options.value;
|
||||
this.key = options.key || '';
|
||||
@ -21,5 +24,6 @@ export class QuestionBase<T> {
|
||||
this.required = !!options.required;
|
||||
this.order = options.order === undefined ? 1 : options.order;
|
||||
this.controlType = options.controlType || '';
|
||||
this.type = options.type || '';
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import { QuestionBase } from './question-base';
|
||||
export class QuestionControlService {
|
||||
constructor() { }
|
||||
|
||||
toFormGroup(questions: QuestionBase<any>[] ) {
|
||||
toFormGroup(questions: QuestionBase<string>[] ) {
|
||||
let group: any = {};
|
||||
|
||||
questions.forEach(question => {
|
||||
|
@ -4,15 +4,15 @@ import { Injectable } from '@angular/core';
|
||||
import { DropdownQuestion } from './question-dropdown';
|
||||
import { QuestionBase } from './question-base';
|
||||
import { TextboxQuestion } from './question-textbox';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class QuestionService {
|
||||
|
||||
// TODO: get from a remote source of question metadata
|
||||
// TODO: make asynchronous
|
||||
getQuestions() {
|
||||
|
||||
let questions: QuestionBase<any>[] = [
|
||||
let questions: QuestionBase<string>[] = [
|
||||
|
||||
new DropdownQuestion({
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -77,12 +77,20 @@ When `false`, disables this rewriting, requiring the rewriting to be done manual
|
||||
|
||||
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`
|
||||
|
||||
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.
|
||||
|
||||
For library projects generated with the CLI, the dev configuration default is true.
|
||||
|
||||
|
||||
{@a enablelegacytemplate}
|
||||
|
||||
@ -118,9 +126,9 @@ would be `"index.d.ts"`.
|
||||
|
||||
### `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`
|
||||
|
||||
@ -154,6 +162,8 @@ When true, does not emit `.ngfactory.js` and `.ngstyle.js` files. This turns off
|
||||
|
||||
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`
|
||||
|
||||
When true, reports an error to the `.metadata.json` file if `"skipMetadataEmit"` is `false`.
|
||||
@ -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
|
||||
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`
|
||||
|
||||
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`
|
||||
|
||||
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`.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/animations/open-closed.png" alt="open and closed states">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/animations/open-closed.png" alt="open and closed states">
|
||||
</div>
|
||||
|
||||
### 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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/animations/triggering-the-animation.png" alt="triggering the animation">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/animations/triggering-the-animation.png" alt="triggering the animation">
|
||||
</div>
|
||||
|
||||
<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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/architecture/component-tree.png" alt="Component tree" class="left">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/component-tree.png" alt="Component tree" class="left">
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/architecture/databinding.png" alt="Data Binding" class="left">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/databinding.png" alt="Data Binding" class="left">
|
||||
</div>
|
||||
|
||||
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,
|
||||
from the root of the application component tree through all child components.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/architecture/component-databinding.png" alt="Data Binding" class="left">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/component-databinding.png" alt="Data Binding" class="left">
|
||||
</div>
|
||||
|
||||
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="card">
|
||||
<img src="generated/images/guide/architecture/parent-child-binding.png" alt="Parent/Child binding" class="left">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/parent-child-binding.png" alt="Parent/Child binding" class="left">
|
||||
</div>
|
||||
|
||||
### 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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/architecture/compilation-context.png" alt="Component compilation context" class="left">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/compilation-context.png" alt="Component compilation context" class="left">
|
||||
</div>
|
||||
|
||||
<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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/architecture/view-hierarchy.png" alt="View hierarchy" class="left">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/view-hierarchy.png" alt="View hierarchy" class="left">
|
||||
</div>
|
||||
|
||||
<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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/architecture/injector-injects.png" alt="Service" class="left">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/injector-injects.png" alt="Service" class="left">
|
||||
</div>
|
||||
|
||||
### 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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/architecture/overview2.png" alt="overview">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/overview2.png" alt="overview">
|
||||
</div>
|
||||
|
||||
* 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.
|
||||
|
@ -175,11 +175,9 @@ Here's the updated directive in full:
|
||||
Run the app and confirm that the background color appears when
|
||||
the mouse hovers over the `p` and disappears as it moves out.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/attribute-directives/highlight-directive-anim.gif" alt="Second Highlight">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/attribute-directives/highlight-directive-anim.gif" alt="Second Highlight">
|
||||
</div>
|
||||
|
||||
{@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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/attribute-directives/highlight-directive-v2-anim.gif" alt="Highlight v.2">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/attribute-directives/highlight-directive-v2-anim.gif" alt="Highlight v.2">
|
||||
</div>
|
||||
|
||||
{@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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight">
|
||||
</div>
|
||||
|
||||
## Summary
|
||||
|
||||
|
@ -50,11 +50,9 @@ and each iteration's `hero` instance to the child's `hero` property.
|
||||
The running application displays three heroes:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/component-interaction/parent-to-child.png" alt="Parent-to-child">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/component-interaction/parent-to-child.png" alt="Parent-to-child">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -96,11 +94,9 @@ Here's the `NameParentComponent` demonstrating name variations including a name
|
||||
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/component-interaction/setter.png" alt="Parent-to-child-setter">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/component-interaction/setter.png" alt="Parent-to-child-setter">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -156,11 +152,9 @@ The `VersionParentComponent` supplies the `minor` and `major` values and binds b
|
||||
Here's the output of a button-pushing sequence:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/component-interaction/parent-to-child-on-changes.gif" alt="Parent-to-child-onchanges">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/component-interaction/parent-to-child-on-changes.gif" alt="Parent-to-child-onchanges">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -212,11 +206,9 @@ The framework passes the event argument—represented by `$event`—to t
|
||||
and the method processes it:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/component-interaction/child-to-parent.gif" alt="Child-to-parent">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/component-interaction/child-to-parent.gif" alt="Child-to-parent">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -276,11 +268,9 @@ uses interpolation to display the child's `seconds` property.
|
||||
Here we see the parent and child working together.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/component-interaction/countdown-timer-anim.gif" alt="countdown timer">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/component-interaction/countdown-timer-anim.gif" alt="countdown timer">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -431,11 +421,9 @@ the parent `MissionControlComponent` and the `AstronautComponent` children,
|
||||
facilitated by the service:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/component-interaction/bidirectional-service.gif" alt="bidirectional-service">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/component-interaction/bidirectional-service.gif" alt="bidirectional-service">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
@ -40,11 +40,9 @@ and the framework resolves the nested dependencies.
|
||||
|
||||
When all dependencies are in place, `AppComponent` displays the user information.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/logged-in-user.png" alt="Logged In User">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/logged-in-user.png" alt="Logged In User">
|
||||
</div>
|
||||
|
||||
{@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>
|
||||
and confirm that the three `HeroBioComponent` instances have their own cached hero data.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bios.png" alt="Bios">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bios.png" alt="Bios">
|
||||
</div>
|
||||
|
||||
{@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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bio-and-content.png" alt="bio and contact">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bio-and-content.png" alt="bio and contact">
|
||||
</div>
|
||||
|
||||
|
||||
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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bios-and-contacts.png" alt="Bios with contact into">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bios-and-contacts.png" alt="Bios with contact into">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -240,11 +232,9 @@ until it finds the logger at the `AppComponent` level.
|
||||
The logger logic kicks in and the hero display updates
|
||||
with the "!!!" marker to indicate that the logger was found.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bio-contact-no-host.png" alt="Without @Host">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-bio-contact-no-host.png" alt="Without @Host">
|
||||
</div>
|
||||
|
||||
|
||||
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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/highlight.png" alt="Highlighted bios">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/highlight.png" alt="Highlighted bios">
|
||||
</div>
|
||||
|
||||
{@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.
|
||||
It's visually simple: a few properties and the logs produced by a logger.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-of-month.png" alt="Hero of the month">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/hero-of-month.png" alt="Hero of the month">
|
||||
</div>
|
||||
|
||||
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.
|
||||
@ -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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/minimal-logger-intellisense.png" alt="MinimalLogger restricted API">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/minimal-logger-intellisense.png" alt="MinimalLogger restricted API">
|
||||
</div>
|
||||
|
||||
|
||||
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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/date-logger-entry.png" alt="DateLoggerService entry">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/date-logger-entry.png" alt="DateLoggerService entry">
|
||||
</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`
|
||||
to display a *sorted* list of heroes.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/sorted-heroes.png" alt="Sorted Heroes">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/sorted-heroes.png" alt="Sorted Heroes">
|
||||
</div>
|
||||
|
||||
The `HeroesBaseComponent` can stand on its own.
|
||||
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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/alex.png" alt="Alex in action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/alex.png" alt="Alex in action">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -203,13 +201,9 @@ which *is* what parent means.
|
||||
Here's *Alice*, *Barry*, and family in action.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/alice.png" alt="Alice in action">
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection-in-action/alice.png" alt="Alice in action">
|
||||
</div>
|
||||
|
||||
{@a parent-token}
|
||||
|
||||
|
@ -140,7 +140,7 @@ Check out [angular-cli-ghpages](https://github.com/angular-buch/angular-cli-ghpa
|
||||
|
||||
## 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}
|
||||
|
||||
@ -230,7 +230,7 @@ modified to serve `index.html`:
|
||||
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
|
||||
@ -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`.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/deployment/quickstart-sourcemap-explorer.png" alt="quickstart sourcemap explorer">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/deployment/quickstart-sourcemap-explorer.png" alt="quickstart sourcemap explorer">
|
||||
</div>
|
||||
|
||||
{@a base-tag}
|
||||
|
||||
@ -669,7 +667,7 @@ In `angular.json` add two new configuration sections under the `build` and `serv
|
||||
...
|
||||
},
|
||||
"es5": {
|
||||
"browserTarget": "<app-name>:build:es5"
|
||||
"browserTarget": "<app-name>:build:es5"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -741,7 +739,7 @@ Create an [ES5 serve configuration](guide/deployment#configuring-serve-for-es5)
|
||||
...
|
||||
},
|
||||
"es5": {
|
||||
"devServerTarget": "<app-name>:serve:es5"
|
||||
"devServerTarget": "<app-name>:serve:es5"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -8,12 +8,9 @@ conditionally show a message below the list.
|
||||
|
||||
The final UI looks like this:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/displaying-data/final.png" alt="Final UI">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/displaying-data/final.png" alt="Final UI">
|
||||
</div>
|
||||
|
||||
<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:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/displaying-data/title-and-hero.png" alt="Title and Hero">
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/displaying-data/title-and-hero.png" alt="Title and Hero">
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/displaying-data/hero-names-list.png" alt="After ngfor">
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/displaying-data/hero-names-list.png" alt="After ngfor">
|
||||
</div>
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
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
|
||||
|
||||
<figure>
|
||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png" alt="flying hero">
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
||||
alt="flying hero">
|
||||
</div>
|
||||
|
||||
```html
|
||||
<figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
||||
alt="flying hero">
|
||||
</figure>
|
||||
alt="flying hero">
|
||||
</div>
|
||||
```
|
||||
|
||||
_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.
|
||||
|
||||
<figure>
|
||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png" alt="flying Angular hero" width="200">
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
||||
alt="flying Angular hero"
|
||||
width="200">
|
||||
</div>
|
||||
|
||||
```html
|
||||
|
||||
<figure>
|
||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
||||
alt="flying Angular hero"
|
||||
width="200">
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/docs-style-guide/flying-hero.png"
|
||||
alt="flying Angular hero"
|
||||
width="200">
|
||||
</div>
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
<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">
|
||||
</figure>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<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
|
||||
The final ad banner looks like this:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dynamic-component-loader/ads-example.gif" alt="Ads">
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dynamic-component-loader/ads-example.gif" alt="Ads">
|
||||
</div>
|
||||
|
||||
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:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dynamic-form/dynamic-form.png" alt="Dynamic-Form">
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dynamic-form/dynamic-form.png" alt="Dynamic-Form">
|
||||
</div>
|
||||
|
||||
|
||||
[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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/elements/customElement1.png" alt="Custom element in browser" class="left">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/elements/customElement1.png" alt="Custom element in browser" class="left">
|
||||
</div>
|
||||
|
||||
<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`.
|
||||
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="card">
|
||||
<img src="generated/images/guide/elements/createElement.png" alt="Transform a component to a custom element" class="left">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/elements/createElement.png" alt="Transform a component to a custom element" class="left">
|
||||
</div>
|
||||
|
||||
### Mapping
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
|
||||
</div>
|
||||
|
||||
<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. |
|
||||
| `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). |
|
||||
| `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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms-overview/key-diff-reactive-forms.png" alt="Reactive forms key differences">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms-overview/key-diff-reactive-forms.png" alt="Reactive forms key differences">
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms-overview/key-diff-td-forms.png" alt="Template-driven forms key differences">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms-overview/key-diff-td-forms.png" alt="Template-driven forms key differences">
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
<figure 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%">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-vtm.png" alt="Reactive forms data flow - view to model" width="100%">
|
||||
</div>
|
||||
|
||||
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. Any subscribers to the `valueChanges` observable receive the new value.
|
||||
|
||||
<figure 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%">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-mtv.png" alt="Reactive forms data flow - model to view" width="100%">
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
<figure 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%">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms-overview/dataflow-td-forms-vtm.png" alt="Template-driven forms data flow - view to model" width="100%">
|
||||
</div>
|
||||
|
||||
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
|
||||
is updated to the value emitted by the `ngModelChange` event (*Blue*).
|
||||
|
||||
<figure 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%">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms-overview/dataflow-td-forms-mtv.png" alt="Template-driven forms data flow - model to view" width="100%">
|
||||
</div>
|
||||
|
||||
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:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms/hero-form-1.png" alt="Clean Form">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms/hero-form-1.png" alt="Clean Form">
|
||||
</div>
|
||||
|
||||
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.
|
||||
@ -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:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms/hero-form-2.png" alt="Invalid, Name Required">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms/hero-form-2.png" alt="Invalid, Name Required">
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms/hero-form-3.png" alt="Early form with no binding">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms/hero-form-3.png" alt="Early form with no binding">
|
||||
</div>
|
||||
|
||||
|
||||
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.
|
||||
At some point it might look like this:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms/ng-model-in-action.png" alt="ngModel in action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms/ng-model-in-action.png" alt="ngModel in action">
|
||||
</div>
|
||||
|
||||
The diagnostic is evidence that values really are flowing from the input box to the model and
|
||||
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:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms/ng-model-in-action-2.png" alt="ngModel in action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms/ng-model-in-action-2.png" alt="ngModel in action">
|
||||
</div>
|
||||
|
||||
The diagnostic near the top of the form
|
||||
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:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms/control-state-transitions-anim.gif" alt="Control State Transition">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms/control-state-transitions-anim.gif" alt="Control State Transition">
|
||||
</div>
|
||||
|
||||
You should see the following transitions and class names:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms/ng-control-class-changes.png" alt="Control state transitions">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms/ng-control-class-changes.png" alt="Control state transitions">
|
||||
</div>
|
||||
|
||||
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.
|
||||
@ -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
|
||||
on the left of the input box:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms/validity-required-indicator.png" alt="Invalid Form">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms/validity-required-indicator.png" alt="Invalid Form">
|
||||
</div>
|
||||
|
||||
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`:
|
||||
@ -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:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/forms/name-required-error.png" alt="Name required">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/forms/name-required-error.png" alt="Name required">
|
||||
</div>
|
||||
|
||||
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,
|
||||
Angular returns an error telling you to use `CommonModule` instead.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/frequent-ngmodules/browser-module-error.gif" width=750 alt="BrowserModule error">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/frequent-ngmodules/browser-module-error.gif" width=750 alt="BrowserModule error">
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
|
@ -108,11 +108,9 @@ The following diagram represents the relationship between the
|
||||
`root` `ModuleInjector` and its parent injectors as the
|
||||
previous paragraphs describe.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection/injectors.svg" alt="NullInjector, ModuleInjector, root injector">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection/injectors.svg" alt="NullInjector, ModuleInjector, root injector">
|
||||
</div>
|
||||
|
||||
While the name `root` is a special alias, other `ModuleInjector`s
|
||||
don't have aliases. You have the option to create `ModuleInjector`s
|
||||
@ -1098,12 +1096,9 @@ Each tax return component has the following characteristics:
|
||||
* 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.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection/hid-heroes-anim.gif" alt="Heroes in action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection/hid-heroes-anim.gif" alt="Heroes in action">
|
||||
</div>
|
||||
|
||||
Suppose that the `HeroTaxReturnComponent` had logic to manage and restore changes.
|
||||
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`.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection/car-components.png" alt="car components">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection/car-components.png" alt="car components">
|
||||
</div>
|
||||
|
||||
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).
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/dependency-injection/injector-tree.png" alt="car injector tree">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/dependency-injection/injector-tree.png" alt="car injector tree">
|
||||
</div>
|
||||
|
||||
|
||||
<hr />
|
||||
|
@ -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.
|
||||
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.
|
||||
|
||||
@ -21,40 +21,39 @@ If the errors are gone, switch back to Ivy by removing the changes to the `tscon
|
||||
{@a common-changes}
|
||||
### 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).
|
||||
|
||||
- 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).
|
||||
* 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).
|
||||
|
||||
* 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}
|
||||
### 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}`).
|
@ -38,7 +38,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.
|
||||
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.
|
||||
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 +86,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.
|
||||
|
||||
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.
|
||||
|
||||
<code-example language="json" header="tsconfig.app.json">
|
||||
@ -70,17 +97,94 @@ The following example shows how to set the `enableIvy` option to `false` in orde
|
||||
"outDir": "./out-tsc/app",
|
||||
"types": []
|
||||
},
|
||||
"files": [
|
||||
"src/main.ts",
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"src/**/*.spec.ts"
|
||||
],
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
</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>
|
||||
|
||||
{@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>
|
||||
|
@ -25,11 +25,9 @@ contextual possibilities and hints as you type.
|
||||
This example shows autocomplete in an interpolation. As you type it out,
|
||||
you can hit tab to complete.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/language-service/language-completion.gif" alt="autocompletion">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/language-service/language-completion.gif" alt="autocompletion">
|
||||
</div>
|
||||
|
||||
There are also completions within elements. Any elements you have as a component selector will
|
||||
show up in the completion list.
|
||||
@ -39,22 +37,18 @@ show up in the completion list.
|
||||
The Angular Language Service can forewarn you of mistakes in your code.
|
||||
In this example, Angular doesn't know what `orders` is or where it comes from.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/language-service/language-error.gif" alt="error checking">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/language-service/language-error.gif" alt="error checking">
|
||||
</div>
|
||||
|
||||
### Quick info and navigation
|
||||
|
||||
The quick-info feature allows you to hover to see where components, directives, modules, and so on come from.
|
||||
You can then click "Go to definition" or press F12 to go directly to the definition.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/language-service/language-navigation.gif" alt="navigation">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/language-service/language-navigation.gif" alt="navigation">
|
||||
</div>
|
||||
|
||||
|
||||
## Angular Language Service in your editor
|
||||
|
@ -29,6 +29,13 @@ generates a file called `app-routing.module.ts`, which is one of
|
||||
the files you need for setting up lazy loading for your feature module.
|
||||
Navigate into the project by issuing the command `cd customer-app`.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The `--routing` option requires Angular/CLI version 8.1 or higher.
|
||||
See [Keeping Up to Date](guide/updating).
|
||||
|
||||
</div>
|
||||
|
||||
## Create a feature module with routing
|
||||
|
||||
Next, you’ll need a feature module with a component to route to.
|
||||
@ -91,11 +98,9 @@ ng serve
|
||||
|
||||
Then go to `localhost:4200` where you should see “customer-app” and three buttons.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/three-buttons.png" width="300" alt="three buttons in the browser">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/three-buttons.png" width="300" alt="three buttons in the browser">
|
||||
</div>
|
||||
|
||||
These buttons work, because the CLI automatically added the routes to the feature modules to the `routes` array in `app.module.ts`.
|
||||
|
||||
@ -137,30 +142,24 @@ The other feature module's routing module is configured similarly.
|
||||
|
||||
You can check to see that a module is indeed being lazy loaded with the Chrome developer tools. In Chrome, open the dev tools by pressing `Cmd+Option+i` on a Mac or `Ctrl+Shift+j` on a PC and go to the Network Tab.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/network-tab.png" width="600" alt="lazy loaded modules diagram">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/network-tab.png" width="600" alt="lazy loaded modules diagram">
|
||||
</div>
|
||||
|
||||
|
||||
Click on the Orders or Customers button. If you see a chunk appear, everything is wired up properly and the feature module is being lazy loaded. A chunk should appear for Orders and for Customers but will only appear once for each.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/chunk-arrow.png" width="600" alt="lazy loaded modules diagram">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/chunk-arrow.png" width="600" alt="lazy loaded modules diagram">
|
||||
</div>
|
||||
|
||||
|
||||
To see it again, or to test after working in the project, clear everything out by clicking the circle with a line through it in the upper left of the Network Tab:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/clear.gif" width="200" alt="lazy loaded modules diagram">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/clear.gif" width="200" alt="lazy loaded modules diagram">
|
||||
</div>
|
||||
|
||||
|
||||
Then reload with `Cmd+r` or `Ctrl+r`, depending on your platform.
|
||||
|
@ -291,11 +291,9 @@ The peek-a-boo exists to show how Angular calls the hooks in the expected order.
|
||||
|
||||
This snapshot reflects the state of the log after the user clicked the *Create...* button and then the *Destroy...* button.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/lifecycle-hooks/peek-a-boo.png" alt="Peek-a-boo">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/lifecycle-hooks/peek-a-boo.png" alt="Peek-a-boo">
|
||||
</div>
|
||||
|
||||
The sequence of log messages follows the prescribed hook calling order:
|
||||
`OnChanges`, `OnInit`, `DoCheck` (3x), `AfterContentInit`, `AfterContentChecked` (3x),
|
||||
@ -351,11 +349,9 @@ Here it is attached to the repeated hero `<div>`:
|
||||
Each spy's birth and death marks the birth and death of the attached hero `<div>`
|
||||
with an entry in the *Hook Log* as seen here:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/lifecycle-hooks/spy-directive.gif' alt="Spy Directive">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/lifecycle-hooks/spy-directive.gif' alt="Spy Directive">
|
||||
</div>
|
||||
|
||||
Adding a hero results in a new hero `<div>`. The spy's `ngOnInit()` logs that event.
|
||||
|
||||
@ -444,11 +440,9 @@ The host `OnChangesParentComponent` binds to them like this:
|
||||
|
||||
Here's the sample in action as the user makes changes.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/lifecycle-hooks/on-changes-anim.gif' alt="OnChanges">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/lifecycle-hooks/on-changes-anim.gif' alt="OnChanges">
|
||||
</div>
|
||||
|
||||
The log entries appear as the string value of the *power* property changes.
|
||||
But the `ngOnChanges` does not catch changes to `hero.name`
|
||||
@ -479,11 +473,9 @@ This code inspects certain _values of interest_, capturing and comparing their c
|
||||
It writes a special message to the log when there are no substantive changes to the `hero` or the `power`
|
||||
so you can see how often `DoCheck` is called. The results are illuminating:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/lifecycle-hooks/do-check-anim.gif' alt="DoCheck">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/lifecycle-hooks/do-check-anim.gif' alt="DoCheck">
|
||||
</div>
|
||||
|
||||
While the `ngDoCheck()` hook can detect when the hero's `name` has changed, it has a frightful cost.
|
||||
This hook is called with enormous frequency—after _every_
|
||||
@ -535,11 +527,9 @@ for one turn of the browser's JavaScript cycle and that's just long enough.
|
||||
|
||||
Here's *AfterView* in action:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/lifecycle-hooks/after-view-anim.gif' alt="AfterView">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/lifecycle-hooks/after-view-anim.gif' alt="AfterView">
|
||||
</div>
|
||||
|
||||
Notice that Angular frequently calls `AfterViewChecked()`, often when there are no changes of interest.
|
||||
Write lean hook methods to avoid performance problems.
|
||||
@ -582,11 +572,9 @@ The `<ng-content>` tag is a *placeholder* for the external content.
|
||||
It tells Angular where to insert that content.
|
||||
In this case, the projected content is the `<app-child>` from the parent.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/lifecycle-hooks/projected-child-view.png' alt="Projected Content">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/lifecycle-hooks/projected-child-view.png' alt="Projected Content">
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
|
@ -1,79 +0,0 @@
|
||||
# Migration to `ngcc` npm `postinstall` script
|
||||
|
||||
## What does this schematic do?
|
||||
|
||||
This schematic adds an [Angular compatibility compiler](guide/ngcc), or `ngcc`, invocation to npm/yarn's `postinstall` script in the `package.json` of an Angular CLI workspace.
|
||||
This script is invoked after each execution of `npm install` and modifies `node_modules` by converting any found Angular libraries to a format that is compatible with Angular version 9.
|
||||
|
||||
An example diff might look like the following:
|
||||
|
||||
**Before:**
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
```
|
||||
|
||||
**After:**
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e",
|
||||
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points"
|
||||
},
|
||||
```
|
||||
|
||||
If the `package.json` already contains a `postinstall` script, then the `ngcc` invocation will be prepended to the current command:
|
||||
|
||||
**Before:**
|
||||
```json
|
||||
"scripts": {
|
||||
...
|
||||
"postinstall": "some-command"
|
||||
},
|
||||
```
|
||||
|
||||
**After:**
|
||||
```json
|
||||
"scripts": {
|
||||
...
|
||||
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points && some-command"
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## Why is this migration necessary?
|
||||
|
||||
This migration is a build performance optimization that enables `ngcc` to parallelize the compilation of npm libraries.
|
||||
An application build performed via CLI's `ng build` should succeed regardless of this `postinstall` script being installed, because the CLI has `ngcc` built-in.
|
||||
However, this built-in `ngcc` can't parallelize the compilation of multiple libraries, and therefore often takes considerably longer to run.
|
||||
|
||||
|
||||
## Can I customize the `ngcc` options in the `postinstall` script?
|
||||
|
||||
By default the `postinstall` script invokes `ngcc` with options to compile only the most commonly needed library formats.
|
||||
For some projects, especially those that depend on the CommonJS distribution of Angular (for example, Angular Universal apps), it might be beneficial to modify the `postinstall` script to also compile the CommonJS distribution of the library:
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
...
|
||||
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points && ngcc --properties main --create-ivy-entry-points"
|
||||
},
|
||||
```
|
||||
|
||||
For the full set of options run `npx ngcc --help` or `yarn ngcc --help`.
|
||||
|
||||
## Will libraries compiled with `ngcc` still be compatible with Angular version 8?
|
||||
|
||||
Yes, the migration causes `ngcc` to be invoked with the `--create-ivy-entry-points` flag, which ensures that the `ngcc` compilation is non-destructive, so the same `node_modules` can be used with Angular version 8 and version 9.
|
@ -86,11 +86,11 @@ The following table shows all methods that the migration maps from `Renderer` to
|
||||
|`createText(parentElement, value, debugInfo?)`|`appendChild(parentElement, createText(value))`|
|
||||
|`createTemplateAnchor(parentElement)`|`appendChild(parentElement, createComment(''))`|
|
||||
|`setElementClass(renderElement, className, isAdd)`|`isAdd ? addClass(renderElement, className) : removeClass(renderElement, className)`|
|
||||
|`projectNodes(parentElement, nodes)`|`for (let i = 0; i < nodes.length; i<ins></ins>) { appendChild(parentElement, nodes<i>); }`|
|
||||
|`attachViewAfter(node, viewRootNodes)`|`const parentElement = parentNode(node); const nextSibling = nextSibling(node); for (let i = 0; i < viewRootNodes.length; i<ins></ins>) { insertBefore(parentElement, viewRootNodes<i>, nextSibling);}`|
|
||||
|`detachView(viewRootNodes)`|`for (let i = 0; i < viewRootNodes.length; i<ins></ins>) {const node = viewRootNodes<i>; const parentElement = parentNode(node); removeChild(parentElement, node);}`|
|
||||
|`destroyView(hostElement, viewAllNodes)`|`for (let i = 0; i < viewAllNodes.length; i<ins></ins>) { destroyNode(viewAllNodes<i>); }`|
|
||||
|`projectNodes(parentElement, nodes)`|`for (let i = 0; i < nodes.length; i++) { appendChild(parentElement, nodes[i]); }`|
|
||||
|`attachViewAfter(node, viewRootNodes)`|`const parentElement = parentNode(node); const nextSibling = nextSibling(node); for (let i = 0; i < viewRootNodes.length; i++) { insertBefore(parentElement, viewRootNodes[i], nextSibling);}`|
|
||||
|`detachView(viewRootNodes)`|`for (let i = 0; i < viewRootNodes.length; i++) {const node = viewRootNodes[i]; const parentElement = parentNode(node); removeChild(parentElement, node);}`|
|
||||
|`destroyView(hostElement, viewAllNodes)`|`for (let i = 0; i < viewAllNodes.length; i++) { destroyNode(viewAllNodes[i]); }`|
|
||||
|`setBindingDebugInfo()`|This function is a noop in `Renderer2`.|
|
||||
|`createViewRoot(hostElement)`|Should be replaced with a reference to `hostElement`|
|
||||
|`invokeElementMethod(renderElement, methodName, args?)`|`(renderElement as any)<methodName>.apply(renderElement, args);`|
|
||||
|`invokeElementMethod(renderElement, methodName, args?)`|`(renderElement as any)[methodName].apply(renderElement, args);`|
|
||||
|`animate(element, startingStyles, keyframes, duration, delay, easing, previousPlayers?)`|Throws an error (same behavior as `Renderer.animate()`)|
|
||||
|
@ -106,13 +106,9 @@ As you click the button, the displayed date alternates between
|
||||
"**<samp>04/15/1988</samp>**" and
|
||||
"**<samp>Friday, April 15, 1988</samp>**".
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/pipes/date-format-toggle-anim.gif' alt="Date Format Toggle">
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/date-format-toggle-anim.gif' alt="Date Format Toggle">
|
||||
</div>
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
@ -188,11 +184,9 @@ Now you need a component to demonstrate the pipe.
|
||||
|
||||
<code-example path="pipes/src/app/power-booster.component.ts" header="src/app/power-booster.component.ts"></code-example>
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/pipes/power-booster.png' alt="Power Booster">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/power-booster.png' alt="Power Booster">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -234,11 +228,9 @@ your pipe and two-way data binding with `ngModel`.
|
||||
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/pipes/power-boost-calculator-anim.gif' alt="Power Boost Calculator">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/power-boost-calculator-anim.gif' alt="Power Boost Calculator">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -313,11 +305,9 @@ The Flying Heroes application extends the
|
||||
code with checkbox switches and additional displays to help you experience these effects.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/pipes/flying-heroes-anim.gif' alt="Flying Heroes">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/flying-heroes-anim.gif' alt="Flying Heroes">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -494,11 +484,9 @@ both requesting the heroes from the `heroes.json` file.
|
||||
The component renders as the following:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/pipes/hero-list.png' alt="Hero List">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/hero-list.png' alt="Hero List">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
@ -57,7 +57,7 @@ Though you can provide services by lazy loading modules, not all services can be
|
||||
|
||||
Another way to limit provider scope is by adding the service you want to limit to the component’s
|
||||
`providers` array. Component providers and NgModule providers are independent of each other. This
|
||||
method is helpful for when you want to eagerly load a module that needs a service all to itself.
|
||||
method is helpful when you want to eagerly load a module that needs a service all to itself.
|
||||
Providing a service in the component limits the service only to that component (other components in
|
||||
the same module can’t access it.)
|
||||
|
||||
|
@ -64,11 +64,9 @@ The form control assigned to `name` is displayed when the component is added to
|
||||
|
||||
<code-example path="reactive-forms/src/app/app.component.1.html" region="app-name-editor" header="src/app/app.component.html (name editor)"></code-example>
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/reactive-forms/name-editor-1.png" alt="Name Editor">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/reactive-forms/name-editor-1.png" alt="Name Editor">
|
||||
</div>
|
||||
|
||||
## Managing control values
|
||||
|
||||
@ -110,11 +108,9 @@ Update the template with a button to simulate a name update. When you click the
|
||||
|
||||
The form model is the source of truth for the control, so when you click the button, the value of the input is changed within the component class, overriding its current value.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/reactive-forms/name-editor-2.png" alt="Name Editor Update">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/reactive-forms/name-editor-2.png" alt="Name Editor Update">
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@ -192,11 +188,9 @@ To display the `ProfileEditor` component that contains the form, add it to a com
|
||||
|
||||
`ProfileEditor` allows you to manage the form control instances for the `firstName` and `lastName` controls within the form group instance.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/reactive-forms/profile-editor-1.png" alt="Profile Editor">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/reactive-forms/profile-editor-1.png" alt="Profile Editor">
|
||||
</div>
|
||||
|
||||
## Creating nested form groups
|
||||
|
||||
@ -220,11 +214,9 @@ Add the `address` form group containing the `street`, `city`, `state`, and `zip`
|
||||
|
||||
The `ProfileEditor` form is displayed as one group, but the model is broken down further to represent the logical grouping areas.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/reactive-forms/profile-editor-2.png" alt="Profile Editor Update">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/reactive-forms/profile-editor-2.png" alt="Profile Editor Update">
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@ -354,11 +346,9 @@ Display the current status of `profileForm` using interpolation.
|
||||
|
||||
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="display-status" header="src/app/profile-editor/profile-editor.component.html (display status)"></code-example>
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/reactive-forms/profile-editor-3.png" alt="Profile Editor Validation">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/reactive-forms/profile-editor-3.png" alt="Profile Editor Validation">
|
||||
</div>
|
||||
|
||||
The **Submit** button is disabled because `profileForm` is invalid due to the required `firstName` form control. After you fill out the `firstName` input, the form becomes valid and the **Submit** button is enabled.
|
||||
|
||||
@ -422,11 +412,9 @@ Add the template HTML below after the `<div>` closing the `formGroupName` elemen
|
||||
|
||||
The `*ngFor` directive iterates over each form control instance provided by the aliases form array instance. Because form array elements are unnamed, you assign the index to the `i` variable and pass it to each control to bind it to the `formControlName` input.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/reactive-forms/profile-editor-4.png" alt="Profile Editor Aliases">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/reactive-forms/profile-editor-4.png" alt="Profile Editor Aliases">
|
||||
</div>
|
||||
|
||||
Each time a new alias instance is added, the new form array instance is provided its control based on the index. This allows you to track each individual control when calculating the status and value of the root control.
|
||||
|
||||
|
@ -25,11 +25,9 @@ Let's illustrate a router transition animation by navigating between two routes,
|
||||
|
||||
</br>
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/animations/route-animation.gif" alt="Animations in action" width="440">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/animations/route-animation.gif" alt="Animations in action" width="440">
|
||||
</div>
|
||||
|
||||
## Route configuration
|
||||
|
||||
|
@ -765,21 +765,17 @@ Once the app warms up, you'll see a row of navigation buttons
|
||||
and the *Heroes* view with its list of heroes.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/hero-list.png' alt="Hero List">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/hero-list.png' alt="Hero List">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Select one hero and the app takes you to a hero editing screen.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/hero-detail.png' alt="Crisis Center Detail">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/hero-detail.png' alt="Crisis Center Detail">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -794,11 +790,9 @@ Angular app navigation updates the browser history as normal web navigation does
|
||||
Now click the *Crisis Center* link for a list of ongoing crises.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/crisis-center-list.png' alt="Crisis Center List">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/crisis-center-list.png' alt="Crisis Center List">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -809,11 +803,9 @@ Alter the name of a crisis.
|
||||
Notice that the corresponding name in the crisis list does _not_ change.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/crisis-center-detail.png' alt="Crisis Center Detail">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/crisis-center-detail.png' alt="Crisis Center Detail">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -827,11 +819,9 @@ Click the browser back button or the "Heroes" link instead.
|
||||
Up pops a dialog box.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/confirm-dialog.png' alt="Confirm Dialog">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/confirm-dialog.png' alt="Confirm Dialog">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -852,11 +842,9 @@ Proceed to the first application milestone.
|
||||
Begin with a simple version of the app that navigates between two empty views.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/router-1-anim.gif' alt="App in action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/router-1-anim.gif' alt="App in action">
|
||||
</div>
|
||||
|
||||
{@a import}
|
||||
|
||||
@ -940,11 +928,9 @@ Registering the `RouterModule.forRoot()` in the `AppModule` imports makes the `R
|
||||
The root `AppComponent` is the application shell. It has a title, a navigation bar with two links, and a router outlet where the router swaps components on and off the page. Here's what you get:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/shell-and-outlet.png' alt="Shell">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/shell-and-outlet.png' alt="Shell">
|
||||
</div>
|
||||
|
||||
The router outlet serves as a placeholder when the routed components will be rendered below it.
|
||||
|
||||
@ -1377,11 +1363,9 @@ from the <live-example name="toh-pt4" title="Tour of Heroes: Services example co
|
||||
Here's how the user will experience this version of the app:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/router-2-anim.gif' alt="App in action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/router-2-anim.gif' alt="App in action">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -1960,11 +1944,9 @@ For example, when returning to the hero-detail.component.ts list from the hero d
|
||||
it would be nice if the viewed hero was preselected in the list.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/selected-hero.png' alt="Selected hero">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/selected-hero.png' alt="Selected hero">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -2147,11 +2129,9 @@ Add some styles to apply when the list item is selected.
|
||||
|
||||
When the user navigates from the heroes list to the "Magneta" hero and back, "Magneta" appears selected:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/selected-hero.png' alt="Selected List">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/selected-hero.png' alt="Selected List">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -2543,11 +2523,9 @@ to conform to the following recommended pattern for Angular applications:
|
||||
If your app had many feature areas, the app component trees might look like this:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/component-tree.png' alt="Component Tree">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/component-tree.png' alt="Component Tree">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -2811,11 +2789,9 @@ It displays a simple form with a header, an input box for the message,
|
||||
and two buttons, "Send" and "Cancel".
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/router/contact-popup.png' alt="Contact popup">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/router/contact-popup.png' alt="Contact popup">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
@ -359,11 +359,9 @@ When you add a new named schematic to this collection, it is automatically added
|
||||
In addition to the name and description, each schematic has a `factory` property that identifies the schematic’s entry point.
|
||||
In the example, you invoke the schematic's defined functionality by calling the `helloWorld()` function in the main file, `hello-world/index.ts`.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/schematics/collection-files.gif" alt="overview">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/schematics/collection-files.gif" alt="overview">
|
||||
</div>
|
||||
|
||||
Each named schematic in the collection has the following main parts.
|
||||
|
||||
|
@ -118,11 +118,9 @@ Angular recognizes the value as unsafe and automatically sanitizes it, which rem
|
||||
tag but keeps safe content such as the `<b>` element.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/security/binding-inner-html.png' alt='A screenshot showing interpolated and bound HTML values'>
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/security/binding-inner-html.png' alt='A screenshot showing interpolated and bound HTML values'>
|
||||
</div>
|
||||
|
||||
|
||||
### Direct use of the DOM APIs and explicit sanitization calls
|
||||
@ -211,11 +209,9 @@ this, mark the URL value as a trusted URL using the `bypassSecurityTrustUrl` cal
|
||||
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/security/bypass-security-component.png' alt='A screenshot showing an alert box created from a trusted URL'>
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/security/bypass-security-component.png' alt='A screenshot showing an alert box created from a trusted URL'>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
@ -74,11 +74,9 @@ To simulate a network issue, disable network interaction for your application. I
|
||||
2. Go to the **Network tab**.
|
||||
3. Check the **Offline box**.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/service-worker/offline-checkbox.png" alt="The offline checkbox in the Network tab is checked">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/service-worker/offline-checkbox.png" alt="The offline checkbox in the Network tab is checked">
|
||||
</div>
|
||||
|
||||
Now the app has no access to network interaction.
|
||||
|
||||
@ -88,11 +86,9 @@ With the addition of an Angular service worker, the application behavior changes
|
||||
|
||||
If you look at the Network tab, you can verify that the service worker is active.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/service-worker/sw-active.png" alt="Requests are marked as from ServiceWorker">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/service-worker/sw-active.png" alt="Requests are marked as from ServiceWorker">
|
||||
</div>
|
||||
|
||||
Notice that under the "Size" column, the requests state is `(from ServiceWorker)`. This means that the resources are not being loaded from the network. Instead, they are being loaded from the service worker's cache.
|
||||
|
||||
@ -146,11 +142,9 @@ Now look at how the browser and service worker handle the updated application.
|
||||
|
||||
1. Open http://localhost:8080 again in the same window. What happens?
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/service-worker/welcome-msg-en.png" alt="It still says Welcome to Service Workers!">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/service-worker/welcome-msg-en.png" alt="It still says Welcome to Service Workers!">
|
||||
</div>
|
||||
|
||||
What went wrong? Nothing, actually. The Angular service worker is doing its job and serving the version of the application that it has **installed**, even though there is an update available. In the interest of speed, the service worker doesn't wait to check for updates before it serves the application that it has cached.
|
||||
|
||||
@ -158,11 +152,9 @@ If you look at the `http-server` logs, you can see the service worker requesting
|
||||
|
||||
2. Refresh the page.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/service-worker/welcome-msg-fr.png" alt="The text has changed to say Bienvenue à app!">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/service-worker/welcome-msg-fr.png" alt="The text has changed to say Bienvenue à app!">
|
||||
</div>
|
||||
|
||||
The service worker installed the updated version of your app *in the background*, and the next time the page is loaded or reloaded, the service worker switches to the latest version.
|
||||
|
||||
|
@ -47,11 +47,9 @@ You can inject the `Title` service into the root `AppComponent` and expose a bin
|
||||
|
||||
Bind that method to three anchor tags and voilà!
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/set-document-title/set-title-anim.gif" alt="Set title">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/set-document-title/set-title-anim.gif" alt="Set title">
|
||||
</div>
|
||||
|
||||
Here's the complete solution:
|
||||
|
||||
|
@ -104,11 +104,9 @@ to `http://localhost:4200/`.
|
||||
Your app greets you with a message:
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/setup-local/app-works.png' alt="Welcome to my-app!">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/setup-local/app-works.png' alt="Welcome to my-app!">
|
||||
</div>
|
||||
|
||||
|
||||
## Next steps
|
||||
|
@ -125,11 +125,9 @@ The `ngIf` directive doesn't hide elements with CSS. It adds and removes them ph
|
||||
Confirm that fact using browser developer tools to inspect the DOM.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/structural-directives/element-not-in-dom.png' alt="ngIf=false element not in DOM">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/structural-directives/element-not-in-dom.png' alt="ngIf=false element not in DOM">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -153,11 +151,9 @@ A directive could hide the unwanted paragraph instead by setting its `display` s
|
||||
While invisible, the element remains in the DOM.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/structural-directives/element-display-in-dom.png' alt="hidden element still in DOM">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/structural-directives/element-display-in-dom.png' alt="hidden element still in DOM">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -215,11 +211,9 @@ Internally, Angular translates the `*ngIf` _attribute_ into a `<ng-template>` _e
|
||||
The first form is not actually rendered, only the finished product ends up in the DOM.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/structural-directives/hero-div-in-dom.png' alt="hero div in DOM">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/structural-directives/hero-div-in-dom.png' alt="hero div in DOM">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -565,11 +559,9 @@ That's the fate of the middle "Hip!" in the phrase "Hip! Hip! Hooray!".
|
||||
Angular erases the middle "Hip!", leaving the cheer a bit less enthusiastic.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/structural-directives/template-rendering.png' alt="template tag rendering">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/structural-directives/template-rendering.png' alt="template tag rendering">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -625,11 +617,9 @@ You also have a CSS style rule that happens to apply to a `<span>` within a `<p>
|
||||
The constructed paragraph renders strangely.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/structural-directives/bad-paragraph.png' alt="spanned paragraph with bad style">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/structural-directives/bad-paragraph.png' alt="spanned paragraph with bad style">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -649,11 +639,9 @@ When you try this,
|
||||
the drop down is empty.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/structural-directives/bad-select.png' alt="spanned options don't work">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/structural-directives/bad-select.png' alt="spanned options don't work">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -674,11 +662,9 @@ Here's the conditional paragraph again, this time using `<ng-container>`.
|
||||
It renders properly.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/structural-directives/good-paragraph.png' alt="ngcontainer paragraph with proper style">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/structural-directives/good-paragraph.png' alt="ngcontainer paragraph with proper style">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -692,11 +678,9 @@ Now conditionally exclude a _select_ `<option>` with `<ng-container>`.
|
||||
The drop down works properly.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/structural-directives/select-ngcontainer-anim.gif' alt="ngcontainer options work properly">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/structural-directives/select-ngcontainer-anim.gif' alt="ngcontainer options work properly">
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@ -844,11 +828,9 @@ When the `condition` is falsy, the top (A) paragraph appears and the bottom (B)
|
||||
When the `condition` is truthy, the top (A) paragraph is removed and the bottom (B) paragraph appears.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/structural-directives/unless-anim.gif' alt="UnlessDirective in action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/structural-directives/unless-anim.gif' alt="UnlessDirective in action">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
@ -969,11 +969,9 @@ template statement on the right.
|
||||
The following event binding listens for the button's click events, calling
|
||||
the component's `onSave()` method whenever a click occurs:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/template-syntax/syntax-diagram.svg' alt="Syntax diagram">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/template-syntax/syntax-diagram.svg' alt="Syntax diagram">
|
||||
</div>
|
||||
|
||||
### Target event
|
||||
|
||||
@ -1107,6 +1105,8 @@ It has a `size` value property and a companion `sizeChange` event:
|
||||
|
||||
<code-example path="two-way-binding/src/app/sizer/sizer.component.ts" header="src/app/sizer.component.ts"></code-example>
|
||||
|
||||
<code-example path="two-way-binding/src/app/sizer/sizer.component.html" header="src/app/sizer.component.html"></code-example>
|
||||
|
||||
The initial `size` is an input value from a property binding.
|
||||
Clicking the buttons increases or decreases the `size`, within
|
||||
min/max value constraints,
|
||||
@ -1308,11 +1308,9 @@ for example, the following changes the `<input>` value to uppercase:
|
||||
|
||||
Here are all variations in action, including the uppercase version:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/built-in-directives/ng-model-anim.gif' alt="NgModel variations">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/built-in-directives/ng-model-anim.gif' alt="NgModel variations">
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
@ -1516,11 +1514,9 @@ Here is an illustration of the `trackBy` effect.
|
||||
* With no `trackBy`, both buttons trigger complete DOM element replacement.
|
||||
* With `trackBy`, only changing the `id` triggers element replacement.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/built-in-directives/ngfor-trackby.gif" alt="Animation of trackBy">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/built-in-directives/ngfor-trackby.gif" alt="Animation of trackBy">
|
||||
</div>
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
@ -1544,11 +1540,9 @@ Angular puts only the selected element into the DOM.
|
||||
|
||||
<code-example path="built-in-directives/src/app/app.component.html" region="NgSwitch" header="src/app/app.component.html"></code-example>
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/built-in-directives/ngswitch.gif" alt="Animation of NgSwitch">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/built-in-directives/ngswitch.gif" alt="Animation of NgSwitch">
|
||||
</div>
|
||||
|
||||
`NgSwitch` is the controller directive. Bind it to an expression that returns
|
||||
the *switch value*, such as `feature`. Though the `feature` value in this
|
||||
@ -1703,11 +1697,9 @@ child component. So an `@Input()` allows data to be input _into_ the
|
||||
child component from the parent component.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/inputs-outputs/input.svg" alt="Input data flow diagram">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/inputs-outputs/input.svg" alt="Input data flow diagram">
|
||||
</div>
|
||||
|
||||
To illustrate the use of `@Input()`, edit these parts of your app:
|
||||
|
||||
@ -1752,11 +1744,9 @@ With `@Input()`, Angular passes the value for `currentItem` to the child so that
|
||||
|
||||
The following diagram shows this structure:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/inputs-outputs/input-diagram-target-source.svg" alt="Property binding diagram">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/inputs-outputs/input-diagram-target-source.svg" alt="Property binding diagram">
|
||||
</div>
|
||||
|
||||
The target in the square brackets, `[]`, is the property you decorate
|
||||
with `@Input()` in the child component. The binding source, the part
|
||||
@ -1788,11 +1778,9 @@ the child _out_ to the parent.
|
||||
An `@Output()` property should normally be initialized to an Angular [`EventEmitter`](api/core/EventEmitter) with values flowing out of the component as [events](#event-binding).
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/inputs-outputs/output.svg" alt="Output diagram">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/inputs-outputs/output.svg" alt="Output diagram">
|
||||
</div>
|
||||
|
||||
Just like with `@Input()`, you can use `@Output()`
|
||||
on a property of the child component but its type should be
|
||||
@ -1932,11 +1920,9 @@ The target, `item`, which is an `@Input()` property in the child component class
|
||||
The following diagram is of an `@Input()` and an `@Output()` on the same
|
||||
child component and shows the different parts of each:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/inputs-outputs/input-output-diagram.svg" alt="Input/Output diagram">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/inputs-outputs/input-output-diagram.svg" alt="Input/Output diagram">
|
||||
</div>
|
||||
|
||||
As the diagram shows, use inputs and outputs together in the same manner as using them separately. Here, the child selector is `<app-input-output>` with `item` and `deleteRequest` being `@Input()` and `@Output()`
|
||||
properties in the child component class. The property `currentItem` and the method `crossOffItem()` are both in the parent component class.
|
||||
|
@ -1,41 +1,47 @@
|
||||
# Template type-checking
|
||||
# Template type checking
|
||||
|
||||
## Overview of template type-checking
|
||||
## Overview of template type checking
|
||||
|
||||
Just as TypeScript catches type errors in your code, Angular checks the expressions and bindings within the templates of your application and can report any type errors it finds. Angular currently has three modes of doing this, depending on the value of the `fullTemplateTypeCheck` and `strictTemplates` flags.
|
||||
Just as TypeScript catches type errors in your code, Angular checks the expressions and bindings within the templates of your application and can report any type errors it finds.
|
||||
Angular currently has three modes of doing this, depending on the value of the `fullTemplateTypeCheck` and `strictTemplates` flags in the [TypeScript configuration file](guide/typescript-configuration), `tsconfig.json`.
|
||||
|
||||
### Basic mode
|
||||
|
||||
In the most basic type-checking mode, with the `fullTemplateTypeCheck` flag set to `false`, Angular will only validate top-level expressions in a template.
|
||||
In the most basic type-checking mode, with the `fullTemplateTypeCheck` flag set to `false`, Angular validates only top-level expressions in a template.
|
||||
|
||||
If you write `<map [city]="user.address.city">`, the compiler will verify the following:
|
||||
If you write `<map [city]="user.address.city">`, the compiler verifies the following:
|
||||
|
||||
* `user` is a property on the component class.
|
||||
* `user` is an object with an address property.
|
||||
* `user.address` is an object with a city property.
|
||||
|
||||
The compiler will not verify that the value of `user.address.city` is assignable to the city input of the `<map>` component.
|
||||
The compiler does not verify that the value of `user.address.city` is assignable to the city input of the `<map>` component.
|
||||
|
||||
The compiler also has some major limitations in this mode:
|
||||
|
||||
* Importantly, it won't check embedded views, such as `*ngIf`, `*ngFor`, other `<ng-template>` embedded view.
|
||||
* It won't figure out the types of `#refs`, the results of pipes, the type of `$event` in event bindings, etc.
|
||||
* In many cases, these things end up as type `any` which can cause subsequent parts of the expression to go unchecked.
|
||||
* Importantly, it doesn't check embedded views, such as `*ngIf`, `*ngFor`, other `<ng-template>` embedded view.
|
||||
* It doesn't figure out the types of `#refs`, the results of pipes, the type of `$event` in event bindings, and so on.
|
||||
|
||||
In many cases, these things end up as type `any`, which can cause subsequent parts of the expression to go unchecked.
|
||||
|
||||
|
||||
|
||||
### Full mode
|
||||
|
||||
If the `fullTemplateTypeCheck` flag is set to `true`, Angular will be more aggressive in its type-checking within templates.
|
||||
If the `fullTemplateTypeCheck` flag is set to `true`, Angular is more aggressive in its type-checking within templates.
|
||||
In particular:
|
||||
|
||||
* Embedded views (such as those within an `*ngIf` or `*ngFor`) will be checked.
|
||||
* Pipes will have the correct return type.
|
||||
* Local references to directives and pipes will have the correct type (except for any generic parameters, which will be `any`).
|
||||
* Local references to DOM elements will still have type `any`.
|
||||
* `$event` will still have type `any`.
|
||||
* Safe navigation expressions will still have type `any`.
|
||||
* Embedded views (such as those within an `*ngIf` or `*ngFor`) are checked.
|
||||
* Pipes have the correct return type.
|
||||
* Local references to directives and pipes have the correct type (except for any generic parameters, which will be `any`).
|
||||
|
||||
The following still have type `any`.
|
||||
|
||||
* Local references to DOM elements.
|
||||
* The `$event` object.
|
||||
* Safe navigation expressions.
|
||||
|
||||
{@a strict-mode}
|
||||
|
||||
### Strict mode
|
||||
|
||||
@ -56,7 +62,7 @@ In addition to the full mode behavior, Angular version 9:
|
||||
|
||||
## Checking of `*ngFor`
|
||||
|
||||
The three modes of type-checking treat embedded views differently. Consider the following example:
|
||||
The three modes of type-checking treat embedded views differently. Consider the following example.
|
||||
|
||||
|
||||
<code-example language="ts" header="User interface">
|
||||
@ -81,27 +87,28 @@ interface User {
|
||||
|
||||
The `<h2>` and the `<span>` are in the `*ngFor` embedded view.
|
||||
In basic mode, Angular doesn't check either of them.
|
||||
However, in full mode, Angular checks that `config` and `user` exists and assumes a type of `any`.
|
||||
In strict mode, Angular knows that the `user` in the `<span>` has a type of `User` as well as `address` is an object with a `city` property of type `string`.
|
||||
However, in full mode, Angular checks that `config` and `user` exist and assumes a type of `any`.
|
||||
In strict mode, Angular knows that the `user` in the `<span>` has a type of `User`, and that `address` is an object with a `city` property of type `string`.
|
||||
|
||||
{@a troubleshooting-template-errors}
|
||||
|
||||
## Troubleshooting template errors
|
||||
|
||||
When enabling the new strict mode in version 9, you might encounter template errors which didn't arise in either of the previous modes. These errors often represent genuine type mismatches in the templates which were not caught by the previous tooling. If this is the case, the error message should make it clear where in the template the problem occurs.
|
||||
When enabling the new strict mode in version 9, you might encounter template errors that didn't arise in either of the previous modes.
|
||||
These errors often represent genuine type mismatches in the templates that were not caught by the previous tooling.
|
||||
If this is the case, the error message should make it clear where in the template the problem occurs.
|
||||
|
||||
They can also be false positives when the typings of an Angular library are either incomplete or incorrect, or when the typings don't quite line up with expectations as in the following:
|
||||
There can also be false positives when the typings of an Angular library are either incomplete or incorrect, or when the typings don't quite line up with expectations as in the following cases.
|
||||
|
||||
1. When a library's typings are wrong or incomplete (for example, missing `null | undefined` if the library was not written with `strictNullChecks` in mind).
|
||||
1. When a library's input types are too narrow and the library hasn't added appropriate metadata for Angular to figure this out. This usually occurs with disabled or other common boolean inputs used as attributes, for example, `<input disabled>`.
|
||||
1. When using `$event.target` for DOM events (because of the possibility of event bubbling, `$event.target` in the DOM typings doesn't have the type you might expect).
|
||||
|
||||
It's also possible that an error can be the result of a bug in the template type-checker itself.
|
||||
* When a library's typings are wrong or incomplete (for example, missing `null | undefined` if the library was not written with `strictNullChecks` in mind).
|
||||
* When a library's input types are too narrow and the library hasn't added appropriate metadata for Angular to figure this out. This usually occurs with disabled or other common Boolean inputs used as attributes, for example, `<input disabled>`.
|
||||
* When using `$event.target` for DOM events (because of the possibility of event bubbling, `$event.target` in the DOM typings doesn't have the type you might expect).
|
||||
|
||||
In case of a false positive like these, there are a few options:
|
||||
|
||||
* `$any()` can be used in certain contexts to opt out of type-checking for a part of the expression.
|
||||
* `strictTemplates` can be disabled entirely.
|
||||
* Certain type-checking operations can be disabled individually, while maintaining strictness in other aspects, by setting a _strictness flag_ to `false`.
|
||||
* Use the [`$any()` type-cast function](guide/template-syntax#any-type-cast-function) in certain contexts to opt out of type-checking for a part of the expression.
|
||||
* You can disable strict checks entirely by setting `strictTemplates: false` in the application's TypeScript configuration file, `tsconfig.json`.
|
||||
* You can disable certain type-checking operations individually, while maintaining strictness in other aspects, by setting a _strictness flag_ to `false`.
|
||||
|
||||
|Strictness flag|Effect|
|
||||
|-|-|
|
||||
@ -116,4 +123,8 @@ In case of a false positive like these, there are a few options:
|
||||
|
||||
If you still have issues after troubleshooting with these flags, you can fall back to full mode by disabling `strictTemplates`.
|
||||
|
||||
If that doesn't work, an option of last resort is to turn off full mode entirely with `fullTemplateTypeCheck: false`, as we've made a special effort to make Angular version 9 backwards compatible in this case. If you get errors that require falling back to basic mode, then please [file an issue](https://github.com/angular/angular/issues) so the team can address it, as it is almost definitely a bug.
|
||||
If that doesn't work, an option of last resort is to turn off full mode entirely with `fullTemplateTypeCheck: false`, as we've made a special effort to make Angular version 9 backwards compatible in this case.
|
||||
|
||||
A type-checking error that you cannot resolve with any of the recommended methods can be the result of a bug in the template type-checker itself.
|
||||
If you get errors that require falling back to basic mode, it is likely to be such a bug.
|
||||
If this happens, please [file an issue](https://github.com/angular/angular/issues) so the team can address it.
|
||||
|
@ -41,11 +41,9 @@ It shows that Karma ran three tests that all passed.
|
||||
|
||||
A chrome browser also opens and displays the test output in the "Jasmine HTML Reporter" like this.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/testing/initial-jasmine-html-reporter.png' alt="Jasmine HTML Reporter in the browser">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/testing/initial-jasmine-html-reporter.png' alt="Jasmine HTML Reporter in the browser">
|
||||
</div>
|
||||
|
||||
Most people find this browser output easier to read than the console log.
|
||||
You can click on a test row to re-run just that test or click on a description to re-run the tests in the selected test group ("test suite").
|
||||
@ -2262,11 +2260,9 @@ tests with the `RouterTestingModule`.
|
||||
|
||||
The `HeroDetailComponent` is a simple view with a title, two hero fields, and two buttons.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/testing/hero-detail.component.png' alt="HeroDetailComponent in action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/testing/hero-detail.component.png' alt="HeroDetailComponent in action">
|
||||
</div>
|
||||
|
||||
But there's plenty of template complexity even in this simple form.
|
||||
|
||||
@ -2693,11 +2689,9 @@ A better solution is to create an artificial test component that demonstrates al
|
||||
|
||||
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="test-component" header="app/shared/highlight.directive.spec.ts (TestComponent)"></code-example>
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/testing/highlight-directive-spec.png' alt="HighlightDirective spec in action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/testing/highlight-directive-spec.png' alt="HighlightDirective spec in action">
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@ -2776,11 +2770,9 @@ Debug specs in the browser in the same way that you debug an application.
|
||||
1. Set a breakpoint in the test.
|
||||
1. Refresh the browser, and it stops at the breakpoint.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging">
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
|
@ -14,11 +14,9 @@ An asterisk `*` or *wildcard* matches any animation state. This is useful for de
|
||||
|
||||
For example, a transition of `open => *` applies when the element's state changes from open to anything else.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/animations/wildcard-state-500.png" alt="wildcard state expressions">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/animations/wildcard-state-500.png" alt="wildcard state expressions">
|
||||
</div>
|
||||
|
||||
Here's another code sample using the wildcard state together with our previous example using the `open` and `closed` states. Instead of defining each state-to-state transition pair, we're now saying that any transition to `closed` takes 1 second, and any transition to `open` takes 0.5 seconds.
|
||||
|
||||
@ -34,11 +32,9 @@ Use a double arrow syntax to specify state-to-state transitions in both directio
|
||||
|
||||
In our two-state button example, the wildcard isn't that useful because there are only two possible states, `open` and `closed`. Wildcard states are better when an element in one particular state has multiple potential states that it can change to. If our button can change from `open` to either `closed` or something like `inProgress`, using a wildcard state could reduce the amount of coding needed.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/animations/wildcard-3-states.png" alt="wildcard state with 3 states">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/animations/wildcard-3-states.png" alt="wildcard state with 3 states">
|
||||
</div>
|
||||
|
||||
|
||||
<code-example path="animations/src/app/open-close.component.ts" header="src/app/open-close.component.ts" region="trigger-transition" language="typescript"></code-example>
|
||||
@ -221,11 +217,9 @@ In the previous section, we saw a simple two-state transition. Now we'll create
|
||||
|
||||
Angular's `keyframe()` function is similar to keyframes in CSS. Keyframes allow several style changes within a single timing segment. For example, our button, instead of fading, could change color several times over a single 2-second timespan.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/animations/keyframes-500.png" alt="keyframes">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/animations/keyframes-500.png" alt="keyframes">
|
||||
</div>
|
||||
|
||||
The code for this color change might look like this.
|
||||
|
||||
@ -237,11 +231,9 @@ Keyframes include an *offset* that defines the point in the animation where each
|
||||
|
||||
Defining offsets for keyframes is optional. If you omit them, evenly spaced offsets are automatically assigned. For example, three keyframes without predefined offsets receive offsets of 0, 0.5, and 1. Specifying an offset of 0.8 for the middle transition in the above example might look like this.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/animations/keyframes-offset-500.png" alt="keyframes with offset">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/animations/keyframes-offset-500.png" alt="keyframes with offset">
|
||||
</div>
|
||||
|
||||
The code with offsets specified would be as follows.
|
||||
|
||||
@ -260,11 +252,9 @@ Here's an example of using keyframes to create a pulse effect:
|
||||
|
||||
* A keyframes sequence inserted in the middle that causes the button to appear to pulsate irregularly over the course of that same 1-second timeframe
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/animations/keyframes-pulsation.png" alt="keyframes with irregular pulsation">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/animations/keyframes-pulsation.png" alt="keyframes with irregular pulsation">
|
||||
</div>
|
||||
|
||||
The code snippet for this animation might look like this.
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
TypeScript is a primary language for Angular application development.
|
||||
It is a superset of JavaScript with design-time support for type safety and tooling.
|
||||
|
||||
Browsers can't execute TypeScript directly. Typescript must be "transpiled" into JavaScript using the *tsc* compiler,
|
||||
which requires some configuration.
|
||||
Browsers can't execute TypeScript directly.
|
||||
Typescript must be "transpiled" into JavaScript using the *tsc* compiler, which requires some configuration.
|
||||
|
||||
This page covers some aspects of TypeScript configuration and the TypeScript environment
|
||||
that are important to Angular developers, including details about the following files:
|
||||
@ -15,11 +15,11 @@ that are important to Angular developers, including details about the following
|
||||
|
||||
{@a tsconfig}
|
||||
|
||||
## TypeScript configuration
|
||||
|
||||
|
||||
## *tsconfig.json*
|
||||
Typically, you add a TypeScript configuration file called `tsconfig.json` to your project to
|
||||
guide the compiler as it generates JavaScript files.
|
||||
A TypeScript configuration file called `tsconfig.json` guides the compiler as it generates JavaScript files for a project.
|
||||
This file contains options and flags that are essential for Angular applications.
|
||||
Typically, the file is found at the [root level of the workspace](guide/file-structure).
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@ -28,38 +28,38 @@ For details about `tsconfig.json`, see the official
|
||||
|
||||
</div>
|
||||
|
||||
The initial `tsconfig.json` for an Angular app typically looks like this example:
|
||||
|
||||
The initial `tsconfig.json` for an Angular app typically looks like the following example.
|
||||
|
||||
<code-example lang="json" header="tsconfig.json" linenums="false">
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"importHelpers": true,
|
||||
"target": "es5",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
]
|
||||
}
|
||||
}
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true
|
||||
}
|
||||
}
|
||||
</code-example>
|
||||
|
||||
|
||||
This file contains options and flags that are essential for Angular applications.
|
||||
|
||||
|
||||
{@a noImplicitAny}
|
||||
|
||||
|
||||
@ -90,9 +90,15 @@ You can suppress them with the following additional flag:
|
||||
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For more information about how the TypeScript configuration affects compilation, see [Angular Compiler Options](guide/angular-compiler-options) and [Template Type Checking](guide/template-typecheck).
|
||||
|
||||
</div>
|
||||
|
||||
{@a typings}
|
||||
|
||||
## TypeScript Typings
|
||||
## TypeScript typings
|
||||
|
||||
Many JavaScript libraries, such as jQuery, the Jasmine testing library, and Angular,
|
||||
extend the JavaScript environment with features and syntax
|
||||
@ -107,8 +113,12 @@ Many libraries include definition files in their npm packages where both the Typ
|
||||
can find them. Angular is one such library.
|
||||
The `node_modules/@angular/core/` folder of any Angular application contains several `d.ts` files that describe parts of Angular.
|
||||
|
||||
**You don't need to do anything to get *typings* files for library packages that include `d.ts` files.
|
||||
Angular packages include them already.**
|
||||
<div class="alert is-helpful">
|
||||
|
||||
You don't need to do anything to get *typings* files for library packages that include `d.ts` files.
|
||||
Angular packages include them already.
|
||||
|
||||
</div>
|
||||
|
||||
### lib.d.ts
|
||||
|
||||
|
@ -2,35 +2,52 @@
|
||||
|
||||
This guide contains everything you need to know about updating to the next Angular version.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For step-by-step instructions on how to update to the latest Angular release, use the interactive update guide at [update.angular.io](https://update.angular.io).
|
||||
|
||||
</div>
|
||||
|
||||
## Updating CLI Apps
|
||||
|
||||
If your application uses the CLI, you can update to version 9 automatically with the help of the `ng update` script:
|
||||
|
||||
```
|
||||
npm install --no-save @angular/cli@^8.3.15
|
||||
```sh
|
||||
ng update @angular/core@8 @angular/cli@8
|
||||
git add .
|
||||
git commit --all -m "build: update Angular packages to latest 8.x version"
|
||||
ng update @angular/cli @angular/core --next
|
||||
```
|
||||
|
||||
<div class="alert is-important">
|
||||
In order to improve the updating experience, we strongly suggest that you update your local `@angular/cli` to version 8.3.15 or later 8.x version before updating.
|
||||
In order to improve the updating experience, we strongly suggest that you update to the latest 8.x version of `@angular/core` and `@angular/cli`.
|
||||
|
||||
Additionally, during the RC period, the `--next` command line flag is required. This flag will no longer be necessary once version 9 final is released.
|
||||
</div>
|
||||
|
||||
The script will run a series of small migrations that will transform the code of your application to be compatible with version 9.
|
||||
|
||||
If you're curious about the specific migrations being run (e.g. what code is changing and why), see the [automated migrations section](#migrations).
|
||||
The script runs a series of small migrations that will transform the code of your application to be compatible with version 9.
|
||||
If you're curious about the specific migrations being run, see the [automated migrations section](#migrations) for details on what code is changing and why.
|
||||
|
||||
## Changes and Deprecations in Version 9
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For information about Angular's deprecation and removal practices, see [Angular Release Practices](guide/releases#deprecation-practices "Angular Release Practices: Deprecation practices").
|
||||
|
||||
</div>
|
||||
|
||||
{@a breaking-changes}
|
||||
### New Breaking Changes
|
||||
|
||||
- Angular now compiles with Ivy by default. See [Ivy compatibility section](#ivy).
|
||||
|
||||
- CLI apps compile in [AOT mode](/guide/aot-compiler) by default (which includes template type-checking).
|
||||
Users who only built with JIT before may see new type errors.
|
||||
See our [template type-checking guide](guide/template-typecheck) for more information and debugging tips.
|
||||
|
||||
- Typescript 3.4 and 3.5 are no longer supported. Please update to Typescript 3.6.
|
||||
|
||||
- tslib is now listed as a peer dependency rather than a direct dependency. Users not using the CLI will need to manually install tslib via `yarn add tslib` or `npm install tslib --save`.
|
||||
- `tslib` is now listed as a peer dependency rather than a direct dependency. If you are not using the CLI, you must manually install `tslib`, using `yarn add tslib` or `npm install tslib --save`.
|
||||
|
||||
{@a deprecations}
|
||||
### New Deprecations
|
||||
@ -61,23 +78,17 @@ If you're curious about the specific migrations being run (e.g. what code is cha
|
||||
| `@angular/forms` | `ngForm` element selector | `ng-form` element selector | none |
|
||||
| `@angular/service-worker` | `versionedFiles` | `files` | In the service worker configuration file `ngsw-config.json`, replace `versionedFiles` with `files`. See [Service Worker Configuration](guide/service-worker-config#assetgroups). |
|
||||
|
||||
|
||||
|
||||
{@a ivy-features}
|
||||
## Ivy Features
|
||||
|
||||
Angular version 9 introduces more comprehensive type-checking. For details, see [Template Type-checking](guide/template-typecheck).
|
||||
|
||||
|
||||
{@a ivy}
|
||||
## Ivy Compatibility
|
||||
|
||||
## Ivy features and compatibility
|
||||
|
||||
In Version 9, Angular Ivy is the default rendering engine. If you haven't heard of Ivy, you can read more about it in the [Angular Ivy guide](guide/ivy).
|
||||
|
||||
For guidance on debugging and a list of minor changes associated with Ivy, please see our [compatibility guide](guide/ivy-compatibility).
|
||||
* Among other features, Ivy introduces more comprehensive type-checking within templates. For details, see [Template Type-checking](guide/template-typecheck).
|
||||
|
||||
For help with opting out of Ivy, please see the instructions [here](guide/ivy#opting-out-of-angular-ivy).
|
||||
* For general guidance on debugging and a list of minor changes associated with Ivy, see the [Ivy compatibility guide](guide/ivy-compatibility).
|
||||
|
||||
* For help with opting out of Ivy, see the instructions [here](guide/ivy#opting-out-of-angular-ivy).
|
||||
|
||||
{@a migrations}
|
||||
## Automated Migrations for Version 9
|
||||
@ -90,4 +101,3 @@ Read about the migrations the CLI handles for you automatically:
|
||||
- [Migrating dynamic queries](guide/migration-dynamic-flag)
|
||||
- [Migrating to the new `$localize` i18n support](guide/migration-localize)
|
||||
- [Migrating `ModuleWithProviders`](guide/migration-module-with-providers)
|
||||
- [Migrating to `ngcc` npm `postinstall` script](guide/migration-ngcc)
|
||||
|
@ -266,11 +266,9 @@ everything work seamlessly:
|
||||
When you register a downgraded service, you must explicitly specify a *string token* that you want to
|
||||
use in AngularJS.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/upgrade/injectors.png" alt="The two injectors in a hybrid application">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/upgrade/injectors.png" alt="The two injectors in a hybrid application">
|
||||
</div>
|
||||
|
||||
#### Components and the DOM
|
||||
|
||||
@ -304,11 +302,9 @@ ways:
|
||||
bridges the related concepts of AngularJS transclusion and Angular content
|
||||
projection together.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/upgrade/dom.png" alt="DOM element ownership in a hybrid application">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/upgrade/dom.png" alt="DOM element ownership in a hybrid application">
|
||||
</div>
|
||||
|
||||
Whenever you use a component that belongs to the other framework, a
|
||||
switch between framework boundaries occurs. However, that switch only
|
||||
@ -351,11 +347,9 @@ AngularJS and Angular approaches. Here's what happens:
|
||||
every turn of the Angular zone. This also triggers AngularJS change
|
||||
detection after every event.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/upgrade/change_detection.png" alt="Change detection in a hybrid application">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/upgrade/change_detection.png" alt="Change detection in a hybrid application">
|
||||
</div>
|
||||
|
||||
In practice, you do not need to call `$apply()`,
|
||||
regardless of whether it is in AngularJS or Angular. The
|
||||
|
@ -82,11 +82,9 @@ Here's what the UI displays:
|
||||
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/user-input/keyup1-anim.gif' alt="key up 1">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/user-input/keyup1-anim.gif' alt="key up 1">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -163,11 +161,9 @@ and the component does nothing.
|
||||
Type something in the input box, and watch the display update with each keystroke.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/user-input/keyup-loop-back-anim.gif' alt="loop back">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/user-input/keyup-loop-back-anim.gif' alt="loop back">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -215,11 +211,9 @@ Then Angular calls the event handler only when the user presses _Enter_.
|
||||
|
||||
Here's how it works.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/user-input/keyup3-anim.gif' alt="key up 3">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/user-input/keyup3-anim.gif' alt="key up 3">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -249,11 +243,9 @@ The user can add a hero by typing the hero's name in the input box and
|
||||
clicking **Add**.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/user-input/little-tour-anim.gif' alt="Little Tour of Heroes">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/user-input/little-tour-anim.gif' alt="Little Tour of Heroes">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
@ -174,6 +174,12 @@ By default, a `production` configuration is defined, and the `ng build` command
|
||||
|
||||
You can define and name additional alternate configurations (such as `stage`, for instance) appropriate to your development process. Some examples of different build configurations are `stable`, `archive` and `next` used by AIO itself, and the individual locale-specific configurations required for building localized versions of an app. For details, see [Internationalization (i18n)](guide/i18n#merge-aot).
|
||||
|
||||
You can select an alternate configuration by passing its name to the `--configuration` command line flag.
|
||||
|
||||
You can also pass in more than one configuration name as a comma-separated list. For example, to apply both `stage` and `fr` build configurations, use the command `ng build --configuration stage,fr`. In this case, the command parses the named configurations from left to right. If multiple configurations change the same setting, the last-set value is the final one.
|
||||
|
||||
If the `--prod` command line flag is also used, it is applied first, and its settings can be overridden by any configurations specified via the `--configuration` flag.
|
||||
|
||||
{@a build-props}
|
||||
|
||||
### Additional build and test options
|
||||
|
@ -670,12 +670,12 @@
|
||||
"groups": ["Collaborators", "GDE"],
|
||||
"mentor": "gkalpak"
|
||||
},
|
||||
"JiaLiPassion": {
|
||||
"name": "JiaLi Passion",
|
||||
"jiali": {
|
||||
"name": "Jia Li",
|
||||
"groups": ["Collaborators"],
|
||||
"mentor": "mhevery",
|
||||
"picture": "JiaLiPassion.jpg",
|
||||
"bio": "A programmer with passion, angular/zone.js guy! Web frontend engineer @sylabs"
|
||||
"bio": "A programmer with passion, angular/zone.js guy! Web frontend engineer @thisdot"
|
||||
},
|
||||
"cexbrayat": {
|
||||
"name": "Cédric Exbrayat",
|
||||
|
@ -29,7 +29,7 @@ Tutorials and guides include downloadable example to accelerate your projects.
|
||||
## Assumptions
|
||||
|
||||
|
||||
These docs assume that you are already familiar with HTML, CSS, [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript "Learn JavaScript"),
|
||||
These docs assume that you are already familiar with [HTML](https://developer.mozilla.org/docs/Learn/HTML/Introduction_to_HTML "Learn HTML"), [CSS](https://developer.mozilla.org/docs/Learn/CSS/First_steps "Learn CSS"), [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript "Learn JavaScript"),
|
||||
and some of the tools from the [latest standards](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Language_Resources "Latest JavaScript standards"), such as [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes "ES2015 Classes") and [modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import "ES2015 Modules").
|
||||
The code samples are written using [TypeScript](https://www.typescriptlang.org/ "TypeScript").
|
||||
Most Angular code can be written with just the latest JavaScript, using [types](https://www.typescriptlang.org/docs/handbook/classes.html "TypeScript Types") for dependency injection, and using [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html "Decorators") for metadata.
|
||||
|
@ -414,7 +414,7 @@
|
||||
"url": "https://www.jqwidgets.com/angular/"
|
||||
},
|
||||
"amexio": {
|
||||
"desc": "Amexio (Angular MetaMagic EXtensions for Inputs and Outputs) is a rich set of Angular components powered by Bootstrap for Responsive Design. UI Components include Standard Form Components, Data Grids, Tree Grids, Tabs etc. Open Source (Apache 2 License) & Free and backed by MetaMagic Global Inc",
|
||||
"desc": "Amexio is a rich set of Angular components powered by HTML5 & CSS3 for Responsive Web Design and 80+ built-in Material Design Themes. Amexio has 3 Editions, Standard, Enterprise and Creative. Std Edition consists of basic UI Components which include Grid, Tabs, Form Inputs and so on. While Enterprise Edition consists of components like Calendar, Tree Tabs, Social Media Logins (Facebook, GitHub, Twitter and so on) and Creative Edition is focused building elegant and beautiful websites. With more than 200+ components/features. All the editions are open-sourced and free, based on Apache 2 License.",
|
||||
"rev": true,
|
||||
"title": "Amexio - Angular Extensions",
|
||||
"url": "http://www.amexio.tech/",
|
||||
|
@ -105,19 +105,15 @@ When the "Buy" button is clicked, you'll use the cart service to add the current
|
||||
|
||||
1. To see the new "Buy" button, refresh the application and click on a product's name to display its details.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/start/product-details-buy.png' alt="Display details for selected product with a Buy button">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/start/product-details-buy.png' alt="Display details for selected product with a Buy button">
|
||||
</div>
|
||||
|
||||
1. Click the "Buy" button. The product is added to the stored list of items in the cart, and a message is displayed.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/start/buy-alert.png' alt="Display details for selected product with a Buy button">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/start/buy-alert.png' alt="Display details for selected product with a Buy button">
|
||||
</div>
|
||||
|
||||
|
||||
## Create the cart page
|
||||
@ -154,11 +150,9 @@ We'll create the cart page in two steps:
|
||||
|
||||
(Note: The "Checkout" button that we provided in the top-bar component was already configured with a `routerLink` for `/cart`.)
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/start/cart-works.png' alt="Display cart page before customizing">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/start/cart-works.png' alt="Display cart page before customizing">
|
||||
</div>
|
||||
|
||||
|
||||
### Display the cart items
|
||||
@ -210,11 +204,9 @@ Services can be used to share data across components:
|
||||
1. Click "Checkout" to see the cart.
|
||||
1. To add another product, click "My Store" to return to the product list. Repeat the steps above.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/start/cart-page-full.png' alt="Cart page with products added">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/start/cart-page-full.png' alt="Cart page with products added">
|
||||
</div>
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
@ -371,19 +363,15 @@ Now that your app can retrieve shipping data, you'll create a shipping component
|
||||
|
||||
Click on the "Checkout" button to see the updated cart. (Remember that changing the app causes the preview to refresh, which empties the cart.)
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/start/cart-empty-with-shipping-prices.png' alt="Cart with link to shipping prices">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/start/cart-empty-with-shipping-prices.png' alt="Cart with link to shipping prices">
|
||||
</div>
|
||||
|
||||
Click on the link to navigate to the shipping prices.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/start/shipping-prices.png' alt="Display shipping prices">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/start/shipping-prices.png' alt="Display shipping prices">
|
||||
</div>
|
||||
|
||||
|
||||
## Next steps
|
||||
|
@ -73,11 +73,9 @@ Next, you'll add a checkout form at the bottom of the "Cart" page.
|
||||
|
||||
After putting a few items in the cart, users can now review their items, enter name and address, and submit their purchase:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/start/cart-with-items-and-form.png' alt="Cart page with checkout form">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/start/cart-with-items-and-form.png' alt="Cart page with checkout form">
|
||||
</div>
|
||||
|
||||
|
||||
## Next steps
|
||||
|
@ -21,11 +21,9 @@ To help you get started right away, this guide uses a simple ready-made applicat
|
||||
<live-example name="getting-started-v0" noDownload>Click here to create the ready-made sample project in StackBlitz.</live-example>
|
||||
</h4>
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/start/new-app-all.gif" alt="Starter online store app">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/new-app-all.gif" alt="Starter online store app">
|
||||
</div>
|
||||
|
||||
* The preview pane on the right shows the starting state of the sample Angular app.
|
||||
It defines a frame with a top bar (containing the store name and checkout icon) and the title for a product list (which will be populated and dynamically updated with data from the application).
|
||||
@ -100,11 +98,9 @@ To help you get going, the following steps use predefined product data and metho
|
||||
|
||||
The preview pane immediately updates to display the name of each product in the list.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/start/template-syntax-product-names.png" alt="Product names added to list">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/template-syntax-product-names.png" alt="Product names added to list">
|
||||
</div>
|
||||
|
||||
1. To make each product name a link to product details, add the `<a>` element and set its title to be the product's name by using the property binding `[ ]` syntax, as follows:
|
||||
|
||||
@ -118,46 +114,38 @@ To help you get going, the following steps use predefined product data and metho
|
||||
property value as text; property binding `[ ]` lets you
|
||||
use the property value in a template expression.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/start/template-syntax-product-anchor.png" alt="Product name anchor text is product name property">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/template-syntax-product-anchor.png" alt="Product name anchor text is product name property">
|
||||
</div>
|
||||
|
||||
|
||||
1. Add the product descriptions. On the `<p>` element, use an `*ngIf` directive so that Angular only creates the `<p>` element if the current product has a description.
|
||||
4. Add the product descriptions. On the `<p>` element, use an `*ngIf` directive so that Angular only creates the `<p>` element if the current product has a description.
|
||||
|
||||
<code-example path="getting-started/src/app/product-list/product-list.component.3.html" header="src/app/product-list/product-list.component.html">
|
||||
</code-example>
|
||||
|
||||
The app now displays the name and description of each product in the list. Notice that the final product does not have a description paragraph. Because the product's description property is empty, Angular doesn't create the `<p>` element—including the word "Description".
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/template-syntax-product-description.png" alt="Product descriptions added to list">
|
||||
</div>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
1. Add a button so users can share a product with friends. Bind the button's `click` event to the `share()` method (in `product-list.component.ts`). Event binding uses a set of parentheses, `( )`, around the event, as in the following `<button>` element:
|
||||
5. Add a button so users can share a product with friends. Bind the button's `click` event to the `share()` method (in `product-list.component.ts`). Event binding uses a set of parentheses, `( )`, around the event, as in the following `<button>` element:
|
||||
|
||||
<code-example path="getting-started/src/app/product-list/product-list.component.4.html" header="src/app/product-list/product-list.component.html">
|
||||
</code-example>
|
||||
|
||||
Each product now has a "Share" button:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/template-syntax-product-share-button.png" alt="Share button added for each product">
|
||||
</div>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
Test the "Share" button:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/template-syntax-product-share-alert.png" alt="Alert box indicating product has been shared">
|
||||
</div>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
The app now has a product list and sharing feature.
|
||||
In the process, you've learned to use five common features of Angular's template syntax:
|
||||
@ -212,11 +200,9 @@ An Angular application comprises a tree of components, in which each Angular com
|
||||
|
||||
Currently, the example app has three components:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/app-components.png" alt="Online store with three components">
|
||||
</div>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
* `app-root` (orange box) is the application shell. This is the first component to load and the parent of all other components. You can think of it as the base page.
|
||||
* `app-top-bar` (blue background) is the store name and checkout button.
|
||||
@ -244,11 +230,9 @@ The next step is to create a new alert feature that takes a product as an input.
|
||||
|
||||
1. Right click on the `app` folder and use the `Angular Generator` to generate a new component named `product-alerts`.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/generate-component.png" alt="StackBlitz command to generate component">
|
||||
</div>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
The generator creates starter files for all three parts of the component:
|
||||
* `product-alerts.component.ts`
|
||||
@ -295,11 +279,9 @@ The next step is to create a new alert feature that takes a product as an input.
|
||||
|
||||
The new product alert component takes a product as input from the product list. With that input, it shows or hides the "Notify Me" button, based on the price of the product. The Phone XL price is over $700, so the "Notify Me" button appears on that product.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/product-alert-button.png" alt="Product alert button added to products over $700">
|
||||
</div>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@ -342,11 +324,9 @@ To make the "Notify Me" button work, you need to configure two things:
|
||||
|
||||
1. Try the "Notify Me" button:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/product-alert-notification.png" alt="Product alert notification confirmation dialog">
|
||||
</div>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
@ -54,11 +54,9 @@ The app is already set up to use the Angular router and to use routing to naviga
|
||||
|
||||
Notice that the URL in the preview window changes. The final segment is `products/1`.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/start/product-details-works.png" alt="Product details page with updated URL">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/product-details-works.png" alt="Product details page with updated URL">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -110,11 +108,9 @@ The product details component handles the display of each product. The Angular R
|
||||
|
||||
Now, when the user clicks on a name in the product list, the router navigates you to the distinct URL for the product, swaps out the product list component for the product details component, and displays the product details.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src="generated/images/guide/start/product-details-routed.png" alt="Product details page with updated URL and full details displayed">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/start/product-details-routed.png" alt="Product details page with updated URL and full details displayed">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
@ -49,11 +49,9 @@ After completing all tutorial steps, the final app will look like this: <live-ex
|
||||
Here's a visual idea of where this tutorial leads, beginning with the "Dashboard"
|
||||
view and the most heroic heroes:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/toh/heroes-dashboard-1.png' alt="Output of heroes dashboard">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/heroes-dashboard-1.png' alt="Output of heroes dashboard">
|
||||
</div>
|
||||
|
||||
You can click the two links above the dashboard ("Dashboard" and "Heroes")
|
||||
to navigate between this Dashboard view and a Heroes view.
|
||||
@ -61,22 +59,18 @@ to navigate between this Dashboard view and a Heroes view.
|
||||
If you click the dashboard hero "Magneta," the router opens a "Hero Details" view
|
||||
where you can change the hero's name.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/toh/hero-details-1.png' alt="Details of hero in app">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/hero-details-1.png' alt="Details of hero in app">
|
||||
</div>
|
||||
|
||||
Clicking the "Back" button returns you to the Dashboard.
|
||||
Links at the top take you to either of the main views.
|
||||
If you click "Heroes," the app displays the "Heroes" master list view.
|
||||
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/toh/heroes-list-2.png' alt="Output of heroes list app">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/heroes-list-2.png' alt="Output of heroes list app">
|
||||
</div>
|
||||
|
||||
When you click a different hero name, the read-only mini detail beneath the list reflects the new choice.
|
||||
|
||||
@ -85,16 +79,12 @@ editable details of the selected hero.
|
||||
|
||||
The following diagram captures all of the navigation options.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||
</div>
|
||||
|
||||
Here's the app in action:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/toh/toh-anim.gif' alt="Tour of Heroes in Action">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/toh-anim.gif' alt="Tour of Heroes in Action">
|
||||
</div>
|
||||
|
@ -196,11 +196,9 @@ It's difficult to identify the _selected hero_ in the list when all `<li>` eleme
|
||||
|
||||
If the user clicks "Magneta", that hero should render with a distinctive but subtle background color like this:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/toh/heroes-list-selected.png' alt="Selected hero">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/heroes-list-selected.png' alt="Selected hero">
|
||||
</div>
|
||||
|
||||
That _selected hero_ coloring is the work of the `.selected` CSS class in the [styles you added earlier](#styles).
|
||||
You just have to apply the `.selected` class to the `<li>` when the user clicks it.
|
||||
|
@ -9,11 +9,9 @@ There are new requirements for the Tour of Heroes app:
|
||||
|
||||
When you’re done, users will be able to navigate the app like this:
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||
</div>
|
||||
|
||||
## Add the `AppRoutingModule`
|
||||
|
||||
|
@ -513,11 +513,9 @@ That's the job of the [`AsyncPipe`](#asyncpipe) in the template.
|
||||
Run the app again. In the *Dashboard*, enter some text in the search box.
|
||||
If you enter characters that match any existing hero names, you'll see something like this.
|
||||
|
||||
<figure class="lightbox">
|
||||
<div class="card">
|
||||
<img src='generated/images/guide/toh/toh-hero-search.png' alt="Hero Search Component">
|
||||
</div>
|
||||
</figure>
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/toh-hero-search.png' alt="Hero Search Component">
|
||||
</div>
|
||||
|
||||
## Final code review
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
"build-local-with-viewengine": "yarn ~~build",
|
||||
"prebuild-local-with-viewengine-ci": "node scripts/switch-to-viewengine && yarn setup-local-ci",
|
||||
"build-local-with-viewengine-ci": "yarn ~~build --progress=false",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js e598c8e89",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js fbfcc45a3",
|
||||
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
|
||||
"test": "yarn check-env && ng test",
|
||||
"pree2e": "yarn check-env && yarn update-webdriver",
|
||||
@ -87,28 +87,28 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^9.0.0-next.10",
|
||||
"@angular/animations": "^9.0.0-rc.1",
|
||||
"@angular/cdk": "9.0.0-next.0",
|
||||
"@angular/common": "^9.0.0-next.10",
|
||||
"@angular/compiler": "^9.0.0-next.10",
|
||||
"@angular/core": "^9.0.0-next.10",
|
||||
"@angular/elements": "^9.0.0-next.10",
|
||||
"@angular/forms": "^9.0.0-next.10",
|
||||
"@angular/common": "^9.0.0-rc.1",
|
||||
"@angular/compiler": "^9.0.0-rc.1",
|
||||
"@angular/core": "^9.0.0-rc.1",
|
||||
"@angular/elements": "^9.0.0-rc.1",
|
||||
"@angular/forms": "^9.0.0-rc.1",
|
||||
"@angular/material": "9.0.0-next.0",
|
||||
"@angular/platform-browser": "^9.0.0-next.10",
|
||||
"@angular/platform-browser-dynamic": "^9.0.0-next.10",
|
||||
"@angular/router": "^9.0.0-next.10",
|
||||
"@angular/service-worker": "^9.0.0-next.10",
|
||||
"@angular/platform-browser": "^9.0.0-rc.1",
|
||||
"@angular/platform-browser-dynamic": "^9.0.0-rc.1",
|
||||
"@angular/router": "^9.0.0-rc.1",
|
||||
"@angular/service-worker": "^9.0.0-rc.1",
|
||||
"@webcomponents/custom-elements": "^1.2.0",
|
||||
"rxjs": "^6.5.3",
|
||||
"tslib": "^1.10.0",
|
||||
"zone.js": "~0.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "0.900.0-next.11",
|
||||
"@angular/cli": "9.0.0-next.11",
|
||||
"@angular/compiler-cli": "^9.0.0-next.10",
|
||||
"@angular/language-service": "^9.0.0-next.10",
|
||||
"@angular-devkit/build-angular": "0.900.0-rc.0",
|
||||
"@angular/cli": "9.0.0-rc.0",
|
||||
"@angular/compiler-cli": "^9.0.0-rc.1",
|
||||
"@angular/language-service": "^9.0.0-rc.1",
|
||||
"@types/jasmine": "^3.4.2",
|
||||
"@types/jasminewd2": "^2.0.8",
|
||||
"@types/lunr": "^2.3.2",
|
||||
@ -175,4 +175,4 @@
|
||||
"xregexp": "^4.0.0",
|
||||
"yargs": "^7.0.2"
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime-es2015": 2987,
|
||||
"main-es2015": 460590,
|
||||
"main-es2015": 464973,
|
||||
"polyfills-es2015": 52503
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime-es2015": 2987,
|
||||
"main-es2015": 461159,
|
||||
"main-es2015": 506857,
|
||||
"polyfills-es2015": 52503
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,13 @@ import { fakeAsync, tick } from '@angular/core/testing';
|
||||
import { ScrollService, topMargin } from './scroll.service';
|
||||
|
||||
describe('ScrollService', () => {
|
||||
const scrollServiceInstances: ScrollService[] = [];
|
||||
const createScrollService = (...args: ConstructorParameters<typeof ScrollService>) => {
|
||||
const instance = new ScrollService(...args);
|
||||
scrollServiceInstances.push(instance);
|
||||
return instance;
|
||||
};
|
||||
|
||||
const topOfPageElem = {} as Element;
|
||||
let injector: ReflectiveInjector;
|
||||
let document: MockDocument;
|
||||
@ -36,7 +43,11 @@ describe('ScrollService', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
injector = ReflectiveInjector.resolveAndCreate([
|
||||
ScrollService,
|
||||
{
|
||||
provide: ScrollService,
|
||||
useFactory: createScrollService,
|
||||
deps: [DOCUMENT, PlatformLocation, ViewportScroller, Location],
|
||||
},
|
||||
{ provide: Location, useClass: SpyLocation },
|
||||
{ provide: DOCUMENT, useClass: MockDocument },
|
||||
{ provide: PlatformLocation, useClass: MockPlatformLocation },
|
||||
@ -51,7 +62,10 @@ describe('ScrollService', () => {
|
||||
spyOn(window, 'scrollBy');
|
||||
});
|
||||
|
||||
afterEach(() => scrollService.ngOnDestroy());
|
||||
afterEach(() => {
|
||||
scrollServiceInstances.forEach(instance => instance.ngOnDestroy());
|
||||
window.sessionStorage.clear();
|
||||
});
|
||||
|
||||
it('should debounce `updateScrollPositonInHistory()`', fakeAsync(() => {
|
||||
const updateScrollPositionInHistorySpy = spyOn(scrollService, 'updateScrollPositionInHistory');
|
||||
@ -67,25 +81,6 @@ describe('ScrollService', () => {
|
||||
expect(updateScrollPositionInHistorySpy).toHaveBeenCalledTimes(1);
|
||||
}));
|
||||
|
||||
it('should stop updating scroll position once destroyed', fakeAsync(() => {
|
||||
const updateScrollPositionInHistorySpy = spyOn(scrollService, 'updateScrollPositionInHistory');
|
||||
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
tick(250);
|
||||
expect(updateScrollPositionInHistorySpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
tick(250);
|
||||
expect(updateScrollPositionInHistorySpy).toHaveBeenCalledTimes(2);
|
||||
|
||||
updateScrollPositionInHistorySpy.calls.reset();
|
||||
scrollService.ngOnDestroy();
|
||||
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
tick(250);
|
||||
expect(updateScrollPositionInHistorySpy).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should set `scrollRestoration` to `manual` if supported', () => {
|
||||
if (scrollService.supportManualScrollRestoration) {
|
||||
expect(window.history.scrollRestoration).toBe('manual');
|
||||
@ -94,6 +89,30 @@ describe('ScrollService', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should not break when cookies are disabled in the browser', () => {
|
||||
expect(() => {
|
||||
const originalSessionStorage = Object.getOwnPropertyDescriptor(window, 'sessionStorage')!;
|
||||
|
||||
try {
|
||||
// Simulate `window.sessionStorage` being inaccessible, when cookies are disabled.
|
||||
Object.defineProperty(window, 'sessionStorage', {
|
||||
get() { throw new Error('The operation is insecure'); },
|
||||
});
|
||||
|
||||
const platformLoc = platformLocation as PlatformLocation;
|
||||
const service = createScrollService(document, platformLoc, viewportScrollerStub, location);
|
||||
|
||||
service.updateScrollLocationHref();
|
||||
expect(service.getStoredScrollLocationHref()).toBeNull();
|
||||
|
||||
service.removeStoredScrollInfo();
|
||||
expect(service.getStoredScrollPosition()).toBeNull();
|
||||
} finally {
|
||||
Object.defineProperty(window, 'sessionStorage', originalSessionStorage);
|
||||
}
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
describe('#topOffset', () => {
|
||||
it('should query for the top-bar by CSS selector', () => {
|
||||
expect(document.querySelector).not.toHaveBeenCalled();
|
||||
@ -406,4 +425,58 @@ describe('ScrollService', () => {
|
||||
expect(scrollToTopSpy).not.toHaveBeenCalled();
|
||||
}));
|
||||
});
|
||||
|
||||
describe('once destroyed', () => {
|
||||
it('should stop updating scroll position', fakeAsync(() => {
|
||||
const updateScrollPositionInHistorySpy =
|
||||
spyOn(scrollService, 'updateScrollPositionInHistory');
|
||||
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
tick(250);
|
||||
expect(updateScrollPositionInHistorySpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
tick(250);
|
||||
expect(updateScrollPositionInHistorySpy).toHaveBeenCalledTimes(2);
|
||||
|
||||
updateScrollPositionInHistorySpy.calls.reset();
|
||||
scrollService.ngOnDestroy();
|
||||
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
tick(250);
|
||||
expect(updateScrollPositionInHistorySpy).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should stop updating the stored location href', () => {
|
||||
const updateScrollLocationHrefSpy = spyOn(scrollService, 'updateScrollLocationHref');
|
||||
|
||||
window.dispatchEvent(new Event('beforeunload'));
|
||||
expect(updateScrollLocationHrefSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
window.dispatchEvent(new Event('beforeunload'));
|
||||
expect(updateScrollLocationHrefSpy).toHaveBeenCalledTimes(2);
|
||||
|
||||
updateScrollLocationHrefSpy.calls.reset();
|
||||
scrollService.ngOnDestroy();
|
||||
|
||||
window.dispatchEvent(new Event('beforeunload'));
|
||||
expect(updateScrollLocationHrefSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should stop scrolling on `hashchange` events', () => {
|
||||
const scrollToPositionSpy = spyOn(scrollService, 'scrollToPosition');
|
||||
|
||||
location.simulateHashChange('foo');
|
||||
expect(scrollToPositionSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
location.simulateHashChange('bar');
|
||||
expect(scrollToPositionSpy).toHaveBeenCalledTimes(2);
|
||||
|
||||
scrollToPositionSpy.calls.reset();
|
||||
scrollService.ngOnDestroy();
|
||||
|
||||
location.simulateHashChange('baz');
|
||||
expect(scrollToPositionSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -19,6 +19,7 @@ export class ScrollService implements OnDestroy {
|
||||
private _topOffset: number | null;
|
||||
private _topOfPageElement: Element;
|
||||
private onDestroy = new Subject<void>();
|
||||
private storage: Storage;
|
||||
|
||||
// The scroll position which has to be restored, after a `popstate` event.
|
||||
poppedStateScrollPosition: ScrollPosition | null = null;
|
||||
@ -49,6 +50,21 @@ export class ScrollService implements OnDestroy {
|
||||
private platformLocation: PlatformLocation,
|
||||
private viewportScroller: ViewportScroller,
|
||||
private location: Location) {
|
||||
try {
|
||||
this.storage = window.sessionStorage;
|
||||
} catch {
|
||||
// When cookies are disabled in the browser, even trying to access
|
||||
// `window.sessionStorage` throws an error. Use a no-op storage.
|
||||
this.storage = {
|
||||
length: 0,
|
||||
clear: () => undefined,
|
||||
getItem: () => null,
|
||||
key: () => null,
|
||||
removeItem: () => undefined,
|
||||
setItem: () => undefined
|
||||
};
|
||||
}
|
||||
|
||||
// On resize, the toolbar might change height, so "invalidate" the top offset.
|
||||
fromEvent(window, 'resize')
|
||||
.pipe(takeUntil(this.onDestroy))
|
||||
@ -62,13 +78,14 @@ export class ScrollService implements OnDestroy {
|
||||
.pipe(takeUntil(this.onDestroy))
|
||||
.subscribe(() => this.updateScrollLocationHref());
|
||||
|
||||
// Change scroll restoration strategy to `manual` if it's supported
|
||||
// Change scroll restoration strategy to `manual` if it's supported.
|
||||
if (this.supportManualScrollRestoration) {
|
||||
history.scrollRestoration = 'manual';
|
||||
// we have to detect forward and back navigation thanks to popState event
|
||||
this.location.subscribe((event: ScrollPositionPopStateEvent) => {
|
||||
// the type is `hashchange` when the fragment identifier of the URL has changed. It allows us to go to position
|
||||
// just before a click on an anchor
|
||||
|
||||
// We have to detect forward and back navigation thanks to popState event.
|
||||
const locationSubscription = this.location.subscribe((event: ScrollPositionPopStateEvent) => {
|
||||
// The type is `hashchange` when the fragment identifier of the URL has changed. It allows
|
||||
// us to go to position just before a click on an anchor.
|
||||
if (event.type === 'hashchange') {
|
||||
this.scrollToPosition();
|
||||
} else {
|
||||
@ -80,6 +97,8 @@ export class ScrollService implements OnDestroy {
|
||||
this.poppedStateScrollPosition = event.state ? event.state.scrollPosition : null;
|
||||
}
|
||||
});
|
||||
|
||||
this.onDestroy.subscribe(() => locationSubscription.unsubscribe());
|
||||
}
|
||||
|
||||
// If this was not a reload, discard the stored scroll info.
|
||||
@ -180,7 +199,7 @@ export class ScrollService implements OnDestroy {
|
||||
}
|
||||
|
||||
updateScrollLocationHref(): void {
|
||||
window.sessionStorage.setItem('scrollLocationHref', window.location.href);
|
||||
this.storage.setItem('scrollLocationHref', window.location.href);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,17 +209,17 @@ export class ScrollService implements OnDestroy {
|
||||
if (this.supportManualScrollRestoration) {
|
||||
const currentScrollPosition = this.viewportScroller.getScrollPosition();
|
||||
this.location.replaceState(this.location.path(true), undefined, {scrollPosition: currentScrollPosition});
|
||||
window.sessionStorage.setItem('scrollPosition', currentScrollPosition.join(','));
|
||||
this.storage.setItem('scrollPosition', currentScrollPosition.join(','));
|
||||
}
|
||||
}
|
||||
|
||||
getStoredScrollLocationHref(): string | null {
|
||||
const href = window.sessionStorage.getItem('scrollLocationHref');
|
||||
const href = this.storage.getItem('scrollLocationHref');
|
||||
return href || null;
|
||||
}
|
||||
|
||||
getStoredScrollPosition(): ScrollPosition | null {
|
||||
const position = window.sessionStorage.getItem('scrollPosition');
|
||||
const position = this.storage.getItem('scrollPosition');
|
||||
if (!position) { return null; }
|
||||
|
||||
const [x, y] = position.split(',');
|
||||
@ -208,8 +227,8 @@ export class ScrollService implements OnDestroy {
|
||||
}
|
||||
|
||||
removeStoredScrollInfo() {
|
||||
window.sessionStorage.removeItem('scrollLocationHref');
|
||||
window.sessionStorage.removeItem('scrollPosition');
|
||||
this.storage.removeItem('scrollLocationHref');
|
||||
this.storage.removeItem('scrollPosition');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
figure {
|
||||
.lightbox {
|
||||
margin: 0;
|
||||
margin-top: 14px;
|
||||
margin-bottom: 14px;
|
||||
@ -45,24 +45,19 @@
|
||||
justify-content: center;
|
||||
box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, .2);
|
||||
margin: 16px 0;
|
||||
background-color: $lightboxgray;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
&.lightbox {
|
||||
background-color: $lightboxgray;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
div.card {
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
padding: 8px;
|
||||
margin: auto;
|
||||
box-shadow: 0 2px 2px rgba(10, 16, 20, 0.24), 0 0 2px rgba(10, 16, 20, 0.12);
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
background-color: $white;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,9 @@
|
||||
"preinstall": "node ../../../../tools/yarn/check-yarn.js",
|
||||
"postinstall": "yarn webdriver:update"
|
||||
},
|
||||
"//engines-comment": "Keep this in sync with aio/package.json",
|
||||
"engines": {
|
||||
"node": ">=10.9.0 <11.0.0",
|
||||
"node": ">=10.9.0 <13.0.0",
|
||||
"yarn": ">=1.17.3 <=1.19.1"
|
||||
},
|
||||
"keywords": [],
|
||||
|
@ -15,7 +15,8 @@ const PACKAGE_JSON_REGEX = /^[^/]+\/package\.json$/;
|
||||
|
||||
const ANGULAR_ROOT_DIR = path.resolve(__dirname, '../../..');
|
||||
const ANGULAR_DIST_PACKAGES = path.join(ANGULAR_ROOT_DIR, 'dist/packages-dist');
|
||||
const ANGULAR_DIST_PACKAGES_BUILD_CMD = path.join(ANGULAR_ROOT_DIR, 'scripts/build-packages-dist.sh');
|
||||
const ANGULAR_DIST_PACKAGES_BUILD_SCRIPT = path.join(ANGULAR_ROOT_DIR, 'scripts/build-packages-dist.js');
|
||||
const ANGULAR_DIST_PACKAGES_BUILD_CMD = `"${process.execPath}" "${ANGULAR_DIST_PACKAGES_BUILD_SCRIPT}"`;
|
||||
|
||||
/**
|
||||
* A tool that can install Angular dependencies for a project from NPM or from the
|
||||
@ -173,13 +174,13 @@ class NgPackagesInstaller {
|
||||
const canBuild = process.platform !== 'win32';
|
||||
|
||||
if (canBuild) {
|
||||
this._log(`Building the Angular packages with: ${ANGULAR_DIST_PACKAGES_BUILD_CMD}`);
|
||||
this._log(`Building the Angular packages with: ${ANGULAR_DIST_PACKAGES_BUILD_SCRIPT}`);
|
||||
shelljs.exec(ANGULAR_DIST_PACKAGES_BUILD_CMD);
|
||||
} else {
|
||||
this._warn([
|
||||
'Automatically building the local Angular packages is currently not supported on Windows.',
|
||||
`Please, ensure '${ANGULAR_DIST_PACKAGES}' exists and is up-to-date (e.g. by running ` +
|
||||
`'${ANGULAR_DIST_PACKAGES_BUILD_CMD}' in Git Bash for Windows, Windows Subsystem for Linux or a Linux ` +
|
||||
`'${ANGULAR_DIST_PACKAGES_BUILD_SCRIPT}' in Git Bash for Windows, Windows Subsystem for Linux or a Linux ` +
|
||||
'docker container or VM).',
|
||||
'',
|
||||
'Proceeding anyway...',
|
||||
|
@ -253,20 +253,21 @@ describe('NgPackagesInstaller', () => {
|
||||
};
|
||||
|
||||
it('should build the local packages, when not on Windows', () => {
|
||||
const buildScript = path.join(ngRootDir, 'scripts/build-packages-dist.sh');
|
||||
const buildScript = path.join(ngRootDir, 'scripts/build-packages-dist.js');
|
||||
const buildCmd = `"${process.execPath}" "${buildScript}"`;
|
||||
|
||||
buildDistPackagesOnPlatform('linux');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildScript);
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildCmd);
|
||||
|
||||
shelljs.exec.calls.reset();
|
||||
|
||||
buildDistPackagesOnPlatform('darwin');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildScript);
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildCmd);
|
||||
|
||||
shelljs.exec.calls.reset();
|
||||
|
||||
buildDistPackagesOnPlatform('anythingButWindows :(');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildScript);
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildCmd);
|
||||
|
||||
// Ensure that the script does actually exist (e.g. it was not renamed/moved).
|
||||
fs.existsSync.and.callThrough();
|
||||
|
@ -24,20 +24,23 @@ module.exports = function autoLinkCode(getDocFromAlias) {
|
||||
autoLinkCodeImpl.docTypes = [];
|
||||
autoLinkCodeImpl.customFilters = [];
|
||||
autoLinkCodeImpl.codeElements = ['code'];
|
||||
autoLinkCodeImpl.ignoredLanguages = ['bash', 'sh', 'shell', 'json', 'markdown'];
|
||||
return autoLinkCodeImpl;
|
||||
|
||||
function autoLinkCodeImpl() {
|
||||
function autoLinkCodeImpl() {
|
||||
return (ast) => {
|
||||
visit(ast, 'element', (node, ancestors) => {
|
||||
// Only interested in code elements that are not inside links
|
||||
if (autoLinkCodeImpl.codeElements.some(elementType =>
|
||||
is(node, elementType)) &&
|
||||
(!node.properties.className || node.properties.className.indexOf('no-auto-link') === -1) &&
|
||||
// Only interested in code elements that:
|
||||
// * do not have `no-auto-link` class
|
||||
// * do not have an ignored language
|
||||
// * are not inside links
|
||||
if (autoLinkCodeImpl.codeElements.some(elementType => is(node, elementType)) &&
|
||||
(!node.properties.className || !node.properties.className.includes('no-auto-link')) &&
|
||||
!autoLinkCodeImpl.ignoredLanguages.includes(node.properties.language) &&
|
||||
ancestors.every(ancestor => !is(ancestor, 'a'))) {
|
||||
visit(node, 'text', (node, ancestors) => {
|
||||
// Only interested in text nodes that are not inside links
|
||||
if (ancestors.every(ancestor => !is(ancestor, 'a'))) {
|
||||
|
||||
const parent = ancestors[ancestors.length - 1];
|
||||
const index = parent.children.indexOf(node);
|
||||
|
||||
@ -47,15 +50,20 @@ module.exports = function autoLinkCode(getDocFromAlias) {
|
||||
parent.children.splice(index, 1, createLinkNode(docs[0], node.value));
|
||||
} else {
|
||||
// Parse the text for words that we can convert to links
|
||||
const nodes = textContent(node).split(/([A-Za-z0-9_.-]+)/)
|
||||
.filter(word => word.length)
|
||||
.map((word, index, words) => {
|
||||
// remove docs that fail the custom filter tests
|
||||
const filteredDocs = autoLinkCodeImpl.customFilters.reduce((docs, filter) => filter(docs, words, index), getDocFromAlias(word));
|
||||
return foundValidDoc(filteredDocs) ?
|
||||
createLinkNode(filteredDocs[0], word) : // Create a link wrapping the text node.
|
||||
{ type: 'text', value: word }; // this is just text so push a new text node
|
||||
});
|
||||
const nodes =
|
||||
textContent(node)
|
||||
.split(/([A-Za-z0-9_.-]+)/)
|
||||
.filter(word => word.length)
|
||||
.map((word, index, words) => {
|
||||
// remove docs that fail the custom filter tests
|
||||
const filteredDocs = autoLinkCodeImpl.customFilters.reduce(
|
||||
(docs, filter) => filter(docs, words, index), getDocFromAlias(word));
|
||||
return foundValidDoc(filteredDocs) ?
|
||||
// Create a link wrapping the text node.
|
||||
createLinkNode(filteredDocs[0], word) :
|
||||
// this is just text so push a new text node
|
||||
{type: 'text', value: word};
|
||||
});
|
||||
|
||||
// Replace the text node with the links and leftover text nodes
|
||||
Array.prototype.splice.apply(parent.children, [index, 1].concat(nodes));
|
||||
@ -68,17 +76,16 @@ module.exports = function autoLinkCode(getDocFromAlias) {
|
||||
}
|
||||
|
||||
function foundValidDoc(docs) {
|
||||
return docs.length === 1 &&
|
||||
!docs[0].internal &&
|
||||
autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1;
|
||||
return docs.length === 1 && !docs[0].internal &&
|
||||
autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1;
|
||||
}
|
||||
|
||||
function createLinkNode(doc, text) {
|
||||
return {
|
||||
type: 'element',
|
||||
tagName: 'a',
|
||||
properties: { href: doc.path, class: 'code-anchor' },
|
||||
children: [{ type: 'text', value: text }]
|
||||
properties: {href: doc.path, class: 'code-anchor'},
|
||||
children: [{type: 'text', value: text}]
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -18,102 +18,161 @@ describe('autoLinkCode post-processor', () => {
|
||||
});
|
||||
|
||||
it('should insert an anchor into every code item that matches the id of an API doc', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
|
||||
aliasMap.addDoc({docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code>MyClass</code>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code><a href="a/b/myclass" class="code-anchor">MyClass</a></code>');
|
||||
expect(doc.renderedContent)
|
||||
.toEqual('<code><a href="a/b/myclass" class="code-anchor">MyClass</a></code>');
|
||||
});
|
||||
|
||||
it('should insert an anchor into every code item that matches an alias of an API doc', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass', 'foo.MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>foo.MyClass</code>' };
|
||||
aliasMap.addDoc({
|
||||
docType: 'class',
|
||||
id: 'MyClass',
|
||||
aliases: ['MyClass', 'foo.MyClass'],
|
||||
path: 'a/b/myclass'
|
||||
});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code>foo.MyClass</code>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code><a href="a/b/myclass" class="code-anchor">foo.MyClass</a></code>');
|
||||
expect(doc.renderedContent)
|
||||
.toEqual('<code><a href="a/b/myclass" class="code-anchor">foo.MyClass</a></code>');
|
||||
});
|
||||
|
||||
it('should match code items within a block of code that contain a dot in their identifier', () => {
|
||||
aliasMap.addDoc({ docType: 'member', id: 'MyEnum.Value', aliases: ['Value', 'MyEnum.Value'], path: 'a/b/myenum' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>someFn(): MyEnum.Value</code>' };
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>someFn(): <a href="a/b/myenum" class="code-anchor">MyEnum.Value</a></code>');
|
||||
});
|
||||
it('should match code items within a block of code that contain a dot in their identifier',
|
||||
() => {
|
||||
aliasMap.addDoc({
|
||||
docType: 'member',
|
||||
id: 'MyEnum.Value',
|
||||
aliases: ['Value', 'MyEnum.Value'],
|
||||
path: 'a/b/myenum'
|
||||
});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code>someFn(): MyEnum.Value</code>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent)
|
||||
.toEqual(
|
||||
'<code>someFn(): <a href="a/b/myenum" class="code-anchor">MyEnum.Value</a></code>');
|
||||
});
|
||||
|
||||
it('should ignore code items that do not match a link to an API doc', () => {
|
||||
aliasMap.addDoc({ docType: 'guide', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
|
||||
aliasMap.addDoc({docType: 'guide', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code>MyClass</code>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
|
||||
});
|
||||
|
||||
it('should ignore code items that are already inside a link', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<a href="..."><div><code>MyClass</code></div></a>' };
|
||||
aliasMap.addDoc({docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
const doc = {
|
||||
docType: 'test-doc',
|
||||
renderedContent: '<a href="..."><div><code>MyClass</code></div></a>'
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<a href="..."><div><code>MyClass</code></div></a>');
|
||||
});
|
||||
|
||||
it('should ignore code items match an API doc but are not in the list of acceptable docTypes', () => {
|
||||
aliasMap.addDoc({ docType: 'directive', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
|
||||
});
|
||||
it('should ignore code items match an API doc but are not in the list of acceptable docTypes',
|
||||
() => {
|
||||
aliasMap.addDoc(
|
||||
{docType: 'directive', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code>MyClass</code>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
|
||||
});
|
||||
|
||||
it('should ignore code items that match an API doc but are attached to other text via a dash', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>xyz-MyClass</code>' };
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>xyz-MyClass</code>');
|
||||
});
|
||||
it('should ignore code items that match an API doc but are attached to other text via a dash',
|
||||
() => {
|
||||
aliasMap.addDoc(
|
||||
{docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code>xyz-MyClass</code>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>xyz-MyClass</code>');
|
||||
});
|
||||
|
||||
it('should ignore code items that are filtered out by custom filters', () => {
|
||||
autoLinkCode.customFilters = [filterPipes];
|
||||
aliasMap.addDoc({ docType: 'pipe', id: 'MyClass', aliases: ['MyClass', 'myClass'], path: 'a/b/myclass', pipeOptions: { name: '\'myClass\'' } });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>{ xyz | myClass } { xyz|myClass } MyClass myClass OtherClass|MyClass</code>' };
|
||||
aliasMap.addDoc({
|
||||
docType: 'pipe',
|
||||
id: 'MyClass',
|
||||
aliases: ['MyClass', 'myClass'],
|
||||
path: 'a/b/myclass',
|
||||
pipeOptions: {name: '\'myClass\''}
|
||||
});
|
||||
const doc = {
|
||||
docType: 'test-doc',
|
||||
renderedContent:
|
||||
'<code>{ xyz | myClass } { xyz|myClass } MyClass myClass OtherClass|MyClass</code>'
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>' +
|
||||
'{ xyz | <a href="a/b/myclass" class="code-anchor">myClass</a> } ' +
|
||||
'{ xyz|<a href="a/b/myclass" class="code-anchor">myClass</a> } ' +
|
||||
'<a href="a/b/myclass" class="code-anchor">MyClass</a> ' +
|
||||
'myClass OtherClass|<a href="a/b/myclass" class="code-anchor">MyClass</a>' +
|
||||
'</code>');
|
||||
expect(doc.renderedContent)
|
||||
.toEqual(
|
||||
'<code>' +
|
||||
'{ xyz | <a href="a/b/myclass" class="code-anchor">myClass</a> } ' +
|
||||
'{ xyz|<a href="a/b/myclass" class="code-anchor">myClass</a> } ' +
|
||||
'<a href="a/b/myclass" class="code-anchor">MyClass</a> ' +
|
||||
'myClass OtherClass|<a href="a/b/myclass" class="code-anchor">MyClass</a>' +
|
||||
'</code>');
|
||||
});
|
||||
|
||||
it('should ignore code items that match an internal API doc', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass', internal: true });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
|
||||
aliasMap.addDoc({
|
||||
docType: 'class',
|
||||
id: 'MyClass',
|
||||
aliases: ['MyClass'],
|
||||
path: 'a/b/myclass',
|
||||
internal: true
|
||||
});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code>MyClass</code>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
|
||||
});
|
||||
|
||||
it('should insert anchors for individual text nodes within a code block', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code><span>MyClass</span><span>MyClass</span></code>' };
|
||||
aliasMap.addDoc({docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
const doc = {
|
||||
docType: 'test-doc',
|
||||
renderedContent: '<code><span>MyClass</span><span>MyClass</span></code>'
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code><span><a href="a/b/myclass" class="code-anchor">MyClass</a></span><span><a href="a/b/myclass" class="code-anchor">MyClass</a></span></code>');
|
||||
expect(doc.renderedContent)
|
||||
.toEqual(
|
||||
'<code><span><a href="a/b/myclass" class="code-anchor">MyClass</a></span><span><a href="a/b/myclass" class="code-anchor">MyClass</a></span></code>');
|
||||
});
|
||||
|
||||
it('should insert anchors for words that match within text nodes in a code block', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
aliasMap.addDoc({ docType: 'function', id: 'myFunc', aliases: ['myFunc'], path: 'ng/myfunc' });
|
||||
aliasMap.addDoc({ docType: 'const', id: 'MY_CONST', aliases: ['MY_CONST'], path: 'ng/my_const' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>myFunc() {\n return new MyClass(MY_CONST);\n}</code>' };
|
||||
aliasMap.addDoc({docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
aliasMap.addDoc({docType: 'function', id: 'myFunc', aliases: ['myFunc'], path: 'ng/myfunc'});
|
||||
aliasMap.addDoc({docType: 'const', id: 'MY_CONST', aliases: ['MY_CONST'], path: 'ng/my_const'});
|
||||
const doc = {
|
||||
docType: 'test-doc',
|
||||
renderedContent: '<code>myFunc() {\n return new MyClass(MY_CONST);\n}</code>'
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code><a href="ng/myfunc" class="code-anchor">myFunc</a>() {\n return new <a href="a/b/myclass" class="code-anchor">MyClass</a>(<a href="ng/my_const" class="code-anchor">MY_CONST</a>);\n}</code>');
|
||||
expect(doc.renderedContent)
|
||||
.toEqual(
|
||||
'<code><a href="ng/myfunc" class="code-anchor">myFunc</a>() {\n return new <a href="a/b/myclass" class="code-anchor">MyClass</a>(<a href="ng/my_const" class="code-anchor">MY_CONST</a>);\n}</code>');
|
||||
});
|
||||
|
||||
it('should work with custom elements', () => {
|
||||
autoLinkCode.codeElements = ['code-example'];
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code-example>MyClass</code-example>' };
|
||||
aliasMap.addDoc({docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code-example>MyClass</code-example>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code-example><a href="a/b/myclass" class="code-anchor">MyClass</a></code-example>');
|
||||
expect(doc.renderedContent)
|
||||
.toEqual(
|
||||
'<code-example><a href="a/b/myclass" class="code-anchor">MyClass</a></code-example>');
|
||||
});
|
||||
|
||||
it('should ignore code blocks that are marked with a `no-auto-link` class', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code class="no-auto-link">MyClass</code>' };
|
||||
aliasMap.addDoc({docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code class="no-auto-link">MyClass</code>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code class="no-auto-link">MyClass</code>');
|
||||
});
|
||||
|
||||
it('should ignore code blocks that are marked with an "ignored" language', () => {
|
||||
aliasMap.addDoc({docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass'});
|
||||
const doc = {docType: 'test-doc', renderedContent: '<code language="bash">MyClass</code>'};
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code language="bash">MyClass</code>');
|
||||
});
|
||||
});
|
||||
|
540
aio/yarn.lock
540
aio/yarn.lock
@ -2,38 +2,39 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@angular-devkit/architect@0.900.0-next.11":
|
||||
version "0.900.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-next.11.tgz#c1b1f6b428903eedf70422b34471d80a1243a682"
|
||||
integrity sha512-SHgxd0tou/xlBG5XTPa//l0h1czxV0CUzMQ/QoMNin0n11JXFCIBooUzg5kguR8g4LvwzTAhHIx3ZVpypTOMtQ==
|
||||
"@angular-devkit/architect@0.900.0-rc.0":
|
||||
version "0.900.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-rc.0.tgz#e37b21dcbc631ddc615860571685194522478fef"
|
||||
integrity sha512-4IayjdSooY0+UchZivy5kOrHzeMEqoGGTxbmUycZ8kHayItH5gzBO+jGuNrQsfAnk3x53lRED1JCsQxAeH1JfQ==
|
||||
dependencies:
|
||||
"@angular-devkit/core" "9.0.0-next.11"
|
||||
"@angular-devkit/core" "9.0.0-rc.0"
|
||||
rxjs "6.5.3"
|
||||
|
||||
"@angular-devkit/build-angular@0.900.0-next.11":
|
||||
version "0.900.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.900.0-next.11.tgz#6ce47d1dc31437785c2e758900f67517b8debad6"
|
||||
integrity sha512-f0UbBAfseXVd4ldQPNgn3y/QYQwu/Pj+A6wsJAtA5LQaCHVCd4tn+0076Lqj/m6ooWlOM7n0kXL6OrD1lLsn3A==
|
||||
"@angular-devkit/build-angular@0.900.0-rc.0":
|
||||
version "0.900.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.900.0-rc.0.tgz#6ab41a55f8d2b6ffc81e27f75bf4b493745d1517"
|
||||
integrity sha512-I1OMWSGNC9th5Ft8n31yds4TgpT8kxo/GITZd/cJy3qgdEmo/uDk15PLqcriEAtNBtfdelhbZcHhGpwXiRsgNg==
|
||||
dependencies:
|
||||
"@angular-devkit/architect" "0.900.0-next.11"
|
||||
"@angular-devkit/build-optimizer" "0.900.0-next.11"
|
||||
"@angular-devkit/build-webpack" "0.900.0-next.11"
|
||||
"@angular-devkit/core" "9.0.0-next.11"
|
||||
"@angular-devkit/architect" "0.900.0-rc.0"
|
||||
"@angular-devkit/build-optimizer" "0.900.0-rc.0"
|
||||
"@angular-devkit/build-webpack" "0.900.0-rc.0"
|
||||
"@angular-devkit/core" "9.0.0-rc.0"
|
||||
"@babel/core" "7.6.4"
|
||||
"@babel/generator" "7.6.4"
|
||||
"@babel/preset-env" "7.6.3"
|
||||
"@ngtools/webpack" "9.0.0-next.11"
|
||||
"@ngtools/webpack" "9.0.0-rc.0"
|
||||
ajv "6.10.2"
|
||||
autoprefixer "9.6.5"
|
||||
browserslist "4.7.0"
|
||||
autoprefixer "9.7.0"
|
||||
browserslist "4.7.2"
|
||||
cacache "13.0.1"
|
||||
caniuse-lite "1.0.30000999"
|
||||
caniuse-lite "1.0.30001006"
|
||||
circular-dependency-plugin "5.2.0"
|
||||
clean-css "4.2.1"
|
||||
copy-webpack-plugin "5.0.4"
|
||||
core-js "3.3.2"
|
||||
core-js "3.3.5"
|
||||
file-loader "4.2.0"
|
||||
find-cache-dir "3.0.0"
|
||||
glob "7.1.4"
|
||||
glob "7.1.5"
|
||||
istanbul-instrumenter-loader "3.0.1"
|
||||
jest-worker "24.9.0"
|
||||
karma-source-map-support "1.4.0"
|
||||
@ -41,42 +42,44 @@
|
||||
less-loader "5.0.0"
|
||||
license-webpack-plugin "2.1.3"
|
||||
loader-utils "1.2.3"
|
||||
magic-string "0.25.4"
|
||||
mini-css-extract-plugin "0.8.0"
|
||||
minimatch "3.0.4"
|
||||
open "6.4.0"
|
||||
open "7.0.0"
|
||||
parse5 "4.0.0"
|
||||
postcss "7.0.18"
|
||||
postcss "7.0.21"
|
||||
postcss-import "12.0.1"
|
||||
postcss-loader "3.0.0"
|
||||
raw-loader "3.1.0"
|
||||
regenerator-runtime "0.13.3"
|
||||
rollup "1.24.0"
|
||||
rimraf "3.0.0"
|
||||
rollup "1.25.2"
|
||||
rxjs "6.5.3"
|
||||
sass "1.23.0"
|
||||
sass "1.23.1"
|
||||
sass-loader "8.0.0"
|
||||
semver "6.3.0"
|
||||
source-map "0.7.3"
|
||||
source-map-loader "0.2.4"
|
||||
source-map-support "0.5.13"
|
||||
source-map-support "0.5.16"
|
||||
speed-measure-webpack-plugin "1.3.1"
|
||||
style-loader "1.0.0"
|
||||
stylus "0.54.7"
|
||||
stylus-loader "3.0.2"
|
||||
terser "4.3.8"
|
||||
terser-webpack-plugin "2.1.3"
|
||||
terser "4.3.9"
|
||||
terser-webpack-plugin "2.2.1"
|
||||
tree-kill "1.2.1"
|
||||
webpack "4.41.1"
|
||||
webpack "4.41.2"
|
||||
webpack-dev-middleware "3.7.2"
|
||||
webpack-dev-server "3.8.2"
|
||||
webpack-dev-server "3.9.0"
|
||||
webpack-merge "4.2.2"
|
||||
webpack-sources "1.4.3"
|
||||
webpack-subresource-integrity "1.3.4"
|
||||
worker-plugin "3.2.0"
|
||||
|
||||
"@angular-devkit/build-optimizer@0.900.0-next.11":
|
||||
version "0.900.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.0-next.11.tgz#dc29609ae65d2c463ebc927cc43bc21d06f47475"
|
||||
integrity sha512-YpPqtOymhnq7I3hMnqgnaUpWvc9oxKPLm1TnRcULmL4SSlHjhCNvEaoWBX+/EBa+4Zba+kG2cNN2jHV1IA/Pjw==
|
||||
"@angular-devkit/build-optimizer@0.900.0-rc.0":
|
||||
version "0.900.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.0-rc.0.tgz#bee14497b69995241f0ff9e50f9e2b4e2dc7dfef"
|
||||
integrity sha512-xp/5WA1BhRep+tJmVOltaKT/P/01AOU4d/YMIPdfEeuvtmIj/yqs6Y1wqkpJVUzZNSJDoYl0sbXEJLk22oyc1A==
|
||||
dependencies:
|
||||
loader-utils "1.2.3"
|
||||
source-map "0.7.3"
|
||||
@ -84,19 +87,19 @@
|
||||
typescript "3.6.4"
|
||||
webpack-sources "1.4.3"
|
||||
|
||||
"@angular-devkit/build-webpack@0.900.0-next.11":
|
||||
version "0.900.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.0-next.11.tgz#21553341a338e07a77bcbaa958f609df648c70d9"
|
||||
integrity sha512-D2ZNQ7h4bL8jBie4PqJc/7IYYbYmNdY8aEPugBnra0IlqjoE+sdjdAxHdCnyi0qTvigDbQZPaZQoYlr1nhygzQ==
|
||||
"@angular-devkit/build-webpack@0.900.0-rc.0":
|
||||
version "0.900.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.0-rc.0.tgz#9b45c9a483f3bb7a4e531c17452cf7bd9d2fe456"
|
||||
integrity sha512-JKUiwo9KceCTEpL5zCDycCnkDfA1T576XlETmkb6CbgXXlCijPI5+ZKY09uL6yde6RU/FDL6aiy55IR8IR0EfQ==
|
||||
dependencies:
|
||||
"@angular-devkit/architect" "0.900.0-next.11"
|
||||
"@angular-devkit/core" "9.0.0-next.11"
|
||||
"@angular-devkit/architect" "0.900.0-rc.0"
|
||||
"@angular-devkit/core" "9.0.0-rc.0"
|
||||
rxjs "6.5.3"
|
||||
|
||||
"@angular-devkit/core@9.0.0-next.11":
|
||||
version "9.0.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-next.11.tgz#b8988c1fbfc3c42600dd5f9127cdfff4d14985b9"
|
||||
integrity sha512-e95eStdGjt4waesu/E3D/J2T3AHucmovUXov/iURZCvzlzG6jCXvwWVsRh7Zk7OWqUBvyCZ5T1cn7lAPc5UW6A==
|
||||
"@angular-devkit/core@9.0.0-rc.0":
|
||||
version "9.0.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-rc.0.tgz#b6b28881a711d8b4d9ccf9a51f63f60637f6cfe4"
|
||||
integrity sha512-ZcMTL7+1w+YhAuxIcW1c6CldT5T5VGmR8hZ5VKOT691QZXAUHmhod31Aic3T8CUzPgQxcrSneBuSN/0u2JgN9g==
|
||||
dependencies:
|
||||
ajv "6.10.2"
|
||||
fast-json-stable-stringify "2.0.0"
|
||||
@ -104,20 +107,19 @@
|
||||
rxjs "6.5.3"
|
||||
source-map "0.7.3"
|
||||
|
||||
"@angular-devkit/schematics@9.0.0-next.11":
|
||||
version "9.0.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-next.11.tgz#bb3659f1ee677db969ced806da7a8857a08633c8"
|
||||
integrity sha512-853PB1+6dQLgNI6DSFmsFFR6H3ivWcEjyCQWyC74OvwtCGl8ZvrJuJLUy7TQB2f7ygkRqyaJMV7PhNpk3dw+vg==
|
||||
"@angular-devkit/schematics@9.0.0-rc.0":
|
||||
version "9.0.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-rc.0.tgz#079ec1e6294c8df597a998738015469272b4f104"
|
||||
integrity sha512-LS+mDgats6bOlOYuSzOcAs43kIW4HuVFyDNRuJrWAhm304iGE1m0MpRT7Uh+nw2UBQp9AsHU8gCIzSH7Jv3tFQ==
|
||||
dependencies:
|
||||
"@angular-devkit/core" "9.0.0-next.11"
|
||||
"@angular-devkit/core" "9.0.0-rc.0"
|
||||
ora "4.0.2"
|
||||
rxjs "6.5.3"
|
||||
|
||||
"@angular/animations@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-9.0.0-next.10.tgz#965e5f1b9533fc1177dd122c21dadd8f7a349d2b"
|
||||
integrity sha512-KEH0oW2JCIUCsdA6NjJIP8V0fEYWLkccYwBGXvlhDnNW5d5JLhNEpjugrFaREYIQD/Qguu71eoZDFTdaJr7e/g==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/animations@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-9.0.0-rc.1.tgz#9f0645da9bf4b482eb8e33a0d50ee6d7e37bf1e4"
|
||||
integrity sha512-MBYF9mkPYeNMkOeHB3csWTbr0SLtb0MbaM4jTbVguv4026XV07bFmj/xqKWc7385uYslqp1HlVWJjUtCGZibgQ==
|
||||
|
||||
"@angular/cdk@9.0.0-next.0":
|
||||
version "9.0.0-next.0"
|
||||
@ -128,16 +130,16 @@
|
||||
optionalDependencies:
|
||||
parse5 "^5.0.0"
|
||||
|
||||
"@angular/cli@9.0.0-next.11":
|
||||
version "9.0.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.0.0-next.11.tgz#aa20668fdc6431b89c43532f567fbc9351cf9185"
|
||||
integrity sha512-S31iYhtyRKt8zYCfapSWfIc1C9CLysaw/h4s6U6cmePxX1i/MNz3AiClIM7D5xqiTqv5YNrvcf0jOdC8DxYMvw==
|
||||
"@angular/cli@9.0.0-rc.0":
|
||||
version "9.0.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.0.0-rc.0.tgz#135cfa008002135267d2e93a829e1356bd83a1a9"
|
||||
integrity sha512-iplRWAeNWDVHpFb6vVC27mSkvBT1AOZ1fJR9CkuAMJTfmGUkOPj8NFkAlzGUw1HbBpUI5IGIRoaSzEfNFjQfKQ==
|
||||
dependencies:
|
||||
"@angular-devkit/architect" "0.900.0-next.11"
|
||||
"@angular-devkit/core" "9.0.0-next.11"
|
||||
"@angular-devkit/schematics" "9.0.0-next.11"
|
||||
"@schematics/angular" "9.0.0-next.11"
|
||||
"@schematics/update" "0.900.0-next.11"
|
||||
"@angular-devkit/architect" "0.900.0-rc.0"
|
||||
"@angular-devkit/core" "9.0.0-rc.0"
|
||||
"@angular-devkit/schematics" "9.0.0-rc.0"
|
||||
"@schematics/angular" "9.0.0-rc.0"
|
||||
"@schematics/update" "0.900.0-rc.0"
|
||||
"@yarnpkg/lockfile" "1.1.0"
|
||||
ansi-colors "4.1.1"
|
||||
debug "^4.1.1"
|
||||
@ -145,25 +147,24 @@
|
||||
inquirer "7.0.0"
|
||||
npm-package-arg "6.1.1"
|
||||
npm-pick-manifest "3.0.2"
|
||||
open "6.4.0"
|
||||
open "7.0.0"
|
||||
pacote "9.5.8"
|
||||
read-package-tree "5.3.1"
|
||||
rimraf "3.0.0"
|
||||
semver "6.3.0"
|
||||
symbol-observable "1.2.0"
|
||||
universal-analytics "^0.4.20"
|
||||
uuid "^3.3.2"
|
||||
|
||||
"@angular/common@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/common/-/common-9.0.0-next.10.tgz#1d57400d0c4af121546177b143b5ab10be0bf8f2"
|
||||
integrity sha512-PrXIb+5f6IuZSgWpn0YpOWIYHCDcBJMihMBafHk+VaWtAPjdXGBo9PeBhXROPXGQrcMxorZHBCaj7REZcrh3Ug==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/common@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/common/-/common-9.0.0-rc.1.tgz#fe8a71137396c60f4972f5838c5aee9b5a5b9d30"
|
||||
integrity sha512-WwscTDPgAA4tp0luylMXyvN7dJWWwTt/chW56EshlnVJ49VL2Fp3wGHw6Ht2Mfa753CI2giZM61HI6HVhby/yA==
|
||||
|
||||
"@angular/compiler-cli@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-9.0.0-next.10.tgz#6465bd2b98bbbf8e6ec29260de4ee48c69272d23"
|
||||
integrity sha512-D4deoczwl6iNTjWtd4Cp8bQYmH9GE1CI64bK2WQLEp35UZRizRSFvFSht/7+BzdiEi7/+Sn31MiDUdkQCnYe2A==
|
||||
"@angular/compiler-cli@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-9.0.0-rc.1.tgz#bed7ac98698ef50fda330f7a4b5e9d0fe36705b4"
|
||||
integrity sha512-ZjbGNS8vtvAXOKcC6n3XNjyqIlED60Yfk/ODDv7D8IjlUtGkLccy9gB8+/olEHoLe6H7HxKZrRlJ72GJki8wNw==
|
||||
dependencies:
|
||||
canonical-path "1.0.0"
|
||||
chokidar "^2.1.1"
|
||||
@ -172,42 +173,34 @@
|
||||
magic-string "^0.25.0"
|
||||
minimist "^1.2.0"
|
||||
reflect-metadata "^0.1.2"
|
||||
semver "^6.3.0"
|
||||
source-map "^0.6.1"
|
||||
tslib "^1.9.0"
|
||||
yargs "13.1.0"
|
||||
|
||||
"@angular/compiler@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.0.0-next.10.tgz#299a0d5b63e68debe1b2469b12bda61f76d47450"
|
||||
integrity sha512-02+et2JJ8lkwBTFj+OiLcDat8mWgpLJRpUFFWzHJyEOIkfv/maDMmF6pQzI6X8YCyKaaOEIXaNZcfIYshewxJA==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/compiler@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.0.0-rc.1.tgz#4685c2fad9f2c0dc8e6e26f9f351eab3b6448cab"
|
||||
integrity sha512-L2y3o+eGRKU/BrY+V00sKNo3TBbL5kGmG96H57570N+WURDg9+xnzqsctJutUdVZkA2iM8Pa4f1ndoQoWlyZHg==
|
||||
|
||||
"@angular/core@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.0.0-next.10.tgz#6617be2e5e757b081e2c2bb52278240586020214"
|
||||
integrity sha512-YXQacLAB4yk1bFztUr0XdHCeZAMsX3UXxisEdJwB1TT+6XTthMC0rv4ja3pwgz6oXGRP7hSLKdx3UWj3xE2BLw==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/core@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.0.0-rc.1.tgz#9e2434089ecbedfb1f4c65267f293d067729277e"
|
||||
integrity sha512-W770tj/lVfXFljOo98zfAJelf1iiAdhrU2hC5Aic1Qa1C9yQK9+DAhsSA9ta/fxIRxrkYPjESx2UxQBS95e/wA==
|
||||
|
||||
"@angular/elements@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/elements/-/elements-9.0.0-next.10.tgz#8d5d0d7d171309f83b07805a2981fb8d69fdd200"
|
||||
integrity sha512-iodQnAbcfmn02szbxHr4hwcdnfE0PvJ0bYq+7+gqvGahym+CYdWWEcbPFQ3u84p4a6bS4TJxYjGY6JvDUcFV8w==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/elements@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/elements/-/elements-9.0.0-rc.1.tgz#a6d6356d775f102835219c8419517b667180bb44"
|
||||
integrity sha512-LEcK+bkkjROMFhN6v5ZOsFatXs4yk9gk+MXVdGnVhTmBH7YILcsPqqt+t+tm2cmSCTGDoBYOMszWfePy2nF4KQ==
|
||||
|
||||
"@angular/forms@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-9.0.0-next.10.tgz#2b46797ba2da0555077fc4a4184a284edbf7d17d"
|
||||
integrity sha512-oBamuJ3Y7lLwnBGcrJUlmj4px8KtVj+elQPkUY54D/r394/RLmck839o62dljPR2vd0wVjhPKkbUl7aUIDrvEw==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/forms@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-9.0.0-rc.1.tgz#89bb607013d9738676d112cf31183aadb99d216b"
|
||||
integrity sha512-/X+GUyiHV7VwTACouHhE519qP4qJdNXJ7435sO8W5hfqBg6pADMiQjxNzBvJA5ejfqb89FNviBEcVDDvfG9Pyw==
|
||||
|
||||
"@angular/language-service@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-9.0.0-next.10.tgz#2b1acf0419eacc1d4b6e48d298d808f1e4f1ddb5"
|
||||
integrity sha512-c7eHBNAKf+neP5Wr1YSNSq85sA8xVPMj0PpXKFyX5WMVyC/iRWZ3B/W+fbkpGCoMyxpDNn+4QZ6ewPr3Y8vbKg==
|
||||
"@angular/language-service@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-9.0.0-rc.1.tgz#e37162410b1e73f2cbbd85863fb975a008f6c473"
|
||||
integrity sha512-q4MjZ5xzrMRktC0nduUslXAAeyBRm6Rpw+gpfOaj0EUmtm1moEMAXHrQ2lVrRxolc8QdI6h4F3f1wMqB8sv3lA==
|
||||
|
||||
"@angular/material@9.0.0-next.0":
|
||||
version "9.0.0-next.0"
|
||||
@ -216,33 +209,25 @@
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/platform-browser-dynamic@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.0.0-next.10.tgz#49650e94eab8e468b2e2934d5ba46b7105a7a8dc"
|
||||
integrity sha512-RfDSqTZYHiHRc2j7OyppbrgYX1hTtUPqJOpNwytMwoyzwG3aHg9iNzlVw6h7b99euBxBpVwR96fmws2x52DFKw==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/platform-browser-dynamic@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.0.0-rc.1.tgz#4dad074d0f077d2d6e59ad7184d50857b109cbb2"
|
||||
integrity sha512-fE+vv8eq93uulSGtx7AAipTrdqMqC8Q4iU8gcogT7Mb08tIJfnkGMhYb1zt1b0LB/5RvEXf4TUHJnKCuOpbYjA==
|
||||
|
||||
"@angular/platform-browser@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-9.0.0-next.10.tgz#496d99a169a7b7941f6046ba9dc2852150a3745e"
|
||||
integrity sha512-PDcDscEwkEXhFhmiwn5dIs7MjmspgjeJJlW+JDHPPZntqgqiTIXiOhhDwvGyo0/Yi9cT1IP63w8gHbZp9Sx36w==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/platform-browser@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-9.0.0-rc.1.tgz#3c6ab23e94d59e01b5b699c2b5499ec0e713a2ef"
|
||||
integrity sha512-xWeq5rIP/+eRAGPYgilz8zVCirA9QqM6p+QwX2xlmXuUym1vjdHRgzCDyEt3aIrNGnnXnEm9boe9nhcuP5L+lg==
|
||||
|
||||
"@angular/router@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/router/-/router-9.0.0-next.10.tgz#d36aa9763d99fd532616eac985399118f881eced"
|
||||
integrity sha512-Il0KaD3Orm5HWGZvywJy8I9oH3uJVQZFX3FlZweaOsmlsAlrRw9tE4n51aOOVDff/NwJANdDLoQ5Kd8tBRqRPQ==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/router@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/router/-/router-9.0.0-rc.1.tgz#0fed7454135074722ffb7c427c6b8d871959eadd"
|
||||
integrity sha512-iACjciFfRhZvhpXoO1PryEITe5Lhwt8rCC4HKn4zy/xYOtyGhrHoALkdoC7/DmwtIIXKWkxVDjq1GdK1l8W3Ow==
|
||||
|
||||
"@angular/service-worker@^9.0.0-next.10":
|
||||
version "9.0.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-9.0.0-next.10.tgz#b096478e49a7a16df10753531cb5cb9ee8bf91b0"
|
||||
integrity sha512-krY0c+E3cZJ0zZ+/IKm4iQjAAk+kJgf92S1tYvU8qDebZHaiq3wA/Fjs+ziyHtY4NCcrRtIAGl3g6TvnKLMvwg==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
"@angular/service-worker@^9.0.0-rc.1":
|
||||
version "9.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-9.0.0-rc.1.tgz#e3913596b29b51f0aff0cc49ee5f6957a8211867"
|
||||
integrity sha512-QMd40tsJi+R6XAc7ei9euXKeWu9Zp7s5ks8uFeSjJlDya+vUWyaIUBs7L9MH9jFJ1flb6eYZKMqPKVQOfEkfgw==
|
||||
|
||||
"@babel/code-frame@^7.0.0":
|
||||
version "7.0.0"
|
||||
@ -278,6 +263,16 @@
|
||||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@7.6.4", "@babel/generator@^7.6.3", "@babel/generator@^7.6.4":
|
||||
version "7.6.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.4.tgz#a4f8437287bf9671b07f483b76e3bb731bc97671"
|
||||
integrity sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==
|
||||
dependencies:
|
||||
"@babel/types" "^7.6.3"
|
||||
jsesc "^2.5.1"
|
||||
lodash "^4.17.13"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.4.0", "@babel/generator@^7.5.0":
|
||||
version "7.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.0.tgz#f20e4b7a91750ee8b63656073d843d2a736dca4a"
|
||||
@ -310,16 +305,6 @@
|
||||
lodash "^4.17.13"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.6.3", "@babel/generator@^7.6.4":
|
||||
version "7.6.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.4.tgz#a4f8437287bf9671b07f483b76e3bb731bc97671"
|
||||
integrity sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==
|
||||
dependencies:
|
||||
"@babel/types" "^7.6.3"
|
||||
jsesc "^2.5.1"
|
||||
lodash "^4.17.13"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/helper-annotate-as-pure@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32"
|
||||
@ -1087,32 +1072,31 @@
|
||||
through2 "^2.0.0"
|
||||
xdg-basedir "^3.0.0"
|
||||
|
||||
"@ngtools/webpack@9.0.0-next.11":
|
||||
version "9.0.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.0-next.11.tgz#fcff75b83509161e257e29bdbe4578097f8a370d"
|
||||
integrity sha512-Z94ZJCW7pdR1k26T8puFD3zoL525HORFO9o6mURSLnFLapGLp7Y6H6CetRZuCLiFHjMaV6wWixXeE6Uph2JUZA==
|
||||
"@ngtools/webpack@9.0.0-rc.0":
|
||||
version "9.0.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.0-rc.0.tgz#c39b6d08d6aeb91d2758996e3e3de9a24bb4cf15"
|
||||
integrity sha512-OQKbqwOZD7hNo/iU5NHszu5E4LAyRJR7Z6bHR0+8VwL2Im021Xmv5yLvOpNq0UYp00Yyl+3AjqjPCR5VnIg6Pw==
|
||||
dependencies:
|
||||
"@angular-devkit/core" "9.0.0-next.11"
|
||||
"@angular-devkit/core" "9.0.0-rc.0"
|
||||
enhanced-resolve "4.1.1"
|
||||
rxjs "6.5.3"
|
||||
tree-kill "1.2.1"
|
||||
webpack-sources "1.4.3"
|
||||
|
||||
"@schematics/angular@9.0.0-next.11":
|
||||
version "9.0.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.0-next.11.tgz#166e7d8ef0d1992831dd88820c7a519ca5ab6c80"
|
||||
integrity sha512-fAA2jnT4NzO286FtoqYjxugRe1wq69o1SpuKtFXbIvFGvPPQdv1/UlNGjDkuURT7SiNRuLLALOqyFXh2LC9vXg==
|
||||
"@schematics/angular@9.0.0-rc.0":
|
||||
version "9.0.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.0-rc.0.tgz#e38a0bf86ece397ed1e49f768e02b02720af8c79"
|
||||
integrity sha512-64Lr1QbhuOxQtLCfcFDATj8xAa96+kQUqnM8Xr8ab1FVaBfFahMG14AcpsLXaOVpL7LLDHu3/23QGjxng6E3gg==
|
||||
dependencies:
|
||||
"@angular-devkit/core" "9.0.0-next.11"
|
||||
"@angular-devkit/schematics" "9.0.0-next.11"
|
||||
"@angular-devkit/core" "9.0.0-rc.0"
|
||||
"@angular-devkit/schematics" "9.0.0-rc.0"
|
||||
|
||||
"@schematics/update@0.900.0-next.11":
|
||||
version "0.900.0-next.11"
|
||||
resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.0-next.11.tgz#235c895e8ebbbf92d1e33fa2e1be5ece407c12cf"
|
||||
integrity sha512-qZ/Ry3ckREcM0rCr0JUy+I076P9lSRZ8e3dgKb5lsehdP1YqNkDO+mRtbbsKD37+YlPFIOigA7OYkcol78862Q==
|
||||
"@schematics/update@0.900.0-rc.0":
|
||||
version "0.900.0-rc.0"
|
||||
resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.0-rc.0.tgz#bc60f9446271239d0863b131aae8f9681b9416b9"
|
||||
integrity sha512-98Vhh6U6ADFMIb60xLqCqVGZnqp+e9XFu6jMAmRW6hykVwzgyp0ZZsJMQnITTTT7onhFnmmtw8NU+LkFoYSLzw==
|
||||
dependencies:
|
||||
"@angular-devkit/core" "9.0.0-next.11"
|
||||
"@angular-devkit/schematics" "9.0.0-next.11"
|
||||
"@angular-devkit/core" "9.0.0-rc.0"
|
||||
"@angular-devkit/schematics" "9.0.0-rc.0"
|
||||
"@yarnpkg/lockfile" "1.1.0"
|
||||
ini "1.3.5"
|
||||
pacote "9.5.8"
|
||||
@ -1923,17 +1907,17 @@ atob@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
autoprefixer@9.6.5:
|
||||
version "9.6.5"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.5.tgz#98f4afe7e93cccf323287515d426019619775e5e"
|
||||
integrity sha512-rGd50YV8LgwFQ2WQp4XzOTG69u1qQsXn0amww7tjqV5jJuNazgFKYEVItEBngyyvVITKOg20zr2V+9VsrXJQ2g==
|
||||
autoprefixer@9.7.0:
|
||||
version "9.7.0"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.0.tgz#905ec19e50f04545fe9ff131182cc9ab25246901"
|
||||
integrity sha512-j2IRvaCfrUxIiZun9ba4mhJ2omhw4OY88/yVzLO+lHhGBumAAK72PgM6gkbSN8iregPOn1ZlxGkmZh2CQ7X4AQ==
|
||||
dependencies:
|
||||
browserslist "^4.7.0"
|
||||
caniuse-lite "^1.0.30000999"
|
||||
browserslist "^4.7.2"
|
||||
caniuse-lite "^1.0.30001004"
|
||||
chalk "^2.4.2"
|
||||
normalize-range "^0.1.2"
|
||||
num2fraction "^1.2.2"
|
||||
postcss "^7.0.18"
|
||||
postcss "^7.0.19"
|
||||
postcss-value-parser "^4.0.2"
|
||||
|
||||
aws-sign2@~0.7.0:
|
||||
@ -2353,7 +2337,16 @@ browserify-zlib@^0.2.0:
|
||||
dependencies:
|
||||
pako "~1.0.5"
|
||||
|
||||
browserslist@4.7.0, browserslist@^4.6.0, browserslist@^4.6.6, browserslist@^4.7.0:
|
||||
browserslist@4.7.2, browserslist@^4.7.2:
|
||||
version "4.7.2"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.2.tgz#1bb984531a476b5d389cedecb195b2cd69fb1348"
|
||||
integrity sha512-uZavT/gZXJd2UTi9Ov7/Z340WOSQ3+m1iBVRUknf+okKxonL9P83S3ctiBDtuRmRu8PiCHjqyueqQ9HYlJhxiw==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30001004"
|
||||
electron-to-chromium "^1.3.295"
|
||||
node-releases "^1.1.38"
|
||||
|
||||
browserslist@^4.6.0, browserslist@^4.6.6:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17"
|
||||
integrity sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==
|
||||
@ -2558,10 +2551,10 @@ camelcase@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.2.0.tgz#e7522abda5ed94cc0489e1b8466610e88404cf45"
|
||||
integrity sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==
|
||||
|
||||
caniuse-lite@1.0.30000999, caniuse-lite@^1.0.30000999:
|
||||
version "1.0.30000999"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000999.tgz#427253a69ad7bea4aa8d8345687b8eec51ca0e43"
|
||||
integrity sha512-1CUyKyecPeksKwXZvYw0tEoaMCo/RwBlXmEtN5vVnabvO0KPd9RQLcaAuR9/1F+KDMv6esmOFWlsXuzDk+8rxg==
|
||||
caniuse-lite@1.0.30001006, caniuse-lite@^1.0.30001004:
|
||||
version "1.0.30001006"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001006.tgz#5b6e8288792cfa275f007b2819a00ccad7112655"
|
||||
integrity sha512-MXnUVX27aGs/QINz+QG1sWSLDr3P1A3Hq5EUWoIt0T7K24DuvMxZEnh3Y5aHlJW6Bz2aApJdSewdYLd8zQnUuw==
|
||||
|
||||
caniuse-lite@^1.0.30000989:
|
||||
version "1.0.30000989"
|
||||
@ -2876,6 +2869,11 @@ cli-spinners@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
|
||||
|
||||
cli-spinners@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77"
|
||||
integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==
|
||||
|
||||
cli-table2@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-table2/-/cli-table2-0.2.0.tgz#2d1ef7f218a0e786e214540562d4bd177fe32d97"
|
||||
@ -2928,6 +2926,11 @@ clone-response@1.0.2:
|
||||
dependencies:
|
||||
mimic-response "^1.0.0"
|
||||
|
||||
clone@^1.0.2:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
||||
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
|
||||
|
||||
clone@^2.1.1, clone@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
|
||||
@ -3321,10 +3324,10 @@ core-js-compat@^3.1.1:
|
||||
browserslist "^4.6.6"
|
||||
semver "^6.3.0"
|
||||
|
||||
core-js@3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.3.2.tgz#cd42da1d7b0bb33ef11326be3a721934277ceb42"
|
||||
integrity sha512-S1FfZpeBchkhyoY76YAdFzKS4zz9aOK7EeFaNA2aJlyXyA+sgqz6xdxmLPGXEAf0nF44MVN1kSjrA9Kt3ATDQg==
|
||||
core-js@3.3.5:
|
||||
version "3.3.5"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.3.5.tgz#58d20f48a95a07304b62ff752742b82b56431ed8"
|
||||
integrity sha512-0J3K+Par/ZydhKg8pEiTcK/9d65/nqJOzY62uMkjeBmt05fDOt/khUVjDdh8TpeIuGQDy1yLDDCjiWN/8pFIuw==
|
||||
|
||||
core-js@^2.4.0, core-js@^2.5.7:
|
||||
version "2.6.5"
|
||||
@ -3588,7 +3591,7 @@ debug@3.1.0, debug@=3.1.0, debug@~3.1.0:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.0.0, debug@^3.1.0, debug@^3.2.5, debug@^3.2.6:
|
||||
debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
@ -3661,6 +3664,13 @@ default-require-extensions@^2.0.0:
|
||||
dependencies:
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
defaults@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
|
||||
integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
|
||||
dependencies:
|
||||
clone "^1.0.2"
|
||||
|
||||
define-properties@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
|
||||
@ -4024,6 +4034,11 @@ electron-to-chromium@^1.3.247:
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.257.tgz#35da0ad5833b27184c8298804c498a4d2f4ed27d"
|
||||
integrity sha512-EcKVmUeHCZelPA0wnIaSmpAN8karKhKBwFb+xLUjSVZ8sGRE1l3fst1zQZ7KJUkyJ7H5edPd4RP94pzC9sG00A==
|
||||
|
||||
electron-to-chromium@^1.3.295:
|
||||
version "1.3.301"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.301.tgz#a501a4542ceb78eeba55736fdaafb64a4c421a3a"
|
||||
integrity sha512-MRUScWKAi/zh0B0vCOIWTXvFZDdCGtqFH9rmB0r8s6CR6zPgDFpc80JYj/kEB7dvoU5LpwGhIxF4BkeUWwKlqA==
|
||||
|
||||
elliptic@^6.0.0:
|
||||
version "6.4.1"
|
||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a"
|
||||
@ -5208,10 +5223,10 @@ glob-slasher@^1.0.1:
|
||||
lodash.isobject "^2.4.1"
|
||||
toxic "^1.0.0"
|
||||
|
||||
glob@7.1.4, glob@^7.1.4, glob@~7.1.1:
|
||||
version "7.1.4"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
|
||||
integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
|
||||
glob@7.1.5:
|
||||
version "7.1.5"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0"
|
||||
integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
@ -5231,6 +5246,18 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, gl
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.1.4, glob@~7.1.1:
|
||||
version "7.1.4"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
|
||||
integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
global-dirs@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.0.tgz#10d34039e0df04272e262cf24224f7209434df4f"
|
||||
@ -6372,6 +6399,11 @@ is-installed-globally@^0.1.0:
|
||||
global-dirs "^0.1.0"
|
||||
is-path-inside "^1.0.0"
|
||||
|
||||
is-interactive@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
|
||||
integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
|
||||
|
||||
is-lower-case@^1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393"
|
||||
@ -6540,6 +6572,11 @@ is-wsl@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
|
||||
integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=
|
||||
|
||||
is-wsl@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d"
|
||||
integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==
|
||||
|
||||
is@^3.0.1, is@^3.2.0, is@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5"
|
||||
@ -7443,6 +7480,13 @@ log-driver@1.2.7:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8"
|
||||
|
||||
log-symbols@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4"
|
||||
integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==
|
||||
dependencies:
|
||||
chalk "^2.4.2"
|
||||
|
||||
log4js@^4.0.0:
|
||||
version "4.5.1"
|
||||
resolved "https://registry.yarnpkg.com/log4js/-/log4js-4.5.1.tgz#e543625e97d9e6f3e6e7c9fc196dd6ab2cae30b5"
|
||||
@ -8216,6 +8260,13 @@ node-releases@^1.1.29:
|
||||
dependencies:
|
||||
semver "^5.3.0"
|
||||
|
||||
node-releases@^1.1.38:
|
||||
version "1.1.39"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.39.tgz#c1011f30343aff5b633153b10ff691d278d08e8d"
|
||||
integrity sha512-8MRC/ErwNCHOlAFycy9OPca46fQYUjbJRDcZTHVWIGXIjYLM73k70vv3WkYutVnM4cCo4hE0MqBVVZjP6vjISA==
|
||||
dependencies:
|
||||
semver "^6.3.0"
|
||||
|
||||
"nomnom@>= 1.5.x":
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7"
|
||||
@ -8529,12 +8580,12 @@ onetime@^5.1.0:
|
||||
dependencies:
|
||||
mimic-fn "^2.1.0"
|
||||
|
||||
open@6.4.0:
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9"
|
||||
integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==
|
||||
open@7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/open/-/open-7.0.0.tgz#7e52999b14eb73f90f0f0807fe93897c4ae73ec9"
|
||||
integrity sha512-K6EKzYqnwQzk+/dzJAQSBORub3xlBTxMz+ntpZpH/LyCa1o6KjXhuN+2npAaI9jaSmU3R1Q8NWf4KUWcyytGsQ==
|
||||
dependencies:
|
||||
is-wsl "^1.1.0"
|
||||
is-wsl "^2.1.0"
|
||||
|
||||
opener@^1.5.1:
|
||||
version "1.5.1"
|
||||
@ -8593,6 +8644,19 @@ ora@0.2.3:
|
||||
cli-spinners "^0.1.2"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
ora@4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ora/-/ora-4.0.2.tgz#0e1e68fd45b135d28648b27cf08081fa6e8a297d"
|
||||
integrity sha512-YUOZbamht5mfLxPmk4M35CD/5DuOkAacxlEUbStVXpBAt4fyhBf+vZHI/HRkI++QUp3sNoeA2Gw4C+hi4eGSig==
|
||||
dependencies:
|
||||
chalk "^2.4.2"
|
||||
cli-cursor "^3.1.0"
|
||||
cli-spinners "^2.2.0"
|
||||
is-interactive "^1.0.0"
|
||||
log-symbols "^3.0.0"
|
||||
strip-ansi "^5.2.0"
|
||||
wcwidth "^1.0.1"
|
||||
|
||||
original@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
|
||||
@ -9081,14 +9145,14 @@ portfinder@^1.0.13:
|
||||
debug "^2.2.0"
|
||||
mkdirp "0.5.x"
|
||||
|
||||
portfinder@^1.0.24:
|
||||
version "1.0.24"
|
||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.24.tgz#11efbc6865f12f37624b6531ead1d809ed965cfa"
|
||||
integrity sha512-ekRl7zD2qxYndYflwiryJwMioBI7LI7rVXg3EnLK3sjkouT5eOuhS3gS255XxBksa30VG8UPZYZCdgfGOfkSUg==
|
||||
portfinder@^1.0.25:
|
||||
version "1.0.25"
|
||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca"
|
||||
integrity sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==
|
||||
dependencies:
|
||||
async "^1.5.2"
|
||||
debug "^2.2.0"
|
||||
mkdirp "0.5.x"
|
||||
async "^2.6.2"
|
||||
debug "^3.1.1"
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
posix-character-classes@^0.1.0:
|
||||
version "0.1.1"
|
||||
@ -9133,10 +9197,10 @@ postcss-value-parser@^4.0.2:
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9"
|
||||
integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==
|
||||
|
||||
postcss@7.0.18, postcss@^7.0.18:
|
||||
version "7.0.18"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.18.tgz#4b9cda95ae6c069c67a4d933029eddd4838ac233"
|
||||
integrity sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==
|
||||
postcss@7.0.21, postcss@^7.0.19:
|
||||
version "7.0.21"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17"
|
||||
integrity sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==
|
||||
dependencies:
|
||||
chalk "^2.4.2"
|
||||
source-map "^0.6.1"
|
||||
@ -10112,6 +10176,13 @@ rimraf@2.6.2, rimraf@2.x.x, rimraf@^2.6.0:
|
||||
dependencies:
|
||||
glob "^7.0.5"
|
||||
|
||||
rimraf@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.0.tgz#614176d4b3010b75e5c390eb0ee96f6dc0cebb9b"
|
||||
integrity sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||
@ -10138,10 +10209,10 @@ robots-parser@^2.0.1:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/robots-parser/-/robots-parser-2.1.0.tgz#d16b78ce34e861ab6afbbf0aac65974dbe01566e"
|
||||
|
||||
rollup@1.24.0:
|
||||
version "1.24.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.24.0.tgz#0ace969508babb7a5fcb228e831e9c9a2873c2b0"
|
||||
integrity sha512-PiFETY/rPwodQ8TTC52Nz2DSCYUATznGh/ChnxActCr8rV5FIk3afBUb3uxNritQW/Jpbdn3kq1Rwh1HHYMwdQ==
|
||||
rollup@1.25.2:
|
||||
version "1.25.2"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.25.2.tgz#739f508bd8f7ece52bb6c1fcda83466af82b7f6d"
|
||||
integrity sha512-+7z6Wab/L45QCPcfpuTZKwKiB0tynj05s/+s2U3F2Bi7rOLPr9UcjUwO7/xpjlPNXA/hwnth6jBExFRGyf3tMg==
|
||||
dependencies:
|
||||
"@types/estree" "*"
|
||||
"@types/node" "*"
|
||||
@ -10261,10 +10332,10 @@ sass-loader@8.0.0:
|
||||
schema-utils "^2.1.0"
|
||||
semver "^6.3.0"
|
||||
|
||||
sass@1.23.0:
|
||||
version "1.23.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.23.0.tgz#bd526ff40dbc5d09a4ed69e2cffa849749977710"
|
||||
integrity sha512-W4HT8+WE31Rzk3EPQC++CXjD5O+lOxgYBIB8Ohvt7/zeE2UzYW+TOczDrRU3KcEy3+xwXXbmDsOZFkoqgD4TKw==
|
||||
sass@1.23.1:
|
||||
version "1.23.1"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.23.1.tgz#0e5b72ba2bd9f0229a637d33f8dd5bf2d810beb3"
|
||||
integrity sha512-zQzJ3UETUWOMd/pJJGH/zvRsBVO97m11RcpfUhcQUHEXf0yHUBgOIE/Nw8aK0m1XyVJPeq228iIK7gVxsJ/Puw==
|
||||
dependencies:
|
||||
chokidar ">=2.0.0 <4.0.0"
|
||||
|
||||
@ -10312,7 +10383,7 @@ schema-utils@^2.0.0, schema-utils@^2.0.1, schema-utils@^2.1.0:
|
||||
ajv "^6.10.2"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
schema-utils@^2.4.1:
|
||||
schema-utils@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.5.0.tgz#8f254f618d402cc80257486213c8970edfd7c22f"
|
||||
integrity sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==
|
||||
@ -10762,10 +10833,10 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
|
||||
source-map-url "^0.4.0"
|
||||
urix "^0.1.0"
|
||||
|
||||
source-map-support@0.5.13, source-map-support@^0.5.6, source-map-support@~0.5.12:
|
||||
version "0.5.13"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"
|
||||
integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
|
||||
source-map-support@0.5.16:
|
||||
version "0.5.16"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
|
||||
integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
@ -10784,6 +10855,14 @@ source-map-support@^0.5.5:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map-support@^0.5.6, source-map-support@~0.5.12:
|
||||
version "0.5.13"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"
|
||||
integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map-url@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||
@ -11434,18 +11513,18 @@ term-size@^1.2.0:
|
||||
dependencies:
|
||||
execa "^0.7.0"
|
||||
|
||||
terser-webpack-plugin@2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.1.3.tgz#85430da71ba88a60072bf659589eafaf6a00dc22"
|
||||
integrity sha512-z5Utx0TxmirZvRNL1GC795tlDM+bO83ZfcbtkL1y1VLoWtZ7S2a9+HFCLnabSRE/Yjsu4zCEX6U6CIRo4dVmcQ==
|
||||
terser-webpack-plugin@2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.2.1.tgz#5569e6c7d8be79e5e43d6da23acc3b6ba77d22bd"
|
||||
integrity sha512-jwdauV5Al7zopR6OAYvIIRcxXCSvLjZjr7uZE8l2tIWb/ryrGN48sJftqGf5k9z09tWhajx53ldp0XPI080YnA==
|
||||
dependencies:
|
||||
cacache "^13.0.1"
|
||||
find-cache-dir "^3.0.0"
|
||||
jest-worker "^24.9.0"
|
||||
schema-utils "^2.4.1"
|
||||
schema-utils "^2.5.0"
|
||||
serialize-javascript "^2.1.0"
|
||||
source-map "^0.6.1"
|
||||
terser "^4.3.8"
|
||||
terser "^4.3.9"
|
||||
webpack-sources "^1.4.3"
|
||||
|
||||
terser-webpack-plugin@^1.4.1:
|
||||
@ -11463,19 +11542,19 @@ terser-webpack-plugin@^1.4.1:
|
||||
webpack-sources "^1.4.0"
|
||||
worker-farm "^1.7.0"
|
||||
|
||||
terser@4.3.8, terser@^4.1.2:
|
||||
version "4.3.8"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.8.tgz#707f05f3f4c1c70c840e626addfdb1c158a17136"
|
||||
integrity sha512-otmIRlRVmLChAWsnSFNO0Bfk6YySuBp6G9qrHiJwlLDd4mxe2ta4sjI7TzIR+W1nBMjilzrMcPOz9pSusgx3hQ==
|
||||
terser@4.3.9, terser@^4.3.9:
|
||||
version "4.3.9"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.9.tgz#e4be37f80553d02645668727777687dad26bbca8"
|
||||
integrity sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA==
|
||||
dependencies:
|
||||
commander "^2.20.0"
|
||||
source-map "~0.6.1"
|
||||
source-map-support "~0.5.12"
|
||||
|
||||
terser@^4.3.8:
|
||||
version "4.3.9"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.9.tgz#e4be37f80553d02645668727777687dad26bbca8"
|
||||
integrity sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA==
|
||||
terser@^4.1.2:
|
||||
version "4.3.8"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.8.tgz#707f05f3f4c1c70c840e626addfdb1c158a17136"
|
||||
integrity sha512-otmIRlRVmLChAWsnSFNO0Bfk6YySuBp6G9qrHiJwlLDd4mxe2ta4sjI7TzIR+W1nBMjilzrMcPOz9pSusgx3hQ==
|
||||
dependencies:
|
||||
commander "^2.20.0"
|
||||
source-map "~0.6.1"
|
||||
@ -12318,6 +12397,13 @@ wbuf@^1.1.0, wbuf@^1.7.2, wbuf@^1.7.3:
|
||||
dependencies:
|
||||
minimalistic-assert "^1.0.0"
|
||||
|
||||
wcwidth@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
|
||||
integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
|
||||
dependencies:
|
||||
defaults "^1.0.3"
|
||||
|
||||
web-namespaces@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.2.tgz#c8dc267ab639505276bae19e129dbd6ae72b22b4"
|
||||
@ -12366,10 +12452,10 @@ webpack-dev-middleware@3.7.2, webpack-dev-middleware@^3.7.2:
|
||||
range-parser "^1.2.1"
|
||||
webpack-log "^2.0.0"
|
||||
|
||||
webpack-dev-server@3.8.2:
|
||||
version "3.8.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.8.2.tgz#3292427bf6510da9a3ac2d500b924a4197667ff9"
|
||||
integrity sha512-0xxogS7n5jHDQWy0WST0q6Ykp7UGj4YvWh+HVN71JoE7BwPxMZrwgraBvmdEMbDVMBzF0u+mEzn8TQzBm5NYJQ==
|
||||
webpack-dev-server@3.9.0:
|
||||
version "3.9.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.9.0.tgz#27c3b5d0f6b6677c4304465ac817623c8b27b89c"
|
||||
integrity sha512-E6uQ4kRrTX9URN9s/lIbqTAztwEPdvzVrcmHE8EQ9YnuT9J8Es5Wrd8n9BKg1a0oZ5EgEke/EQFgUsp18dSTBw==
|
||||
dependencies:
|
||||
ansi-html "0.0.7"
|
||||
bonjour "^3.5.0"
|
||||
@ -12389,7 +12475,7 @@ webpack-dev-server@3.8.2:
|
||||
loglevel "^1.6.4"
|
||||
opn "^5.5.0"
|
||||
p-retry "^3.0.1"
|
||||
portfinder "^1.0.24"
|
||||
portfinder "^1.0.25"
|
||||
schema-utils "^1.0.0"
|
||||
selfsigned "^1.10.7"
|
||||
semver "^6.3.0"
|
||||
@ -12443,10 +12529,10 @@ webpack-subresource-integrity@1.3.4:
|
||||
dependencies:
|
||||
webpack-sources "^1.3.0"
|
||||
|
||||
webpack@4.41.1:
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.1.tgz#5388dd3047d680d5d382a84249fd4750e87372fd"
|
||||
integrity sha512-ak7u4tUu/U63sCVxA571IuPZO/Q0pZ9cEXKg+R/woxkDzVovq57uB6L2Hlg/pC8LCU+TWpvtcYwsstivQwMJmw==
|
||||
webpack@4.41.2:
|
||||
version "4.41.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.2.tgz#c34ec76daa3a8468c9b61a50336d8e3303dce74e"
|
||||
integrity sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A==
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.8.5"
|
||||
"@webassemblyjs/helper-module-context" "1.8.5"
|
||||
|
@ -4,7 +4,7 @@ Currently all changes to Ivy are validated against the test suite of the
|
||||
`angular/components` repository. In order to debug the `material-unit-tests` CI
|
||||
job, the following steps can be used:
|
||||
|
||||
1\) Build the Ivy package output by running `./scripts/build-ivy-npm-packages.sh` in
|
||||
1\) Build the Ivy package output by running `node ./scripts/build-ivy-npm-packages.js` in
|
||||
the `angular/angular` repo.
|
||||
|
||||
2\) Clone the `angular/components` repository if not done yet ([quick link to repo](https://github.com/angular/components)).
|
||||
@ -32,9 +32,9 @@ selecting a given test target.
|
||||
|
||||
Here is an example of commands that run individual test targets. Note that it is
|
||||
**important** to specify the `--define=compile=aot` flag in order to run tests with Ivy.
|
||||
|
||||
|
||||
```bash
|
||||
yarn bazel test --define=compile=aot src/material/slider:unit_tests
|
||||
yarn bazel test --define=compile=aot src/cdk/a11y:unit_tests
|
||||
yarn bazel test --define=compile=aot src/material/toolbar:unit_tests
|
||||
```
|
||||
```
|
||||
|
@ -69,7 +69,7 @@ yarn install
|
||||
To build Angular run:
|
||||
|
||||
```shell
|
||||
./scripts/build-packages-dist.sh
|
||||
node ./scripts/build-packages-dist.js
|
||||
```
|
||||
|
||||
* Results are put in the `dist/packages-dist` folder.
|
||||
@ -151,7 +151,7 @@ time of the build.
|
||||
You can access the artifacts for a specific CI run by going to the workflow page, clicking on the
|
||||
`publish_packages_as_artifacts` job and then switching to the "Artifacts" tab.
|
||||
(If you happen to know the build number of the job, the URL will be something like:
|
||||
https://circleci.com/gh/angular/angular/<build-number>#artifacts)
|
||||
`https://circleci.com/gh/angular/angular/<build-number>#artifacts`)
|
||||
|
||||
#### Archives for each Package
|
||||
On the "Artifacts" tab, there is a list of links to compressed archives for Angular packages. The
|
||||
@ -190,7 +190,7 @@ c. Some package managers (such as `pnpm` or `yarn pnp`) might not work correctly
|
||||
### Publishing to GitHub repos
|
||||
You can also manually publish `*-builds` snapshots just like our CircleCI build does for upstream
|
||||
builds. Before being able to publish the packages, you need to build them locally by running the
|
||||
`./scripts/build-packages-dist.sh` script.
|
||||
`./scripts/build-packages-dist.js` script.
|
||||
|
||||
First time, you need to create the GitHub repositories:
|
||||
|
||||
|
@ -56,5 +56,4 @@ gulp.task('changelog', loadTask('changelog'));
|
||||
gulp.task('changelog:zonejs', loadTask('changelog-zonejs'));
|
||||
gulp.task('check-env', () => {/* this is a noop because the env test ran already above */});
|
||||
gulp.task('cldr:extract', loadTask('cldr', 'extract'));
|
||||
gulp.task('cldr:download', loadTask('cldr', 'download'));
|
||||
gulp.task('cldr:gen-closure-locale', loadTask('cldr', 'closure'));
|
||||
|
@ -3,7 +3,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime-es2015": 1485,
|
||||
"main-es2015": 143181,
|
||||
"main-es2015": 141575,
|
||||
"polyfills-es2015": 36808
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime-es2015": 1485,
|
||||
"main-es2015": 14786,
|
||||
"main-es2015": 15267,
|
||||
"polyfills-es2015": 36808
|
||||
}
|
||||
}
|
||||
@ -21,7 +21,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime-es2015": 1485,
|
||||
"main-es2015": 149315,
|
||||
"main-es2015": 147719,
|
||||
"polyfills-es2015": 36808
|
||||
}
|
||||
}
|
||||
@ -39,7 +39,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime-es2015": 2289,
|
||||
"main-es2015": 268331,
|
||||
"main-es2015": 312772,
|
||||
"polyfills-es2015": 36808,
|
||||
"5-es2015": 751
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
# Fetch rules_nodejs so we can install our npm dependencies
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = "3d7296d834208792fa3b2ded8ec04e75068e3de172fae79db217615bd75a6ff7",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.39.1/rules_nodejs-0.39.1.tar.gz"],
|
||||
sha256 = "9901bc17138a79135048fb0c107ee7a56e91815ec6594c08cb9a17b80276d62b",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.40.0/rules_nodejs-0.40.0.tar.gz"],
|
||||
)
|
||||
|
||||
# Fetch sass rules for compiling sass files
|
||||
|
@ -23,11 +23,11 @@
|
||||
"@angular/compiler": "file:../../dist/packages-dist/compiler",
|
||||
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
||||
"@bazel/bazel": "file:../../node_modules/@bazel/bazel",
|
||||
"@bazel/karma": "0.39.1",
|
||||
"@bazel/protractor": "0.39.1",
|
||||
"@bazel/rollup": "0.39.1",
|
||||
"@bazel/terser": "0.39.1",
|
||||
"@bazel/typescript": "0.39.1",
|
||||
"@bazel/karma": "0.40.0",
|
||||
"@bazel/protractor": "0.40.0",
|
||||
"@bazel/rollup": "0.40.0",
|
||||
"@bazel/terser": "0.40.0",
|
||||
"@bazel/typescript": "0.40.0",
|
||||
"@types/jasmine": "2.8.8",
|
||||
"http-server": "^0.11.1",
|
||||
"rollup": "~1.25.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("@npm_bazel_karma//:index.bzl", "ts_web_test_suite")
|
||||
load("@npm_bazel_karma//:index.bzl", "karma_web_test_suite")
|
||||
load("@npm_bazel_typescript//:index.bzl", "ts_library")
|
||||
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_binary")
|
||||
load("@npm_angular_bazel//:index.bzl", "ng_module", "ng_package")
|
||||
@ -43,7 +43,7 @@ ts_library(
|
||||
],
|
||||
)
|
||||
|
||||
ts_web_test_suite(
|
||||
karma_web_test_suite(
|
||||
name = "test",
|
||||
bootstrap = [
|
||||
"@npm//:node_modules/zone.js/dist/zone-testing-bundle.js",
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
|
||||
"@angular/animations@file:../../dist/packages-dist/animations":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
|
||||
"@angular/bazel@file:../../dist/packages-dist/bazel":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
dependencies:
|
||||
"@microsoft/api-extractor" "^7.3.9"
|
||||
shelljs "0.8.2"
|
||||
@ -22,10 +22,10 @@
|
||||
parse5 "^5.0.0"
|
||||
|
||||
"@angular/common@file:../../dist/packages-dist/common":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
|
||||
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
dependencies:
|
||||
canonical-path "1.0.0"
|
||||
chokidar "^2.1.1"
|
||||
@ -39,13 +39,13 @@
|
||||
yargs "13.1.0"
|
||||
|
||||
"@angular/compiler@file:../../dist/packages-dist/compiler":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
|
||||
"@angular/core@file:../../dist/packages-dist/core":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
|
||||
"@angular/forms@file:../../dist/packages-dist/forms":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
|
||||
"@angular/material@8.0.1":
|
||||
version "8.0.1"
|
||||
@ -55,13 +55,13 @@
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
|
||||
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
|
||||
"@angular/router@file:../../dist/packages-dist/router":
|
||||
version "9.0.0-next.14"
|
||||
version "9.0.0-rc.1"
|
||||
|
||||
"@bazel/bazel-darwin_x64@1.0.0":
|
||||
version "1.0.0"
|
||||
@ -92,10 +92,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@bazel/hide-bazel-files/-/hide-bazel-files-0.38.3.tgz#e98231d3d360d51860d9c1a7c3345b40dab4cf81"
|
||||
integrity sha512-o+dNkfDm3qxWQ8h/04cWuTcjR7qnjZi3pQGv4aklVb16oPWx2jF8BzbkwvWuIkdbOl9VnqYP0vaHzwQVJRRcIA==
|
||||
|
||||
"@bazel/karma@0.39.1":
|
||||
version "0.39.1"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/karma/-/karma-0.39.1.tgz#23898875444a5ef1fd9ac0dbaebcdd05b90d51f8"
|
||||
integrity sha512-P4LNCeopKGmhwRJrA6qtMLAvMgIalq5I9XYlaPOLjkoYKcjwAReBKyWY9VYhDEYld2P/P1YJmx/+nQDZAowocA==
|
||||
"@bazel/karma@0.40.0":
|
||||
version "0.40.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/karma/-/karma-0.40.0.tgz#5d6b669355d173dea02e9b5d21ff41db91ceb3fd"
|
||||
integrity sha512-xRbUU3vg2KUmCTYBkHsvdDEy6vhtmWICiE/s0vikb4c3lCY5UtY/Y9fmoflhNHjOgjnncEFS8J4uMaWn5rZmhg==
|
||||
dependencies:
|
||||
jasmine-core "2.8.0"
|
||||
karma "~4.1.0"
|
||||
@ -109,27 +109,27 @@
|
||||
semver "5.6.0"
|
||||
tmp "0.0.33"
|
||||
|
||||
"@bazel/protractor@0.39.1":
|
||||
version "0.39.1"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/protractor/-/protractor-0.39.1.tgz#24988e12eaa3efbcdbb7e80dba20105e379e4016"
|
||||
integrity sha512-zVbCrK8Uyfd2D93laHYp+YLvoR2Pfov/i13b6MTDkgDkzWd0NoPIlPqLAXuKhOUi5rYUcbp+DoY9A+HA2Rfy1g==
|
||||
"@bazel/protractor@0.40.0":
|
||||
version "0.40.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/protractor/-/protractor-0.40.0.tgz#0c64ddbf5a063417f43520ec1fed5cbc485792cf"
|
||||
integrity sha512-qio8c8ie6Ajwu6hEs3vYf5+18JvrYH/6bv2b5YcE7HnyQZKGeJCDyTUErIUkCHwq8RsIqpsgxtCj69xmUxZXbw==
|
||||
dependencies:
|
||||
protractor "^5.4.2"
|
||||
|
||||
"@bazel/rollup@0.39.1":
|
||||
version "0.39.1"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/rollup/-/rollup-0.39.1.tgz#9c7ca1fef256743353b8acb7944ca2f9723d83a1"
|
||||
integrity sha512-5EqAgupj8NHQ2p3GgtuOZ8O0qM6S0NfDj8OgROuSF0sJFH9ojQkXBZowHfZfWT3Xt6Igi3dw55bZS964havh8Q==
|
||||
"@bazel/rollup@0.40.0":
|
||||
version "0.40.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/rollup/-/rollup-0.40.0.tgz#8ee08e1967c1ff7d549ce81b676872fa7e45afdb"
|
||||
integrity sha512-7ZKzOIfHm0lEc3G/o2ykCZQlc7xcKSHiwIV4GIeaYJIbFUnO/L0cmaWzxOhdlr7NFfTdXcltTFnCrG7wlaad9A==
|
||||
|
||||
"@bazel/terser@0.39.1":
|
||||
version "0.39.1"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/terser/-/terser-0.39.1.tgz#fa8ad78502d6e953a953dc6ef4e135e6a50aaf3e"
|
||||
integrity sha512-YIfs7uoEQU2xnpfY3bF7GjCaaHTE6e5gUIy0Ua9V1qeLZECUmVQgIfmSEV/JTykzIQpO+l3dX3IcIzkYZGlF/A==
|
||||
"@bazel/terser@0.40.0":
|
||||
version "0.40.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/terser/-/terser-0.40.0.tgz#e31c76c32055a6bdffc711b05b530ae8df7ed1d5"
|
||||
integrity sha512-XSnoLnB9i+RTJ4T1Tyrq0NMcIStzb9LQ1szMBOkJY4mBTRRNpf8Qnq+k5Vu9YY/dNIKVWtowNYBSWHzxxcL05g==
|
||||
|
||||
"@bazel/typescript@0.39.1":
|
||||
version "0.39.1"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-0.39.1.tgz#fbe3f9e287aa294935987bbbd9f2dce5341a9b02"
|
||||
integrity sha512-n4P6VKir1L3+rM/DgHa5mnlCfT7Wo0ra+TnkbTuZ08SeN/r8HTmClK6YADoDc5ORMQhzq8eXuVuLWeUUsFJyHQ==
|
||||
"@bazel/typescript@0.40.0":
|
||||
version "0.40.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-0.40.0.tgz#4f70d1365ee28fb8c1fd430a25034b74deecada9"
|
||||
integrity sha512-826LXZYVlvcf9zNNcywzGprMUgCFqcwCeM/VLp+xG8/q6idJpqCBxABfJy2U6iZ8qIg5+wlxgYkOcmAZBfKMfA==
|
||||
dependencies:
|
||||
protobufjs "6.8.8"
|
||||
semver "5.6.0"
|
||||
|
@ -11,7 +11,7 @@ set -u -e -o pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
$(pwd)/../../scripts/build-packages-dist.sh
|
||||
node $(pwd)/../../scripts/build-packages-dist.js
|
||||
|
||||
# Workaround https://github.com/yarnpkg/yarn/issues/2165
|
||||
# Yarn will cache file://dist URIs and not update Angular code
|
||||
@ -26,4 +26,4 @@ trap rm_cache EXIT
|
||||
rm -rf dist
|
||||
rm -rf node_modules
|
||||
yarn install --cache-folder $cache
|
||||
yarn test
|
||||
yarn test
|
||||
|
@ -25,7 +25,7 @@
|
||||
"@angular/router": "file:../../dist/packages-dist/router",
|
||||
"rxjs": "file:../../node_modules/rxjs",
|
||||
"tslib": "file:../../node_modules/tslib",
|
||||
"zone.js": "file:../../dist/bin/packages/zone.js/npm_package"
|
||||
"zone.js": "file:../../dist/zone.js-dist/zone.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^0.900.0-rc.0",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user