mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
228 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 296bc993ea | |||
| 79f1be5e70 | |||
| 35a3fde5b7 | |||
| 37bbc61cfe | |||
| 82fd24ba83 | |||
| 8fd95aa05f | |||
| 61e69c87e6 | |||
| 244a7d2d0c | |||
| 54814c8e9b | |||
| 0cd056abe7 | |||
| aef353c143 | |||
| 11809badb2 | |||
| 1248992631 | |||
| b358b61304 | |||
| a4312e1be5 | |||
| 28efb06a96 | |||
| c3bc035f5d | |||
| db867fee77 | |||
| 6d4f75931b | |||
| 956025aa40 | |||
| 6c940eb07e | |||
| cc1e96da45 | |||
| e93b3a5245 | |||
| 6cc5b3e015 | |||
| bab5f9a18f | |||
| f7f354a1f7 | |||
| 92d28bdd99 | |||
| 65a3338e54 | |||
| a5e1104508 | |||
| d2d9bbf5ce | |||
| 8707475341 | |||
| 9d12a072b8 | |||
| a478ab17de | |||
| 8161b98069 | |||
| 37788b6554 | |||
| 7c4f77a062 | |||
| a42c8cfc67 | |||
| 4d18ba1af7 | |||
| 15044737a6 | |||
| 64c8ebaf9f | |||
| 3a4ddbac4e | |||
| 64d6a4fc49 | |||
| c62246c038 | |||
| ad78d25974 | |||
| 13d6221a0b | |||
| 46d33dd206 | |||
| 2e7e4024ca | |||
| 2ca213747c | |||
| 24950dd2a5 | |||
| 0fdd6f9726 | |||
| 09d5f51764 | |||
| 3fd176a905 | |||
| b82da42725 | |||
| b9a0396097 | |||
| fe5adc7d15 | |||
| 6c9b5a2557 | |||
| 5154d121ac | |||
| 2fd893d52c | |||
| 2aaca8e0be | |||
| 6be93cf4e4 | |||
| a7de7366b2 | |||
| f57bb389a8 | |||
| 477adb7586 | |||
| f791326dec | |||
| f87757dd7b | |||
| 9c86916831 | |||
| cfd0cdbd9b | |||
| 9e1465849e | |||
| c3821f5ab5 | |||
| 4620fbdf04 | |||
| e3ef401c25 | |||
| 197e8b4963 | |||
| 1095dc5fd1 | |||
| 5819c8ecff | |||
| 5782d632f5 | |||
| 6f4f16219b | |||
| f457b6c26b | |||
| 730af49171 | |||
| 229629b37f | |||
| dacdd27866 | |||
| 9b32883b74 | |||
| 0aed24c5b8 | |||
| c025ef9c9e | |||
| 771f2c33e7 | |||
| 60e758a837 | |||
| 98d842375a | |||
| 66aece3aad | |||
| ce9134ffcb | |||
| ed51ecd95c | |||
| 653701be10 | |||
| ae87019441 | |||
| 18c10f6497 | |||
| c8d891ec30 | |||
| a4b66fe1e5 | |||
| 10a3cefdb4 | |||
| 9ac4b75ce4 | |||
| 2c3e2d6df0 | |||
| 7e7769f869 | |||
| 76f393b322 | |||
| 6ed3371e79 | |||
| 2c46b5ab24 | |||
| d22976a2a4 | |||
| 7e6fc10a0d | |||
| bba2dae812 | |||
| fe6d33c3e7 | |||
| aaad830d24 | |||
| e5d0cd84c0 | |||
| 1dd5b4250a | |||
| 0095a981de | |||
| 9d59bd80f4 | |||
| be7a0ee928 | |||
| 1e0b07824d | |||
| 7872371921 | |||
| e563139d30 | |||
| 08cd6e1056 | |||
| 3f4cbe4ca7 | |||
| 1b42b0444e | |||
| ef7d888e48 | |||
| db3b532950 | |||
| 3119f60edc | |||
| d961f1fb9b | |||
| cc2d32adb9 | |||
| a0cb5011ed | |||
| ad23934a61 | |||
| e21494a333 | |||
| 937e6c5b3d | |||
| 24e5c2a83f | |||
| e0f09ec2b9 | |||
| bb06432948 | |||
| 183dbb7c44 | |||
| 4b7b1aee96 | |||
| f9f414e948 | |||
| 47ed62f6c5 | |||
| 2d7ce00caa | |||
| c9bdf9bab1 | |||
| a61d553d73 | |||
| 80c66a1e57 | |||
| 055b4721b5 | |||
| 403b970e78 | |||
| f4a65b2590 | |||
| 07a4882beb | |||
| a3e1303f04 | |||
| ea6f6eb79d | |||
| 16ba9aaaef | |||
| b75a37491e | |||
| c9666cc8e6 | |||
| 223e27ef57 | |||
| 4002f0121e | |||
| 0e35829580 | |||
| 124a600535 | |||
| 2b503c8da9 | |||
| 6091786696 | |||
| 65d936296d | |||
| f5cfbe00df | |||
| 28d33505fd | |||
| 56304d6b95 | |||
| d8cfb7cbe5 | |||
| f4825c7b9d | |||
| e6b6e89163 | |||
| da7dc4670c | |||
| 1875ce520a | |||
| c0d7ac9ec2 | |||
| 0d337c9ff2 | |||
| b7c1d72a61 | |||
| 844f48ccdb | |||
| 57f13bfe73 | |||
| f11d6ffbb1 | |||
| 798a92db91 | |||
| be5180a6e0 | |||
| 200ddce88f | |||
| 0ba363d5b5 | |||
| 5f065441ca | |||
| 55cc287ad5 | |||
| 0e2d2a576b | |||
| a62f3fab45 | |||
| 577673dcf7 | |||
| 58fd2dccdc | |||
| d10b6f54c7 | |||
| c5d0da9dce | |||
| 3f81b2ac33 | |||
| 24660f6a37 | |||
| 80155e8605 | |||
| 921ab02b3b | |||
| 5d9f93395c | |||
| fd1bfaa823 | |||
| ee8a3a25b8 | |||
| 6ef1d37453 | |||
| 41c845b4a7 | |||
| acfa5cb2db | |||
| 8c6227f186 | |||
| 7b92f214bb | |||
| 626340b2a6 | |||
| af975d5bef | |||
| 4ac5ea3ee8 | |||
| 20e1a2470b | |||
| 59a6fe72a0 | |||
| fed626d4cb | |||
| e9b3d2072b | |||
| c5db867ddc | |||
| f9511bf6e8 | |||
| 40d8821dde | |||
| 9e02af8c7c | |||
| dc29e21b14 | |||
| e05d6db2cd | |||
| 32caa8b669 | |||
| 6790d3ceb1 | |||
| fff8056e7f | |||
| 0dd6102c79 | |||
| 78e72db19c | |||
| e2be52671e | |||
| e717980d77 | |||
| e9ac16ad02 | |||
| b8562eaf01 | |||
| 9aeede60cb | |||
| b96e571897 | |||
| 45a5aa8e01 | |||
| 33f9dba686 | |||
| b9aa77d1d0 | |||
| 7f74e35ffc | |||
| 8e9ab02444 | |||
| e5de9a0722 | |||
| 7c5ede6552 | |||
| d14603fdb5 | |||
| 591068afc7 | |||
| 482b6119c2 | |||
| 1142a1026b | |||
| 3f548610dd | |||
| c83e861a3f |
+27
-24
@@ -24,20 +24,20 @@ version: 2.1
|
||||
# **NOTE 2 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
|
||||
# **NOTE 3 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
|
||||
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
|
||||
var_3: &cache_key v7-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
var_3: &cache_key v8-angular-node-16-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
# We invalidate the cache if the Bazel version changes because otherwise the `bazelisk` cache
|
||||
# folder will contain all previously used versions and ultimately cause the cache restoring to
|
||||
# be slower due to its growing size.
|
||||
var_4: &cache_key_fallback v7-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
var_4: &cache_key_fallback v8-angular-node-16-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Windows needs its own cache key because binaries in node_modules are different.
|
||||
var_3_win: &cache_key_win v9-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}
|
||||
var_4_win: &cache_key_win_fallback v9-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
var_3_win: &cache_key_win v10-angular-win-node-16-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}
|
||||
var_4_win: &cache_key_win_fallback v10-angular-win-node-16-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
||||
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
||||
var_5: &components_repo_unit_tests_cache_key v1-angular-components-{{ checksum "month.txt" }}-7a24e95bafbdeb697f74a48e275c2442bcbefc74
|
||||
var_6: &components_repo_unit_tests_cache_key_fallback v1-angular-components-{{ checksum "month.txt" }}
|
||||
var_5: &components_repo_unit_tests_cache_key v2-angular-components-{{ checksum "month.txt" }}-7a24e95bafbdeb697f74a48e275c2442bcbefc74
|
||||
var_6: &components_repo_unit_tests_cache_key_fallback v2-angular-components-{{ checksum "month.txt" }}
|
||||
|
||||
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages`.
|
||||
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
|
||||
@@ -77,6 +77,7 @@ var_11: &only_release_branches
|
||||
# https://circleci.com/developer/orbs.
|
||||
orbs:
|
||||
node: circleci/node@5.0.1
|
||||
devinfra: angular/dev-infra@1.0.8
|
||||
|
||||
# Executor Definitions
|
||||
# https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-executors
|
||||
@@ -91,7 +92,7 @@ executors:
|
||||
type: string
|
||||
default: medium
|
||||
docker:
|
||||
- image: cimg/node:16.10.0
|
||||
- image: cimg/node:16.13.0
|
||||
resource_class: << parameters.resource_class >>
|
||||
working_directory: ~/ng
|
||||
|
||||
@@ -101,7 +102,7 @@ executors:
|
||||
type: string
|
||||
default: medium
|
||||
docker:
|
||||
- image: cimg/node:16.10.0-browsers
|
||||
- image: cimg/node:16.13.0-browsers
|
||||
resource_class: << parameters.resource_class >>
|
||||
working_directory: ~/ng
|
||||
|
||||
@@ -144,6 +145,7 @@ commands:
|
||||
CIRCLE_GIT_BASE_REVISION: << pipeline.git.base_revision >>
|
||||
CIRCLE_GIT_REVISION: << pipeline.git.revision >>
|
||||
command: ./.circleci/env.sh
|
||||
- devinfra/setup-bazel-remote-exec
|
||||
- run:
|
||||
# Configure git as the CircleCI `checkout` command does.
|
||||
# This is needed because we only checkout on the setup job.
|
||||
@@ -151,7 +153,7 @@ commands:
|
||||
name: Configure git
|
||||
command: |
|
||||
mkdir -p ~/.ssh
|
||||
echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts
|
||||
echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=' >> ~/.ssh/known_hosts
|
||||
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
|
||||
git config --global gc.auto 0 || true
|
||||
|
||||
@@ -218,19 +220,9 @@ jobs:
|
||||
- checkout
|
||||
- save_month_to_file
|
||||
- init_environment
|
||||
- run:
|
||||
name: Rebase PR on target branch
|
||||
# After checkout, rebase on top of target branch.
|
||||
command: >
|
||||
if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then
|
||||
# User is required for rebase.
|
||||
git config user.name "angular-ci"
|
||||
git config user.email "angular-ci"
|
||||
# Rebase PR on top of target branch.
|
||||
node .circleci/rebase-pr.js
|
||||
else
|
||||
echo "This build is not over a PR, nothing to do."
|
||||
fi
|
||||
- devinfra/rebase-pr-on-target-branch:
|
||||
base_revision: << pipeline.git.base_revision >>
|
||||
head_revision: << pipeline.git.revision >>
|
||||
# This cache is saved in the build-npm-packages so that Bazel cache is also included.
|
||||
- restore_cache:
|
||||
keys:
|
||||
@@ -700,16 +692,27 @@ jobs:
|
||||
executor: windows-executor
|
||||
steps:
|
||||
- checkout
|
||||
- save_month_to_file
|
||||
- init_environment
|
||||
|
||||
# Setup the proper NodeJS version. The image comes pre-installed with `nvm-windows`.
|
||||
# Note: This happens immediately after checkout because environment initialization logic
|
||||
# might rely on Node and shouldn't use the older image-provided NodeJS version.
|
||||
- run:
|
||||
name: Install NodeJS version from `.nvmrc`.
|
||||
command: |
|
||||
nvm install $(cat .nvmrc)
|
||||
nvm use $(cat .nvmrc)
|
||||
- run:
|
||||
name: Debug information for flakiness of Windows job
|
||||
command: |
|
||||
node -v
|
||||
yarn -v
|
||||
which node
|
||||
which yarn
|
||||
echo "Path: $PATH"
|
||||
yarn node -v
|
||||
|
||||
- save_month_to_file
|
||||
- init_environment
|
||||
- restore_cache:
|
||||
keys:
|
||||
- *cache_key_win
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
####################################################################################################
|
||||
# Decrypt GCP Credentials and store them as the Google default credentials.
|
||||
####################################################################################################
|
||||
mkdir -p "$HOME/.config/gcloud";
|
||||
openssl aes-256-cbc -d -in "${PROJECT_ROOT}/.circleci/gcp_token" \
|
||||
-md md5 -k "$CIRCLE_PROJECT_REPONAME" -out "$HOME/.config/gcloud/application_default_credentials.json"
|
||||
|
||||
####################################################################################################
|
||||
# Set bazel configuration for CircleCI runs.
|
||||
####################################################################################################
|
||||
cp "${PROJECT_ROOT}/.circleci/bazel.linux.rc" "$HOME/.bazelrc";
|
||||
cp "${PROJECT_ROOT}/.circleci/bazel.linux.rc" ".bazelrc.user";
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
####################################################################################################
|
||||
# Decrypt GCP Credentials and store them as the Google default credentials.
|
||||
####################################################################################################
|
||||
mkdir -p "${APPDATA}/gcloud/";
|
||||
openssl aes-256-cbc -d -in "${PROJECT_ROOT}/.circleci/gcp_token" \
|
||||
-md md5 -k "$CIRCLE_PROJECT_REPONAME" -out "${APPDATA}/gcloud/application_default_credentials.json"
|
||||
|
||||
####################################################################################################
|
||||
# Set bazel configuration for CircleCI runs.
|
||||
####################################################################################################
|
||||
cp "${PROJECT_ROOT}/.circleci/bazel.windows.rc" "${USERPROFILE}/.bazelrc";
|
||||
cp "${PROJECT_ROOT}/.circleci/bazel.windows.rc" ".bazelrc.user";
|
||||
|
||||
|
||||
# Expose the Bazelisk version. We need to run Bazelisk globally since Windows has problems launching
|
||||
# Bazel from a node modules directoy that might be modified by the Bazel Yarn install then.
|
||||
setPublicVar BAZELISK_VERSION \
|
||||
"$(cd ${PROJECT_ROOT}; node -p 'require("./package.json").devDependencies["@bazel/bazelisk"]')"
|
||||
"$(cd ${PROJECT_ROOT}; node -p 'require("./package.json").devDependencies["@bazel/bazelisk"]')"
|
||||
|
||||
Binary file not shown.
@@ -1,208 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Rebases the current branch on top of the GitHub PR target branch.
|
||||
*
|
||||
* **Context:**
|
||||
* Since a GitHub PR is not necessarily up to date with its target branch, it is useful to rebase
|
||||
* prior to testing it on CI to ensure more up to date test results.
|
||||
*
|
||||
* **NOTE:**
|
||||
* This script cannot use external dependencies or be compiled because it needs to run before the
|
||||
* environment is setup.
|
||||
* Use only features supported by the NodeJS versions used in the environment.
|
||||
*/
|
||||
// tslint:disable:no-console
|
||||
const {execSync} = require('child_process');
|
||||
|
||||
|
||||
/** A regex to select a ref that matches our semver refs. */
|
||||
const semverRegex = /^(\d+)\.(\d+)\.x$/;
|
||||
|
||||
// Run
|
||||
_main().catch(err => {
|
||||
console.log('Failed to rebase on top of target branch.\n');
|
||||
console.error(err);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
|
||||
// Helpers
|
||||
async function _main() {
|
||||
const refs = await getRefsAndShasForChange();
|
||||
|
||||
// Log known refs and shas
|
||||
console.log(`--------------------------------`);
|
||||
console.log(` Target Branch: ${refs.base.ref}`);
|
||||
console.log(` Latest Commit for Target Branch: ${refs.target.latestSha}`);
|
||||
console.log(` Latest Commit for PR: ${refs.base.latestSha}`);
|
||||
console.log(` First Common Ancestor SHA: ${refs.commonAncestorSha}`);
|
||||
console.log(`--------------------------------`);
|
||||
console.log();
|
||||
|
||||
// Get the count of commits between the latest commit from origin and the common ancestor SHA.
|
||||
const commitCount =
|
||||
exec(`git rev-list --count origin/${refs.base.ref}...${refs.commonAncestorSha}`);
|
||||
console.log(`Checking ${commitCount} commits for changes in the CircleCI config file.`);
|
||||
|
||||
// Check if the files changed between the latest commit from origin and the common ancestor SHA
|
||||
// includes the CircleCI config.
|
||||
const circleCIConfigChanged = exec(`git diff --name-only origin/${refs.base.ref} ${
|
||||
refs.commonAncestorSha} -- .circleci/config.yml`);
|
||||
|
||||
if (!!circleCIConfigChanged) {
|
||||
throw Error(`
|
||||
CircleCI config on ${refs.base.ref} has been modified since commit
|
||||
${refs.commonAncestorSha.slice(0, 7)}, which this PR is based on.
|
||||
|
||||
Please rebase the PR on ${refs.base.ref} after fetching from upstream.
|
||||
|
||||
Rebase instructions for PR Author, please run the following commands:
|
||||
|
||||
git fetch upstream ${refs.base.ref};
|
||||
git checkout ${refs.target.ref};
|
||||
git rebase upstream/${refs.base.ref};
|
||||
git push --force-with-lease;
|
||||
`);
|
||||
} else {
|
||||
console.log('No change found in the CircleCI config file, continuing.');
|
||||
}
|
||||
console.log();
|
||||
|
||||
// Rebase the PR.
|
||||
exec(`git rebase origin/${refs.base.ref}`);
|
||||
console.log(`Rebased current branch onto ${refs.base.ref}.`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sort a list of fullpath refs into a list and then provide the first entry.
|
||||
*
|
||||
* The sort order will first find the the main branch, and then any semver ref, followed
|
||||
* by the rest of the refs in the order provided.
|
||||
*
|
||||
* Branches are sorted in this order as work is primarily done on main branches, and
|
||||
* otherwise on a semver branch. If neither of those were to match, the most
|
||||
* likely correct branch will be the first one encountered in the list.
|
||||
*/
|
||||
function getRefFromBranchList(gitOutput) {
|
||||
const branches = gitOutput.split('\n').map(b => b.split('/').slice(1).join('/').trim());
|
||||
return branches.sort((a, b) => {
|
||||
if (a === 'main') {
|
||||
return -1;
|
||||
}
|
||||
if (b === 'main') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const aIsSemver = semverRegex.test(a);
|
||||
const bIsSemver = semverRegex.test(b);
|
||||
if (aIsSemver && bIsSemver) {
|
||||
const [, aMajor, aMinor] = a.match(semverRegex);
|
||||
const [, bMajor, bMinor] = b.match(semverRegex);
|
||||
return parseInt(bMajor, 10) - parseInt(aMajor, 10) ||
|
||||
parseInt(aMinor, 10) - parseInt(bMinor, 10) || 0;
|
||||
}
|
||||
if (aIsSemver) {
|
||||
return -1;
|
||||
}
|
||||
if (bIsSemver) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
})[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full sha of the ref provided.
|
||||
*
|
||||
* example: 1bc0c1a6c01ede7168f22fa9b3508ba51f1f464e
|
||||
*/
|
||||
function getShaFromRef(ref) {
|
||||
return exec(`git rev-parse ${ref}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of branches which contain the provided sha, sorted in descending order
|
||||
* by committerdate.
|
||||
*
|
||||
* example:
|
||||
* upstream/main
|
||||
* upstream/9.0.x
|
||||
* upstream/test
|
||||
* upstream/1.1.x
|
||||
*/
|
||||
function getBranchListForSha(sha, remote) {
|
||||
return exec(`git branch -r '${remote}/*' --sort=-committerdate --contains ${sha}`);
|
||||
}
|
||||
|
||||
/** Get the common ancestor sha of the two provided shas. */
|
||||
function getCommonAncestorSha(sha1, sha2) {
|
||||
return exec(`git merge-base ${sha1} ${sha2}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the remote to git, if it doesn't already exist. Returns a boolean indicating
|
||||
* whether the remote was added by the command.
|
||||
*/
|
||||
function addAndFetchRemote(owner, name) {
|
||||
const remoteName = `${owner}_${name}`;
|
||||
exec(`git remote add ${remoteName} https://github.com/${owner}/${name}.git`, true);
|
||||
exec(`git fetch ${remoteName}`);
|
||||
return remoteName;
|
||||
}
|
||||
|
||||
|
||||
/** Get the ref and latest shas for the provided sha on a specific remote. */
|
||||
function getRefAndShas(sha, owner, name) {
|
||||
const remoteName = addAndFetchRemote(owner, name);
|
||||
|
||||
// Get the ref on the remote for the sha provided.
|
||||
const branches = getBranchListForSha(sha, remoteName);
|
||||
const ref = getRefFromBranchList(branches);
|
||||
|
||||
// Get the latest sha on the discovered remote ref.
|
||||
const latestSha = getShaFromRef(`${remoteName}/${ref}`);
|
||||
|
||||
return {remote: remoteName, ref, latestSha, sha};
|
||||
}
|
||||
|
||||
|
||||
/** Gets the refs and shas for the base and target of the current environment. */
|
||||
function getRefsAndShasForChange() {
|
||||
const base = getRefAndShas(
|
||||
process.env['CI_GIT_BASE_REVISION'], process.env['CI_REPO_OWNER'],
|
||||
process.env['CI_REPO_NAME']);
|
||||
const target = getRefAndShas(
|
||||
process.env['CI_GIT_REVISION'], process.env['CI_PR_USERNAME'], process.env['CI_PR_REPONAME']);
|
||||
const commonAncestorSha = getCommonAncestorSha(base.sha, target.sha);
|
||||
return {
|
||||
base,
|
||||
target,
|
||||
commonAncestorSha,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Synchronously executes the command.
|
||||
*
|
||||
* Return the trimmed stdout as a string, with an added attribute of the exit code.
|
||||
*/
|
||||
function exec(command, ignoreError = false) {
|
||||
try {
|
||||
return execSync(command, {stdio: 'pipe'}).toString().trim();
|
||||
} catch (err) {
|
||||
if (ignoreError) {
|
||||
return '';
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -5,38 +5,54 @@ body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
label: Describe the problem that you experienced
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: affected-url
|
||||
attributes:
|
||||
label: What is the affected URL?
|
||||
label: Enter the URL of the topic with the problem
|
||||
|
||||
- type: textarea
|
||||
id: documentation-goal
|
||||
attributes:
|
||||
label: Describe what you were looking for in the documentation
|
||||
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Please provide the steps to reproduce the issue
|
||||
label: Describe the actions that led you to experience the problem
|
||||
|
||||
- type: textarea
|
||||
id: expected-vs-actual-behavior
|
||||
attributes:
|
||||
label: Please provide the expected behavior vs the actual behavior you encountered
|
||||
label: Describe what you want to experience that would fix the problem
|
||||
|
||||
- type: textarea
|
||||
id: screenshot
|
||||
attributes:
|
||||
label: Please provide a screenshot if possible
|
||||
label: Add a screenshot if that helps illustrate the problem
|
||||
|
||||
- type: textarea
|
||||
id: exception-or-error
|
||||
attributes:
|
||||
label: Please provide the exception or error you saw
|
||||
label: If this problem caused an exception or error, please paste it here
|
||||
render: true
|
||||
placeholder: |
|
||||
```
|
||||
Paste the exception or error here inside a markdown code block,
|
||||
which is annotated by three grave \(`\) characters before and after the text block.
|
||||
```
|
||||
|
||||
- type: textarea
|
||||
id: browser-info
|
||||
attributes:
|
||||
label: Is this a browser-specific issue? If so, please specify the device, browser, and version.
|
||||
label: If the problem is browser-specific, please specify the device, OS, browser, and version
|
||||
render: true
|
||||
|
||||
- type: textarea
|
||||
id: additional-info
|
||||
attributes:
|
||||
label: Provide any additional information here in as much as detail as you can
|
||||
render: true
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
name: 'Angular DevTools'
|
||||
description: Report an issue or suggest a feature for Angular DevTools
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: bug-report-or-feature-request
|
||||
attributes:
|
||||
label: Is this a bug report or a feature request?
|
||||
description: Select one.
|
||||
options:
|
||||
- label: Bug Report
|
||||
- label: Feature Request
|
||||
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Please provide the steps to reproduce the issue [Bug Report only]
|
||||
|
||||
- type: textarea
|
||||
id: expected-vs-actual-behavior
|
||||
attributes:
|
||||
label: Please provide the expected behavior vs the actual behavior you encountered [Bug Report only]
|
||||
|
||||
- type: textarea
|
||||
id: screenshot
|
||||
attributes:
|
||||
label: Please provide a screenshot if possible [Bug Report only]
|
||||
|
||||
- type: textarea
|
||||
id: exception-or-error
|
||||
attributes:
|
||||
label: Please provide the exception or error you saw [Bug Report only]
|
||||
render: true
|
||||
|
||||
- type: textarea
|
||||
id: browser-info
|
||||
attributes:
|
||||
label: Is this a browser-specific issue? If so, please specify the device, browser, and version. [Bug Report only]
|
||||
render: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description [Feature Request only]
|
||||
|
||||
- type: textarea
|
||||
id: proposed-solution
|
||||
attributes:
|
||||
label: Proposed solution [Feature Request only]
|
||||
|
||||
- type: textarea
|
||||
id: alternatives-considered
|
||||
attributes:
|
||||
label: Alternatives considered [Feature Request only]
|
||||
+13
-13
@@ -143,29 +143,29 @@ triage:
|
||||
defaultMilestone: 82,
|
||||
# arrays of labels that determine if an issue has been triaged by the caretaker
|
||||
l1TriageLabels:
|
||||
- - 'comp: *'
|
||||
- - 'area: *'
|
||||
# arrays of labels that determine if an issue has been fully triaged
|
||||
l2TriageLabels:
|
||||
- - 'P0'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
- - 'P1'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
- - 'P2'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
- - 'P3'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
- - 'P4'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
- - 'P5'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
- - 'feature'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
- - 'discussion'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
- - 'needs clarification'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
- - 'needs reproduction'
|
||||
- 'comp: *'
|
||||
- 'area: *'
|
||||
|
||||
# options for the triage PR plugin
|
||||
triagePR:
|
||||
@@ -177,10 +177,10 @@ triagePR:
|
||||
defaultMilestone: 82,
|
||||
# arrays of labels that determine if a PR has been triaged by the caretaker
|
||||
l1TriageLabels:
|
||||
- - 'comp: *'
|
||||
- - 'area: *'
|
||||
# arrays of labels that determine if a PR has been fully triaged
|
||||
l2TriageLabels:
|
||||
- - 'comp: *'
|
||||
- - 'area: *'
|
||||
|
||||
# options for rerunning CI
|
||||
rerunCircleCI:
|
||||
|
||||
@@ -18,17 +18,19 @@ jobs:
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Needed to publish results
|
||||
id-token: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: 'Checkout code'
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
|
||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: 'Run analysis'
|
||||
uses: ossf/scorecard-action@ce330fde6b1a5c9c75b417e7efc510b822a35564 # tag=v1.1.2
|
||||
uses: ossf/scorecard-action@e363bfca00e752f91de7b7d2a77340e2e523cb18 # tag=v2.0.4
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -45,6 +47,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: 'Upload to code-scanning'
|
||||
uses: github/codeql-action/upload-sarif@2ca79b6fa8d3ec278944088b4aa5f46912db5d63 # tag=v2.1.18
|
||||
uses: github/codeql-action/upload-sarif@807578363a7869ca324a79039e6db9c843e0e100 # tag=v2.1.27
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# Update the `events.json` file that powers the [AIO events page](https://angular.io/events) (if
|
||||
# necessary) and create a pull request.
|
||||
#
|
||||
# For more details on the overall process, see
|
||||
# [aio/scripts/generate-events/README.md](../../aio/scripts/generate-events/README.md).
|
||||
|
||||
name: Update AIO events
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
schedule:
|
||||
# Run every day at 15:00.
|
||||
- cron: '0 15 * * *'
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update_events:
|
||||
name: Update `events.json` (if necessary)
|
||||
if: github.repository == 'angular/angular'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
|
||||
with:
|
||||
# Setting `persist-credentials: false` prevents the github-action account from being the
|
||||
# account that is attempted to be used for authentication, instead the remote is set to
|
||||
# an authenticated URL.
|
||||
persist-credentials: false
|
||||
- name: Install AIO dependencies
|
||||
run: yarn --cwd=aio install
|
||||
- name: Generate `events.json`
|
||||
run: node aio/scripts/generate-events/index.mjs --ignore-invalid-dates
|
||||
- name: Create a PR (if necessary)
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@3c526cbb36b8517829dbbf02a7833fa3081479bb
|
||||
with:
|
||||
branch-prefix: docs-update-events
|
||||
pr-title: 'docs: update events'
|
||||
pr-description: |
|
||||
Generated `events.json` with the latest events retrieved from the Firebase DB.
|
||||
pr-labels: |
|
||||
action: review
|
||||
area: docs
|
||||
target: patch
|
||||
angular-robot-token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }}
|
||||
@@ -7,8 +7,8 @@ import {PullRequestConfig} from '@angular/ng-dev';
|
||||
export const pullRequest: PullRequestConfig = {
|
||||
githubApiMerge: false,
|
||||
mergeReadyLabel: 'action: merge',
|
||||
caretakerNoteLabel: 'action: merge-assistance',
|
||||
commitMessageFixupLabel: 'commit message fixup',
|
||||
caretakerNoteLabel: 'action: caretaker note',
|
||||
commitMessageFixupLabel: 'merge: fix commit message',
|
||||
requiredBaseCommits: {
|
||||
// PRs that target either `main` or the patch branch, need to be rebased
|
||||
// on top of the latest commit message validation fix.
|
||||
|
||||
+1
-1
@@ -31,5 +31,5 @@ export const release: ReleaseConfig = {
|
||||
releaseNotes: {
|
||||
hiddenScopes: ['aio', 'bazel', 'dev-infra', 'docs-infra', 'zone.js', 'devtools'],
|
||||
},
|
||||
releasePrLabels: ['comp: build & ci', 'action: merge', 'PullApprove: disable'],
|
||||
releasePrLabels: ['area: build & ci', 'action: merge', 'PullApprove: disable'],
|
||||
};
|
||||
|
||||
+52
-14
@@ -54,7 +54,6 @@
|
||||
# =========================================================
|
||||
# Used for approving minor documentation-only changes that don't require engineering review.
|
||||
#
|
||||
# gkalpak
|
||||
# josmar-crwdstffng
|
||||
# ileil
|
||||
# TeriGlover
|
||||
@@ -62,9 +61,8 @@
|
||||
|
||||
version: 3
|
||||
|
||||
availability:
|
||||
users_unavailable:
|
||||
- atscott # August 15 - September 20 (at least)
|
||||
# availability:
|
||||
# users_unavailable:
|
||||
|
||||
# Meta field that goes unused by PullApprove to allow for defining aliases to be
|
||||
# used throughout the config.
|
||||
@@ -177,7 +175,6 @@ groups:
|
||||
reviewers:
|
||||
users:
|
||||
- alxhub
|
||||
- gkalpak
|
||||
- JoostK
|
||||
|
||||
# =========================================================
|
||||
@@ -229,6 +226,27 @@ groups:
|
||||
'aio/content/images/guide/change-detection/**/{*,.*}',
|
||||
'aio/content/guide/class-binding.md',
|
||||
'aio/content/guide/cheatsheet.md',
|
||||
'aio/content/guide/component/component-content-projection-complex.md',
|
||||
'aio/content/guide/component/component-content-projection-conditional.md',
|
||||
'aio/content/guide/component/component-content-projection-multi-slot.md',
|
||||
'aio/content/guide/component/component-content-projection-overview.md',
|
||||
'aio/content/guide/component/component-content-projection-single-slot.md',
|
||||
'aio/content/guide/component/component-create-cli.md',
|
||||
'aio/content/guide/component/component-create-manual.md',
|
||||
'aio/content/guide/component/component-example-dynamic-load.md',
|
||||
'aio/content/guide/component/component-example-interaction.md',
|
||||
'aio/content/guide/component/component-example.md',
|
||||
'aio/content/guide/component/component-exchange-data.md',
|
||||
'aio/content/guide/component/component-lifecycle-overview.md',
|
||||
'aio/content/guide/component/component-overview.md',
|
||||
'aio/content/guide/component/component-share-data-overview.md',
|
||||
'aio/content/guide/component/component-share-data-to-child.md',
|
||||
'aio/content/guide/component/component-share-data-to-parent.md',
|
||||
'aio/content/guide/component/component-structure.md',
|
||||
'aio/content/guide/component/component-style-overview.md',
|
||||
'aio/content/guide/component/component-style-view-encapsulate.md',
|
||||
'aio/content/guide/component/component-style.md',
|
||||
'aio/content/guide/component/component-use-overview.md',
|
||||
'aio/content/guide/component-interaction.md',
|
||||
'aio/content/examples/component-interaction/**/{*,.*}',
|
||||
'aio/content/images/guide/component-interaction/**/{*,.*}',
|
||||
@@ -266,11 +284,15 @@ groups:
|
||||
'aio/content/images/guide/frequent-ngmodules/**/{*,.*}',
|
||||
'aio/content/guide/hierarchical-dependency-injection.md',
|
||||
'aio/content/examples/hierarchical-dependency-injection/**/{*,.*}',
|
||||
'aio/content/guide/image-directive.md',
|
||||
'aio/content/guide/image-directive-setup.md',
|
||||
'aio/content/examples/providers-viewproviders/**/{*,.*}',
|
||||
'aio/content/examples/resolution-modifiers/**/{*,.*}',
|
||||
'aio/content/guide/lazy-loading-ngmodules.md',
|
||||
'aio/content/examples/lazy-loading-ngmodules/**/{*,.*}',
|
||||
'aio/content/images/guide/lazy-loading-ngmodules/**/{*,.*}',
|
||||
'aio/content/guide/lifecycle-hook/lifecycle-hook-example.md',
|
||||
'aio/content/guide/lifecycle-hook/lifecycle-hook-overview.md',
|
||||
'aio/content/guide/lifecycle-hooks.md',
|
||||
'aio/content/examples/lifecycle-hooks/**/{*,.*}',
|
||||
'aio/content/images/guide/lifecycle-hooks/**/{*,.*}',
|
||||
@@ -413,7 +435,6 @@ groups:
|
||||
- andrewseguin
|
||||
- atscott
|
||||
- dylhunn
|
||||
- gkalpak
|
||||
- jessicajaniuk
|
||||
- pkozlowski-opensource
|
||||
|
||||
@@ -564,7 +585,6 @@ groups:
|
||||
reviewers:
|
||||
users:
|
||||
- alxhub
|
||||
- gkalpak
|
||||
|
||||
# =========================================================
|
||||
# Framework: Upgrade
|
||||
@@ -592,7 +612,6 @@ groups:
|
||||
reviewers:
|
||||
users:
|
||||
- alxhub
|
||||
- gkalpak
|
||||
- jessicajaniuk
|
||||
|
||||
# =========================================================
|
||||
@@ -1063,11 +1082,32 @@ groups:
|
||||
'aio/content/guide/reviewing-content.md',
|
||||
'aio/content/guide/updating-content-github-ui.md',
|
||||
'aio/content/guide/updating-search-keywords.md',
|
||||
'aio/content/guide/doc-build-test.md',
|
||||
'aio/content/guide/doc-edit-finish.md',
|
||||
'aio/content/guide/doc-editing.md',
|
||||
'aio/content/guide/doc-github-tasks.md',
|
||||
'aio/content/guide/doc-pr-open.md',
|
||||
'aio/content/guide/doc-pr-prep.md',
|
||||
'aio/content/guide/doc-pr-update.md',
|
||||
'aio/content/guide/doc-prepare-to-edit.md',
|
||||
'aio/content/guide/doc-select-issue.md',
|
||||
'aio/content/guide/doc-tasks.md',
|
||||
'aio/content/guide/doc-update-overview.md',
|
||||
'aio/content/guide/doc-update-start.md',
|
||||
'aio/content/guide/docs-lint-errors.md',
|
||||
'aio/content/images/guide/preparing-to-edit-docs/**/{*,.*}',
|
||||
'aio/content/images/guide/github-for-docs/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-update-start/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-update-overview/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-pr-update/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-pr-prep/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-pr-open/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-github-tasks/**/{*,.*}',
|
||||
'aio/content/images/guide/doc-prepare-to-edit/**/{*,.*}',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- AndrewKushnir
|
||||
- gkalpak
|
||||
- jessicajaniuk
|
||||
- josephperrott
|
||||
|
||||
@@ -1083,7 +1123,7 @@ groups:
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- aleksanderbodurri
|
||||
- AleksanderBodurri
|
||||
- devversion
|
||||
- josephperrott
|
||||
- mgechev
|
||||
@@ -1096,7 +1136,7 @@ groups:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
contains_any_globs(files.exclude('.pullapprove.yml'), [
|
||||
'{*,.*}',
|
||||
'.circleci/**/{*,.*}',
|
||||
'.devcontainer/**/{*,.*}',
|
||||
@@ -1134,7 +1174,6 @@ groups:
|
||||
reviewers:
|
||||
users:
|
||||
- devversion
|
||||
- gkalpak
|
||||
- josephperrott
|
||||
|
||||
# =========================================================
|
||||
@@ -1321,7 +1360,7 @@ groups:
|
||||
reviewers:
|
||||
users:
|
||||
- alan-agius4 # Alan Agius
|
||||
- aleksanderbodurri # Aleksander Bodurri
|
||||
- AleksanderBodurri # Aleksander Bodurri
|
||||
- alxhub # Alex Rickabaugh
|
||||
- AndrewKushnir # Andrew Kushnir
|
||||
- andrewseguin # Andrew Seguin
|
||||
@@ -1332,7 +1371,6 @@ groups:
|
||||
- dgp1130 # Doug Parker
|
||||
- dylhunn # Dylan Hunn
|
||||
- filipesilva # Filipe Silva
|
||||
- gkalpak # Georgios Kalpakas
|
||||
- jelbourn # Jeremy Elbourn
|
||||
- jessicajaniuk # Jessica Janiuk
|
||||
- JiaLiPassion # Jia Li
|
||||
|
||||
Vendored
+9
-21
@@ -16,7 +16,7 @@
|
||||
"remoteRoot": "${workspaceRoot}",
|
||||
"stopOnEntry": false,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
},
|
||||
{
|
||||
"name": "Attach to bazel test ... --config=debug (no source maps)",
|
||||
@@ -30,58 +30,46 @@
|
||||
"remoteRoot": "${workspaceRoot}",
|
||||
"stopOnEntry": false,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
},
|
||||
{
|
||||
"name": "IVY:packages/core/test/acceptance",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
|
||||
"args": [
|
||||
"test",
|
||||
"packages/core/test/acceptance",
|
||||
"--config=debug"
|
||||
],
|
||||
"args": ["test", "packages/core/test/acceptance", "--config=debug"],
|
||||
"port": 9229,
|
||||
"address": "localhost",
|
||||
"restart": true,
|
||||
"sourceMaps": true,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
},
|
||||
{
|
||||
"name": "IVY:packages/core/test/render3",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
|
||||
"args": [
|
||||
"test",
|
||||
"packages/core/test/render3",
|
||||
"--config=debug"
|
||||
],
|
||||
"args": ["test", "packages/core/test/render3", "--config=debug"],
|
||||
"port": 9229,
|
||||
"address": "localhost",
|
||||
"restart": true,
|
||||
"sourceMaps": true,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
},
|
||||
{
|
||||
"name": "IVY:packages/core/test",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
|
||||
"args": [
|
||||
"test",
|
||||
"packages/core/test",
|
||||
"--config=debug"
|
||||
],
|
||||
"args": ["test", "packages/core/test", "--config=debug"],
|
||||
"port": 9229,
|
||||
"address": "localhost",
|
||||
"restart": true,
|
||||
"sourceMaps": true,
|
||||
"timeout": 600000,
|
||||
"outFiles": ["${workspaceFolder}/bazel-out/**/angular/**/*.js"],
|
||||
},
|
||||
"outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+245
-85
@@ -1,3 +1,232 @@
|
||||
<a name="14.3.0"></a>
|
||||
# 14.3.0 (2023-03-13)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [37bbc61cfe](https://github.com/angular/angular/commit/37bbc61cfeca1531a80393636c096ce452a67d27) | feat | Backport NgOptimizedImage to Angular 14. |
|
||||
## Special Thanks
|
||||
Alex Castle, Joey Perrott and Paul Gschwendtner
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.12"></a>
|
||||
# 14.2.12 (2022-11-21)
|
||||
## Breaking Changes
|
||||
### core
|
||||
- Existing iframe usages may have security-sensitive attributes applied as an attribute or property binding in a template or via host bindings in a directive. Such usages would require an update to ensure compliance with the new stricter rules around iframe bindings.
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [54814c8e9b](https://github.com/angular/angular/commit/54814c8e9ba6b82a7f4748ef2b2f47507efd758b) | fix | hardening attribute and property binding rules for iframe elements ([#48028](https://github.com/angular/angular/pull/48028)) |
|
||||
## Special Thanks
|
||||
Andrew Kushnir
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.11"></a>
|
||||
# 14.2.11 (2022-11-16)
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [aef353c143](https://github.com/angular/angular/commit/aef353c143ea4e31d76f00ae91efe49eecc3a321) | fix | Ensure renavigating in component init works with enabledBlocking ([#48066](https://github.com/angular/angular/pull/48066)) |
|
||||
## Special Thanks
|
||||
Alan Agius, Andrew Scott and Mujo Osmanovic
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.10"></a>
|
||||
# 14.2.10 (2022-11-09)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a4312e1be5](https://github.com/angular/angular/commit/a4312e1be55f0677a77c9015688dbd4cf8163c69) | fix | add` zone.js` version `0.12.x` as a valid peer dependency ([#48002](https://github.com/angular/angular/pull/48002)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [db867fee77](https://github.com/angular/angular/commit/db867fee77bc62f367fc5d484fc3951d72d998c8) | fix | fix redirectTo on named outlets - resolves [#33783](https://github.com/angular/angular/pull/33783) ([#47927](https://github.com/angular/angular/pull/47927)) |
|
||||
## Special Thanks
|
||||
Alan Agius, Albert Szekely, Andrew Scott, Doug Parker, Kristiyan Kostadinov, Markus Eckstein, Peter Scriven and abergquist
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.9"></a>
|
||||
# 14.2.9 (2022-11-03)
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [92d28bdd99](https://github.com/angular/angular/commit/92d28bdd99d3e18f42f6ed8494344b72b15d0104) | perf | resolve memory leak when using animations with shadow DOM ([#47903](https://github.com/angular/angular/pull/47903)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d2d9bbf5ce](https://github.com/angular/angular/commit/d2d9bbf5ce5a2f5e95e7c836fbca67d90db62371) | fix | call `onSerialize` when state is empty ([#47888](https://github.com/angular/angular/pull/47888)) |
|
||||
## Special Thanks
|
||||
Alan Agius, Kristiyan Kostadinov, Virginia Dooley and mgechev
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.8"></a>
|
||||
# 14.2.8 (2022-10-26)
|
||||
## Special Thanks
|
||||
Andrew Scott, Balaji, Paul Gschwendtner, WD Snoeijer, onrails and vyom1611
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.7"></a>
|
||||
# 14.2.7 (2022-10-19)
|
||||
|
||||
This release contains API docs improvements.
|
||||
|
||||
## Special Thanks
|
||||
Bob Watson, Charles Barnes, Joey Perrott, Virginia Dooley, WD Snoeijer, abergquist and urugator
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.6"></a>
|
||||
# 14.2.6 (2022-10-12)
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [3fd176a905](https://github.com/angular/angular/commit/3fd176a9054bea6f6c4cd22e8ff3b8f63b86b637) | fix | add missing period to error message ([#47744](https://github.com/angular/angular/pull/47744)) |
|
||||
| [c3821f5ab5](https://github.com/angular/angular/commit/c3821f5ab5bf54b2c9d7868da79a742d4e4b7667) | perf | minimize filesystem calls when generating shims ([#47682](https://github.com/angular/angular/pull/47682)) |
|
||||
## Special Thanks
|
||||
Alan Agius, Andrew Kushnir, Andrew Scott, Aristeidis Bampakos, Bob Watson, Charles Lyding, Joey Perrott, Joshua Morony, Mathew Berg, Paul Gschwendtner, Peter Dickten, Renan Ferro, Sri Ram, WD Snoeijer, markostanimirovic and Álvaro Martínez
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.5"></a>
|
||||
# 14.2.5 (2022-10-05)
|
||||
|
||||
This release contains various API docs improvements.
|
||||
|
||||
## Special Thanks
|
||||
Alexander Wiebe, Ciprian Sauliuc, Dmytro Mezhenskyi, George Kalpakas, Joe Martin (Crowdstaffing), Jordan, Ole M, Paul Gschwendtner, Pawel Kozlowski and mgechev
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.4"></a>
|
||||
# 14.2.4 (2022-09-28)
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a4b66fe1e5](https://github.com/angular/angular/commit/a4b66fe1e5acaf148069933720499652f21a7bce) | perf | cache source file for reporting type-checking diagnostics ([#47508](https://github.com/angular/angular/pull/47508)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2c46b5ab24](https://github.com/angular/angular/commit/2c46b5ab24e209381bca70d875bf0e98a2846ef5) | fix | correctly check for `typeof` of undefined in `ngDevMode` check ([#47480](https://github.com/angular/angular/pull/47480)) |
|
||||
## Special Thanks
|
||||
Alan Agius, Ashley Hunter, Doug Parker, Jessica Janiuk, JoostK, Kristiyan Kostadinov, Rokas Brazdžionis and Simona Cotin
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.3"></a>
|
||||
# 14.2.3 (2022-09-21)
|
||||
### animations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [bba2dae812](https://github.com/angular/angular/commit/bba2dae81263d07c55cd059eb8ef51baa7774055) | fix | make sure that the useAnimation function delay is applied ([#47468](https://github.com/angular/angular/pull/47468)) |
|
||||
## Special Thanks
|
||||
AleksanderBodurri, Andrew Kushnir, Andrew Scott, Bob Watson, George Kalpakas, Joey Perrott, Mauro Mattos, dario-piotrowicz, fabioemoutinho and famzila
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.2"></a>
|
||||
# 14.2.2 (2022-09-14)
|
||||
### animations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [937e6c5b3d](https://github.com/angular/angular/commit/937e6c5b3d4c4bfc6ba202ee6692bc2fd8a35b89) | fix | make sure that the animation function delay is applied ([#47285](https://github.com/angular/angular/pull/47285)) |
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c9bdf9bab1](https://github.com/angular/angular/commit/c9bdf9bab1bc4cc4da207f6bfc8ebc75eb605486) | fix | rename `rawSrc` -> `ngSrc` in NgOptimizedImage directive ([#47362](https://github.com/angular/angular/pull/47362)) ([#47396](https://github.com/angular/angular/pull/47396)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [a3e1303f04](https://github.com/angular/angular/commit/a3e1303f04d4afe456f3728939b3aa54e29f9fb3) | fix | imply @Optional flag when a default value is provided ([#47242](https://github.com/angular/angular/pull/47242)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [80c66a1e57](https://github.com/angular/angular/commit/80c66a1e57af33342ed851a0de886fc17b53f7a3) | fix | don't prevent default behavior for forms with method="dialog" ([#47308](https://github.com/angular/angular/pull/47308)) |
|
||||
## Special Thanks
|
||||
Abhishek Rawat, Andrew Kushnir, Benjamin Chanudet, Bob Watson, George Kalpakas, Ikko Ashimine, Kristiyan Kostadinov, Marc Wrobel, Mariia Subkov, Pawel Kozlowski, Sebastian, abergquist, dario-piotrowicz, onrails and vyom1611
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.1"></a>
|
||||
# 14.2.1 (2022-09-07)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c0d7ac9ec2](https://github.com/angular/angular/commit/c0d7ac9ec2df9af36d80382bc70c4580720f35a3) | fix | improve formatting of image warnings ([#47299](https://github.com/angular/angular/pull/47299)) |
|
||||
| [1875ce520a](https://github.com/angular/angular/commit/1875ce520afe7b5c55680b8c6a938a2331dda599) | fix | use DOCUMENT token to query for preconnect links ([#47353](https://github.com/angular/angular/pull/47353)) |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0e35829580](https://github.com/angular/angular/commit/0e3582958079f798a75240873aebf3c4f5e3df5b) | fix | avoid errors for inputs with Object-builtin names ([#47220](https://github.com/angular/angular/pull/47220)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [6091786696](https://github.com/angular/angular/commit/60917866961b7ab80ec9637c72300f2707aadd09) | fix | include headers in requests for assets ([#47260](https://github.com/angular/angular/pull/47260)) |
|
||||
| [28d33505fd](https://github.com/angular/angular/commit/28d33505fd4be00eaf4bf417cd27e20733ddfb80) | fix | only consider GET requests as navigation requests ([#47263](https://github.com/angular/angular/pull/47263)) |
|
||||
## Special Thanks
|
||||
Aristeidis Bampakos, Asaf M, Bingo's Code, Bob Watson, Daniel Ostrovsky, George Kalpakas, Giovanni Alberto Rivas, Jeremy Elbourn, Jobayer Hossain, Joe Martin (Crowdstaffing), Joey Perrott, JoostK, Kara Erickson, Kristiyan Kostadinov, Maina Wycliffe, Sabareesh Kappagantu, Simona Cotin, Sonu Sindhu, Yann Provoost, abergquist, jaybell and vyom1611
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.0"></a>
|
||||
# 14.2.0 (2022-08-25)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d5f7da2120](https://github.com/angular/angular/commit/d5f7da21207f7808dffb3932fa61d22614e6bd57) | feat | introduce the NgOptimizedImage directive ([#47082](https://github.com/angular/angular/pull/47082)) |
|
||||
| [e2ab99b95e](https://github.com/angular/angular/commit/e2ab99b95efd893c49d15c02cccd72ef82ea1cae) | fix | allow null/undefined to be passed to ngClass input ([#39280](https://github.com/angular/angular/pull/39280)) ([#46906](https://github.com/angular/angular/pull/46906)) |
|
||||
| [bedf537951](https://github.com/angular/angular/commit/bedf537951e64c55dde9b38936e451daa4a4bde9) | fix | allow null/undefined to be passed to ngStyle input ([#47069](https://github.com/angular/angular/pull/47069)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d1e83e1b30](https://github.com/angular/angular/commit/d1e83e1b30f2cea9f2ed16bff2d3b969335072ab) | feat | add `createComponent` function ([#46685](https://github.com/angular/angular/pull/46685)) |
|
||||
| [10becab70e](https://github.com/angular/angular/commit/10becab70e0f2afee29da7b3358eedcc22f655a2) | feat | add `reflectComponentType` function ([#46685](https://github.com/angular/angular/pull/46685)) |
|
||||
| [4b377d3a6d](https://github.com/angular/angular/commit/4b377d3a6d069da23ec577f8deca761b01d4e2f5) | feat | introduce createApplication API ([#46475](https://github.com/angular/angular/pull/46475)) |
|
||||
| [31429eaccc](https://github.com/angular/angular/commit/31429eaccc973672efb4ed98a628cf9842e24b02) | feat | support TypeScript 4.8 ([#47038](https://github.com/angular/angular/pull/47038)) |
|
||||
| [796840209c](https://github.com/angular/angular/commit/796840209cd38aacc5061a31701efe7eda1f6587) | fix | align TestBed interfaces and implementation ([#46635](https://github.com/angular/angular/pull/46635)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [426af91a42](https://github.com/angular/angular/commit/426af91a42104d6ce227ab52c8c4db3e218f5e03) | feat | add `FormBuilder.record()` method ([#46485](https://github.com/angular/angular/pull/46485)) |
|
||||
| [b302797de4](https://github.com/angular/angular/commit/b302797de47409b988ad77e87f766a5f18374ded) | fix | Correctly infer `FormBuilder` types involving `[value, validators]` shorthand in more cases. ([#47034](https://github.com/angular/angular/pull/47034)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [598b72bd05](https://github.com/angular/angular/commit/598b72bd05ea33468c70ac35b8ea5286439f41d9) | feat | support fix the component missing member ([#46764](https://github.com/angular/angular/pull/46764)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [07606e3181](https://github.com/angular/angular/commit/07606e3181fc7aa9f9185eb771fc9c44f01fe344) | feat | add `isEmpty` method to the `TransferState` class ([#46915](https://github.com/angular/angular/pull/46915)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2b4d7f6733](https://github.com/angular/angular/commit/2b4d7f6733e10e45e3ca8a448307bbc2834fc4a1) | feat | support document reference in render functions ([#47032](https://github.com/angular/angular/pull/47032)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0abb67af59](https://github.com/angular/angular/commit/0abb67af59a92a2b29082a259aa9f4ea3fbaab7d) | feat | allow guards and resolvers to be plain functions ([#46684](https://github.com/angular/angular/pull/46684)) |
|
||||
| [75df404467](https://github.com/angular/angular/commit/75df4044675c61d2b646437cfe64fe828a39b3a0) | feat | Create APIs for using Router without RouterModule ([#47010](https://github.com/angular/angular/pull/47010)) |
|
||||
| [10289f1f6e](https://github.com/angular/angular/commit/10289f1f6e3d5935304a38d4300d4dadfea66150) | feat | expose resolved route title ([#46826](https://github.com/angular/angular/pull/46826)) |
|
||||
| [8600732b09](https://github.com/angular/angular/commit/8600732b090a4c253eb89ffde6db3858e4a2021c) | feat | Expose the default matcher for `Routes` used by the `Router` ([#46913](https://github.com/angular/angular/pull/46913)) |
|
||||
| [422323cee0](https://github.com/angular/angular/commit/422323cee00192239d1ab279e6a7c3a808098169) | feat | improve typings for RouterLink boolean inputs ([#47101](https://github.com/angular/angular/pull/47101)) |
|
||||
| [26ea97688c](https://github.com/angular/angular/commit/26ea97688cba5850588d8da83abaf8b539577241) | feat | Make router directives standalone ([#46758](https://github.com/angular/angular/pull/46758)) |
|
||||
| [2a43beec15](https://github.com/angular/angular/commit/2a43beec159990b8c4bafc7f189e2bd85002dc7a) | fix | Fix route recognition behavior with some versions of rxjs ([#47098](https://github.com/angular/angular/pull/47098)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [383090858c](https://github.com/angular/angular/commit/383090858caf04c27ee8b320cceca2da0ae54bb3) | feat | support `sendRequest` as a `notificationclick` action ([#46912](https://github.com/angular/angular/pull/46912)) |
|
||||
| [3f548610dd](https://github.com/angular/angular/commit/3f548610dd05f484cd33fa2cee4e3693ed731126) | fix | export NoNewVersionDetectedEvent ([#47044](https://github.com/angular/angular/pull/47044)) |
|
||||
| [482b6119c2](https://github.com/angular/angular/commit/482b6119c2f3fff5ec0623e101d308a49c416b42) | fix | update golden `index.md` ([#47044](https://github.com/angular/angular/pull/47044)) |
|
||||
## Special Thanks
|
||||
Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Bob Watson, Cédric Exbrayat, Dylan Hunn, Emmanuel Roux, FatalMerlin, George Kalpakas, Ilia Mirkin, Jan Kuehle, Jeremy Elbourn, Jessica Janiuk, JiaLiPassion, Kalbarczyk, Kara Erickson, Katie Hempenius, Kristiyan Kostadinov, Merlin, Paul Gschwendtner, Pawel Kozlowski, Tristan Sprößer, Victor Porof, angular-robot[bot], dario-piotrowicz, ivanwonder and vyom
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.1.3"></a>
|
||||
# 14.1.3 (2022-08-17)
|
||||
### compiler
|
||||
@@ -24,74 +253,6 @@ AlirezaEbrahimkhani, Alma Eyre, Andrew Scott, Bob Watson, George Kalpakas, Kalba
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.0-next.1"></a>
|
||||
# 14.2.0-next.1 (2022-08-10)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [bedf537951](https://github.com/angular/angular/commit/bedf537951e64c55dde9b38936e451daa4a4bde9) | fix | allow null/undefined to be passed to ngStyle input ([#47069](https://github.com/angular/angular/pull/47069)) |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ea89677c12](https://github.com/angular/angular/commit/ea89677c125c16654e3e521998b575687c2bd20c) | feat | support more recent version of `tsickle` ([#47018](https://github.com/angular/angular/pull/47018)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [dbed2cf079](https://github.com/angular/angular/commit/dbed2cf079c52825ce0aa67fc2a46bc3d38f408f) | fix | check if transplanted views are attached to change detector ([#46974](https://github.com/angular/angular/pull/46974)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2b4d7f6733](https://github.com/angular/angular/commit/2b4d7f6733e10e45e3ca8a448307bbc2834fc4a1) | feat | support document reference in render functions ([#47032](https://github.com/angular/angular/pull/47032)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0abb67af59](https://github.com/angular/angular/commit/0abb67af59a92a2b29082a259aa9f4ea3fbaab7d) | feat | allow guards and resolvers to be plain functions ([#46684](https://github.com/angular/angular/pull/46684)) |
|
||||
| [2a43beec15](https://github.com/angular/angular/commit/2a43beec159990b8c4bafc7f189e2bd85002dc7a) | fix | Fix route recognition behavior with some versions of rxjs ([#47098](https://github.com/angular/angular/pull/47098)) |
|
||||
## Special Thanks
|
||||
4javier, Andrew Kushnir, Andrew Scott, AntonioCardenas, Bob Watson, Bruno Barbosa, Eduardo Speroni, Edward, George Kalpakas, Ilia Mirkin, Jan Melcher, Jessica Janiuk, JiaLiPassion, Kristiyan Kostadinov, Mladen Jakovljević, Paul Gschwendtner, Pawel Kozlowski, Roman Matusevich, Victor Porof, Vovch, ashide2729, ileil and onrails
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.2.0-next.0"></a>
|
||||
# 14.2.0-next.0 (2022-08-03)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e2ab99b95e](https://github.com/angular/angular/commit/e2ab99b95efd893c49d15c02cccd72ef82ea1cae) | fix | allow null/undefined to be passed to ngClass input ([#39280](https://github.com/angular/angular/pull/39280)) ([#46906](https://github.com/angular/angular/pull/46906)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d1e83e1b30](https://github.com/angular/angular/commit/d1e83e1b30f2cea9f2ed16bff2d3b969335072ab) | feat | add `createComponent` function ([#46685](https://github.com/angular/angular/pull/46685)) |
|
||||
| [10becab70e](https://github.com/angular/angular/commit/10becab70e0f2afee29da7b3358eedcc22f655a2) | feat | add `reflectComponentType` function ([#46685](https://github.com/angular/angular/pull/46685)) |
|
||||
| [4b377d3a6d](https://github.com/angular/angular/commit/4b377d3a6d069da23ec577f8deca761b01d4e2f5) | feat | introduce createApplication API ([#46475](https://github.com/angular/angular/pull/46475)) |
|
||||
| [796840209c](https://github.com/angular/angular/commit/796840209cd38aacc5061a31701efe7eda1f6587) | fix | align TestBed interfaces and implementation ([#46635](https://github.com/angular/angular/pull/46635)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [426af91a42](https://github.com/angular/angular/commit/426af91a42104d6ce227ab52c8c4db3e218f5e03) | feat | add `FormBuilder.record()` method ([#46485](https://github.com/angular/angular/pull/46485)) |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [598b72bd05](https://github.com/angular/angular/commit/598b72bd05ea33468c70ac35b8ea5286439f41d9) | feat | support fix the component missing member ([#46764](https://github.com/angular/angular/pull/46764)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [07606e3181](https://github.com/angular/angular/commit/07606e3181fc7aa9f9185eb771fc9c44f01fe344) | feat | add `isEmpty` method to the `TransferState` class ([#46915](https://github.com/angular/angular/pull/46915)) |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [10289f1f6e](https://github.com/angular/angular/commit/10289f1f6e3d5935304a38d4300d4dadfea66150) | feat | expose resolved route title ([#46826](https://github.com/angular/angular/pull/46826)) |
|
||||
| [8600732b09](https://github.com/angular/angular/commit/8600732b090a4c253eb89ffde6db3858e4a2021c) | feat | Expose the default matcher for `Routes` used by the `Router` ([#46913](https://github.com/angular/angular/pull/46913)) |
|
||||
| [26ea97688c](https://github.com/angular/angular/commit/26ea97688cba5850588d8da83abaf8b539577241) | feat | Make router directives standalone ([#46758](https://github.com/angular/angular/pull/46758)) |
|
||||
### service-worker
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [383090858c](https://github.com/angular/angular/commit/383090858caf04c27ee8b320cceca2da0ae54bb3) | feat | support `sendRequest` as a `notificationclick` action ([#46912](https://github.com/angular/angular/pull/46912)) |
|
||||
## Special Thanks
|
||||
Andrew Kushnir, Andrew Scott, Cédric Exbrayat, Emmanuel Roux, George Kalpakas, Ilia Mirkin, Jessica Janiuk, Paul Gschwendtner, Pawel Kozlowski, Tristan Sprößer, angular-robot[bot], dario-piotrowicz and ivanwonder
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="14.1.1"></a>
|
||||
# 14.1.1 (2022-08-03)
|
||||
### core
|
||||
@@ -166,7 +327,7 @@ Alan Agius, Andrew Kushnir, Andrew Quinn, Andrew Scott, Aristeidis Bampakos, Asa
|
||||
| [ce20ed067f](https://github.com/angular/angular/commit/ce20ed067f12714ee6488ffe07f1a1c18bb60a15) | fix | Ensure Route injector is created before running CanMatch guards ([#46394](https://github.com/angular/angular/pull/46394)) |
|
||||
| [6a7b818d94](https://github.com/angular/angular/commit/6a7b818d94fdd13d81a01285e3e4be953a29cc06) | fix | Ensure target `RouterStateSnapshot` is defined in `NavigationError` ([#46842](https://github.com/angular/angular/pull/46842)) |
|
||||
| [f94c6f433d](https://github.com/angular/angular/commit/f94c6f433dba3924b79f137cfcc49d2dfd4d679c) | fix | Expose CanMatchFn as public API ([#46394](https://github.com/angular/angular/pull/46394)) |
|
||||
| [e8ae0fe3e9](https://github.com/angular/angular/commit/e8ae0fe3e91e2e805146fad0d2f0976b1f886112) | fix | Fix cancellation code for canLoad rejections ([#46752](https://github.com/angular/angular/pull/46752)) |
|
||||
| [e8ae0fe3e9](https://github.com/angular/angular/commit/e8ae0fe3e91e2e805146fad0d2f0976b1f886112) | fix | Fix cancelation code for canLoad rejections ([#46752](https://github.com/angular/angular/pull/46752)) |
|
||||
### upgrade
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
@@ -380,7 +541,7 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
|
||||
|
||||
This tightens parameter types of `TransferState` usage, and is a minor breaking change which may reveal existing problematic calls.
|
||||
### router
|
||||
- The type of `Route.pathMatch` is now more strict. Places that use
|
||||
- The type of `Route.pathMatch` is now stricter. Places that use
|
||||
`pathMatch` will likely need to be updated to have an explicit
|
||||
`Route`/`Routes` type so that TypeScript does not infer the type as
|
||||
`string`.
|
||||
@@ -620,7 +781,7 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ec0a0e0669](https://github.com/angular/angular/commit/ec0a0e0669ef5d2f524fbf9a540eb2b306b2e24a) | feat | add `cacheOpaqueResponses` option for data-groups ([#44723](https://github.com/angular/angular/pull/44723)) |
|
||||
| [bd04fbc05b](https://github.com/angular/angular/commit/bd04fbc05b0397de966a493a863e1054203c86d9) | feat | emit a notification when the service worker is already up to date after check ([#45216](https://github.com/angular/angular/pull/45216)) |
|
||||
| [bd04fbc05b](https://github.com/angular/angular/commit/bd04fbc05b0397de966a493a863e1054203c86d9) | feat | emit a notification when the service worker is already up-to-date after check ([#45216](https://github.com/angular/angular/pull/45216)) |
|
||||
## Special Thanks
|
||||
Adrian Kunz, Alan Agius, AleksanderBodurri, Alex Rickabaugh, AlirezaEbrahimkhani, Amir Rustamzadeh, Andrew Kushnir, Andrew Scott, Chabbey François, Charles Lyding, Cédric Exbrayat, Daan De Smedt, David Schmidt, Derek Cormier, Dmitrij Kuba, Doug Parker, Dylan Hunn, Emma Twersky, George Kalpakas, George Looshch, Jan Kuehle, Jessica Janiuk, JiaLiPassion, JimMorrison723, Joe Martin (Crowdstaffing), Joey Perrott, JoostK, Kristiyan Kostadinov, Krzysztof Platis, Leosvel Pérez Espinosa, Maddie Klein, Mark Whitfeld, Martin Sikora, Michael-Doner, Michal Materowski, Minko Gechev, Paul Gschwendtner, Pawel Kozlowski, Payam Shahidi, Pusztai Tibor, Ricardo Mattiazzi Baumgartner, Roy Dorombozi, Ruslan Lekhman, Samuel Littley, Sergej Grilborzer, Sumit Arora, Tobias Speicher, Virginia Dooley, Zack Elliott, alirezaghey, ananyahs96, arturovt, cexbrayat, dario-piotrowicz, ivanwonder, kamikopi, markostanimirovic, markwhitfeld, mgechev, renovate[bot], twerske and zverbeta
|
||||
|
||||
@@ -1040,7 +1201,7 @@ Aristeidis Bampakos, Dylan Hunn, George Kalpakas, JoostK, Kristiyan Kostadinov,
|
||||
- The `downgradeModule` function calls with NgModule factories are deprecated. Please use NgModule class based `downgradeModule` calls instead.
|
||||
### common
|
||||
- `TestRequest` from `@angular/common/http/testing` no longer
|
||||
accepts `ErrorEvent` when simulating XHR errors. Instead instances of
|
||||
accepts `ErrorEvent` when simulating XHR errors. Instead, instances of
|
||||
`ProgressEvent` should be passed, matching with the native browser behavior.
|
||||
###
|
||||
| Commit | Type | Description |
|
||||
@@ -1262,11 +1423,11 @@ return type.
|
||||
### core
|
||||
- Angular no longer requires component factories to dynamically create components. The factory-based signature of the `ViewContainerRef.createComponent` function is deprecated in favor of a different signature that allows passing component classes instead.
|
||||
|
||||
- The `getModuleFactory` function is deprecated in favor of the `getNgModuleById` one. With Ivy it's possible to work with NgModule classes directly, without retrieving corresponding factories, so the `getNgModuleById` should be used instead.
|
||||
- The `getModuleFactory` function is deprecated in favor of the `getNgModuleById` one. With Ivy, it's possible to work with NgModule classes directly, without retrieving corresponding factories, so the `getNgModuleById` should be used instead.
|
||||
|
||||
- Ivy made it possible to avoid the need to resolve Component and NgModule factories. Framework APIs allow to use Component and NgModule Types directly. As a result, the `PlatformRef.bootstrapModuleFactory` and a factory-based signature of the `ApplicationRef.bootstrap` method are now obsolete and are now deprecated. The `PlatformRef.bootstrapModuleFactory` calls can be replaced with `PlatformRef.bootstrapModule` ones. The `ApplicationRef.bootstrap` method allows to provide Component Type, so this can be used a replacement for the factory-based calls.
|
||||
|
||||
- In ViewEngine, [JIT compilation](https://angular.io/guide/glossary#jit) required special providers (like `Compiler`, `CompilerFactory`, etc) to be injected in the app and corresponding methods to be invoked. With Ivy, JIT compilation takes place implicitly if the Component, NgModule, etc have not already been [AOT compiled](https://angular.io/guide/glossary#aot). Those special providers were made available in Ivy for backwards-compatibility with ViewEngine to make the transition to Ivy smoother. Since ViewEngine is deprecated and will soon be removed, those symbols are now deprecated as well:
|
||||
- In ViewEngine, [JIT compilation](https://angular.io/guide/glossary#jit) required special providers (like `Compiler`, `CompilerFactory`, etc) to be injected in the app and corresponding methods to be invoked. With Ivy, JIT compilation takes place implicitly if the Component, NgModule, etc. have not already been [AOT compiled](https://angular.io/guide/glossary#aot). Those special providers were made available in Ivy for backwards-compatibility with ViewEngine to make the transition to Ivy smoother. Since ViewEngine is deprecated and will soon be removed, those symbols are now deprecated as well:
|
||||
|
||||
- `ModuleWithComponentFactories`
|
||||
- `Compiler`
|
||||
@@ -2207,7 +2368,7 @@ Alex Rickabaugh, Daniel Díaz, David Shevitz, Dylan Hunn, Front-end developer, G
|
||||
* **router:** update type castings for JSON.parse usage ([#40710](https://github.com/angular/angular/issues/40710)) ([350dada](https://github.com/angular/angular/commit/350dada))
|
||||
* **service-worker:** update supported range of node versions to only include LTS versions ([#41822](https://github.com/angular/angular/issues/41822)) ([6b823d7](https://github.com/angular/angular/commit/6b823d7071d59234ab52bdf7eaa248df6b7d9faa))
|
||||
* **service-worker:** update type castings for JSON.parse usage ([#40710](https://github.com/angular/angular/issues/40710)) ([4f7ff96](https://github.com/angular/angular/commit/4f7ff96))
|
||||
* **upgrade:** preserve $interval.flush when ngMocks is being used ([#30229](https://github.com/angular/angular/issues/30229)) ([87dc851](https://github.com/angular/angular/commit/87dc8511ccb9c75d78866ebd2c250ea96fc91bd0))
|
||||
* **upgrade:** preserve $interval flush when ngMocks is being used ([#30229](https://github.com/angular/angular/issues/30229)) ([87dc851](https://github.com/angular/angular/commit/87dc8511ccb9c75d78866ebd2c250ea96fc91bd0))
|
||||
* **upgrade:** update supported range of node versions to only include LTS versions ([#41822](https://github.com/angular/angular/issues/41822)) ([10c4523](https://github.com/angular/angular/commit/10c45239a68e82ea52c1601fae09953aa7843351))
|
||||
|
||||
|
||||
@@ -2223,7 +2384,7 @@ Alex Rickabaugh, Daniel Díaz, David Shevitz, Dylan Hunn, Front-end developer, G
|
||||
* **bazel:** update supported range of node versions ([#41544](https://github.com/angular/angular/issues/41544)) ([d583d92](https://github.com/angular/angular/commit/d583d926db537cc74f9235cad51189dbe83fbb44))
|
||||
* **common:** update supported range of node versions ([#41544](https://github.com/angular/angular/issues/41544)) ([e0250e5](https://github.com/angular/angular/commit/e0250e567ae47ed7b77e9d88a3289727c056a6f1))
|
||||
* **common:** add `historyGo` method to `Location` service ([#38890](https://github.com/angular/angular/issues/38890)) ([e05a6f3](https://github.com/angular/angular/commit/e05a6f3bb3048e9a94a4b154526221dea290312d))
|
||||
* **common:** support ICU standard "stand alone day of week" with `DatePipe` ([#40766](https://github.com/angular/angular/issues/40766)) ([c56ecab](https://github.com/angular/angular/commit/c56ecab515c28d2ad45c630080bfbf549675528a)), closes [#26922](https://github.com/angular/angular/issues/26922)
|
||||
* **common:** support ICU standard "stand-alone day of week" with `DatePipe` ([#40766](https://github.com/angular/angular/issues/40766)) ([c56ecab](https://github.com/angular/angular/commit/c56ecab515c28d2ad45c630080bfbf549675528a)), closes [#26922](https://github.com/angular/angular/issues/26922)
|
||||
* **common:** implement `appendAll()` method on `HttpParams` ([#20930](https://github.com/angular/angular/issues/20930)) ([575a2d1](https://github.com/angular/angular/commit/575a2d1)), closes [#20798](https://github.com/angular/angular/issues/20798)
|
||||
* **compiler:** support nullish coalescing in templates ([#41437](https://github.com/angular/angular/issues/41437)) ([ec27bd4](https://github.com/angular/angular/commit/ec27bd4ed1cc086d76d8142fadf87354b38aa61a)), closes [#36528](https://github.com/angular/angular/issues/36528)
|
||||
* **compiler:** update supported range of node versions ([#41544](https://github.com/angular/angular/issues/41544)) ([75cc813](https://github.com/angular/angular/commit/75cc8133ad8efd6453694f222e2cc6789c4de7b2))
|
||||
@@ -2307,7 +2468,7 @@ migrate their message ids using the `localize-migrate` command line tool.
|
||||
* **core:** Angular no longer maintains support for node v10
|
||||
* **core:** Previously the `ng.getDirectives` function threw an error in case a
|
||||
given DOM node had no Angular context associated with it (for example
|
||||
if a function was called for a DOM element outside of an Angular app).
|
||||
if a function was called for a DOM element outside an Angular app).
|
||||
This behavior was inconsistent with other debugging utilities under `ng`
|
||||
namespace, which handled this situation without raising an exception.
|
||||
Now calling the `ng.getDirectives` function for such DOM nodes would
|
||||
@@ -2341,8 +2502,7 @@ export class QueryCompWithStrictChangeEmitParent {
|
||||
}
|
||||
```
|
||||
For backward compatibility before v12
|
||||
`emitDistinctChangesOnlyDefaultValue` was set to `false`. This change
|
||||
changes the default to `true`.
|
||||
`emitDistinctChangesOnlyDefaultValue` was set to `false`. This change the default to `true`.
|
||||
* **core:** The type of the `APP_INITIALIZER` token has been changed to more accurately
|
||||
reflect the types of return values that are handled by Angular. Previously,
|
||||
each initializer callback was typed to return `any`, this is now
|
||||
@@ -2353,7 +2513,7 @@ the stricter type.
|
||||
|
||||
Additionally, TypeScript may report the TS2742 error if the `APP_INITIALIZER`
|
||||
token is used in an expression of which its inferred type has to be emitted
|
||||
into a .d.ts file. To workaround this, an explicit type annotation is needed,
|
||||
into a .d.ts file. To work around this, an explicit type annotation is needed,
|
||||
which would typically be `Provider` or `Provider[]`.
|
||||
* **core:** Minimum supported `zone.js` version is `0.11.4`
|
||||
* **forms:** The `emitEvent` option was added to the following `FormArray` and `FormGroup` methods:
|
||||
@@ -2438,7 +2598,7 @@ Alex Rickabaugh, Andrew J Asche, Georgii Dolzhykov, Joey Perrott, Joost Koehoorn
|
||||
* **core:** Angular no longer maintains support for node v10
|
||||
* **core:** Previously the `ng.getDirectives` function threw an error in case a
|
||||
given DOM node had no Angular context associated with it (for example
|
||||
if a function was called for a DOM element outside of an Angular app).
|
||||
if a function was called for a DOM element outside an Angular app).
|
||||
This behavior was inconsistent with other debugging utilities under `ng`
|
||||
namespace, which handled this situation without raising an exception.
|
||||
Now calling the `ng.getDirectives` function for such DOM nodes would
|
||||
@@ -2782,7 +2942,7 @@ This release contains the same set the of changes as 11.2.0-next.1.
|
||||
* **core:** Allow passing AbstractType to the inject function ([#37958](https://github.com/angular/angular/issues/37958)) ([a1b6ad0](https://github.com/angular/angular/commit/a1b6ad0))
|
||||
* **core:** Ensure OnPush ancestors are marked dirty when events occur ([#39833](https://github.com/angular/angular/issues/39833)) ([68d4a74](https://github.com/angular/angular/commit/68d4a74)), closes [#39832](https://github.com/angular/angular/issues/39832)
|
||||
* **core:** meta addTag() adds incorrect attribute for httpEquiv ([#32531](https://github.com/angular/angular/issues/32531)) ([ff0a90e](https://github.com/angular/angular/commit/ff0a90e))
|
||||
* **core:** migration error if program contains files outside of the project ([#39790](https://github.com/angular/angular/issues/39790)) ([1a26f6d](https://github.com/angular/angular/commit/1a26f6d)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** migration error if program contains files outside the project ([#39790](https://github.com/angular/angular/issues/39790)) ([1a26f6d](https://github.com/angular/angular/commit/1a26f6d)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** not invoking object's toString when rendering to the DOM ([#39843](https://github.com/angular/angular/issues/39843)) ([11cd37f](https://github.com/angular/angular/commit/11cd37f)), closes [#38839](https://github.com/angular/angular/issues/38839)
|
||||
* **core:** remove duplicated noop function ([#39761](https://github.com/angular/angular/issues/39761)) ([066126a](https://github.com/angular/angular/commit/066126a))
|
||||
* **core:** support `Attribute` DI decorator in `deps` section of a token ([#37085](https://github.com/angular/angular/issues/37085)) ([f5cbf0b](https://github.com/angular/angular/commit/f5cbf0b)), closes [#36479](https://github.com/angular/angular/issues/36479)
|
||||
@@ -2980,7 +3140,7 @@ This release contains the same set the of changes as 11.2.0-next.1.
|
||||
* **compiler-cli:** report error when a reference target is missing instead of crashing ([#39805](https://github.com/angular/angular/issues/39805)) ([8634611](https://github.com/angular/angular/commit/8634611)), closes [#38618](https://github.com/angular/angular/issues/38618) [#39744](https://github.com/angular/angular/issues/39744)
|
||||
* **core:** Ensure OnPush ancestors are marked dirty when events occur ([#39833](https://github.com/angular/angular/issues/39833)) ([01c1bfd](https://github.com/angular/angular/commit/01c1bfd)), closes [#39832](https://github.com/angular/angular/issues/39832)
|
||||
* **core:** meta addTag() adds incorrect attribute for httpEquiv ([#32531](https://github.com/angular/angular/issues/32531)) ([3114b0a](https://github.com/angular/angular/commit/3114b0a))
|
||||
* **core:** migration error if program contains files outside of the project ([#39790](https://github.com/angular/angular/issues/39790)) ([7dcc212](https://github.com/angular/angular/commit/7dcc212)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** migration error if program contains files outside the project ([#39790](https://github.com/angular/angular/issues/39790)) ([7dcc212](https://github.com/angular/angular/commit/7dcc212)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** not invoking object's toString when rendering to the DOM ([#39843](https://github.com/angular/angular/issues/39843)) ([75e22ab](https://github.com/angular/angular/commit/75e22ab)), closes [#38839](https://github.com/angular/angular/issues/38839)
|
||||
* **core:** remove duplicated noop function ([#39761](https://github.com/angular/angular/issues/39761)) ([26a1337](https://github.com/angular/angular/commit/26a1337))
|
||||
* **core:** support `Attribute` DI decorator in `deps` section of a token ([#37085](https://github.com/angular/angular/issues/37085)) ([aaa3111](https://github.com/angular/angular/commit/aaa3111)), closes [#36479](https://github.com/angular/angular/issues/36479)
|
||||
@@ -3183,7 +3343,7 @@ This release contains the same set the of changes as 11.2.0-next.1.
|
||||
`CollectionChangeRecord` has been removed, use `IterableChangeRecord` instead.
|
||||
- **[c8f056b](https://github.com/angular/angular/commit/c8f056beb696d176530ee4e86f64964c3b834c9a):**
|
||||
If you call `TestBed.overrideProvider` after TestBed initialization, provider overrides are not applied.
|
||||
This behavior is consistent with other override methods (such as `TestBed.overrideDirective`, etc) but they throw an error to indicate that, when the check was missing in the `TestBed.overrideProvider` function.
|
||||
This behavior is consistent with other override methods (such as `TestBed.overrideDirective`, etc.) but they throw an error to indicate that, when the check was missing in the `TestBed.overrideProvider` function.
|
||||
Now calling `TestBed.overrideProvider` after `TestBed` initialization also triggers an error, thus there is a chance that some tests (where `TestBed.overrideProvider` is called after `TestBed` initialization) will start to fail and require updates to move `TestBed.overrideProvider` calls before `TestBed` initialization is completed.
|
||||
- **[4ca1c73](https://github.com/angular/angular/commit/4ca1c736bb020de166b6a1fbfb9fe264602ccd5c):**
|
||||
In v10, IE 9, 10, and IE mobile support was deprecated.
|
||||
@@ -3209,7 +3369,7 @@ This release contains the same set the of changes as 11.2.0-next.1.
|
||||
In an unlikely case your code was testing the parent against `undefined` with strict equality, you'll need to change this to `=== null` instead, since the parent is now explicitly initialized with `null` instead of being left `undefined`.
|
||||
* **platform-server:**
|
||||
- **[b4e8399](https://github.com/angular/angular/commit/b4e8399144ae4b6d4f0da9ff2a8e1fa73643f766):**
|
||||
If you use `useAbsoluteUrl` to setup `platform-server`, you now need to also specify `baseUrl`.
|
||||
If you use `useAbsoluteUrl` to set up `platform-server`, you now need to also specify `baseUrl`.
|
||||
We are intentionally making this a breaking change in a minor release, because if `useAbsoluteUrl` is set to `true` then the behavior of the application could be unpredictable, resulting in issues that are hard to discover but could be affecting production environments.
|
||||
* **platform-webworker:**
|
||||
- **[93c3d8f](https://github.com/angular/angular/commit/93c3d8f9fd79014bf700a1447503f5ee6f170bf9):**
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an safe and welcoming environment, we as
|
||||
In the interest of fostering a safe and welcoming environment, we as
|
||||
the Angular team pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity, gender expression,
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ A minimal reproduction allows us to quickly confirm a bug (or point out a coding
|
||||
|
||||
We require a minimal reproduction to save maintainers' time and ultimately be able to fix more bugs.
|
||||
Often, developers find coding problems themselves while preparing a minimal reproduction.
|
||||
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
|
||||
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase, but we really need to isolate the problem before we can fix it.
|
||||
|
||||
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced.
|
||||
|
||||
|
||||
@@ -115,11 +115,11 @@ Check out our [upgrade guide](https://update.angular.io/) to find out the best w
|
||||
|
||||
### Contributing Guidelines
|
||||
|
||||
Read through our [contributing guidelines][contributing] to learn about our submission process, coding rules and more.
|
||||
Read through our [contributing guidelines][contributing] to learn about our submission process, coding rules, and more.
|
||||
|
||||
### Want to Help?
|
||||
|
||||
Want to report a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for [contributing][contributing] and then check out one of our issues labeled as <kbd>[help wanted](https://github.com/angular/angular/labels/help%20wanted)</kbd> or <kbd>[good first issue](https://github.com/angular/angular/labels/good%20first%20issue)</kbd>.
|
||||
Want to report a bug, contribute some code, or improve the documentation? Excellent! Read up on our guidelines for [contributing][contributing] and then check out one of our issues labeled as <kbd>[help wanted](https://github.com/angular/angular/labels/help%20wanted)</kbd> or <kbd>[good first issue](https://github.com/angular/angular/labels/good%20first%20issue)</kbd>.
|
||||
|
||||
### Code of Conduct
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
|
||||
|
||||
nodejs_register_toolchains(
|
||||
name = "nodejs",
|
||||
node_version = "16.10.0",
|
||||
node_version = "16.13.0",
|
||||
)
|
||||
|
||||
# Download npm dependencies.
|
||||
@@ -158,10 +158,10 @@ cldr_xml_data_repository(
|
||||
# sass rules
|
||||
http_archive(
|
||||
name = "io_bazel_rules_sass",
|
||||
sha256 = "85b34f2e5e227aa586b6e0fd6942262e17b3cface596891eeef5a29a0b7467e3",
|
||||
strip_prefix = "rules_sass-697e5a08bdd39aee49f2c6f4eb621ef59e677e49",
|
||||
sha256 = "0cde2dd9ff34994f27ba4d5c74d34cca3c727bf41bc6024cf66ad298a1f5e5c2",
|
||||
strip_prefix = "rules_sass-f6ceac7f5e11424880ae41f9c1a5cfd02968376c",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_sass/archive/697e5a08bdd39aee49f2c6f4eb621ef59e677e49.zip",
|
||||
"https://github.com/bazelbuild/rules_sass/archive/f6ceac7f5e11424880ae41f9c1a5cfd02968376c.zip",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -90,7 +90,6 @@ TEST_DEPS = APPLICATION_DEPS + [
|
||||
"@aio_npm//karma-jasmine",
|
||||
"@aio_npm//karma-jasmine-html-reporter",
|
||||
"@aio_npm//puppeteer",
|
||||
"@aio_npm//timezone-mock",
|
||||
]
|
||||
|
||||
architect(
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ serve the files in `dist/` with `yarn http-server dist -p 4200`.
|
||||
|
||||
There are two types of content in the documentation:
|
||||
|
||||
* **API docs**: descriptions of the modules, classes, interfaces, decorators, etc that make up the Angular platform.
|
||||
* **API docs**: descriptions of all that make up the Angular platform, such as the modules, classes, interfaces or decorators.
|
||||
API docs are generated directly from the source code.
|
||||
The source code is contained in TypeScript files, located in the `angular/packages` folder.
|
||||
Each API item may have a preceding comment, which contains JSDoc style tags and content.
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Update the angular.io app
|
||||
|
||||
The dependencies of the angular.io app (including Angular, Angular Material and Angular CLI) are automatically updated using [Renovate](https://renovatebot.com/).
|
||||
|
||||
However, it is useful to periodically also manually update the app to more closely match (in file layout, configs, etc.) what a new Angular CLI app would look like.
|
||||
This is typically only needed once for each new major Angular version.
|
||||
|
||||
Since angular.io is an Angular CLI app, we can take advantage of `ng update` to apply migrations.
|
||||
|
||||
Follow these steps to align the angular.io app with new CLI apps.
|
||||
|
||||
> **Note:**
|
||||
> The following steps assume that the related Angular dependencies have already been updated in [aio/package.json](./package.json) (for example, automatically by Renovate).
|
||||
|
||||
> **Note:**
|
||||
> All commands shown below are expected to be executed from inside the [aio/](./) directory (unless specified otherwise).
|
||||
|
||||
- Determine (for example, by examining git history) what is the last versions for which this process was performed.
|
||||
These will be referred to as `<FROM_VERSION_*>`.
|
||||
If you can't determine these, use arbitrary versions, such as the previous major version.
|
||||
|
||||
- Run the following commands to automatically apply any available migrations to the project:
|
||||
```sh
|
||||
# Ensure dependencies are installed.
|
||||
yarn install
|
||||
|
||||
# Migrate project to new versions.
|
||||
yarn ng update @angular/cli --allow-dirty --migrate-only --from=<FROM_VERSION_CLI>
|
||||
yarn ng update @angular/core --allow-dirty --migrate-only --from=<FROM_VERSION_ANGULAR>
|
||||
yarn ng update @angular/material --allow-dirty --migrate-only --from=<FROM_VERSION_MATERIAL>
|
||||
```
|
||||
|
||||
> **Note:**
|
||||
> Depending on the number of changes generated from each `ng update` command, it might make sense to create a separate commit for each update.
|
||||
|
||||
- Inspect [package.json](./package.json) to determine what is the current version of Angular CLI (i.e. `@angular/cli`) used in the app.
|
||||
This will be referred to as `<TO_VERSION_CLI>`.
|
||||
|
||||
- Use the [angular-cli-diff](https://github.com/cexbrayat/angular-cli-diff) repository to discover more changes (which are not automatically applied via `ng update` migrations) between Angular CLI apps of different versions.
|
||||
Visit https://github.com/cexbrayat/angular-cli-diff/compare/<FROM_VERSION_CLI>...<TO_VERSION_CLI>, inspect the changes between the two versions and apply the ones that make sense to the angular.io source code.
|
||||
|
||||
- Commit all changes and [submit a pull request](../CONTRIBUTING.md#submit-pr).
|
||||
@@ -40,7 +40,7 @@ ARG AIO_TRUSTED_PR_LABEL="aio: preview"
|
||||
ARG TEST_AIO_TRUSTED_PR_LABEL=$AIO_TRUSTED_PR_LABEL
|
||||
ARG AIO_PREVIEW_SERVER_HOSTNAME=preview.localhost
|
||||
ARG TEST_AIO_PREVIEW_SERVER_HOSTNAME=$AIO_PREVIEW_SERVER_HOSTNAME
|
||||
ARG AIO_ARTIFACT_MAX_SIZE=26214400
|
||||
ARG AIO_ARTIFACT_MAX_SIZE=36700160
|
||||
ARG TEST_AIO_ARTIFACT_MAX_SIZE=200
|
||||
ARG AIO_PREVIEW_SERVER_PORT=3000
|
||||
ARG TEST_AIO_PREVIEW_SERVER_PORT=3001
|
||||
|
||||
@@ -49,6 +49,6 @@
|
||||
"supertest": "^6.0.0",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-jasmine-noSkipOrFocus": "^1.0.9",
|
||||
"typescript": "~4.7.2"
|
||||
"typescript": "~4.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1668,10 +1668,10 @@ type-is@~1.6.18:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
typescript@~4.7.2:
|
||||
version "4.7.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
|
||||
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
|
||||
typescript@~4.8.0:
|
||||
version "4.8.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790"
|
||||
integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==
|
||||
|
||||
unbox-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
|
||||
@@ -30,4 +30,5 @@
|
||||
|
||||
## Miscellaneous
|
||||
- [Debug docker container](misc--debug-docker-container.md)
|
||||
- [Use Let's Encrypt certificates](misc--use-lets-encrypt-certs.md)
|
||||
- [Integrate with CI](misc--integrate-with-ci.md)
|
||||
|
||||
@@ -26,7 +26,7 @@ you don't need to specify values for those.
|
||||
See also `AIO_GITHUB_TEAM_SLUGS`.
|
||||
|
||||
- `AIO_GITHUB_REPO`:
|
||||
The Github repository for which PRs will be hosted.
|
||||
The GitHub repository for which PRs will be hosted.
|
||||
|
||||
- `AIO_GITHUB_TEAM_SLUGS`:
|
||||
A comma-separated list of teams, whose authors are allowed to preview PRs.
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# Miscellaneous - Use Let's Encrypt TLS certificates
|
||||
|
||||
|
||||
[Let's Encrypt](https://letsencrypt.org/) is a free, automated, and open certificate authority (CA),
|
||||
provided by the [Internet Security Research Group (ISRG)](https://www.abetterinternet.org/). It can
|
||||
be used for issuing the certificates needed by the preview server. See the "Create TLS certificates"
|
||||
section in [this doc](vm-setup--create-host-dirs-and-files.md) for more details.
|
||||
|
||||
Let's Encrypt supports issuing
|
||||
[wildcard certificates](https://letsencrypt.org/docs/faq/#does-let-s-encrypt-issue-wildcard-certificates),
|
||||
but they have to be renewed every 3 months using a
|
||||
[DNS-01 challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge).
|
||||
|
||||
Below are instructions for the creation of certificates using Let's Encrypt.
|
||||
|
||||
**Note 1:**
|
||||
It is assumed that the commands are executed on the VM that hosts the preview server. You can run
|
||||
the commands on any machine and adjust accordingly the steps for transfering the generated
|
||||
certificate and private key to the preview server VM.
|
||||
|
||||
**Note 2:**
|
||||
In order to complete the DNS-01 challenge and generate the certificate, one needs to have access
|
||||
to update the DNS records associated with the `ngbuilds.io` domain and subdomains.
|
||||
|
||||
|
||||
## Prerequisites
|
||||
- Install [certbot](https://certbot.eff.org/):
|
||||
- Old method: `sudo apt-get install certbot`
|
||||
- New method: Follow the instructions [here](https://certbot.eff.org/instructions).
|
||||
|
||||
|
||||
## Create new certificate
|
||||
- Run the following command and follow the on-screen instructions:
|
||||
```sh
|
||||
sudo certbot certonly \
|
||||
-d "ngbuilds.io,*.ngbuilds.io" \
|
||||
-m "devops@angular.io" \
|
||||
--agree-tos \
|
||||
--manual \
|
||||
--manual-public-ip-logging-ok \
|
||||
--preferred-challenges="dns"
|
||||
```
|
||||
|
||||
**Hint:**
|
||||
You can use `dig -t txt _acme-challenge.ngbuilds.io` (on Linux/macOS) or something like
|
||||
[DNSChecker.org](https://dnschecker.org/all-dns-records-of-domain.php?query=_acme-challenge.ngbuilds.io&rtype=TXT) to verify that the DNS updates have been successfully deployed and propagated.
|
||||
|
||||
- [Optional] Remove the DNS TXT records added in the previous step.
|
||||
(They are no longer needed, unless you want to create more certificates now.)
|
||||
|
||||
|
||||
## Deploy new certificate
|
||||
- Copy files to the host machine's `/etc/ssl/localcerts` directory, replacing `YYYY-MM` in the file
|
||||
names with the current year and month (for example, `2022-08`):
|
||||
```sh
|
||||
# Copy certificate.
|
||||
sudo cp /etc/letsencrypt/live/ngbuilds.io/fullchain.pem /etc/ssl/localcerts/ngbuilds.io.crt.YYYY-MM
|
||||
sudo cp /etc/letsencrypt/live/ngbuilds.io/fullchain.pem /etc/ssl/localcerts/ngbuilds.io.crt
|
||||
|
||||
# Copy private key.
|
||||
sudo cp /etc/letsencrypt/live/ngbuilds.io/privkey.pem /etc/ssl/localcerts/ngbuilds.io.key.YYYY-MM
|
||||
sudo cp /etc/letsencrypt/live/ngbuilds.io/privkey.pem /etc/ssl/localcerts/ngbuilds.io.key
|
||||
|
||||
# Update permissions.
|
||||
sudo find /etc/ssl/localcerts -type f -exec chmod 400 {} \;
|
||||
```
|
||||
|
||||
**Note:**
|
||||
The `.YYYY-MM`-suffixed copies are not needed/used. They are just kept for reference and backup
|
||||
purposes.
|
||||
|
||||
- Reload `nginx`:
|
||||
```sh
|
||||
# Connect to the Docker container and reload reload `nginx`.
|
||||
sudo docker exec -it aio service nginx reload
|
||||
```
|
||||
|
||||
- [Optional] Verify that the certificate has been successfully deployed by visiting
|
||||
https://ngbuilds.io/ in a browser and inspecting the TLS certificate details. See, for example,
|
||||
[how to view certificate details in Chrome](https://www.howtogeek.com/292076/how-do-you-view-ssl-certificate-details-in-google-chrome/).
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
## Objective
|
||||
Whenever a PR job is run on the CI infrastructure (e.g. CircleCI), we want to build `angular.io`
|
||||
and host the build artifacts on a publicly accessible server so that collaborators (developers,
|
||||
designers, authors, etc) can preview the changes without having to checkout and build the app
|
||||
locally.
|
||||
and host the build artifacts on a publicly accessible server so that collaborators, such as the
|
||||
developers, designers, or authors, can preview the changes without having to check out and build
|
||||
the app locally.
|
||||
|
||||
|
||||
## Source code
|
||||
@@ -57,7 +57,7 @@ More info on how to set things up on CI can be found [here](misc--integrate-with
|
||||
If the PR transitions from "non-public" to "public", the preview-server posts a comment on the
|
||||
corresponding PR on GitHub mentioning the SHAs and the links where the previews can be found.
|
||||
- The preview-server verifies that it is not trying to overwrite an existing build.
|
||||
- The preview-server deploys the artifacts to a sub-directory named after the PR number and the
|
||||
- The preview-server deploys the artifacts to a subdirectory named after the PR number and the
|
||||
first few characters of the SHA: `<PR>/<SHA>/`
|
||||
(Non-publicly accessible PRs will be stored in a different location, but again derived from the PR
|
||||
number and SHA.)
|
||||
@@ -89,7 +89,7 @@ More info on the possible HTTP status codes and their meaning can be found
|
||||
### Serving build artifacts
|
||||
- nginx receives a request for a hosted preview resource on a subdomain corresponding to the PR and SHA.
|
||||
E.g.: `pr<PR>-<SHA>.ngbuilds.io/path/to/resource`
|
||||
- nginx maps the subdomain to the correct sub-directory and serves the resource.
|
||||
- nginx maps the subdomain to the correct subdirectory and serves the resource.
|
||||
E.g.: `/<PR>/<SHA>/path/to/resource`
|
||||
|
||||
More info on the possible HTTP status codes and their meaning can be found
|
||||
|
||||
@@ -19,7 +19,7 @@ along with a brief explanation of what they mean:
|
||||
segment).
|
||||
|
||||
- **403 (Forbidden)**:
|
||||
Trying to access a sub-directory.
|
||||
Trying to access a subdirectory.
|
||||
|
||||
- **404 (Not Found)**:
|
||||
File not found.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
|
||||
Whenever a PR job is run on CircleCI, we want to build `angular.io` and host the build artifacts on
|
||||
a publicly accessible server so that collaborators (developers, designers, authors, etc) can preview
|
||||
the changes without having to checkout and build the app locally.
|
||||
a publicly accessible server so that collaborators, such as the developers, designers, or authors,
|
||||
can preview the changes without having to check out and build the app locally.
|
||||
|
||||
This document discusses the security considerations associated with moving build artifacts as
|
||||
part of the CI process and serving them publicly.
|
||||
@@ -136,7 +136,7 @@ This section describes how each of the aforementioned sub-tasks is accomplished:
|
||||
## Assumptions / Things to keep in mind
|
||||
|
||||
- Other than the initial webhook trigger, which provides a build number, all requests for data come
|
||||
from the preview-server making requests to well defined API endpoints (e.g. CircleCI and Github).
|
||||
from the preview-server making requests to well-defined API endpoints (e.g. CircleCI and Github).
|
||||
This means that any secret access keys need only be stored on the preview-server and not on any of
|
||||
the CI build infrastructure (e.g. CircleCI).
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ persistent disk can be used (as described [here](vm-setup--attach-persistent-dis
|
||||
**Note:** The directories created inside that directory will be owned by user `www-data`.
|
||||
|
||||
|
||||
## Create SSL certificates (Optional for dev)
|
||||
The host VM can attach a directory containing the SSL certificate and key to be used by the nginx
|
||||
## Create TLS certificates (Optional for dev)
|
||||
The host VM can attach a directory containing the TLS certificate and key to be used by the nginx
|
||||
server for serving the hosted previews. More info on how to attach the directory when
|
||||
starting the container can be found [here](vm-setup--start-docker-container.md).
|
||||
|
||||
@@ -32,10 +32,15 @@ specify the domain name see [here](vm-setup--create-docker-image.md).
|
||||
If no directory is attached, nginx will use an internal self-signed certificate. This is convenient
|
||||
during development, but is not suitable for production.
|
||||
|
||||
Certificates from any certificate authority can be used. As an example, see
|
||||
[here](misc--use-lets-encrypt-certs) for instructions on using certificates from
|
||||
[Let's Encrypt](https://letsencrypt.org/).
|
||||
|
||||
**Note:**
|
||||
Since nginx needs to be able to serve requests for both the main domain as well as any subdomain
|
||||
(e.g. `ngbuilds.io/` and `foo-bar.ngbuilds.io/`), the provided certificate needs to be a wildcard
|
||||
certificate covering both the domain and subdomains.
|
||||
(e.g. `ngbuilds.io/` and `foo-bar.ngbuilds.io/`), the provided certificate needs to be a
|
||||
[wildcard certificate](https://en.wikipedia.org/wiki/Wildcard_certificate) covering both the domain
|
||||
and all subdomains.
|
||||
|
||||
|
||||
## Create directory for logs (Optional)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
## The `docker run` command
|
||||
Once everything has been setup and configured, a docker container can be started with the following
|
||||
Once everything has been set up and configured, a docker container can be started with the following
|
||||
command:
|
||||
|
||||
```
|
||||
@@ -48,14 +48,22 @@ sudo docker run \
|
||||
|
||||
# The directory the contains the secrets (e.g. GitHub token, JWT secret, etc).
|
||||
# (See [here](vm-setup--set-up-secrets.md) for more info.)
|
||||
#
|
||||
# NOTE:
|
||||
# Omitting this is OK during development/debugging, when you don't care to interact with real
|
||||
# external services.
|
||||
--volume <host-secrets-dir>:/aio-secrets:ro \
|
||||
|
||||
# The build artifacts and hosted previews will stored to and served from this directory.
|
||||
# (If you are using a persistent disk - as described [here](vm-setup--attach-persistent-disk.md) -
|
||||
# this will be a directory inside the disk.)
|
||||
#
|
||||
# NOTE:
|
||||
# Omitting this is OK during development/debugging, when you don't care to interact with real
|
||||
# external services.
|
||||
--volume <host-builds-dir>:/var/www/aio-builds \
|
||||
|
||||
# The directory the contains the SSL certificates.
|
||||
# The directory the contains the TLS certificates.
|
||||
# (See [here](vm-setup--create-host-dirs-and-files.md) for more info.)
|
||||
# If not provided, the container will use self-signed certificates.
|
||||
[--volume <host-cert-dir>:/etc/ssl/localcerts:ro] \
|
||||
@@ -77,10 +85,13 @@ sudo docker run \
|
||||
|
||||
|
||||
## Example
|
||||
The following command would start a docker container based on the previously created `foobar-builds`
|
||||
docker image, alias it as 'foobar-builds-1' and map predefined directories on the host VM to be used
|
||||
by the container for accessing secrets and SSL certificates and keeping the build artifacts and logs;
|
||||
and will map the source scripts from the host to the container.
|
||||
The following command would do the following:
|
||||
1. Start a docker container based on the previously created `foobar-builds` docker image.
|
||||
2. Alias the docker container as `foobar-builds-1` (so it can be references in subsequent docker
|
||||
commands).
|
||||
3. Map predefined directories on the host VM to be used by the container for accessing secrets and
|
||||
TLS certificates and keeping the build artifacts and logs.
|
||||
4. Map the source scripts from the host to the container (for debugging purposes).
|
||||
|
||||
```
|
||||
sudo docker run \
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
Angular throws an `ExpressionChangedAfterItHasBeenCheckedError` when an expression value has been changed after change detection has completed. Angular only throws this error in development mode.
|
||||
|
||||
In development mode, Angular performs an additional check after each change detection run, to ensure the bindings haven't changed. This catches errors where the view is left in an inconsistent state. This can occur, for example, if a method or getter returns a different value each time it is called, or if a child component changes values on its parent. If either of these occur, this is a sign that change detection is not stabilized. Angular throws the error to ensure data is always reflected correctly in the view, which prevents erratic UI behavior or a possible infinite loop.
|
||||
In development mode, Angular performs an additional check after each change detection run, to ensure the bindings haven't changed. This catches errors where the view is left in an inconsistent state. This can occur, for example, if a method or getter returns a different value each time it is called, or if a child component changes values on its parent. If either of these occurs, this is a sign that change detection is not stabilized. Angular throws the error to ensure data is always reflected correctly in the view, which prevents erratic UI behavior or a possible infinite loop.
|
||||
|
||||
This error commonly occurs when you've added template expressions or have begun to implement lifecycle hooks like `ngAfterViewInit` or `ngOnChanges`. It is also common when dealing with loading status and asynchronous operations, or when a child component changes its parent bindings.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@name Wrong Async Validator Return Type
|
||||
@category forms
|
||||
@category runtime
|
||||
@shortDescription Async validator must return a Promise or Observable
|
||||
|
||||
@description
|
||||
@@ -7,7 +7,7 @@ Async validators must return a promise or an observable, and emit/resolve them w
|
||||
|
||||
```typescript
|
||||
export function isTenAsync(control: AbstractControl):
|
||||
Observable<ValidationErrors> | null {
|
||||
Observable<ValidationErrors | null> {
|
||||
const v: number = control.value;
|
||||
if (v !== 10) {
|
||||
// Emit an object with a validation error.
|
||||
@@ -27,4 +27,4 @@ Did you mistakenly use a synchronous validator instead of an async validator?
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-06-28
|
||||
@reviewed 2022-06-28
|
||||
@@ -0,0 +1,71 @@
|
||||
@name Unsafe bindings on an iframe element
|
||||
@category runtime
|
||||
@shortDescription Unsafe bindings on an iframe element
|
||||
|
||||
@description
|
||||
You see this error when Angular detects an attribute binding or a property binding on an `<iframe>` element using the following property names:
|
||||
|
||||
* sandbox
|
||||
* allow
|
||||
* allowFullscreen
|
||||
* referrerPolicy
|
||||
* csp
|
||||
* fetchPriority
|
||||
|
||||
The mentioned attributes affect the security model setup for `<iframe>`s
|
||||
and it's important to apply them before setting the `src` or `srcdoc` attributes.
|
||||
To enforce that, Angular requires these attributes to be set on `<iframe>`s as
|
||||
static attributes, so the values are set at the element creation time and they
|
||||
remain the same throughout the lifetime of an `<iframe>` instance.
|
||||
|
||||
The error is thrown when a property binding with one of the mentioned attribute names is used:
|
||||
```html
|
||||
<iframe [sandbox]="'allow-scripts'" src="..."></iframe>
|
||||
```
|
||||
|
||||
or when it's an attribute bindings:
|
||||
|
||||
```html
|
||||
<iframe [attr.sandbox]="'allow-scripts'" src="..."></iframe>
|
||||
```
|
||||
|
||||
Also, the error is thrown when a similar pattern is used in Directive's host bindings:
|
||||
|
||||
```typescript
|
||||
@Directive({
|
||||
selector: 'iframe',
|
||||
host: {
|
||||
'[sandbox]': `'allow-scripts'`,
|
||||
'[attr.sandbox]': `'allow-scripts'`,
|
||||
}
|
||||
})
|
||||
class IframeDirective {}
|
||||
```
|
||||
|
||||
@debugging
|
||||
|
||||
The error message includes the name of the component with the template where
|
||||
an `<iframe>` element with unsafe bindings is located.
|
||||
|
||||
The recommended solution is to use the mentioned attributes as static ones, for example:
|
||||
|
||||
```html
|
||||
<iframe sandbox="allow-scripts" src="..."></iframe>
|
||||
```
|
||||
|
||||
If you need to have different values for these attributes (depending on various conditions),
|
||||
you can use an `*ngIf` or an `*ngSwitch` on an `<iframe>` element:
|
||||
|
||||
```html
|
||||
<iframe *ngIf="someConditionA" sandbox="allow-scripts" src="..."></iframe>
|
||||
<iframe *ngIf="someConditionB" sandbox="allow-forms" src="..."></iframe>
|
||||
<iframe *ngIf="someConditionC" sandbox="allow-popups" src="..."></iframe>
|
||||
```
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-05-27
|
||||
@@ -14,7 +14,7 @@ NgModules can be declared with an `id`:
|
||||
export class MyModule {}
|
||||
```
|
||||
|
||||
Declaring an `id` makes the NgModule available for lookup via the `getNgModuleById()` operation. This functionality is rarely used, mainly in very specific bundling scenarios when lazily loading NgModules without obtaining direct references to them. In most Angular code, ES dynamic `import()` (`import('./path/to/module')`) should be used instead, as this provides a direct reference to the NgModule being loaded without the need for a global registration side-effect.
|
||||
Declaring an `id` makes the NgModule available for lookup via the `getNgModuleById()` operation. This functionality is rarely used, mainly in very specific bundling scenarios when lazily loading NgModules without obtaining direct references to them. In most Angular code, ES dynamic `import()` (`import('./path/to/module')`) should be used instead, as this provides a direct reference to the NgModule being loaded without the need for a global registration side effect.
|
||||
|
||||
If you are not using `getNgModuleById`, you do not need to provide `id`s for your NgModules. Providing one has a significant drawback: it makes the NgModule non-tree-shakable, which can have an impact on your bundle size.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('Component Communication Cookbook Tests', () => {
|
||||
describe('Parent-to-child communication', () => {
|
||||
// #docregion parent-to-child
|
||||
// ...
|
||||
const heroNames = ['Dr IQ', 'Magneta', 'Bombasto'];
|
||||
const heroNames = ['Dr. IQ', 'Magneta', 'Bombasto'];
|
||||
const masterName = 'Master';
|
||||
|
||||
it('should pass properties to children properly', async () => {
|
||||
@@ -30,7 +30,7 @@ describe('Component Communication Cookbook Tests', () => {
|
||||
// ...
|
||||
it('should display trimmed, non-empty names', async () => {
|
||||
const nonEmptyNameIndex = 0;
|
||||
const nonEmptyName = '"Dr IQ"';
|
||||
const nonEmptyName = '"Dr. IQ"';
|
||||
const parent = element(by.tagName('app-name-parent'));
|
||||
const hero = parent.all(by.tagName('app-name-child')).get(nonEmptyNameIndex);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ export interface Hero {
|
||||
}
|
||||
|
||||
export const HEROES = [
|
||||
{name: 'Dr IQ'},
|
||||
{name: 'Dr. IQ'},
|
||||
{name: 'Magneta'},
|
||||
{name: 'Bombasto'}
|
||||
];
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Component } from '@angular/core';
|
||||
`
|
||||
})
|
||||
export class NameParentComponent {
|
||||
// Displays 'Dr IQ', '<no name set>', 'Bombasto'
|
||||
names = ['Dr IQ', ' ', ' Bombasto '];
|
||||
// Displays 'Dr. IQ', '<no name set>', 'Bombasto'
|
||||
names = ['Dr. IQ', ' ', ' Bombasto '];
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@@ -17,7 +17,7 @@ import { Component } from '@angular/core';
|
||||
export class VoteTakerComponent {
|
||||
agreed = 0;
|
||||
disagreed = 0;
|
||||
voters = ['Dr IQ', 'Celeritas', 'Bombasto'];
|
||||
voters = ['Dr. IQ', 'Celeritas', 'Bombasto'];
|
||||
|
||||
onVoted(agreed: boolean) {
|
||||
if (agreed) {
|
||||
|
||||
@@ -8,7 +8,7 @@ export const HEROES: Hero[] = [
|
||||
{ id: 15, isSecret: false, name: 'Magneta' },
|
||||
{ id: 16, isSecret: false, name: 'RubberMan' },
|
||||
{ id: 17, isSecret: false, name: 'Dynama' },
|
||||
{ id: 18, isSecret: true, name: 'Dr IQ' },
|
||||
{ id: 18, isSecret: true, name: 'Dr. IQ' },
|
||||
{ id: 19, isSecret: true, name: 'Magma' },
|
||||
{ id: 20, isSecret: true, name: 'Tornado' }
|
||||
];
|
||||
|
||||
@@ -15,7 +15,7 @@ export class AdService {
|
||||
),
|
||||
new AdItem(
|
||||
HeroProfileComponent,
|
||||
{ name: 'Dr IQ', bio: 'Smart as they come' }
|
||||
{ name: 'Dr. IQ', bio: 'Smart as they come' }
|
||||
),
|
||||
new AdItem(
|
||||
HeroJobAdComponent,
|
||||
|
||||
@@ -14,7 +14,7 @@ export class HeroFormComponent {
|
||||
powers = ['Really Smart', 'Super Flexible',
|
||||
'Super Hot', 'Weather Changer'];
|
||||
|
||||
model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet');
|
||||
model = new Hero(18, 'Dr. IQ', this.powers[0], 'Chuck Overstreet');
|
||||
|
||||
// #docregion submitted
|
||||
submitted = false;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// #docregion import-http
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
// #docregion props
|
||||
import { Product } from './products';
|
||||
import { Injectable } from '@angular/core';
|
||||
// #enddocregion props, import-http
|
||||
|
||||
// #docregion props, methods, inject-http, get-shipping
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
// #docregion props, methods, inject-http, get-shipping
|
||||
export class CartService {
|
||||
// #enddocregion get-shipping
|
||||
items: Product[] = [];
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-manage-hereos',
|
||||
selector: 'app-manage-heroes',
|
||||
templateUrl: './manage-heroes.component.html',
|
||||
styleUrls: ['./manage-heroes.component.css']
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ export const HEROES: Hero[] = [
|
||||
{ id: 15, name: 'Magneta' },
|
||||
{ id: 16, name: 'RubberMan' },
|
||||
{ id: 17, name: 'Dynama' },
|
||||
{ id: 18, name: 'Dr IQ' },
|
||||
{ id: 18, name: 'Dr. IQ' },
|
||||
{ id: 19, name: 'Magma' },
|
||||
{ id: 20, name: 'Tornado' }
|
||||
];
|
||||
|
||||
+8
-1
@@ -13,6 +13,13 @@ export class CheckForUpdateService {
|
||||
const everySixHours$ = interval(6 * 60 * 60 * 1000);
|
||||
const everySixHoursOnceAppIsStable$ = concat(appIsStable$, everySixHours$);
|
||||
|
||||
everySixHoursOnceAppIsStable$.subscribe(() => updates.checkForUpdate());
|
||||
everySixHoursOnceAppIsStable$.subscribe(async () => {
|
||||
try {
|
||||
const updateFound = await updates.checkForUpdate();
|
||||
console.log(updateFound ? 'A new version is available.' : 'Already on the latest version.');
|
||||
} catch (err) {
|
||||
console.error('Failed to check for updates:', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+30
-10
@@ -1,20 +1,40 @@
|
||||
// #docplaster
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SwUpdate, UpdateAvailableEvent } from '@angular/service-worker';
|
||||
// #docregion sw-replicate-available
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
// #enddocregion sw-replicate-available
|
||||
import { SwUpdate, VersionReadyEvent } from '@angular/service-worker';
|
||||
|
||||
function promptUser(event: UpdateAvailableEvent): boolean {
|
||||
function promptUser(event: VersionReadyEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
// #docregion sw-activate
|
||||
// #docregion sw-version-ready
|
||||
@Injectable()
|
||||
export class PromptUpdateService {
|
||||
|
||||
constructor(updates: SwUpdate) {
|
||||
updates.available.subscribe(event => {
|
||||
if (promptUser(event)) {
|
||||
updates.activateUpdate().then(() => document.location.reload());
|
||||
}
|
||||
});
|
||||
constructor(swUpdate: SwUpdate) {
|
||||
swUpdate.versionUpdates
|
||||
.pipe(filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'))
|
||||
.subscribe(evt => {
|
||||
if (promptUser(evt)) {
|
||||
// Reload the page to update to the latest version.
|
||||
document.location.reload();
|
||||
}
|
||||
});
|
||||
// #enddocregion sw-version-ready
|
||||
// #docregion sw-replicate-available
|
||||
// ...
|
||||
const updatesAvailable = swUpdate.versionUpdates.pipe(
|
||||
filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'),
|
||||
map(evt => ({
|
||||
type: 'UPDATE_AVAILABLE',
|
||||
current: evt.currentVersion,
|
||||
available: evt.latestVersion,
|
||||
})));
|
||||
// #enddocregion sw-replicate-available
|
||||
// #docregion sw-version-ready
|
||||
}
|
||||
|
||||
}
|
||||
// #enddocregion sw-activate
|
||||
// #enddocregion sw-version-ready
|
||||
|
||||
@@ -497,7 +497,7 @@ describe('demo (with TestBed):', () => {
|
||||
@Component({ template: '<my-service-comp></my-service-comp>' })
|
||||
class TestComponent { }
|
||||
|
||||
// 3 levels of ValueService provider: module, TestCompomponent, TestProvidersComponent
|
||||
// 3 levels of ValueService provider: module, TestComponent, TestProvidersComponent
|
||||
const fixture = TestBed.configureTestingModule({
|
||||
declarations: [TestComponent, TestProvidersComponent],
|
||||
providers: [ValueService]
|
||||
|
||||
+2
@@ -6,6 +6,7 @@
|
||||
Trigger alert message
|
||||
</button>
|
||||
<!-- #enddocregion -->
|
||||
|
||||
<!-- #docregion bindings -->
|
||||
<p
|
||||
[id]="sayHelloId"
|
||||
@@ -13,4 +14,5 @@
|
||||
You can set my color in the component!
|
||||
</p>
|
||||
<!-- #enddocregion -->
|
||||
|
||||
<p>My color is {{ fontColor }}</p>
|
||||
|
||||
-1
@@ -15,5 +15,4 @@ export class HelloWorldBindingsComponent {
|
||||
alert(this.message);
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ Extended diagnostics should generally:
|
||||
* Detect a common, non-obvious developer mistake with Angular templates
|
||||
* Clearly articulate why this pattern can lead to bugs or unintended behavior
|
||||
* Suggest one or more clear solutions
|
||||
* Have a low \(preferrably zero\) false-positive rate
|
||||
* Have a low, preferably zero, false-positive rate
|
||||
* Apply to the vast majority of Angular applications \(not specific to an unofficial library\)
|
||||
* Improve program correctness or performance \(not style, that responsibility falls to a linter\)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
The web is used by a wide variety of people, including those who have visual or motor impairments.
|
||||
A variety of assistive technologies are available that make it much easier for these groups to interact with web-based software applications.
|
||||
In addition, designing an application to be more accessible generally improves the user experience for all users.
|
||||
Also, designing an application to be more accessible generally improves the user experience for all users.
|
||||
|
||||
For an in-depth introduction to issues and techniques for designing accessible applications, see the [Accessibility](https://developers.google.com/web/fundamentals/accessibility/#what_is_accessibility) section of the Google's [Web Fundamentals](https://developers.google.com/web/fundamentals).
|
||||
|
||||
@@ -16,10 +16,10 @@ For the sample application that this page describes, see the <live-example></liv
|
||||
|
||||
## Accessibility attributes
|
||||
|
||||
Building accessible web experience often involves setting [ARIA attributes](https://developers.google.com/web/fundamentals/accessibility/semantics-aria) to provide semantic meaning where it might otherwise be missing.
|
||||
Building accessible web experience often involves setting [Accessible Rich Internet Applications \(ARIA\) attributes](https://developers.google.com/web/fundamentals/accessibility/semantics-aria) to provide semantic meaning where it might otherwise be missing.
|
||||
Use [attribute binding](guide/attribute-binding) template syntax to control the values of accessibility-related attributes.
|
||||
|
||||
When binding to ARIA attributes in Angular, you must use the `attr.` prefix, as the ARIA specification depends specifically on HTML attributes rather than properties of DOM elements.
|
||||
When binding to ARIA attributes in Angular, you must use the `attr.` prefix. The ARIA specification depends specifically on HTML attributes rather than properties of DOM elements.
|
||||
|
||||
<code-example format="html" language="html">
|
||||
|
||||
@@ -67,7 +67,7 @@ For full details of these and other tools, see the [Angular CDK accessibility ov
|
||||
|
||||
### Augmenting native elements
|
||||
|
||||
Native HTML elements capture a number of standard interaction patterns that are important to accessibility.
|
||||
Native HTML elements capture several standard interaction patterns that are important to accessibility.
|
||||
When authoring Angular components, you should re-use these native elements directly when possible, rather than re-implementing well-supported behaviors.
|
||||
|
||||
For example, instead of creating a custom element for a new variety of button, create a component that uses an attribute selector with a native `<button>` element.
|
||||
@@ -79,8 +79,8 @@ You can see examples of this pattern in Angular Material:
|
||||
### Using containers for native elements
|
||||
|
||||
Sometimes using the appropriate native element requires a container element.
|
||||
For example, the native `<input>` element cannot have children, so any custom text entry components need to wrap an `<input>` with additional elements.
|
||||
While you might just include the `<input>` in your custom component's template, this makes it impossible for users of the component to set arbitrary properties and attributes to the input element.
|
||||
For example, the native `<input>` element cannot have children, so any custom text entry components need to wrap an `<input>` with extra elements.
|
||||
By just including `<input>` in your custom component's template, it's impossible for your component's users to set arbitrary properties and attributes to the `<input>` element.
|
||||
Instead, create a container component that uses content projection to include the native control in the component's API.
|
||||
|
||||
You can see [`MatFormField`](https://material.angular.io/components/form-field/overview) as an example of this pattern.
|
||||
@@ -121,13 +121,16 @@ router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() =>
|
||||
|
||||
</code-example>
|
||||
|
||||
In a real application, the element that receives focus will depend on your specific application structure and layout.
|
||||
In a real application, the element that receives focus depends on your specific application structure and layout.
|
||||
The focused element should put users in a position to immediately move into the main content that has just been routed into view.
|
||||
You should avoid situations where focus returns to the `body` element after a route change.
|
||||
|
||||
### Active links identification
|
||||
|
||||
CSS classes applied to active `RouterLink` elements (usually via `RouterLinkActive`) provide a visual indication regarding as to which link is currently active. Such indication doesn't apply to blind or visually impaired users, in order to provide such information the `aria-current` attribute should be applied to the element as well (for more information see [MDN aria-current](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)).
|
||||
CSS classes applied to active `RouterLink` elements, such as `RouterLinkActive`, provide a visual cue to identify the active link.
|
||||
Unfortunately, a visual cue doesn't help blind or visually impaired users.
|
||||
Applying the `aria-current` attribute to the element can help identify the active link.
|
||||
For more information, see [Mozilla Developer Network \(MDN\) aria-current](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)).
|
||||
|
||||
The `RouterLinkActive` directive provides the `ariaCurrentWhenActive` input which sets the `aria-current` to a specified value when the link becomes active.
|
||||
|
||||
@@ -153,7 +156,9 @@ The following example shows how to apply the `active-page` class to active links
|
||||
</nav>
|
||||
```
|
||||
|
||||
## Additional resources
|
||||
<!-- vale Angular.Angular_Spelling = NO -->
|
||||
|
||||
## More information
|
||||
|
||||
* [Accessibility - Google Web Fundamentals](https://developers.google.com/web/fundamentals/accessibility)
|
||||
* [ARIA specification and authoring practices](https://www.w3.org/TR/wai-aria)
|
||||
@@ -165,10 +170,16 @@ The following example shows how to apply the `active-page` class to active links
|
||||
* [Rob Dodson A11ycasts](https://www.youtube.com/watch?v=HtTyRajRuyY)
|
||||
* [Angular ESLint](https://github.com/angular-eslint/angular-eslint#functionality) provides linting rules that can help you make sure your code meets accessibility standards.
|
||||
|
||||
<!-- vale Angular.Angular_Spelling = YES -->
|
||||
|
||||
Books
|
||||
|
||||
* "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery
|
||||
* "Inclusive Design Patterns", Heydon Pickering
|
||||
<!-- vale Angular.Google_Quotes = NO -->
|
||||
|
||||
* "A Web for Everyone: Designing Accessible User Experiences," Sarah Horton and Whitney Quesenbery
|
||||
* "Inclusive Design Patterns," Heydon Pickering
|
||||
|
||||
<!-- vale Angular.Google_Quotes = YES -->
|
||||
|
||||
<!-- links -->
|
||||
|
||||
|
||||
@@ -5,28 +5,28 @@
|
||||
*AngularJS* is the name for all v1.x versions of Angular.
|
||||
|
||||
This guide helps you transition from AngularJS to Angular
|
||||
by mapping AngularJS syntax to the equivalent Angular syntax.
|
||||
by mapping AngularJS syntax to the corresponding Angular syntax.
|
||||
|
||||
**See the Angular syntax in this <live-example name="ajs-quick-reference"></live-example>**.
|
||||
|
||||
## Template basics
|
||||
|
||||
Templates are the user-facing part of an Angular application and are written in HTML.
|
||||
The following table lists some of the key AngularJS template features with their equivalent Angular template syntax.
|
||||
The following table lists some of the key AngularJS template features with their corresponding Angular template syntax.
|
||||
|
||||
### Bindings/interpolation → Bindings/interpolation
|
||||
### Bindings / interpolation → bindings / interpolation
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header>Bindings/interpolation</header> <code-example hideCopy format="html" language="html"> Your favorite hero is: {{vm.favoriteHero}} </code-example> In AngularJS, an expression in curly braces denotes one-way binding. This binds the value of the element to a property in the controller associated with this template. <br /> When using the `controller as` syntax, the binding is prefixed with the controller alias \(`vm` or `$ctrl`\) because you have to be specific about the source of the binding. | <header>Bindings/interpolation</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="interpolation"></code-example> In Angular, a template expression in curly braces still denotes one-way binding. This binds the value of the element to a property of the component. The context of the binding is implied and is always the associated component, so it needs no reference variable. <br /> For more information, see the [Interpolation][AioGuideInterpolation] guide. |
|
||||
| <header>Bindings/interpolation</header> <code-example hideCopy format="html" language="html"> Your favorite hero is: {{vm.favoriteHero}} </code-example> In AngularJS, an expression in curly braces denotes one-way binding. This binds the value of the element to a property in the controller associated with this template. <br /> When using the `controller as` syntax, the binding is prefixed with the controller alias `vm` or `$ctrl` because you have to be specific about the source. | <header>Bindings/interpolation</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="interpolation"></code-example> In Angular, a template expression in curly braces still denotes one-way binding. This binds the value of the element to a property of the component. The context of the binding is implied and is always the associated component, so it needs no reference variable. <br /> For more information, see the [Interpolation][AioGuideInterpolation] guide. |
|
||||
|
||||
### Filters → Pipes
|
||||
### Filters → pipes
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header>Filters</header> <code-example hideCopy format="html" language="html"> <td> 
 {{movie.title | uppercase}} 
 </td> </code-example> To filter output in AngularJS templates, use the pipe \(<code>|</code>\) character and one or more filters. <br /> This example filters the `title` property to uppercase. | <header>Pipes</header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="uppercase"></code-example> In Angular you use similar syntax with the pipe \(<code>|</code>\) character to filter output, but now you call them **pipes**. Many \(but not all\) of the built-in filters from AngularJS are built-in pipes in Angular. <br /> For more information, see [Filters/pipes][AioGuideAjsQuickReferenceFiltersPipes]. |
|
||||
| <header>Filters</header> <code-example hideCopy format="html" language="html"> <td> 
 {{movie.title | uppercase}} 
 </td> </code-example> To filter output in AngularJS templates, use the pipe <code>|</code> character and one or more filters. <br /> This example filters the `title` property to uppercase. | <header>Pipes</header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="uppercase"></code-example> In Angular you use similar syntax with the pipe <code>|</code> character to filter output, but now you call them **pipes**. Many, but not all, of the built-in filters from AngularJS are built-in pipes in Angular. <br /> For more information, see [Filters/pipes][AioGuideAjsQuickReferenceFiltersPipes]. |
|
||||
|
||||
### Local variables → Input variables
|
||||
### Local variables → input variables
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
@@ -38,7 +38,7 @@ AngularJS provides more than seventy built-in directives for templates.
|
||||
Many of them are not needed in Angular because of its more capable and expressive binding system.
|
||||
The following are some of the key AngularJS built-in directives and their equivalents in Angular.
|
||||
|
||||
### `ng-app` → Bootstrapping
|
||||
### `ng-app` → bootstrapping
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
@@ -48,7 +48,7 @@ The following are some of the key AngularJS built-in directives and their equiva
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-class</code></header> <code-example hideCopy format="html" language="html"> <div ng-class="{active: isActive}"> 
 <div ng-class="{active: isActive, shazam: isImportant}"> </code-example> In AngularJS, the `ng-class` directive includes/excludes CSS classes based on an expression. That expression is often a key-value control object with each key of the object defined as a CSS class name, and each value defined as a template expression that evaluates to a Boolean value. <br /> In the first example, the `active` class is applied to the element if `isActive` is true. <br /> You can specify multiple classes, as shown in the second example. | <header><code>ngClass</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngClass"></code-example> In Angular, the `ngClass` directive works similarly. It includes/excludes CSS classes based on an expression. <br /> In the first example, the `active` class is applied to the element if `isActive` is true. <br /> You can specify multiple classes, as shown in the second example. <br /> Angular also has **class binding**, which is a good way to add or remove a single class, as shown in the third example. <br /> For more information see [Attribute, class, and style bindings][AioGuideAttributeBinding] page. |
|
||||
| <header><code>ng-class</code></header> <code-example hideCopy format="html" language="html"> <div ng-class="{active: isActive}"> 
 <div ng-class="{active: isActive, shazam: isImportant}"> </code-example> In AngularJS, the `ng-class` directive includes/excludes CSS classes based on an expression. The expression is often a key-value object, with key defined as a CSS class name, and value as a template expression that evaluates to a Boolean. <br /> In the first example, the `active` class is applied to the element if `isActive` is true. <br /> You can specify multiple classes, as shown in the second example. | <header><code>ngClass</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngClass"></code-example> In Angular, the `ngClass` directive works similarly. It includes/excludes CSS classes based on an expression. <br /> In the first example, the `active` class is applied to the element if `isActive` is true. <br /> You can specify multiple classes, as shown in the second example. <br /> Angular also has **class binding**, which is a good way to add or remove a single class, as shown in the third example. <br /> For more information see [Attribute, class, and style bindings][AioGuideAttributeBinding] page. |
|
||||
|
||||
### `ng-click` → Bind to the `click` event
|
||||
|
||||
@@ -56,69 +56,69 @@ The following are some of the key AngularJS built-in directives and their equiva
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-click</code></header> <code-example hideCopy format="html" language="html"> <button ng-click="vm.toggleImage()"> 
 <button ng-click="vm.toggleImage($event)"> </code-example> In AngularJS, the `ng-click` directive allows you to specify custom behavior when an element is clicked. <br /> In the first example, when the user clicks the button, the `toggleImage()` method in the controller referenced by the `vm` `controller as` alias is executed. <br /> The second example demonstrates passing in the `$event` object, which provides details about the event to the controller. | <header>Bind to the <code>click</code> event</header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="event-binding"></code-example> AngularJS event-based directives do not exist in Angular. Rather, define one-way binding from the template view to the component using **event binding**. <br /> For event binding, define the name of the target event within parenthesis and specify a template statement, in quotes, to the right of the equals. Angular then sets up an event handler for the target event. When the event is raised, the handler executes the template statement. <br /> In the first example, when a user clicks the button, the `toggleImage()` method in the associated component is executed. <br /> The second example demonstrates passing in the `$event` object, which provides details about the event to the component. <br /> For a list of DOM events, see [Event reference][MdnDocsWebEvents]. <br /> For more information, see the [Event binding][AioGuideEventBinding] page. |
|
||||
|
||||
### `ng-controller` → Component decorator
|
||||
### `ng-controller` → component decorator
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-controller</code></header> <code-example hideCopy format="html" language="html"> <div ng-controller="MovieListCtrl as vm"> </code-example> In AngularJS, the `ng-controller` directive attaches a controller to the view. Using the `ng-controller` \(or defining the controller as part of the routing\) ties the view to the controller code associated with that view. | <header>Component decorator</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component"></code-example> In Angular, the template no longer specifies its associated controller. Rather, the component specifies its associated template as part of the component class decorator. <br /> For more information, see [Architecture Overview][AioGuideArchitectureComponents]. |
|
||||
| <header><code>ng-controller</code></header> <code-example hideCopy format="html" language="html"> <div ng-controller="MovieListCtrl as vm"> </code-example> In AngularJS, the `ng-controller` directive attaches a controller to the view. Using the `ng-controller`, or defining the controller as part of the routing, ties the view to the controller code associated with that view. | <header>Component decorator</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component"></code-example> In Angular, the template no longer specifies its associated controller. Rather, the component specifies its associated template as part of the component class decorator. <br /> For more information, see [Architecture Overview][AioGuideArchitectureComponents]. |
|
||||
|
||||
### `ng-hide` → Bind to the `hidden` property
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-hide</code></header> In AngularJS, the `ng-hide` directive shows or hides the associated HTML element based on an expression. For more information, see [ng-show][AioGuideAjsQuickReferenceTemplateDirectives]. | <header>Bind to the <code>hidden</code> property</header> In Angular, you use property binding; there is no built-in *hide* directive. For more information, see [ng-show][AioGuideAjsQuickReferenceTemplateDirectives]. |
|
||||
| <header><code>ng-hide</code></header> In AngularJS, the `ng-hide` directive shows or hides the associated HTML element based on an expression. For more information, see [ng-show][AioGuideAjsQuickReferenceTemplateDirectives]. | <header>Bind to the <code>hidden</code> property</header> In Angular, you use property binding. Angular does not have a built-in *hide* directive. For more information, see [ng-show][AioGuideAjsQuickReferenceTemplateDirectives]. |
|
||||
|
||||
### `ng-href` → Bind to the `href` property
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-href</code></header> <code-example hideCopy format="html" language="html"> <a ng-href="{{ angularDocsUrl }}"> 
 Angular Docs 
 </a> </code-example> The `ng-href` directive allows AngularJS to preprocess the `href` property so that it can replace the binding expression with the appropriate URL before the browser fetches from that URL. <br /> In AngularJS, the `ng-href` is often used to activate a route as part of navigation. <br /> <code-example hideCopy format="html" language="html"> <a ng-href="#{{ moviesHash }}"> 
 Movies 
</a> </code-example> Routing is handled differently in Angular. | <header>Bind to the <code>href</code> property</header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="href"></code-example> Angular uses property binding; there is no built-in *href* directive. Place the `href` property of the element in square brackets and set it to a quoted template expression. For more information see the [Property binding][AioGuidePropertyBinding] page. In Angular, `href` is no longer used for routing. Routing uses `routerLink`, as shown in the following example. <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="router-link"></code-example> For more information on routing, see [Defining a basic route][AioGuideRouterDefiningABasicRoute] in the [Routing & Navigation][AioGuideRouter] page. |
|
||||
| <header><code>ng-href</code></header> <code-example hideCopy format="html" language="html"> <a ng-href="{{ angularDocsUrl }}"> 
 Angular Docs 
 </a> </code-example> The `ng-href` directive allows AngularJS to preprocess the `href` property. `ng-href` can replace the binding expression with the appropriate URL before the browser fetches from that URL. <br /> In AngularJS, the `ng-href` is often used to activate a route as part of navigation. <br /> <code-example hideCopy format="html" language="html"> <a ng-href="#{{ moviesHash }}"> 
 Movies 
</a> </code-example> Routing is handled differently in Angular. | <header>Bind to the <code>href</code> property</header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="href"></code-example> Angular uses property binding. Angular does not have a built-in *href* directive. Place the `href` property of the element in square brackets and set it to a quoted template expression. For more information see the [Property binding][AioGuidePropertyBinding] page. In Angular, `href` is no longer used for routing. Routing uses `routerLink`, as shown in the following example. <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="router-link"></code-example> For more information on routing, see [Defining a basic route][AioGuideRouterDefiningABasicRoute] in the [Routing & Navigation][AioGuideRouter] page. |
|
||||
|
||||
### `ng-if` → `*ngIf`
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-if</code></header> <code-example hideCopy format="html" language="html"> <table ng-if="movies.length"> </code-example> In AngularJS, the `ng-if` directive removes or recreates a portion of the DOM, based on an expression. If the expression is false, the element is removed from the DOM. <br /> In this example, the `<table>` element is removed from the DOM unless the `movies` array has a length greater than zero. | <header><code>*ngIf</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngIf"></code-example> The `*ngIf` directive in Angular works the same as the `ng-if` directive in AngularJS. It removes or recreates a portion of the DOM based on an expression. <br /> In this example, the `<table>` element is removed from the DOM unless the `movies` array has a length. <br /> The \(`*`\) before `ngIf` is required in this example. For more information, see [Structural Directives][AioGuideStructuralDirectives]. |
|
||||
| <header><code>ng-if</code></header> <code-example hideCopy format="html" language="html"> <table ng-if="movies.length"> </code-example> In AngularJS, the `ng-if` directive removes or recreates a section of the DOM, based on an expression. If the expression is false, the element is removed from the DOM. <br /> In this example, the `<table>` element is removed from the DOM unless the `movies` array has a length greater than zero. | <header><code>*ngIf</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngIf"></code-example> The `*ngIf` directive in Angular works the same as the `ng-if` directive in AngularJS. It removes or recreates a section of the DOM based on an expression. <br /> In this example, the `<table>` element is removed from the DOM unless the `movies` array has a length. <br /> The \(`*`\) before `ngIf` is required in this example. For more information, see [Structural Directives][AioGuideStructuralDirectives]. |
|
||||
|
||||
### `ng-model` → `ngModel`
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-model</code></header> <code-example hideCopy format="html" language="html"> <input ng-model="vm.favoriteHero" /> </code-example> In AngularJS, the `ng-model` directive binds a form control to a property in the controller associated with the template. This provides **two-way binding**, whereby any change made to the value in the view is synchronized with the model, and any change to the model is synchronized with the value in the view. | <header><code>ngModel</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngModel"></code-example> In Angular, **two-way binding** is indicatedr5t by `[()]`, descriptively referred to as a "banana in a box". This syntax is a shortcut for defining both property binding \(from the component to the view\) and event binding \(from the view to the component\), thereby providing two-way binding. <br /> For more information on two-way binding with `ngModel`, see the [Displaying and updating properties with `ngModel`][AioGuideBuiltInDirectivesDisplayingAndUpdatingPropertiesWithNgmodel] section of [Built-in directives][AioGuideBuiltInDirectives]. |
|
||||
| <header><code>ng-model</code></header> <code-example hideCopy format="html" language="html"> <input ng-model="vm.favoriteHero" /> </code-example> In AngularJS, the `ng-model` directive binds a form control to a property in the controller associated with the template. This provides **two-way binding** whereby changes result in the value in the view and the model being synchronized. | <header><code>ngModel</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngModel"></code-example> In Angular, **two-way binding** is indicatedr5t by `[()]`, descriptively referred to as a "banana in a box." This syntax is a shortcut for defining both:<ul><li>property binding, from the component to the view</li><li>event binding, from the view to the component</li></ul> thereby providing two-way binding. <br /> For more information on two-way binding with `ngModel`, see the [Displaying and updating properties with `ngModel`][AioGuideBuiltInDirectivesDisplayingAndUpdatingPropertiesWithNgmodel] section of [Built-in directives][AioGuideBuiltInDirectives]. |
|
||||
|
||||
### `ng-repeat` → `*ngFor`
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-repeat</code></header> <code-example hideCopy format="html" language="html"> <tr ng-repeat="movie in vm.movies"> </code-example> In AngularJS, the `ng-repeat` directive repeats the associated DOM element for each item in the specified collection. <br /> In this example, the table row \(`<tr>`\) element repeats for each movie object in the collection of movies. | <header><code>*ngFor</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngFor"></code-example> The `*ngFor` directive in Angular is similar to the `ng-repeat` directive in AngularJS. It repeats the associated DOM element for each item in the specified collection. More accurately, it turns the defined element \(`<tr>` in this example\) and its contents into a template and uses that template to instantiate a view for each item in the list. <br /> Notice the other syntax differences: The \(`*`\) before `ngFor` is required; the `let` keyword identifies `movie` as an input variable; the list preposition is `of`, not `in`. <br /> For more information, see [Structural Directives][AioGuideStructuralDirectives]. |
|
||||
| <header><code>ng-repeat</code></header> <code-example hideCopy format="html" language="html"> <tr ng-repeat="movie in vm.movies"> </code-example> In AngularJS, the `ng-repeat` directive repeats the associated DOM element for each item in the specified collection. <br /> In this example, the table row \(`<tr>`\) element repeats for each movie object in the collection of movies. | <header><code>*ngFor</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngFor"></code-example> The `*ngFor` directive in Angular is like the `ng-repeat` directive in AngularJS. It repeats the associated DOM element for each item in the specified collection. More accurately, it turns the defined element \(`<tr>` in this example\) and its contents into a template and uses that template to instantiate a view for each item in the list. <br /> Notice the other syntax differences: <ul><li>The \(`*`\) before `ngFor` is required</li><li>The `let` keyword identifies `movie` as an input variable</li><li>The list preposition is `of`, not `in`</li></ul>For more information, see [Structural Directives][AioGuideStructuralDirectives]. |
|
||||
|
||||
### `ng-show` → Bind to the `hidden` property
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-show</code></header> <code-example hideCopy format="html" language="html"> <h3 ng-show="vm.favoriteHero"> 
 Your favorite hero is: {{vm.favoriteHero}} 
 </h3> </code-example> In AngularJS, the `ng-show` directive shows or hides the associated DOM element, based on an expression. <br /> In this example, the `<div>` element is shown if the `favoriteHero` variable is truthy. | <header>Bind to the <code>hidden</code> property</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="hidden"></code-example> Angular uses property binding; there is no built-in *show* directive. For hiding and showing elements, bind to the HTML `hidden` property. <br /> To conditionally display an element, place the `hidden` property of the element in square brackets and set it to a quoted template expression that evaluates to the *opposite* of *show*. <br /> In this example, the `<div>` element is hidden if the `favoriteHero` variable is not truthy. <br /> For more information on property binding, see the [Property binding][AioGuidePropertyBinding] page. |
|
||||
| <header><code>ng-show</code></header> <code-example hideCopy format="html" language="html"> <h3 ng-show="vm.favoriteHero"> 
 Your favorite hero is: {{vm.favoriteHero}} 
 </h3> </code-example> In AngularJS, the `ng-show` directive shows or hides the associated DOM element, based on an expression. <br /> In this example, the `<div>` element is shown if the `favoriteHero` variable is truthy. | <header>Bind to the <code>hidden</code> property</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="hidden"></code-example> Angular uses property binding. Angular has no built-in *show* directive. For hiding and showing elements, bind to the HTML `hidden` property. <br /> To conditionally display an element the `hidden` property of the element can be used. Place the `hidden` property in square brackets and set it to a quoted template expression that evaluates to the *opposite* of *show*. <br /> In this example, the `<div>` element is hidden if the `favoriteHero` variable is not truthy. <br /> For more information on property binding, see the [Property binding][AioGuidePropertyBinding] page. |
|
||||
|
||||
### `ng-src` → Bind to the `src` property
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-src</code></header> <code-example hideCopy format="html" language="html"> <img ng-src="{{movie.imageurl}}"> </code-example> The `ng-src` directive allows AngularJS to preprocess the `src` property so that it can replace the binding expression with the appropriate URL before the browser fetches from that URL. | <header>Bind to the <code>src</code> property</header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="src"></code-example> Angular uses property binding; there is no built-in *src* directive. Place the `src` property in square brackets and set it to a quoted template expression. <br /> For more information on property binding, see the [Property binding][AioGuidePropertyBinding] page. |
|
||||
| <header><code>ng-src</code></header> <code-example hideCopy format="html" language="html"> <img ng-src="{{movie.imageurl}}"> </code-example> The `ng-src` directive allows AngularJS to preprocess the `src` property. This replaces the binding expression with the appropriate URL before the browser fetches from that URL. | <header>Bind to the <code>src</code> property</header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="src"></code-example> Angular uses property binding. Angular has no built-in *src* directive. Place the `src` property in square brackets and set it to a quoted template expression. <br /> For more information on property binding, see the [Property binding][AioGuidePropertyBinding] page. |
|
||||
|
||||
### `ng-style` → `ngStyle`
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-style</code></header> <code-example hideCopy format="html" language="html"> <div ng-style="{color: colorPreference}"> </code-example> In AngularJS, the `ng-style` directive sets a CSS style on an HTML element based on an expression. That expression is often a key-value control object with each key of the object defined as a CSS property, and each value defined as an expression that evaluates to a value appropriate for the style. <br /> In the example, the `color` style is set to the current value of the `colorPreference` variable. | <header><code>ngStyle</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngStyle"></code-example> In Angular, the `ngStyle` directive works similarly. It sets a CSS style on an HTML element based on an expression. <br /> In the first example, the `color` style is set to the current value of the `colorPreference` variable. <br /> Angular also has **style binding**, which is good way to set a single style. This is shown in the second example. <br /> For more information on style binding, see the [Style binding][AioGuideAttributeBindingBindingToTheStyleAttribute] section of the [Attribute binding][AioGuideAttributeBinding] page. <br /> For more information on the `ngStyle` directive, see the [NgStyle][AioGuideBuiltInDirectivesSettingInlineStylesWithNgstyle] section of the [Built-in directives][AioGuideBuiltInDirectives] page. |
|
||||
| <header><code>ng-style</code></header> <code-example hideCopy format="html" language="html"> <div ng-style="{color: colorPreference}"> </code-example> In AngularJS, the `ng-style` directive sets a CSS style on an HTML element based on an expression. That expression is often a key-value control object with: <ul><li> each key of the object defined as a CSS property</li><li>each value defined as an expression that evaluates to a value appropriate for the style</li></ul> In the example, the `color` style is set to the current value of the `colorPreference` variable. | <header><code>ngStyle</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngStyle"></code-example> In Angular, the `ngStyle` directive works similarly. It sets a CSS style on an HTML element based on an expression. <br /> In the first example, the `color` style is set to the current value of the `colorPreference` variable. <br /> Angular also has **style binding**, which is good way to set a single style. This is shown in the second example. <br /> For more information on style binding, see the [Style binding][AioGuideAttributeBindingBindingToTheStyleAttribute] section of the [Attribute binding][AioGuideAttributeBinding] page. <br /> For more information on the `ngStyle` directive, see the [NgStyle][AioGuideBuiltInDirectivesSettingInlineStylesWithNgstyle] section of the [Built-in directives][AioGuideBuiltInDirectives] page. |
|
||||
|
||||
### `ng-switch` → `ngSwitch`
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>ng-switch</code></header> <code-example hideCopy format="html" language="html"> <div ng-switch="vm.favoriteHero && vm.checkMovieHero(vm.favoriteHero)"> 
 <div ng-switch-when="true"> 
 Excellent choice. 
 </div> 
 <div ng-switch-when="false"> 
 No movie, sorry. 
 </div> 
 <div ng-switch-default> 
 Please enter your favorite hero. 
 </div> 
 </div> </code-example> In AngularJS, the `ng-switch` directive swaps the contents of an element by selecting one of the templates based on the current value of an expression. <br /> In this example, if `favoriteHero` is not set, the template displays "Please enter …". If `favoriteHero` is set, it checks the movie hero by calling a controller method. If that method returns `true`, the template displays "Excellent choice!". If that methods returns `false`, the template displays "No movie, sorry!". | <header><code>ngSwitch</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngSwitch"></code-example> In Angular, the `ngSwitch` directive works similarly. It displays an element whose `*ngSwitchCase` matches the current `ngSwitch` expression value. <br /> In this example, if `favoriteHero` is not set, the `ngSwitch` value is `null` and `*ngSwitchDefault` displays, "Please enter …". If `favoriteHero` is set, the application checks the movie hero by calling a component method. If that method returns `true`, the application selects `*ngSwitchCase="true"` and displays: "Excellent choice!" If that methods returns `false`, the application selects `*ngSwitchCase="false"` and displays: "No movie, sorry!" <br /> The \(`*`\) before `ngSwitchCase` and `ngSwitchDefault` is required in this example. <br /> For more information, see [The NgSwitch directives][AioGuideBuiltInDirectivesSwitchingCasesWithNgswitch] section of the [Built-in directives][AioGuideBuiltInDirectives] page. |
|
||||
| <header><code>ng-switch</code></header> <code-example hideCopy format="html" language="html"> <div ng-switch="vm.favoriteHero && vm.checkMovieHero(vm.favoriteHero)"> 
 <div ng-switch-when="true"> 
 Excellent choice. 
 </div> 
 <div ng-switch-when="false"> 
 No movie, sorry. 
 </div> 
 <div ng-switch-default> 
 Please enter your favorite hero. 
 </div> 
 </div> </code-example> In AngularJS, the `ng-switch` directive swaps the contents of an element by selecting one of the templates based on the current value of an expression. <br /> In this example, if `favoriteHero` is not set, the template displays "Please enter …" If `favoriteHero` is set, it checks the movie hero by calling a controller method. If that method returns `true`, the template displays "Excellent choice!" If that methods returns `false`, the template displays "No movie, sorry!" | <header><code>ngSwitch</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngSwitch"></code-example> In Angular, the `ngSwitch` directive works similarly. It displays an element whose `*ngSwitchCase` matches the current `ngSwitch` expression value. <br /> In this example, if `favoriteHero` is not set, the `ngSwitch` value is `null` and `*ngSwitchDefault` displays, "Please enter your favorite hero." If `favoriteHero` is set, the application checks the movie hero by calling a component method. If that method returns `true`, the application selects `*ngSwitchCase="true"` and displays: "Excellent choice." If that methods returns `false`, the application selects `*ngSwitchCase="false"` and displays: "No movie, sorry." <br /> The \(`*`\) before `ngSwitchCase` and `ngSwitchDefault` is required in this example. <br /> For more information, see [The NgSwitch directives][AioGuideBuiltInDirectivesSwitchingCasesWithNgswitch] section of the [Built-in directives][AioGuideBuiltInDirectives] page. |
|
||||
|
||||
## Filters/pipes
|
||||
## Filters / pipes
|
||||
|
||||
Angular **pipes** provide formatting and transformation for data in the template, similar to AngularJS **filters**.
|
||||
Angular **pipes** provide formatting and transformation for data in the template, like AngularJS **filters**.
|
||||
Many of the built-in filters in AngularJS have corresponding pipes in Angular.
|
||||
For more information on pipes, see [Pipes][AioGuidePipes].
|
||||
|
||||
@@ -150,7 +150,7 @@ For more information on pipes, see [Pipes][AioGuidePipes].
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>limitTo</code></header> <code-example hideCopy format="html" language="html"> <tr ng-repeat="movie in movieList | limitTo:2:0"> </code-example> Selects up to the first parameter \(2\) number of items from the collection starting \(optionally\) at the beginning index \(0\). | <header><code>slice</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="slice"></code-example> The `SlicePipe` does the same thing but the *order of the parameters is reversed*, in keeping with the JavaScript `Slice` method. The first parameter is the starting index; the second is the limit. As in AngularJS, coding this operation within the component instead could improve performance. |
|
||||
| <header><code>limitTo</code></header> <code-example hideCopy format="html" language="html"> <tr ng-repeat="movie in movieList | limitTo:2:0"> </code-example> Selects up to the first parameter `2` number of items from the collection starting optionally at the beginning index `0`. | <header><code>slice</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="slice"></code-example> The `SlicePipe` does the same thing but the *order of the parameters is reversed*, in keeping with the JavaScript `Slice` method. The first parameter is the starting index and the second is the limit. As in AngularJS, coding this operation within the component instead could improve performance. |
|
||||
|
||||
### `lowercase` → `lowercase`
|
||||
|
||||
@@ -162,7 +162,7 @@ For more information on pipes, see [Pipes][AioGuidePipes].
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>number</code></header> <code-example hideCopy format="html" language="html"> <td> 
 {{movie.starRating | number}} 
 </td> </code-example> Formats a number as text. | <header><code>number</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="number"></code-example> The Angular [`number`][AioApiCommonDecimalpipe] pipe is similar. It provides more functionality when defining the decimal places, as shown in the second example above. <br /> Angular also has a `percent` pipe, which formats a number as a local percentage as shown in the third example. |
|
||||
| <header><code>number</code></header> <code-example hideCopy format="html" language="html"> <td> 
 {{movie.starRating | number}} 
 </td> </code-example> Formats a number as text. | <header><code>number</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="number"></code-example> The Angular [`number`][AioApiCommonDecimalpipe] pipe is similar. It provides more capabilities when defining the decimal places, as shown in the preceding second example. <br /> Angular also has a `percent` pipe, which formats a number as a local percentage as shown in the third example. |
|
||||
|
||||
### `orderBy` → none
|
||||
|
||||
@@ -170,9 +170,9 @@ For more information on pipes, see [Pipes][AioGuidePipes].
|
||||
|:--- |:--- |
|
||||
| <header><code>orderBy</code></header> <code-example hideCopy format="html" language="html"> <tr ng-repeat="movie in movieList | orderBy : 'title'"> </code-example> Displays the collection in the order specified by the expression. In this example, the movie title orders the `movieList`. | <header>none</header> For performance reasons, no comparable pipe exists in Angular. Instead, use component code to order or sort results. If you need the same ordering or sorting code in several templates, consider building a custom pipe. |
|
||||
|
||||
## Modules/controllers/components
|
||||
## Modules / controllers / components
|
||||
|
||||
In both AngularJS and Angular, modules help you organize your application into cohesive blocks of functionality.
|
||||
In both AngularJS and Angular, modules help you organize your application into cohesive blocks of features.
|
||||
|
||||
In AngularJS, you write the code that provides the model and the methods for the view in a **controller**.
|
||||
In Angular, you build a **component**.
|
||||
@@ -180,11 +180,11 @@ In Angular, you build a **component**.
|
||||
Because much AngularJS code is in JavaScript, JavaScript code is shown in the AngularJS column.
|
||||
The Angular code is shown using TypeScript.
|
||||
|
||||
### IIFE → none
|
||||
### Immediately invoked function expression (IIFE) → none
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header>IIFE</header> <code-example hideCopy format="typescript" language="typescript"> ( 
 function () { 
 … 
 }() 
); </code-example> In AngularJS, an immediately invoked function expression \(or IIFE\) around controller code keeps it out of the global namespace. | <header>none</header> This is a nonissue in Angular because ES 2015 modules handle the namespacing for you. <br /> For more information on modules, see the [Modules][AioGuideArchitectureModules] section of the [Architecture Overview][AioGuideArchitecture]. |
|
||||
| <header>IIFE</header> <code-example hideCopy format="typescript" language="typescript"> ( 
 function () { 
 … 
 }() 
); </code-example> In AngularJS, an IIFE around controller code keeps it out of the global namespace. | <header>none</header> This is a nonissue in Angular because ES 2015 modules handle the namespace for you. <br /> For more information on modules, see the [Modules][AioGuideArchitectureModules] section of the [Architecture Overview][AioGuideArchitecture]. |
|
||||
|
||||
### Angular modules → `NgModules`
|
||||
|
||||
@@ -192,19 +192,19 @@ The Angular code is shown using TypeScript.
|
||||
|:--- |:--- |
|
||||
| <header>Angular modules</header> <code-example hideCopy format="typescript" language="typescript"> angular .module( 
 "movieHunter", 
 [ 
 "ngRoute" 
 ] 
); </code-example> In AngularJS, an Angular module keeps track of controllers, services, and other code. The second argument defines the list of other modules that this module depends upon. | <header><code>NgModules</code></header> <code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts"></code-example> NgModules, defined with the `NgModule` decorator, serve the same purpose: <ul> <li>`imports`: specifies the list of other modules that this module depends upon</li> <li>`declaration`: keeps track of your components, pipes, and directives.</li> </ul> For more information on modules, see [NgModules][AioGuideNgmodules]. |
|
||||
|
||||
### Controller registration → Component decorator
|
||||
### Controller registration → component decorator
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header>Controller registration</header> <code-example hideCopy format="typescript" language="typescript"> angular .module( 
 "movieHunter" 
) .controller( 
 "MovieListCtrl", 
 [ 
 "movieService", 
 MovieListCtrl 
 ] 
); </code-example> AngularJS has code in each controller that looks up an appropriate Angular module and registers the controller with that module. <br /> The first argument is the controller name. The second argument defines the string names of all dependencies injected into this controller, and a reference to the controller function. | <header>Component decorator</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component"></code-example> Angular adds a decorator to the component class to provide any required metadata. The `@Component` decorator declares that the class is a component and provides metadata about that component such as its selector \(or tag\) and its template. <br /> This is how you associate a template with logic, which is defined in the component class. <br /> For more information, see the [Components][AioGuideArchitectureComponents] section of the [Architecture Overview][AioGuideArchitecture] page. |
|
||||
| <header>Controller registration</header> <code-example hideCopy format="typescript" language="typescript"> angular .module( 
 "movieHunter" 
) .controller( 
 "MovieListCtrl", 
 [ 
 "movieService", 
 MovieListCtrl 
 ] 
); </code-example> AngularJS has code in each controller that looks up an appropriate Angular module and registers the controller with that module. <br /> The first argument is the controller name. The second argument defines the string names of all dependencies injected into this controller, and a reference to the controller function. | <header>Component decorator</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component"></code-example> Angular adds a decorator to the component class to provide any required metadata. The `@Component` decorator declares that the class is a component and provides metadata about that component such as its selector, or tag, and its template. <br /> This is how you associate a template with logic, which is defined in the component class. <br /> For more information, see the [Components][AioGuideArchitectureComponents] section of the [Architecture Overview][AioGuideArchitecture] page. |
|
||||
|
||||
### Controller function → Component class
|
||||
### Controller function → component class
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header>Controller function</header> <code-example hideCopy format="typescript" language="typescript"> function MovieListCtrl(movieService) { 
 } </code-example> In AngularJS, you write the code for the model and methods in a controller function. | <header>Component class</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="class"></code-example> In Angular, you create a component class to contain the data model and control methods. Use the TypeScript <code>export</code> keyword to export the class so that the functionality can be imported into NgModules. <br /> For more information, see the [Components][AioGuideArchitectureComponents] section of the [Architecture Overview][AioGuideArchitecture] page. |
|
||||
| <header>Controller function</header> <code-example hideCopy format="typescript" language="typescript"> function MovieListCtrl(movieService) { 
 } </code-example> In AngularJS, you write the code for the model and methods in a controller function. | <header>Component class</header> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="class"></code-example> In Angular, you create a component class to contain the data model and control methods. Use the TypeScript <code>export</code> keyword to export the class so that the component can be imported into NgModules. <br /> For more information, see the [Components][AioGuideArchitectureComponents] section of the [Architecture Overview][AioGuideArchitecture] page. |
|
||||
|
||||
### Dependency injection → Dependency injection
|
||||
### Dependency injection → dependency injection
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
@@ -216,20 +216,20 @@ Style sheets give your application a nice look.
|
||||
In AngularJS, you specify the style sheets for your entire application.
|
||||
As the application grows over time, the styles for the many parts of the application merge, which can cause unexpected results.
|
||||
In Angular, you can still define style sheets for your entire application.
|
||||
But now you can also encapsulate a style sheet within a specific component.
|
||||
Now you can also encapsulate a style sheet within a specific component.
|
||||
|
||||
### `Link` tag → `styles` configuration or `styleUrls`
|
||||
|
||||
| AngularJS | Angular |
|
||||
|:--- |:--- |
|
||||
| <header><code>Link</code> tag</header> <code-example hideCopy format="html" language="html"> <link href="styles.css" 
 rel="stylesheet" /> </code-example> AngularJS, uses a `link` tag in the head section of the `index.html` file to define the styles for the application. | <header><code>styles</code> configuration</header> <code-example hideCopy path="ajs-quick-reference/.angular-cli.1.json" region="styles"></code-example> With the Angular CLI, you can configure your global styles in the `angular.json` file. You can rename the extension to `.scss` to use sass. <br /><br /> <header><code>styleUrls</code></header> In Angular, you can use the `styles` or `styleUrls` property of the `@Component` metadata to define a style sheet for a particular component. <br /> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="style-url"></code-example> This allows you to set appropriate styles for individual components that will not leak into other parts of the application. |
|
||||
| <header><code>Link</code> tag</header> <code-example hideCopy format="html" language="html"> <link href="styles.css" 
 rel="stylesheet" /> </code-example> AngularJS, uses a `link` tag in the head section of the `index.html` file to define the styles for the application. | <header><code>styles</code> configuration</header> <code-example hideCopy path="ajs-quick-reference/.angular-cli.1.json" region="styles"></code-example> With the Angular CLI, you can configure your global styles in the `angular.json` file. You can rename the extension to `.scss` to use sass. <br /><br /> <header><code>styleUrls</code></header> In Angular, you can use the `styles` or `styleUrls` property of the `@Component` metadata to define a style sheet for a particular component. <br /> <code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="style-url"></code-example> This allows you to set appropriate styles for individual components that do not leak into other parts of the application. |
|
||||
|
||||
<!-- links -->
|
||||
|
||||
[AioApiCommonDecimalpipe]: api/common/DecimalPipe "DecimalPipe | @angular/common - API | Angular"
|
||||
[AioApiCommonJsonpipe]: api/common/JsonPipe "JsonPipe | @angular/common - API | Angular"
|
||||
|
||||
[AioGuideAjsQuickReferenceFiltersPipes]: guide/ajs-quick-reference#filterspipes "Filters/pipes - AngularJS to Angular concepts: Quick reference | Angular"
|
||||
[AioGuideAjsQuickReferenceFiltersPipes]: guide/ajs-quick-reference#filters--pipes "Filters/pipes - AngularJS to Angular concepts: Quick reference | Angular"
|
||||
[AioGuideAjsQuickReferenceTemplateDirectives]: guide/ajs-quick-reference#template-directives "Template directives - AngularJS to Angular concepts: Quick reference | Angular"
|
||||
|
||||
[AioGuideArchitecture]: guide/architecture "Introduction to Angular concepts | Angular"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Angular compiler options
|
||||
|
||||
When you use [AOT compilation](guide/aot-compiler), you can control how your application is compiled by specifying *template* compiler options in the [TypeScript configuration file](guide/typescript-configuration).
|
||||
When you use [ahead-of-time compilation (AOT)](guide/aot-compiler), you can control how your application is compiled by specifying *template* compiler options in the [TypeScript configuration file](guide/typescript-configuration).
|
||||
|
||||
The template options object, `angularCompilerOptions`, is a sibling to the `compilerOptions` object that supplies standard options to the TypeScript compiler.
|
||||
|
||||
@@ -28,7 +28,7 @@ The following options are available for configuring the AOT template compiler.
|
||||
|
||||
### `allowEmptyCodegenFiles`
|
||||
|
||||
When `true`, generate all possible files even if they are empty.
|
||||
When `true`, create all possible files even if they are empty.
|
||||
Default is `false`.
|
||||
Used by the Bazel build rules to simplify how Bazel rules track file dependencies.
|
||||
Do not use this option outside of the Bazel rules.
|
||||
@@ -37,7 +37,7 @@ Do not use this option outside of the Bazel rules.
|
||||
|
||||
Modifies how Angular-specific annotations are emitted to improve tree-shaking.
|
||||
Non-Angular annotations are not affected.
|
||||
One of `static fields` \(the default\) or `decorators`.
|
||||
One of `static fields` or `decorators`. The default value is `static fields`.
|
||||
|
||||
* By default, the compiler replaces decorators with a static field in the class, which allows advanced tree-shakers like [Closure compiler](https://github.com/google/closure-compiler) to remove unused classes
|
||||
* The `decorators` value leaves the decorators in place, which makes compilation faster.
|
||||
@@ -47,15 +47,19 @@ One of `static fields` \(the default\) or `decorators`.
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**NOTE**: <br />
|
||||
That the resulting code will not properly tree-shake.
|
||||
That the resulting code cannot tree-shake properly.
|
||||
|
||||
</div>
|
||||
|
||||
### `annotateForClosureCompiler`
|
||||
|
||||
<!-- vale Angular.Angular_Spelling = NO -->
|
||||
|
||||
When `true`, use [Tsickle](https://github.com/angular/tsickle) to annotate the emitted JavaScript with [JSDoc](https://jsdoc.app) comments needed by the [Closure Compiler](https://github.com/google/closure-compiler).
|
||||
Default is `false`.
|
||||
|
||||
<!-- vale Angular.Angular_Spelling = YES -->
|
||||
|
||||
### `compilationMode`
|
||||
|
||||
Specifies the compilation mode to use.
|
||||
@@ -70,61 +74,61 @@ The default value is `'full'`.
|
||||
|
||||
### `disableExpressionLowering`
|
||||
|
||||
When `true` \(the default\), transforms code that is or could be used in an annotation, to allow it to be imported from template factory modules.
|
||||
When `true`, the default, transforms code that is or could be used in an annotation, to allow it to be imported from template factory modules.
|
||||
See [metadata rewriting](guide/aot-compiler#metadata-rewriting) for more information.
|
||||
|
||||
When `false`, disables this rewriting, requiring the rewriting to be done manually.
|
||||
|
||||
### `disableTypeScriptVersionCheck`
|
||||
|
||||
When `true`, the compiler does not check the TypeScript version and does not report an error when an unsupported version of TypeScript is used.
|
||||
When `true`, the compiler does not look at 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`.
|
||||
|
||||
### `enableI18nLegacyMessageIdFormat`
|
||||
|
||||
Instructs the Angular template compiler to generate legacy ids for messages that are tagged in templates by the `i18n` attribute.
|
||||
Instructs the Angular template compiler to create legacy ids for messages that are tagged in templates by the `i18n` attribute.
|
||||
See [Mark text for translations][AioGuideI18nCommonPrepareMarkTextInComponentTemplate] for more information about marking messages for localization.
|
||||
|
||||
Set this option to `false` unless your project relies upon translations that were previously generated using legacy IDs.
|
||||
Set this option to `false` unless your project relies upon translations that were created earlier using legacy IDs.
|
||||
Default is `true`.
|
||||
|
||||
The pre-Ivy message extraction tooling generated a variety of legacy formats for extracted message IDs.
|
||||
These message formats have a number of issues, such as whitespace handling and reliance upon information inside the original HTML of a template.
|
||||
The pre-Ivy message extraction tooling created a variety of legacy formats for extracted message IDs.
|
||||
These message formats have some issues, such as whitespace handling and reliance upon information inside the original HTML of a template.
|
||||
|
||||
The new message format is more resilient to whitespace changes, is the same across all translation file formats, and can be generated directly from calls to `$localize`.
|
||||
The new message format is more resilient to whitespace changes, is the same across all translation file formats, and can be created directly from calls to `$localize`.
|
||||
This allows `$localize` messages in application code to use the same ID as identical `i18n` messages in component templates.
|
||||
|
||||
### `enableResourceInlining`
|
||||
|
||||
When `true`, replaces the `templateUrl` and `styleUrls` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
|
||||
When `true`, replaces the `templateUrl` and `styleUrls` properties in all `@Component` decorators with inline content in the `template` and `styles` properties.
|
||||
|
||||
When enabled, the `.js` output of `ngc` does not include any lazy-loaded template or style URLs.
|
||||
|
||||
For library projects generated with the CLI, the development configuration default is `true`.
|
||||
For library projects created with the Angular CLI, the development configuration default is `true`.
|
||||
|
||||
<a id="enablelegacytemplate"></a>
|
||||
|
||||
### `enableLegacyTemplate`
|
||||
|
||||
When `true`, enables use of the `<template>` element, which was deprecated in Angular 4.0, in favor of `<ng-template>` \(to avoid colliding with the DOM's element of the same name\).
|
||||
When `true`, enables the deprecated `<template>` element in place of `<ng-template>`.
|
||||
Default is `false`.
|
||||
Might be required by some third-party Angular libraries.
|
||||
|
||||
### `flatModuleId`
|
||||
|
||||
The module ID to use for importing a flat module \(when `flatModuleOutFile` is `true`\).
|
||||
References generated by the template compiler use this module name when importing symbols from the flat module.
|
||||
References created by the template compiler use this module name when importing symbols from the flat module.
|
||||
Ignored if `flatModuleOutFile` is `false`.
|
||||
|
||||
### `flatModuleOutFile`
|
||||
|
||||
When `true`, generates a flat module index of the given file name and the corresponding flat module metadata.
|
||||
When `true`, generates a flat module index of the given filename and the corresponding flat module metadata.
|
||||
Use to create flat modules that are packaged similarly to `@angular/core` and `@angular/common`.
|
||||
When this option is used, the `package.json` for the library should refer to the generated flat module index instead of the library index file.
|
||||
When this option is used, the `package.json` for the library should refer to the created flat module index instead of the library index file.
|
||||
|
||||
Produces only one `.metadata.json` file, which contains all the metadata necessary for symbols exported from the library index.
|
||||
In the generated `.ngfactory.js` files, the flat module index is used to import symbols that include both the public API from the library index as well as shrowded internal symbols.
|
||||
In the created `.ngfactory.js` files, the flat module index is used to import symbols. Symbols that include both the public API from the library index as well as shrouded internal symbols.
|
||||
|
||||
By default the `.ts` file supplied in the `files` field is assumed to be the library index.
|
||||
If more than one `.ts` file is specified, `libraryIndex` is used to select the file to use.
|
||||
@@ -133,15 +137,15 @@ If more than one `.ts` file is supplied without a `libraryIndex`, an error is pr
|
||||
A flat module index `.d.ts` and `.js` is created with the given `flatModuleOutFile` name in the same location as the library index `.d.ts` file.
|
||||
|
||||
For example, if a library uses the `public_api.ts` file as the library index of the module, the `tsconfig.json` `files` field would be `["public_api.ts"]`.
|
||||
The `flatModuleOutFile` option could then be set to \(for example\) `"index.js"`, which produces `index.d.ts` and `index.metadata.json` files.
|
||||
The `flatModuleOutFile` option could then be set, for example, to `"index.js"`, which produces `index.d.ts` and `index.metadata.json` files.
|
||||
The `module` field of the library's `package.json` would be `"index.js"` and the `typings` field 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`, the recommended value, enables the [binding expression validation](guide/aot-compiler#binding-expression-validation) phase of the template compiler. This phase uses TypeScript to verify binding expressions.
|
||||
For more information, see [Template type checking](guide/template-typecheck).
|
||||
|
||||
Default is `false`, but when you use the CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
|
||||
Default is `false`, but when you use the Angular CLI command `ng new --strict`, it is set to `true` in the new project's configuration.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
@@ -151,14 +155,14 @@ The `fullTemplateTypeCheck` option has been deprecated in Angular 13 in favor of
|
||||
|
||||
### `generateCodeForLibraries`
|
||||
|
||||
When `true` \(the default\), generates factory files \(`.ngfactory.js` and `.ngstyle.js`\) for `.d.ts` files with a corresponding `.metadata.json` file.
|
||||
When `true`, creates factory files \(`.ngfactory.js` and `.ngstyle.js`\) for `.d.ts` files with a corresponding `.metadata.json` file. The default value is `true`.
|
||||
|
||||
When `false`, factory files are generated only for `.ts` files.
|
||||
When `false`, factory files are created only for `.ts` files.
|
||||
Do this when using factory summaries.
|
||||
|
||||
### `preserveWhitespaces`
|
||||
|
||||
When `false` \(the default\), removes blank text nodes from compiled templates, which results in smaller emitted template factory modules.
|
||||
When `false`, the default, removes blank text nodes from compiled templates, which results in smaller emitted template factory modules.
|
||||
Set to `true` to preserve blank text nodes.
|
||||
|
||||
### `skipMetadataEmit`
|
||||
@@ -167,12 +171,12 @@ When `true`, does not produce `.metadata.json` files.
|
||||
Default is `false`.
|
||||
|
||||
The `.metadata.json` files contain information needed by the template compiler from a `.ts` file that is not included in the `.d.ts` file produced by the TypeScript compiler.
|
||||
This information includes, for example, the content of annotations \(such as a component's template\), which TypeScript emits to the `.js` file but not to the `.d.ts` file.
|
||||
This information includes, for example, the content of annotations, such as a component's template, which TypeScript emits to the `.js` file but not to the `.d.ts` file.
|
||||
|
||||
You can set to `true` when using factory summaries, because the factory summaries include a copy of the information that is in the `.metadata.json` file.
|
||||
|
||||
Set to `true` if you are using TypeScript's `--outFile` option, because the metadata files are not valid for this style of TypeScript output.
|
||||
However, we do not recommend using `--outFile` with Angular.
|
||||
The Angular community does not recommend using `--outFile` with Angular.
|
||||
Use a bundler, such as [webpack](https://webpack.js.org), instead.
|
||||
|
||||
### `skipTemplateCodegen`
|
||||
@@ -180,9 +184,9 @@ Use a bundler, such as [webpack](https://webpack.js.org), instead.
|
||||
When `true`, does not emit `.ngfactory.js` and `.ngstyle.js` files.
|
||||
This turns off most of the template compiler and disables the reporting of template diagnostics.
|
||||
|
||||
Can be used to instruct the template compiler to produce `.metadata.json` files for distribution with an `npm` package while avoiding the production of `.ngfactory.js` and `.ngstyle.js` files that cannot be distributed to `npm`.
|
||||
Can be used to instruct the template compiler to produce `.metadata.json` files for distribution with an `npm` package. This avoids the production of `.ngfactory.js` and `.ngstyle.js` files that cannot be distributed to `npm`.
|
||||
|
||||
For library projects generated with the CLI, the development configuration default is `true`.
|
||||
For library projects created with the Angular CLI, the development configuration default is `true`.
|
||||
|
||||
### `strictMetadataEmit`
|
||||
|
||||
@@ -190,35 +194,36 @@ When `true`, reports an error to the `.metadata.json` file if `"skipMetadataEmit
|
||||
Default is `false`.
|
||||
Use only when `"skipMetadataEmit"` is `false` and `"skipTemplateCodegen"` is `true`.
|
||||
|
||||
This option is intended to validate the `.metadata.json` files emitted for bundling with an `npm` package.
|
||||
This option is intended to verify the `.metadata.json` files emitted for bundling with an `npm` package.
|
||||
The validation is strict and can emit errors for metadata that would never produce an error when used by the template compiler.
|
||||
You can choose to suppress the error emitted by this option for an exported symbol by including `@dynamic` in the comment documenting the symbol.
|
||||
|
||||
It is valid for `.metadata.json` files to contain errors.
|
||||
The template compiler reports these errors if the metadata is used to determine the contents of an annotation.
|
||||
The metadata collector cannot predict the symbols that are designed for use in an annotation, so it preemptively includes error nodes in the metadata for the exported symbols.
|
||||
The metadata collector cannot predict the symbols that are designed for use in an annotation. It preemptively includes error nodes in the metadata for the exported symbols.
|
||||
The template compiler can then use the error nodes to report an error if these symbols are used.
|
||||
|
||||
If the client of a library intends to use a symbol in an annotation, the template compiler does not normally report this until the client uses the symbol.
|
||||
If the client of a library intends to use a symbol in an annotation, the template compiler does not normally report this. It gets reported after the client actually uses the symbol.
|
||||
This option allows detection of these errors during the build phase of the library and is used, for example, in producing Angular libraries themselves.
|
||||
|
||||
For library projects generated with the CLI, the development configuration default is `true`.
|
||||
For library projects created with the Angular CLI, the development configuration default is `true`.
|
||||
|
||||
### `strictInjectionParameters`
|
||||
|
||||
When `true` \(recommended\), reports an error for a supplied parameter whose injection type cannot be determined.
|
||||
When `false` \(currently the default\), constructor parameters of classes marked with `@Injectable` whose type cannot be resolved produce a warning.
|
||||
When `true`, reports an error for a supplied parameter whose injection type cannot be determined.
|
||||
When `false`, constructor parameters of classes marked with `@Injectable` whose type cannot be resolved produce a warning.
|
||||
The recommended value is `true`, but the default value is `false`.
|
||||
|
||||
When you use the CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
|
||||
When you use the Angular CLI command `ng new --strict`, it is set to `true` in the created project's configuration.
|
||||
|
||||
### `strictTemplates`
|
||||
|
||||
When `true`, enables [strict template type checking](guide/template-typecheck#strict-mode).
|
||||
|
||||
Additional strictness flags allow you to enable and disable specific types of strict template type checking.
|
||||
The strictness flags that this open enables allow you to turn on and off specific types of strict template type checking.
|
||||
See [troubleshooting template errors](guide/template-typecheck#troubleshooting-template-errors).
|
||||
|
||||
When you use the CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
|
||||
When you use the Angular CLI command `ng new --strict`, it is set to `true` in the new project's configuration.
|
||||
|
||||
### `trace`
|
||||
|
||||
@@ -227,14 +232,14 @@ Default is `false`.
|
||||
|
||||
<a id="cli-options"></a>
|
||||
|
||||
## Command Line Options
|
||||
## Command line options
|
||||
|
||||
While most of the time you interact with the Angular Compiler indirectly using Angular CLI, when debugging certain issues, you might find it useful to invoke the Angular Compiler directly.
|
||||
Most of the time you interact with the Angular Compiler indirectly using Angular CLI. When debugging certain issues, you might find it useful to invoke the Angular Compiler directly.
|
||||
You can use the `ngc` command provided by the `@angular/compiler-cli` npm package to call the compiler from the command line.
|
||||
|
||||
The `ngc` command is just a wrapper around TypeScript's `tsc` compiler command and is primarily configured via the `tsconfig.json` configuration options documented in [the previous sections](#angular-compiler-options).
|
||||
|
||||
In addition to the configuration file, you can also use [`tsc` command line options](https://www.typescriptlang.org/docs/handbook/compiler-options.html) to configure `ngc`.
|
||||
Besides the configuration file, you can also use [`tsc` command line options](https://www.typescriptlang.org/docs/handbook/compiler-options.html) to configure `ngc`.
|
||||
|
||||
<!-- links -->
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Angular Package Format
|
||||
# Angular package format
|
||||
|
||||
This document describes the Angular Package Format \(APF\).
|
||||
APF is an Angular specific specification for the structure and format of npm packages that is used by all first-party Angular packages \(`@angular/core`, `@angular/material`, etc.\) and most third-party Angular libraries.
|
||||
@@ -16,7 +16,7 @@ You can find the versions of the specification prior to v13 in this [google doc]
|
||||
|
||||
## Why specify a package format?
|
||||
|
||||
In today's JavaScript landscape, developers will consume packages in many different ways, using many different toolchains \(Webpack, rollup, esbuild, etc.\).
|
||||
In today's JavaScript landscape, developers consume packages in many different ways, using many different toolchains \(Webpack, rollup, esbuild, etc.\).
|
||||
These tools may understand and require different inputs - some tools may be able to process the latest ES language version, while others may benefit from directly consuming an older ES version.
|
||||
|
||||
The Angular distribution format supports all of the commonly used development tools and workflows, and adds emphasis on optimizations that result either in smaller application payload size or faster development iteration cycle \(build time\).
|
||||
@@ -113,8 +113,8 @@ This table describes the file layout under `node_modules/@angular/core` annotate
|
||||
| `index.d.ts` | Bundled `.d.ts` for the primary entrypoint `@angular/core`. |
|
||||
| `esm2020/` <br /> ─ `core.mjs` <br /> ─ `index.mjs` <br /> ─ `public_api.mjs` | Tree of `@angular/core` sources in unflattened ES2020 format. |
|
||||
| `esm2020/testing/` | Tree of the `@angular/core/testing` entrypoint in unflattened ES2020 format. |
|
||||
| `fesm2015/` <br /> ─ `core.mjs` <br /> ─ `core.mjs.map` <br /> ─ `testing.mjs` <br /> ─ `testing.mjs.map` | Code for all entrypoints in a flattened \(FESM\) ES2015 format, along with sourcemaps. |
|
||||
| `fesm2020/` <br /> ─ `core.mjs` <br /> ─ `core.mjs.map` <br /> ─ `testing.mjs` <br /> ─ `testing.mjs.map` | Code for all entrypoints in flattened \(FESM\) ES2020 format, along with sourcemaps. |
|
||||
| `fesm2015/` <br /> ─ `core.mjs` <br /> ─ `core.mjs.map` <br /> ─ `testing.mjs` <br /> ─ `testing.mjs.map` | Code for all entrypoints in a flattened \(FESM\) ES2015 format, along with source maps. |
|
||||
| `fesm2020/` <br /> ─ `core.mjs` <br /> ─ `core.mjs.map` <br /> ─ `testing.mjs` <br /> ─ `testing.mjs.map` | Code for all entrypoints in flattened \(FESM\) ES2020 format, along with source maps. |
|
||||
| `testing/` | Directory representing the "testing" entrypoint. |
|
||||
| `testing/index.d.ts` | Bundled `.d.ts` for the `@angular/core/testing` entrypoint. |
|
||||
|
||||
@@ -125,9 +125,9 @@ The primary `package.json` contains important package metadata, including the fo
|
||||
* It [declares](#esm-declaration) the package to be in EcmaScript Module \(ESM\) format
|
||||
* It contains an [`"exports"` field](#exports) which defines the available source code formats of all entrypoints
|
||||
* It contains [keys](#legacy-resolution-keys) which define the available source code formats of the primary `@angular/core` entrypoint, for tools which do not understand `"exports"`.
|
||||
These keys are considered deprecated, and will be removed as the support for `"exports"` rolls out across the ecosystem.
|
||||
These keys are considered deprecated, and could be removed as the support for `"exports"` rolls out across the ecosystem.
|
||||
|
||||
* It declares whether the package contains [side-effects](#side-effects)
|
||||
* It declares whether the package contains [side effects](#side-effects)
|
||||
|
||||
### ESM declaration
|
||||
|
||||
@@ -218,7 +218,7 @@ For `@angular/core` these are:
|
||||
|
||||
</code-example>
|
||||
|
||||
As above, a module resolver can use these keys to load a specific code format.
|
||||
As shown in the preceding code snippet, a module resolver can use these keys to load a specific code format.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@@ -230,7 +230,7 @@ As with `"node"`, ES2015 code is selected due to the constraints of ZoneJS.
|
||||
|
||||
### Side effects
|
||||
|
||||
The last function of `package.json` is to declare whether the package has [side-effects](#sideeffects-flag).
|
||||
The last function of `package.json` is to declare whether the package has [side effects](#sideeffects-flag).
|
||||
|
||||
<code-example language="javascript">
|
||||
|
||||
@@ -242,14 +242,14 @@ The last function of `package.json` is to declare whether the package has [side-
|
||||
|
||||
Most Angular packages should not depend on top-level side effects, and thus should include this declaration.
|
||||
|
||||
## Entrypoints and Code Splitting
|
||||
## Entrypoints and code splitting
|
||||
|
||||
Packages in the Angular Package Format contain one primary entrypoint and zero or more secondary entrypoints \(for example, `@angular/common/http`\).
|
||||
Entrypoints serve several functions.
|
||||
|
||||
1. They define the module specifiers from which users import code \(for example, `@angular/core` and `@angular/core/testing`\).
|
||||
|
||||
Users typically perceive these entrypoints as distinct groups of symbols, with different purposes or functionality.
|
||||
Users typically perceive these entrypoints as distinct groups of symbols, with different purposes or capability.
|
||||
|
||||
Specific entrypoints might only be used for special purposes, such as testing.
|
||||
Such APIs can be separated out from the primary entrypoint to reduce the chance of them being used accidentally or incorrectly.
|
||||
@@ -257,7 +257,7 @@ Entrypoints serve several functions.
|
||||
1. They define the granularity at which code can be lazily loaded.
|
||||
|
||||
Many modern build tools are only capable of "code splitting" \(aka lazy loading\) at the ES Module level.
|
||||
Since the Angular Package Format uses primarily a single "flat" ES Module per entrypoint, this means that most build tooling will not be able to split code in a single entrypoint into multiple output chunks.
|
||||
The Angular Package Format uses primarily a single "flat" ES Module per entry point. This means that most build tooling is not able to split code with a single entry point into multiple output chunks.
|
||||
|
||||
The general rule for APF packages is to use entrypoints for the smallest sets of logically connected code possible.
|
||||
For example, the Angular Material package publishes each logical component or set of components as a separate entrypoint - one for Button, one for Tabs, etc.
|
||||
@@ -267,15 +267,15 @@ Not all libraries require such granularity.
|
||||
Most libraries with a single logical purpose should be published as a single entrypoint.
|
||||
`@angular/core` for example uses a single entrypoint for the runtime, because the Angular runtime is generally used as a single entity.
|
||||
|
||||
### Resolution of Secondary Entrypoints
|
||||
### Resolution of secondary entry points
|
||||
|
||||
Secondary entrypoints can be resolved via the `"exports"` field of the `package.json` for the package.
|
||||
|
||||
## README.md
|
||||
|
||||
The readme file in the markdown format that is used to display description of a package on npm and github.
|
||||
The README file in the Markdown format that is used to display description of a package on npm and GitHub.
|
||||
|
||||
Example readme content of @angular/core package:
|
||||
Example README content of @angular/core package:
|
||||
|
||||
<code-example language="html">
|
||||
|
||||
@@ -288,20 +288,22 @@ License: MIT
|
||||
|
||||
</code-example>
|
||||
|
||||
## Partial Compilation
|
||||
## Partial compilation
|
||||
|
||||
Libraries in the Angular Package Format must be published in "partial compilation" mode.
|
||||
This is a compilation mode for `ngc` which produces compiled Angular code that is not tied to a specific Angular runtime version, in contrast to the full compilation used for applications, where the Angular compiler and runtime versions must match exactly.
|
||||
|
||||
To partially compile Angular code, use the `"compilationMode"` flag in `"angularCompilerOptions"` in your `tsconfig.json`:
|
||||
To partially compile Angular code, use the `compilationMode` flag in the `angularCompilerOptions` property of your `tsconfig.json`:
|
||||
|
||||
<code-example language="javascript">
|
||||
|
||||
{
|
||||
…
|
||||
"angularCompilerOptions": {
|
||||
"compilationMode": "partial",
|
||||
}
|
||||
}
|
||||
|
||||
</code-example>
|
||||
|
||||
Partially compiled library code is then converted to fully compiled code during the application build process by the Angular CLI.
|
||||
@@ -310,20 +312,20 @@ If your build pipeline does not use the Angular CLI then refer to the [Consuming
|
||||
|
||||
## Optimizations
|
||||
|
||||
### Flattening of ES Modules
|
||||
### Flattening of ES modules
|
||||
|
||||
The Angular Package Format specifies that code be published in "flattened" ES module format.
|
||||
This significantly reduces the build time of Angular applications as well as download and parse time of the final application bundle.
|
||||
Please check out the excellent post ["The cost of small modules"](https://nolanlawson.com/2016/08/15/the-cost-of-small-modules) by Nolan Lawson.
|
||||
|
||||
The Angular compiler has support for generating index ES module files that can then be used to generate flattened modules using tools like Rollup, resulting in a file format we call Flattened ES Module or FESM.
|
||||
The Angular compiler can generate index ES module files. Tools like Rollup can use these files to generate flattened modules in a *Flattened ES Module* (FESM) file format.
|
||||
|
||||
FESM is a file format created by flattening all ES Modules accessible from an entrypoint into a single ES Module.
|
||||
It's formed by following all imports from a package and copying that code into a single file while preserving all public ES exports and removing all private imports.
|
||||
|
||||
The shortened name "FESM" \(pronounced "phesom"\) can have a number after it such as "FESM5" or "FESM2015".
|
||||
The abbreviated name, FESM, pronounced *phe-som*, can be followed by a number such as FESM5 or FESM2015.
|
||||
The number refers to the language level of the JavaScript inside the module.
|
||||
So a FESM5 file would be ESM+ES5 \(import/export statements and ES5 source code\).
|
||||
Accordingly a FESM5 file would be ESM+ES5 and include import/export statements and ES5 source code.
|
||||
|
||||
To generate a flattened ES Module index file, use the following configuration options in your tsconfig.json file:
|
||||
|
||||
@@ -349,40 +351,40 @@ Once the index file \(for example, `my-ui-lib.js`\) is generated by ngc, bundler
|
||||
|
||||
#### Note about the defaults in package.json
|
||||
|
||||
As of webpack v4 the flattening of ES modules optimization should not be necessary for webpack users, and in fact theoretically we should be able to get better code-splitting without flattening of modules in webpack.
|
||||
In practice we still see size regressions when using unflattened modules as input for webpack v4.
|
||||
This is why `"module"` and `"es2020"` package.json entries still point to fesm files.
|
||||
We are investigating this issue and expect that we'll switch the `"module"` and `"es2020"` package.json entry points to unflattened files when the size regression issue is resolved.
|
||||
As of webpack v4, the flattening of ES modules optimization should not be necessary for webpack users. It should be possible to get better code-splitting without flattening of modules in webpack.
|
||||
In practice, size regressions can still be seen when using unflattened modules as input for webpack v4.
|
||||
This is why `module` and `es2020` package.json entries still point to FESM files.
|
||||
This issue is being investigated. It is expected to switch the `module` and `es2020` package.json entry points to unflattened files after the size regression issue is resolved.
|
||||
The APF currently includes unflattened ESM2020 code for the purpose of validating such a future change.
|
||||
|
||||
### "sideEffects" flag
|
||||
|
||||
By default, EcmaScript Modules are side-effectful: importing from a module ensures that any code at the top level of that module will execute.
|
||||
By default, EcmaScript Modules are side-effectful: importing from a module ensures that any code at the top level of that module should run.
|
||||
This is often undesirable, as most side-effectful code in typical modules is not truly side-effectful, but instead only affects specific symbols.
|
||||
If those symbols are not imported and used, it's often desirable to remove them in an optimization process known as tree-shaking, and the side-effectful code can prevent this.
|
||||
|
||||
Build tools such as Webpack support a flag which allows packages to declare that they do not depend on side-effectful code at the top level of their modules, giving the tools more freedom to tree-shake code from the package.
|
||||
The end result of these optimizations should be smaller bundle size and better code distribution in bundle chunks after code-splitting.
|
||||
This optimization can break your code if it contains non-local side-effects - this is however not common in Angular applications and it's usually a sign of bad design.
|
||||
Our recommendation is for all packages to claim the side-effect free status by setting the `sideEffects` property to `false`, and that developers follow the [Angular Style Guide](https://angular.io/guide/styleguide) which naturally results in code without non-local side-effects.
|
||||
The recommendation is for all packages to claim the side-effect free status by setting the `sideEffects` property to `false`, and that developers follow the [Angular Style Guide](https://angular.io/guide/styleguide) which naturally results in code without non-local side-effects.
|
||||
|
||||
More info: [webpack docs on side-effects](https://github.com/webpack/webpack/tree/master/examples/side-effects)
|
||||
More info: [webpack docs on side effects](https://github.com/webpack/webpack/tree/master/examples/side-effects)
|
||||
|
||||
### ES2020 Language Level
|
||||
### ES2020 language level
|
||||
|
||||
ES2020 Language level is now the default language level that is consumed by Angular CLI and other tooling.
|
||||
The Angular CLI will downlevel the bundle to a language level that is supported by all targeted browsers at application build time.
|
||||
The Angular CLI down-levels the bundle to a language level that is supported by all targeted browsers at application build time.
|
||||
|
||||
### d.ts bundling / type definition flattening
|
||||
|
||||
As of APF v8 we now prefer to run [API Extractor](https://api-extractor.com), to bundle TypeScript definitions so that the entire API appears in a single file.
|
||||
As of APF v8 it is now preferred to run [API Extractor](https://api-extractor.com), to bundle TypeScript definitions so that the entire API appears in a single file.
|
||||
|
||||
In prior APF versions each entry point would have a `src` directory next to the .d.ts entry point and this directory contained individual d.ts files matching the structure of the original source code.
|
||||
While this distribution format is still allowed and supported, it is highly discouraged because it confuses tools like IDEs that then offer incorrect autocompletion, and allows users to depend on deep-import paths which are typically not considered to be public API of a library or a package.
|
||||
|
||||
### Tslib
|
||||
|
||||
As of APF v10, we recommend adding tslib as a direct dependency of your primary entry-point.
|
||||
As of APF v10, it is recommended to add tslib as a direct dependency of your primary entry-point.
|
||||
This is because the tslib version is tied to the TypeScript version used to compile your library.
|
||||
|
||||
## Examples
|
||||
@@ -390,10 +392,10 @@ This is because the tslib version is tied to the TypeScript version used to comp
|
||||
* [@angular/core package](https://unpkg.com/browse/@angular/core@13.0.0-rc.0)
|
||||
* [@angular/material package](https://unpkg.com/browse/@angular/material@13.0.0-rc.0)
|
||||
|
||||
## Definition of Terms
|
||||
## Definition of terms
|
||||
|
||||
The following terms are used throughout this document very intentionally.
|
||||
In this section we define all of them to provide additional clarity.
|
||||
The following terms are used throughout this document intentionally.
|
||||
In this section are the definitions of all of them to provide additional clarity.
|
||||
|
||||
#### Package
|
||||
|
||||
@@ -403,7 +405,7 @@ The package is installed with `npm install @angular/core`.
|
||||
|
||||
#### Symbol
|
||||
|
||||
A class, function, constant or variable contained in a module and optionally made visible to the external world via a module export.
|
||||
A class, function, constant, or variable contained in a module and optionally made visible to the external world via a module export.
|
||||
|
||||
#### Module
|
||||
|
||||
@@ -424,16 +426,16 @@ Short for Flattened ES Modules and consists of a file format created by flatteni
|
||||
The identifier of a module used in the import statements \(for example, `@angular/core`\).
|
||||
The ID often maps directly to a path on the filesystem, but this is not always the case due to various module resolution strategies.
|
||||
|
||||
#### Module Specifier
|
||||
#### Module specifier
|
||||
|
||||
A module identifier \(see above\).
|
||||
|
||||
#### Module Resolution Strategy
|
||||
#### Module resolution strategy
|
||||
|
||||
Algorithm used to convert Module IDs to paths on the filesystem.
|
||||
Node.js has one that is well specified and widely used, TypeScript supports several module resolution strategies, [Closure Compiler](https://developers.google.com/closure/compiler) has yet another strategy.
|
||||
|
||||
#### Module Format
|
||||
#### Module format
|
||||
|
||||
Specification of the module syntax that covers at minimum the syntax for the importing and exporting from a file.
|
||||
Common module formats are CommonJS \(CJS, typically used for Node.js applications\) or ECMAScript Modules \(ESM\).
|
||||
@@ -447,12 +449,12 @@ Bundles are a browser-specific workaround that reduce network strain that would
|
||||
Node.js typically doesn't use bundles.
|
||||
Common bundle formats are UMD and System.register.
|
||||
|
||||
#### Language Level
|
||||
#### Language level
|
||||
|
||||
The language of the code \(ES2015 or ES2020\).
|
||||
Independent of the module format.
|
||||
|
||||
#### Entry Point
|
||||
#### Entry point
|
||||
|
||||
A module intended to be imported by the user.
|
||||
It is referenced by a unique module ID and exports the public API referenced by that module ID.
|
||||
@@ -460,12 +462,12 @@ An example is `@angular/core` or `@angular/core/testing`.
|
||||
Both entry points exist in the `@angular/core` package, but they export different symbols.
|
||||
A package can have many entry points.
|
||||
|
||||
#### Deep Import
|
||||
#### Deep import
|
||||
|
||||
A process of retrieving symbols from modules that are not Entry Points.
|
||||
These module IDs are usually considered to be private APIs that can change over the lifetime of the project or while the bundle for the given package is being created.
|
||||
|
||||
#### Top-Level Import
|
||||
#### Top-Level import
|
||||
|
||||
An import coming from an entry point.
|
||||
The available top-level imports are what define the public API and are exposed in "@angular/name" modules, such as `@angular/core` or `@angular/common`.
|
||||
@@ -475,11 +477,11 @@ The available top-level imports are what define the public API and are exposed i
|
||||
The process of identifying and removing code not used by an application - also known as dead code elimination.
|
||||
This is a global optimization performed at the application level using tools like [Rollup](https://rollupjs.org), [Closure Compiler](https://developers.google.com/closure/compiler), or [Terser](https://github.com/terser/terser).
|
||||
|
||||
#### AOT Compiler
|
||||
#### AOT compiler
|
||||
|
||||
The Ahead of Time Compiler for Angular.
|
||||
|
||||
#### Flattened Type Definitions
|
||||
#### Flattened type definitions
|
||||
|
||||
The bundled TypeScript definitions generated from [API Extractor](https://api-extractor.com).
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Learn more in [The App Shell Model](https://developers.google.com/web/fundamenta
|
||||
|
||||
## Step 1: Prepare the application
|
||||
|
||||
Do this with the following CLI command:
|
||||
Do this with the following Angular CLI command:
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
|
||||
@@ -19,9 +19,9 @@ ng new my-app --routing
|
||||
|
||||
For an existing application, you have to manually add the `RouterModule` and defining a `<router-outlet>` within your application.
|
||||
|
||||
## Step 2: Create the app shell
|
||||
## Step 2: Create the application shell
|
||||
|
||||
Use the CLI to automatically create the application shell.
|
||||
Use the Angular CLI to automatically create the application shell.
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
|
||||
@@ -80,9 +80,9 @@ After running this command you can see that the `angular.json` configuration fil
|
||||
|
||||
</code-example>
|
||||
|
||||
## Step 3: Verify the app is built with the shell content
|
||||
## Step 3: Verify the application is built with the shell content
|
||||
|
||||
Use the CLI to build the `app-shell` target.
|
||||
Use the Angular CLI to build the `app-shell` target.
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ This example shows some of the most useful `@Component` configuration options:
|
||||
| Configuration options | Details |
|
||||
|:--- |:--- |
|
||||
| `selector` | A CSS selector that tells Angular to create and insert an instance of this component wherever it finds the corresponding tag in template HTML. For example, if an application's HTML contains `<app-hero-list></app-hero-list>`, then Angular inserts an instance of the `HeroListComponent` view between those tags. |
|
||||
| `templateUrl` | The module-relative address of this component's HTML template. Alternatively, you can provide the HTML template inline, as the value of the `template` property. This template defines the component's *host view*. |
|
||||
| `templateUrl` | The module-relative address of this component's HTML template. Alternatively, you can provide the HTML template inline, as the value of the `template` property. This template defines the component's *host view*. |
|
||||
| `providers` | An array of [providers](guide/glossary#provider) for services that the component requires. In the example, this tells Angular how to provide the `HeroService` instance that the component's constructor uses to get the list of heroes to display. |
|
||||
|
||||
## Templates and views
|
||||
@@ -86,7 +86,7 @@ For example, here is a template for the Tutorial's `HeroListComponent`.
|
||||
|
||||
<code-example header="src/app/hero-list.component.html" path="architecture/src/app/hero-list.component.html" ></code-example>
|
||||
|
||||
This template uses typical HTML elements like `<h2>` and `<p>`, and also includes Angular template-syntax elements, `*ngFor`, `{{hero.name}}`, `(click)`, `[hero]`, and `<app-hero-detail>`.
|
||||
This template uses typical HTML elements like `<h2>` and `<p>`. It also includes Angular template-syntax elements, `*ngFor`, `{{hero.name}}`, `(click)`, `[hero]`, and `<app-hero-detail>`.
|
||||
The template-syntax elements tell Angular how to render the HTML to the screen, using program logic and data.
|
||||
|
||||
* The `*ngFor` directive tells Angular to iterate over a list
|
||||
@@ -154,7 +154,7 @@ Data binding plays an important role in communication between a template and its
|
||||
Angular pipes let you declare display-value transformations in your template HTML.
|
||||
A class with the `@Pipe` decorator defines a function that transforms input values to output values for display in a view.
|
||||
|
||||
Angular defines various pipes, such as the [date](api/common/DatePipe) pipe and [currency](api/common/CurrencyPipe) pipe; for a complete list, see the [Pipes API list](api?type=pipe).
|
||||
Angular defines various pipes, such as the [date](api/common/DatePipe) pipe and [currency](api/common/CurrencyPipe) pipe. For a complete list, see the [Pipes API list](api?type=pipe).
|
||||
You can also define new pipes.
|
||||
|
||||
To specify a value transformation in an HTML template, use the [pipe operator (`|`)](guide/pipes).
|
||||
@@ -212,8 +212,8 @@ The example template uses two built-in structural directives to add application
|
||||
|
||||
| Directives | Details |
|
||||
|:--- |:--- |
|
||||
| [`*ngFor`](guide/built-in-directives#ngFor) | An iterative; it tells Angular to stamp out one `<li>` per hero in the `heroes` list. |
|
||||
| [`*ngIf`](guide/built-in-directives#ngIf) | A conditional; it includes the `HeroDetail` component only if a selected hero exists. |
|
||||
| [`*ngFor`](guide/built-in-directives#ngFor) | An *iterative*, which tells Angular to create one `<li>` per hero in the `heroes` list. |
|
||||
| [`*ngIf`](guide/built-in-directives#ngIf) | A *conditional*, which includes the `HeroDetail` component only if a selected hero exists. |
|
||||
|
||||
#### Attribute directives
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ Use property names or method calls whenever possible. Keep application and busi
|
||||
|
||||
* **Quick execution**
|
||||
|
||||
Angular executes a template expression after every [change detection](guide/glossary#change-detection) cycle. Many asynchronous activities trigger change detection cycles, such as promise resolutions, HTTP results, timer events, key presses and mouse moves.
|
||||
Angular executes a template expression after every [change detection](guide/glossary#change-detection) cycle. Many asynchronous activities trigger change detection cycles, such as promise resolutions, HTTP results, timer events, key presses, and mouse moves.
|
||||
|
||||
An expression should finish quickly to keep the user experience as efficient as possible, especially on slower devices. Consider caching values when their computation requires greater resources.
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ The binding punctuation of `[]`, `()`, `[()]`, and the prefix specify the direct
|
||||
|
||||
* Use `[]` to bind from source to view
|
||||
* Use `()` to bind from view to source
|
||||
* Use `[()]` to bind in a two way sequence of view to source to view
|
||||
* Use `[()]` to bind in a two-way sequence of view to source to view
|
||||
|
||||
Place the expression or statement to the right of the equal sign within double quote \(`""`\) characters.
|
||||
For more information see [Interpolation](guide/interpolation) and [Template statements](guide/template-statements).
|
||||
|
||||
@@ -59,7 +59,7 @@ As you create more components, add them to `declarations`.
|
||||
You must declare every component in exactly one `NgModule` class.
|
||||
If you use a component without declaring it, Angular returns an error message.
|
||||
|
||||
The `declarations` array only takes declarables. Declarables are components, [directives](guide/attribute-directives) and [pipes](guide/pipes).
|
||||
The `declarations` array only takes declarables. Declarables are components, [directives](guide/attribute-directives), and [pipes](guide/pipes).
|
||||
All of a module's declarables must be in the `declarations` array.
|
||||
Declarables must belong to exactly one module. The compiler emits an error if you try to declare the same class in more than one module.
|
||||
|
||||
|
||||
@@ -307,7 +307,7 @@ The CLI uses [Autoprefixer](https://github.com/postcss/autoprefixer) to ensure c
|
||||
You might find it necessary to target specific browsers or exclude certain browser versions from your build.
|
||||
|
||||
Internally, Autoprefixer relies on a library called [Browserslist](https://github.com/browserslist/browserslist) to figure out which browsers to support with prefixing.
|
||||
Browserlist looks for configuration options in a `browserslist` property of the package configuration file, or in a configuration file named `.browserslistrc`.
|
||||
Browserslist looks for configuration options in a `browserslist` property of the package configuration file, or in a configuration file named `.browserslistrc`.
|
||||
Autoprefixer looks for the `browserslist` configuration when it prefixes your CSS.
|
||||
|
||||
* Tell Autoprefixer what browsers to target by adding a browserslist property to the package configuration file, `package.json`:
|
||||
|
||||
@@ -179,7 +179,7 @@ To add or remove an element, bind `*ngIf` to a condition expression such as `isA
|
||||
<code-example header="src/app/app.component.html" path="built-in-directives/src/app/app.component.html" region="NgIf-1"></code-example>
|
||||
|
||||
When the `isActive` expression returns a truthy value, `NgIf` adds the `ItemDetailComponent` to the DOM.
|
||||
When the expression is falsy, `NgIf` removes the `ItemDetailComponent` from the DOM and disposes of the component and all of its sub-components.
|
||||
When the expression is falsy, `NgIf` removes the `ItemDetailComponent` from the DOM and disposes of the component and all of its subcomponents.
|
||||
|
||||
For more information on `NgIf` and `NgIfElse`, see the [NgIf API documentation](api/common/NgIf).
|
||||
|
||||
@@ -204,7 +204,7 @@ In this example, Angular does not display the `nullCustomer` because it is `null
|
||||
Use the `NgFor` directive to present a list of items.
|
||||
|
||||
1. Define a block of HTML that determines how Angular renders a single item.
|
||||
1. To list your items, assign the short hand `let item of items` to `*ngFor`.
|
||||
1. To list your items, assign the shorthand `let item of items` to `*ngFor`.
|
||||
|
||||
<code-example header="src/app/app.component.html" path="built-in-directives/src/app/app.component.html" region="NgFor-1"></code-example>
|
||||
|
||||
@@ -239,7 +239,7 @@ For more information about template input variables, see [Structural directive s
|
||||
|
||||
Get the `index` of `*ngFor` in a template input variable and use it in the template.
|
||||
|
||||
In the `*ngFor`, add a semicolon and `let i=index` to the short hand.
|
||||
In the `*ngFor`, add a semicolon and `let i=index` to the shorthand.
|
||||
The following example gets the `index` in a variable named `i` and displays it with the item name.
|
||||
|
||||
<code-example header="src/app/app.component.html" path="built-in-directives/src/app/app.component.html" region="NgFor-3"></code-example>
|
||||
@@ -271,7 +271,7 @@ With the `*ngFor` `trackBy` property, Angular can change and re-render only thos
|
||||
|
||||
<code-example header="src/app/app.component.ts" path="built-in-directives/src/app/app.component.ts" region="trackByItems"></code-example>
|
||||
|
||||
1. In the short hand expression, set `trackBy` to the `trackByItems()` method.
|
||||
1. In the shorthand expression, set `trackBy` to the `trackByItems()` method.
|
||||
|
||||
<code-example header="src/app/app.component.html" path="built-in-directives/src/app/app.component.html" region="trackBy"></code-example>
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@ Change detection is sufficiently fast for most applications. However, when an ap
|
||||
If you are confident that a part of the application is not affected by a state change, you can use [OnPush](https://angular.io/api/core/ChangeDetectionStrategy) to skip change detection in an entire component subtree.
|
||||
|
||||
|
||||
## Using OnPush
|
||||
## Using `OnPush`
|
||||
|
||||
OnPush change detection instructs Angular to run change detection for a component subtree **only** when:
|
||||
* The root component of the subtree receives new inputs as the result of a template binding. Angular compares the current and past value of the input with `==`
|
||||
* Angular handles an event _(e.g. using event binding, output binding, or `@HostListener`)_ in the subtree's root component or any of its children whether they are using OnPush change detection or not.
|
||||
* Angular handles an event _(for example using event binding, output binding, or `@HostListener` )_ in the subtree's root component or any of its children whether they are using OnPush change detection or not.
|
||||
|
||||
You can set the change detection strategy of a component to `OnPush` in the `@Component` decorator:
|
||||
|
||||
@@ -25,7 +25,7 @@ export class MyComponent {}
|
||||
|
||||
## Common change detection scenarios
|
||||
|
||||
This section examines several common change detection scenarios to illustrate Angular's behavior.
|
||||
This section examines several common change detection scenarios to illustrate Angular's behavior.
|
||||
|
||||
## An event is handled by a component with default change detection
|
||||
|
||||
|
||||
@@ -4,27 +4,27 @@ On every change detection cycle, Angular synchronously:
|
||||
|
||||
* Evaluates all template expressions in all components, unless specified otherwise, based on that each component's detection strategy
|
||||
* Executes the `ngDoCheck`, `ngAfterContentChecked`, `ngAfterViewChecked`, and `ngOnChanges` lifecycle hooks.
|
||||
A single slow computation within a template or a lifecycle hook can slow down the entire change detection process because Angular runs the computations sequentially.
|
||||
A single slow computation within a template or a lifecycle hook can slow down the entire change detection process because Angular runs the computations sequentially.
|
||||
|
||||
## Identifying slow computations
|
||||
|
||||
You can identify heavy computations with Angular DevTools’ profiler. In the performance timeline, click on a bar to preview a particular change detection cycle. This displays a bar chart, which shows how long the framework spent in change detection for each component. When you click on a component, you can preview how long Angular spent evaluating its template and lifecycle hooks.
|
||||
You can identify heavy computations with Angular DevTools’ profiler. In the performance timeline, click a bar to preview a particular change detection cycle. This displays a bar chart, which shows how long the framework spent in change detection for each component. When you click a component, you can preview how long Angular spent evaluating its template and lifecycle hooks.
|
||||
|
||||
<div class="lightbox">
|
||||
<img alt="Angular DevTools profiler preview showing slow computation" src="generated/images/guide/change-detection/slow-computations.png">
|
||||
</div>
|
||||
|
||||
For example, in the screenshot above, we selected the second change detection cycle after the profiler started where Angular spent over 573 ms. Angular spent most time in the `EmployeeListComponent`. In the details panel, we can see that we spent over 297ms in evaluating the template of the `EmployeeListComponent`.
|
||||
For example, in the preceding screenshot, the second recorded change detection cycle is selected. Angular spent over 573 ms on this cycle, with the most time spent in the `EmployeeListComponent`. In the details panel, you can see that Angular spent over 297 ms evaluating the template of the `EmployeeListComponent`.
|
||||
|
||||
|
||||
## Optimizing slow computations
|
||||
|
||||
There are several techniques to eliminate slow computations:
|
||||
Here are several techniques to remove slow computations:
|
||||
|
||||
* **Optimizing the underlying algorithm**. This is the recommended approach; if you can speed up the algorithm that is causing the problem, you can speed up the entire change detection mechanism.
|
||||
* **Caching using pure pipes**. You can move the heavy computation to a pure [pipe](https://angular.io/guide/pipes). Angular will reevaluate a pure pipe only if it detects that its inputs changed, compared to the previous time Angular called it.
|
||||
* **Optimizing the underlying algorithm**. This is the recommended approach. If you can speed up the algorithm that is causing the problem, you can speed up the entire change detection mechanism.
|
||||
* **Caching using pure pipes**. You can move the heavy computation to a pure [pipe](https://angular.io/guide/pipes). Angular reevaluates a pure pipe only if it detects that its inputs have changed, compared to the previous time Angular called it.
|
||||
* **Using memoization**. [Memoization](https://en.wikipedia.org/wiki/Memoization) is a similar technique to pure pipes, with the difference that pure pipes preserve only the last result from the computation where memoization could store multiple results.
|
||||
* **Avoid repaints/reflows in lifecycle hooks**. Certain [operations](https://web.dev/avoid-large-complex-layouts-and-layout-thrashing/) cause the browser to either synchronously recalculate the layout of the page or re-render it. Since reflows and repaints are generally slow, we want to avoid performing them in every change detection cycle.
|
||||
* **Avoid repaints/reflows in lifecycle hooks**. Certain [operations](https://web.dev/avoid-large-complex-layouts-and-layout-thrashing/) cause the browser to either synchronously recalculate the layout of the page or re-render it. Since reflows and repaints are generally slow, you want to avoid performing them in every change detection cycle.
|
||||
|
||||
Pure pipes and memoization have different trade-offs. Pure pipes are an Angular built-in concept compared to memoization, which is a general software engineering practice for caching function results. The memory overhead of memoization could be significant if you invoke the heavy computation frequently with different arguments.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Resolving Zone Pollution
|
||||
# Resolving zone pollution
|
||||
|
||||
**Zone.js** is a signaling mechanism that Angular uses to detect when an application state might have changed. It captures asynchronous operations like `setTimeout`, network requests, and event listeners. Angular schedules change detection based on signals from Zone.js
|
||||
|
||||
There are cases in which scheduled [tasks](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide#tasks) or [microtasks](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide#microtasks) don’t make any changes in the data model, which makes running change detection unnecessary. Common examples are:
|
||||
In some cases scheduled [tasks](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide#tasks) or [microtasks](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide#microtasks) don’t make any changes in the data model, which makes running change detection unnecessary. Common examples are:
|
||||
* `requestAnimationFrame`, `setTimeout` or `setInterval`
|
||||
* Task or microtask scheduling by third-party libraries
|
||||
|
||||
@@ -19,9 +19,9 @@ You can detect unnecessary change detection calls using Angular DevTools. Often
|
||||
In the image above, there is a series of change detection calls triggered by event handlers associated with an element. That’s a common challenge when using third-party, non-native Angular components, which do not alter the default behavior of `NgZone`.
|
||||
|
||||
|
||||
## Run tasks outside NgZone
|
||||
## Run tasks outside `NgZone`
|
||||
|
||||
In such cases, we can instruct Angular to avoid calling change detection for tasks scheduled by a given piece of code using [NgZone](https://angular.io/guide/zone).
|
||||
In such cases, you can instruct Angular to avoid calling change detection for tasks scheduled by a given piece of code using [NgZone](https://angular.io/guide/zone).
|
||||
|
||||
```ts
|
||||
import { Component, NgZone, OnInit } from '@angular/core';
|
||||
@@ -34,7 +34,7 @@ class AppComponent implements OnInit {
|
||||
}
|
||||
```
|
||||
|
||||
The snippet above instructs Angular that it should execute the `setInterval` call outside the Angular Zone and skip running change detection after `pollForUpdates` runs.
|
||||
The preceding snippet instructs Angular to call `setInterval` outside the Angular Zone and skip running change detection after `pollForUpdates` runs.
|
||||
|
||||
Third-party libraries commonly trigger unnecessary change detection cycles because they weren't authored with Zone.js in mind. Avoid these extra cycles by calling library APIs outside the Angular zone:
|
||||
|
||||
@@ -53,8 +53,8 @@ class AppComponent implements OnInit {
|
||||
}
|
||||
```
|
||||
|
||||
Running `Plotly.newPlot('chart', data);` within `runOutsideAngular` instructs the framework that it shouldn’t execute change detection after the execution of tasks scheduled by the initialization logic.
|
||||
Running `Plotly.newPlot('chart', data);` within `runOutsideAngular` instructs the framework that it shouldn’t run change detection after the execution of tasks scheduled by the initialization logic.
|
||||
|
||||
For example, if `Plotly.newPlot('chart', data)` adds event listeners to a DOM element, Angular will not execute change detection after the execution of their handlers.
|
||||
For example, if `Plotly.newPlot('chart', data)` adds event listeners to a DOM element, Angular does not run change detection after the execution of their handlers.
|
||||
|
||||
@reviewed 2022-05-04
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Angular change detection and runtime optimization
|
||||
|
||||
**Change detection** is the process through which Angular checks to see whether your application state has changed, and if any DOM needs to be updated. At a high level, Angular walks your components from top to bottom, looking for changes. Angular runs its change detection mechanism periodically so that changes to the data model are reflected in an app’s view. Change detection can be triggered either manually or through an asynchronous event (for example, a user interaction or an XHR completion).
|
||||
**Change detection** is the process through which Angular checks to see whether your application state has changed, and if any DOM needs to be updated. At a high level, Angular walks your components from top to bottom, looking for changes. Angular runs its change detection mechanism periodically so that changes to the data model are reflected in an application’s view. Change detection can be triggered either manually or through an asynchronous event (for example, a user interaction or an XMLHttpRequest completion).
|
||||
|
||||
Change detection is a highly optimized performant, but it can still cause slowdowns if the application runs it too frequently.
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@
|
||||
| Class field decorators for directives and components | Details |
|
||||
|:--- |:--- |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> import { Input, … } from '@angular/core'; </code-example> | Import `Input, ...` from `@angular/core`. |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @Input() myProperty; </code-example> | Declares an input property that you can update using property binding \(example: `<my-cmp [myProperty]="someExpression">`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @Output() myEvent = new EventEmitter(); </code-example> | Declares an output property that fires events that you can subscribe to with an event binding \(example: `<my-cmp (myEvent)="doSomething()">`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @Input() myProperty; </code-example> | Declares an input property that you can update using property binding \(example: `<my-cmp [myProperty]="someExpression">`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @Output() myEvent = new EventEmitter(); </code-example> | Declares an output property that fires events that you can subscribe to with an event binding \(example: `<my-cmp (myEvent)="doSomething()">`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @HostBinding('class.valid') isValid; </code-example> | Binds a host element property \(here, the CSS class `valid`\) to a directive/component property \(`isValid`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @HostListener('click', ['$event']) onClick(e) {…} </code-example> | Subscribes to a host element event \(`click`\) with a directive/component method \(`onClick`\), optionally passing an argument \(`$event`\). |
|
||||
| <code-example format="typescript" hideCopy language="typescript"> @ContentChild(myPredicate) myChildComponent; </code-example> | Binds the first result of the component content query \(`myPredicate`\) to a property \(`myChildComponent`\) of the class. |
|
||||
|
||||
@@ -30,7 +30,7 @@ With the object format, Angular adds a class only if its associated value is tru
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
With any object-like expression—such as `object`, `Array`, `Map`, or `Set`—the identity of the object must change for Angular to update the class list.
|
||||
With any object-like expression—such as `object`, `Array`, `Map`, or `Set` —the identity of the object must change for Angular to update the class list.
|
||||
Updating the property without changing object identity has no effect.
|
||||
|
||||
</div>
|
||||
@@ -52,7 +52,7 @@ To create a single style binding, use the prefix `style` followed by a dot and t
|
||||
|
||||
For example, to set the `width` style, type the following: `[style.width]="width"`
|
||||
|
||||
Angular sets the property to the value of the bound expression, which is usually a string. Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
|
||||
Angular sets the property to the value of the bound expression, which is usually a string. Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
|
||||
|
||||
1. To write a style in dash-case, type the following:
|
||||
|
||||
|
||||
@@ -445,7 +445,7 @@ Architect can support watch mode, but there are some things to look out for.
|
||||
This prevents Architect from stopping the builder if another run is scheduled.
|
||||
|
||||
When your builder calls `BuilderRun.stop()` to exit watch mode, Architect unsubscribes from the builder's Observable and calls the builder's teardown logic to clean up.
|
||||
\(This behavior also allows for long running builds to be stopped and cleaned up.\)
|
||||
\(This behavior also allows for long-running builds to be stopped and cleaned up.\)
|
||||
|
||||
In general, if your builder is watching an external event, you should separate your run into three phases.
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ If you need to animate the items of an `*ngFor` list and there is a possibility
|
||||
|
||||
## Animations and Component View Encapsulation
|
||||
|
||||
Angular animations are based on the components DOM structure and do not directly take [View Encapsulation](/guide/view-encapsulation) into account, this means that components using `ViewEncapsulation.Emulated` behave exactly as if they where using `ViewEncapsulation.None` (`ViewEncapsulation.ShadowDom` behaves differently as we'll discuss shortly).
|
||||
Angular animations are based on the components DOM structure and do not directly take [View Encapsulation](/guide/view-encapsulation) into account, this means that components using `ViewEncapsulation.Emulated` behave exactly as if they were using `ViewEncapsulation.None` (`ViewEncapsulation.ShadowDom` behaves differently as we'll discuss shortly).
|
||||
|
||||
For example if the `query()` function (which you'll see more of in the rest of the Animations guide) were to be applied at the top of a tree of components using the emulated view encapsulation, such query would be able to identify (and thus animate) DOM elements on any depth of the tree.
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ But it is limited because the parent-child wiring must be done entirely within t
|
||||
The parent component *itself* has no access to the child.
|
||||
|
||||
You can't use the *local variable* technique if the parent component's *class* relies on the child component's *class*.
|
||||
The parent-child relationship of the components is not established within each components respective *class* with the *local variable* technique.
|
||||
The parent-child relationship of the components is not established within each component's respective *class* with the *local variable* technique.
|
||||
Because the *class* instances are not connected to one another, the parent *class* cannot access the child *class* properties and methods.
|
||||
|
||||
When the parent component *class* requires that kind of access, ***inject*** the child component into the parent as a *ViewChild*.
|
||||
@@ -248,7 +248,7 @@ Use [the same countdown timer tests](guide/component-interaction#countdown-tests
|
||||
|
||||
## Parent and children communicate using a service
|
||||
|
||||
A parent component and its children share a service whose interface enables bi-directional communication *within the family*.
|
||||
A parent component and its children share a service whose interface enables bidirectional communication *within the family*.
|
||||
|
||||
The scope of the service instance is the parent component and its children.
|
||||
Components outside this component subtree have no access to the service or their communications.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Angular Components Overview
|
||||
# Angular components overview
|
||||
|
||||
Components are the main building block for Angular applications.
|
||||
Each component consists of:
|
||||
@@ -38,7 +38,7 @@ To create a component using the Angular CLI:
|
||||
|
||||
By default, this command creates the following:
|
||||
|
||||
* A folder named after the component
|
||||
* A directory named after the component
|
||||
* A component file, `<component-name>.component.ts`
|
||||
* A template file, `<component-name>.component.html`
|
||||
* A CSS file, `<component-name>.component.css`
|
||||
|
||||
@@ -49,7 +49,7 @@ While Angular's emulated style encapsulation prevents styles from escaping a com
|
||||
While component consumers should avoid directly overwriting the CSS internals of a component, you can offer a supported customization API via a CSS preprocessor like Sass.
|
||||
|
||||
For example, a component may offer one or more supported mixins to customize various aspects of the component's appearance.
|
||||
While this approach uses global styles in it's implementation, it allows the component author to keep the mixins up to date with changes to the component's private DOM structure and CSS classes.
|
||||
While this approach uses global styles in its implementation, it allows the component author to keep the mixins up to date with changes to the component's private DOM structure and CSS classes.
|
||||
|
||||
#### 3. Customize with CSS `::part`
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-08-22
|
||||
@@ -1,135 +1,134 @@
|
||||
# Documentation contributor guide
|
||||
# Documentation contributors guide
|
||||
|
||||
<!-- markdownLint-disable MD001 -->
|
||||
|
||||
The topics in this section describe how you can contribute to this documentation.
|
||||
For information about contributing only code to the Angular framework, see [Contributing to Angular][GithubAngularAngularBlobMainContributingMd].
|
||||
For information about contributing code to the Angular framework, see [Contributing to Angular][GithubAngularAngularBlobMainContributingMd].
|
||||
|
||||
Angular, an open source project, depends on its community, especially when it comes to the documentation.
|
||||
The more the community contributes to the documentation, the better the documentation becomes.
|
||||
Input from you helps both new and experienced Angular developers.
|
||||
Angular is an open source project that appreciates its community support, especially when it comes to the documentation.
|
||||
|
||||
You can update the Angular documentation in these ways:
|
||||
|
||||
* [Make a minor change][AioGuideContributorsGuideOverviewMakeAMinorChange]
|
||||
* [Make a major change][AioGuideContributorsGuideOverviewMakeAMajorChange]
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
You must have a GitHub account to propose a minor change or review and edit the documentation.
|
||||
**IMPORTANT**:<br />
|
||||
To submit changes to the Angular documentation, you must have:
|
||||
|
||||
* A [GitHub][GithubMain] account
|
||||
* A signed [Contributor License Agreement][GithubAngularAngularBlobMainContributingMdSigningTheCla]
|
||||
|
||||
</div>
|
||||
|
||||
## Propose a minor change
|
||||
## Make a minor change
|
||||
|
||||
You can propose minor changes to a documentation topic without downloading any software. Choose the pencil icon <img alt="drawing of a pencil used as the topic edit icon" src="generated/images/guide/contributors-guide/edit-icon.png" > at the top of the page, to the right of the topic title to enter your suggestion.
|
||||
You can make minor changes to a documentation topic without downloading any software.
|
||||
Many common documentation maintenance tasks require only minor changes to a few words or characters in a topic.
|
||||
Examples of minor changes include:
|
||||
|
||||
## Review and edit documentation topics
|
||||
* [Correcting a typo or two][AioGuideContributorGuideOverviewToMakeAMinorChangeToADocumentationTopic]
|
||||
* [Reviewing a topic and updating its review date][AioGuideReviewingContentUpdateTheLastReviewedDate]
|
||||
* [Adding or updating search keywords][AioGuideUpdatingSearchKeywords]
|
||||
|
||||
This section describes how to make larger contributions to the documentation.
|
||||
For more about keeping the documentation up to date, see [Common documentation maintenance tasks][AioGuideDocTasks].
|
||||
|
||||
### Before you start
|
||||
To make larger changes to the documentation, you must install an Angular development environment on your local computer.
|
||||
You need this environment to edit and test your changes before you submit them.
|
||||
For information about configuring your local computer to make larger documentation updates, see [Preparing to edit the documentation][AioGuideDocPrepareToEdit].
|
||||
|
||||
The following steps set up your local computer to contribute documentation content.
|
||||
<!-- markdownLint-disable MD033 -->
|
||||
|
||||
1. Sign into your account on GitHub.
|
||||
If you don't have an account on GitHub, [create a new account][GithubJoin] before you continue.
|
||||
2. In your browser, navigate to [https://github.com/angular/angular][GithubAngular].
|
||||
3. In your browser, fork the `angular/angular` repo into your GitHub account.
|
||||
1. From [https://github.com/angular/angular][GithubAngular] in the browser, choose the **Fork** button near the top-right corner of the page.
|
||||
2. If asked, choose to create a fork to contribute to the original project.
|
||||
4. On the computer that you want to edit, clone your fork of the `angular` repo.
|
||||
5. In the `angular/aio` directory of your cloned repo, locally build and view the documentation.
|
||||
1. Run the following commands.
|
||||
To learn more, see [Angular documentation project][GithubAngularAngularBlobMainAioReadmeMd].
|
||||
#### To make a minor change to a documentation topic
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
Perform these steps in a browser.
|
||||
|
||||
yarn
|
||||
1. Confirm you have a [signed Contributor License Agreement (CLA)][GoogleDeveloperClaClas] on file.
|
||||
If you don't, [sign a CLA][GithubAngularAngularBlobMainContributingMdSigningTheCla].
|
||||
|
||||
</code-example>
|
||||
1. Sign into [github.com][GithubMain], or if you don't have a GitHub account, [create a new GitHub account][GithubJoin].
|
||||
1. Navigate to the page in [angular.io][AngularMain] that you want to update.
|
||||
1. On the page that you want to update, locate this pencil icon to the right of the topic's title
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
<div class="lightbox">
|
||||
|
||||
yarn setup
|
||||
<img alt="drawing of a pencil used as the topic edit icon" src="generated/images/guide/contributors-guide/edit-icon.png">
|
||||
|
||||
</code-example>
|
||||
</div>
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
1. Click this icon to open the suggestion page.
|
||||
1. In the suggestion page, in **Edit file**, update the content to fix the problem.
|
||||
If the fix requires more than correcting a few characters, it might be better to treat this as a [major change][AioGuideContributorsGuideOverviewMakeAMajorChange].
|
||||
|
||||
yarn build
|
||||
1. Click the **Preview** tab to see how your markdown changes look when rendered.
|
||||
This view shows how the markdown renders.
|
||||
It won't look exactly like the documentation page because it doesn't display the text with the styles used in the documentation.
|
||||
|
||||
</code-example>
|
||||
1. After you finish making your changes:
|
||||
1. In **Propose changes**, enter a brief description of your changes that starts with `docs:` and is 100 characters or less in length.
|
||||
If necessary, you can add more information about the change in the larger edit window below the brief description.
|
||||
|
||||
<code-example format="shell" language="shell">
|
||||
1. Select **Create a new branch for this commit and start a pull request** and accept the default branch name.
|
||||
1. Click **Propose changes** to open a pull request with your updated text.
|
||||
|
||||
yarn start
|
||||
After you open a pull request, the Angular team reviews your change and merges it into the documentation.
|
||||
You can follow the progress of your pull request in the pull request's page.
|
||||
You might receive a notification from GitHub if the Angular team has any questions about your change.
|
||||
|
||||
</code-example>
|
||||
## Make a major change
|
||||
|
||||
<div class="callout is-helpful">
|
||||
Making major changes or adding new topics to the documentation follows a different workflow.
|
||||
Major changes to a topic require that you build and test your changes before you send them to the Angular team.
|
||||
|
||||
**NOTE**: <br/>
|
||||
If you have any errors or issues with your yarn install, just re-run the `yarn` command.
|
||||
These topics provide information about how to set up your local computer to edit, build, and test Angular documentation to make major changes to it.
|
||||
|
||||
</div>
|
||||
* [Overview of the Angular documentation editorial workflow][AioGuideDocUpdateOverview]
|
||||
|
||||
2. In your browser, navigate to [http://localhost:4200][AngularLocalhost]
|
||||
3. Review your local build of the Angular framework documentation.
|
||||
Describes how to configure your local computer to build, edit, and test Angular documentation
|
||||
|
||||
After you can see your local build of the Angular framework documentation on your own system, you are ready to review and edit it. The following sections help you with the next steps.
|
||||
* [Documentation style guide][AioGuideDocStyleGuide]
|
||||
|
||||
### Before you edit the documentation
|
||||
Describes the standards used in the Angular documentation
|
||||
|
||||
The following steps prepare you to edit the Angular documentation successfully:
|
||||
## Localize Angular documentation in a new language
|
||||
|
||||
1. Review [Contributing to Angular][GithubAngularAngularBlobMainContributingMd].
|
||||
2. Install [the documentation linter][GithubAngularAngularTreeMainAioToolsDocLinterInstallValeOnYourDevelopmentSystemReadmeMd].
|
||||
|
||||
### Ways to contribute to Angular documentation
|
||||
|
||||
<div class="card-container">
|
||||
<a href="guide/reviewing-content" class="docs-card" title="Reviewing content">
|
||||
<section>Review content</section>
|
||||
<p>Keep Angular content up-to-date by reviewing topics for accuracy.</p>
|
||||
<p class="card-footer">Help keep content up to date</p>
|
||||
</a>
|
||||
<a href="guide/updating-search-keywords" class="docs-card" title="Updating search keywords">
|
||||
<section>Update search keywords</section>
|
||||
<p>Help Angular developers by improving the search keywords for existing topics.</p>
|
||||
<p class="card-footer">Improve documentation search</p>
|
||||
</a>
|
||||
<a href="guide/updating-content-github-ui" class="docs-card" title="Updating content through GitHub">
|
||||
<section>Update content through GitHub</section>
|
||||
<p>Learn how to make documentation changes through the GitHub UI.</p>
|
||||
<p class="card-footer">Contribute to Angular in your browser</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
### More resources for contributing to documentation
|
||||
|
||||
<div class="card-container">
|
||||
<a href="guide/docs-style-guide" class="docs-card" title="Documentation Style Guide">
|
||||
<section>Documentation style guide</section>
|
||||
<p>Review the syntax and styles used within the Angular documentation set.</p>
|
||||
<p class="card-footer">Get to know the writing style</p>
|
||||
</a>
|
||||
<a href="guide/localizing-angular" class="docs-card" title="Angular localization guidelines">
|
||||
<section>Angular localization guidelines</section>
|
||||
<p>Learn about the guidelines for localizing Angular documentation.</p>
|
||||
<p class="card-footer">Localize documentation</p>
|
||||
</a>
|
||||
</div>
|
||||
Localizing Angular documentation is another way to contribute to Angular documentation.
|
||||
For information about localizing the Angular documentation in a new language, see [Angular localization guidelines][AioGuideLocalizingAngular].
|
||||
|
||||
<!-- links -->
|
||||
|
||||
[AioGuideContributorsGuideOverviewMakeAMajorChange]: guide/contributors-guide-overview#make-a-major-change "Make a major change - Documentation contributors guide | Angular"
|
||||
[AioGuideContributorsGuideOverviewMakeAMinorChange]: guide/contributors-guide-overview#make-a-minor-change "Make a minor change - Documentation contributors guide | Angular"
|
||||
[AioGuideContributorGuideOverviewToMakeAMinorChangeToADocumentationTopic]: guide/contributors-guide-overview#to-make-a-minor-change-to-a-documentation-topic "To make a minor change to a documentation topic - Documentation contributors guide | Angular"
|
||||
|
||||
[AioGuideDocPrepareToEdit]: guide/doc-prepare-to-edit "Preparing to edit documentation | Angular"
|
||||
|
||||
[AioGuideDocStyleGuide]: guide/docs-style-guide "Angular documentation style guide | Angular"
|
||||
|
||||
[AioGuideDocTasks]: guide/doc-tasks "Common documentation maintenance tasks | Angular"
|
||||
|
||||
[AioGuideDocUpdateOverview]: guide/doc-update-overview "Overview of Angular documentation editing | Angular"
|
||||
|
||||
[AioGuideLocalizingAngular]: guide/localizing-angular "Angular documentation style guide | Angular"
|
||||
|
||||
[AioGuideReviewingContentUpdateTheLastReviewedDate]: guide/reviewing-content#update-the-last-reviewed-date "Update the last reviewed date - Test a documentation update | Angular"
|
||||
|
||||
[AioGuideUpdatingSearchKeywords]: guide/updating-search-keywords "Updating search keywords | Angular"
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
[AngularMain]: https://angular.io "Angular"
|
||||
|
||||
[GithubAngularAngularBlobMainContributingMd]: https://github.com/angular/angular/blob/main/CONTRIBUTING.md "Contributing to Angular | angular/angular | GitHub"
|
||||
[GithubAngularAngularBlobMainContributingMdSigningTheCla]: https://github.com/angular/angular/blob/main/CONTRIBUTING.md#-signing-the-cla "Signing the CLA - Contributing to Angular | angular/angular | GitHub"
|
||||
|
||||
[GithubMain]: https://github.com "GitHub"
|
||||
|
||||
[GithubJoin]: https://github.com/join "Join GitHub | GitHub"
|
||||
|
||||
[GithubAngular]: https://github.com/angular/angular "angular/angular | GitHub"
|
||||
|
||||
[GithubAngularAngularBlobMainAioReadmeMd]: https://github.com/angular/angular/blob/main/aio/README.md "Angular documentation project (https://angular.io) | angular/angular | Github"
|
||||
|
||||
[GithubAngularAngularBlobMainContributingMd]: https://github.com/angular/angular/blob/main/CONTRIBUTING.md "Contributing to Angular | angular/angular | Github"
|
||||
|
||||
[GithubAngularAngularTreeMainAioToolsDocLinterInstallValeOnYourDevelopmentSystemReadmeMd]: https://github.com/angular/angular/tree/main/aio/tools/doc-linter/README.md#install-vale-on-your-development-system "Install Vale on your development system - Angular documentation lint tool | angular/angular | Github"
|
||||
|
||||
[AngularLocalhost]: http://localhost:4200 "Angular.io on localhost"
|
||||
[GoogleDeveloperClaClas]: https://cla.developers.google.com/clas "Contributor License Agreements | Google Open Source"
|
||||
|
||||
<!--end links -->
|
||||
|
||||
@reviewed 2022-08-08
|
||||
@reviewed 2022-10-12
|
||||
|
||||
@@ -338,9 +338,9 @@ Notice that this form of provider has a third key, `deps`, which specifies depen
|
||||
Use this technique to create a dependency object with a factory function whose inputs are a combination of *injected services* and *local state*.
|
||||
|
||||
The dependency object \(returned by the factory function\) is typically a class instance, but can be other things as well.
|
||||
In this example, the dependency object is a string of the names of the runners up to the "Hero of the Month" contest.
|
||||
In this example, the dependency object is a string of the names of the runners-up to the "Hero of the Month" contest.
|
||||
|
||||
In the example, the local state is the number `2`, the number of runners up that the component should show.
|
||||
In the example, the local state is the number `2`, the number of runners-up that the component should show.
|
||||
The state value is passed as an argument to `runnersUpFactory()`.
|
||||
The `runnersUpFactory()` returns the *provider factory function*, which can use both the passed-in state value and the injected services `Hero` and `HeroService`.
|
||||
|
||||
@@ -417,7 +417,7 @@ Look again at the TypeScript `MinimalLogger` class to confirm that it has no imp
|
||||
|
||||
### 'InjectionToken' objects
|
||||
|
||||
Dependency objects can be simple values like dates, numbers and strings, or shapeless objects like arrays and functions.
|
||||
Dependency objects can be simple values like dates, numbers, and strings, or shapeless objects like arrays and functions.
|
||||
|
||||
Such objects don't have application interfaces and therefore aren't well represented by a class.
|
||||
They're better represented by a token that is both unique and symbolic, a JavaScript object that has a friendly name but won't conflict with another token that happens to have the same name.
|
||||
@@ -465,7 +465,7 @@ That's why you call the `HeroService` from within the `ngOnInit` rather than the
|
||||
</div>
|
||||
|
||||
Users want to see the heroes in alphabetical order.
|
||||
Rather than modify the original component, sub-class it and create a `SortedHeroesComponent` that sorts the heroes before presenting them.
|
||||
Rather than modify the original component, subclass it and create a `SortedHeroesComponent` that sorts the heroes before presenting them.
|
||||
The `SortedHeroesComponent` lets the base class fetch the heroes.
|
||||
|
||||
Unfortunately, Angular cannot inject the `HeroService` directly into the base class.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user