Compare commits

..

130 Commits
8.2.2 ... 8.2.7

Author SHA1 Message Date
da5d91b97b release: cut the v8.2.7 release 2019-09-18 10:01:57 -07:00
ba1ef6b1a5 fix(bazel): ng_package(data) should support non-text files (#32721)
PR Close #32721
2019-09-17 15:58:43 -07:00
acebf6464e ci: build bazel saucelabs tests remotely (#32719)
PR Close #32719
2019-09-17 15:14:18 -07:00
e367aa2ca5 docs: Typo fixes in hierarchical DI guide (#32536)
Introduce minor typo fixes in the guide for hierarchical dependency injection

PR Close #32536
2019-09-17 13:37:54 -07:00
0ee2b755e2 ci: use automatic strategy selection for AngularTemplateCompile and TypeScriptCompile (#32708)
PR Close #32708
2019-09-16 16:35:54 -07:00
f213c7a643 docs: add autoprefixer backward compatability instruction (#32109)
PR Close #32109
2019-09-16 10:48:03 -07:00
947c076ff2 fix(compiler-cli): fix typo in diagnostic template info. (#32684)
Fixes #32662

PR Close #32684
2019-09-16 08:59:49 -07:00
6600bea815 ci: run ts-api-guardian test remotely on CI (#32677)
PR Close #32677
2019-09-13 15:13:45 -07:00
6cd61aeb1c ci: add @josephperrott to global approvers in CODEOWNERS (#32667)
This change aims to align the documented members in `CODEOWNERS` with
the actual members of the secret `framework-global-approvers` GitHub
team.

PR Close #32667
2019-09-13 08:55:57 -07:00
581b991432 docs: add undecorated classes migration faq (#32478)
PR Close #32478
2019-09-12 12:16:15 -07:00
4014aab300 docs: move renderer2 deprecation guide into own file (#32626)
PR Close #32626
2019-09-12 10:43:01 -07:00
b523844966 build(docs-infra): upgrade cli command docs sources to e21aeeecd (#32635)
Updating [angular#8.2.x](https://github.com/angular/angular/tree/8.2.x) from [cli-builds#8.3.x](https://github.com/angular/cli-builds/tree/8.3.x).

##
Relevant changes in [commit range](6734efe52...e21aeeecd):

**Modified**
- help/generate.json

##

PR Close #32635
2019-09-12 10:32:10 -07:00
8d322c89b7 docs: modify lazy-load module instructions for new cli flag (#32588)
PR Close #32588
2019-09-12 10:23:20 -07:00
08a7c6f0b5 ci: update codeowners to reflect GitHub team members (#32569)
PR Close #32569
2019-09-11 20:26:29 -04:00
31f06ee3f9 build: enforce proper compile mode for size-tracking test (#32613)
Ensures that the "core_all:size_test" target runs with "--define=compile=aot".
This is necessary because we don't run this test on CI currently, but if we run
it manually, we need to ensure that it runs with Ivy for proper size comparisons.

PR Close #32613
2019-09-11 20:22:29 -04:00
1c5b157f10 fix(language-service): cache module resolution (#32483)
This is a patch PR for https://github.com/angular/angular/pull/32479

This PR fixes a critical performance issue where the language
service makes a MASSIVE number of filesystem calls when performing
module resolution.
This is because there is no caching. To make matters worse, module
resolution is performed for every program change (which means every
few keystrokes trigger a massive number of fs calls).

PR Close #32483
2019-09-11 20:21:55 -04:00
38fe47316c docs: fix doc links to current version (#32566)
PR Close #32566
2019-09-11 19:27:01 -04:00
9488da0d0a docs: add header to code examples (#32563)
PR Close #32563
2019-09-11 19:26:20 -04:00
5a8c560373 docs: update CHANGELOG to include default message for 8.2.6 2019-09-11 14:06:37 -07:00
d8675c7e72 release: cut the v8.2.6 release 2019-09-11 12:41:39 -07:00
bf29bd95a6 build: remove localize as a CODEOWNERS entry (#32618)
With v544eb89198304846c8a9c488da6790a1672cac64 the CODEOWNERS file
was amended to include an entry for the `localize` angular package.
This package exists in master, but not in the `8.x` branch. This patch
removes the entry from the file so that CI will work for `8.x`.

PR Close #32618
2019-09-11 15:14:04 -04:00
1775498b40 ci: pin docker images by ID for hermeticity (#32602)
Previously, the docker images used on CI where specified by a tag
(`10.16` and `10.16-browsers`). Since tags are not immutable, this only
pins specific characteristics of the environment (e.g. the OS type and
the Node.js version), but not others. Especially when using a tag that
does not specify the patch version (e.g. `10.16` instead of `10.16.0`),
it is inevitable that the image will change at some point, potentially
leading to unrelated failures due to changes in the environment.

One source of such failures can be the Chrome version used in tests.
Since we install a specific ChromeDriver version (that is only
compatible with specific Chrome version ranges), unexpectedly updating
to a newer Chrome version may break the tests if the new version falls
outside the range of supported version for our pinned ChromeDriver.

Using a tag that specifies the patch version (e.g. `10.16.0`) or even
the OS version (e.g. `10.16.0-buster`) is safer (i.e. has a lower
probability of introducing the kind of breakages described above), but
is still not fully hermetic.

This commit prevents such breakages by pinning the docker images by ID.
Image IDs are based on the image's digest (SHA256) and are thus
immutable, ensuring that all CI jobs will be running on the exact same
image.

See [here][1] for more info on pre-built CircleCI docker images and more
specifically [pinning images by ID][2].

[1]: https://circleci.com/docs/2.0/circleci-images
[2]: https://circleci.com/docs/2.0/circleci-images#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version

PR Close #32602
2019-09-11 12:34:15 -04:00
1eea575dfc ci: add missing code-owners (#32577)
PR Close #32577
2019-09-10 17:30:57 -04:00
0c624b2ca7 ci: check code-ownership on CI (#32577)
This commit expands the `lint` CircleCI job to also run the
`tools/verify-codeownership.js` script. This script verifies that some
important files/directories in the codebase have code-owners assigned in
`.github/CODEOWNERS`.

The main purpose of this change is to prevent adding new directories
(e.g. packages or docs guides/examples) without assigning appropriate
code-owners. When no code-owner is explicitly assigned, corresponding
PRs will automatically request reviews from @igorminar, who is the
"fall-back" code-owner.

PR Close #32577
2019-09-10 17:30:56 -04:00
8659451d13 test: expand the verify-codeownership.js script to also check packages (#32577)
The `aio/scripts/verify-codeownership.js` script (formerly
`verify-docs-codeownership.js`) can be used to verify whether there are
directories in the codebase that don't have a codeowner (in
`.github/CODEOWNERS`) and vice versa. It does not aim to cover all files
and directories, but do a coarse check on some important (or frequently
changing) directories.

Previously, the script only checked for API docs examples (in
`packages/examples/`) and guides (and related images and example) (in
`aio/content/`).

This commit expands the script to also check for packages (i.e.
top-level directories in `packages/`). It also renames the script from
`verify-docs-codeownership.js` to `verify-codeownership.js`, to better
reflect its new behavior.

PR Close #32577
2019-09-10 17:30:56 -04:00
2565f67956 docs: add mdb angular boilerplate to docs resources (#30448)
PR Close #30448
2019-09-10 17:22:32 -04:00
38f4dcd5e1 docs: port accessibility app from stackblitz to aio (#32377)
Fixes #32320

PR Close #32377
2019-09-10 13:11:49 -04:00
6e380cff82 ci: update i18n CODEOWNERS for @angular/localize package (#32570)
PR Close #32570
2019-09-10 13:09:12 -04:00
76a84706b6 docs: fixed typo for toh-pt5.md (#32362)
PR Close #32362
2019-09-10 13:03:37 -04:00
39302ba923 docs: fix typos in the routing and testing documentation (#32329)
PR Close #32329
2019-09-10 07:58:45 -04:00
1c71db846f docs: describe your change... (#32552)
Properly Closed Bracket for the header
PR Close #32552
2019-09-10 06:30:07 -04:00
48e4b0eb7f docs: add NG Rome MMXIX to Events resources (#31500)
PR Close #31500
2019-09-09 15:56:24 -04:00
9fd63c3ef6 docs(forms): correct parameter names in jsdoc (#32530)
PR Close #32530
2019-09-09 15:55:42 -04:00
aaea3878d9 ci: work around CIRCLE_COMPARE_URL not being available wih CircleCI Pipelines (#32537)
The commit range that is associated with a CI build is used for a couple
of things (mostly related to payload-size tracking):
- Determine whether a size change was caused by application code or
  dependencies (or both).
- Add the messages of the commits associated with the build (and thus
  the payload-size change).

NOTE: The commit range is only used on push builds.

Previously, the commit range was computed based on the
`CIRCLE_COMPARE_URL` environment variable. With [CircleCI Pipelines][1]
enabled, `CIRCLE_COMPARE_URL` is no longer available and the commit
range cannot be reliably detected.

This commit switches `CI_COMMIT_RANGE` to only include the last commit.
This can be less accurate in some rare cases, but is true in the
majority of cases (on push builds). Additionally, it stores the CircleCI
build URL in the database along with the payload data, so the relevant
info can be retrieved when needed.

[1]: https://circleci.com/docs/2.0/build-processing

PR Close #32537
2019-09-09 12:21:45 -04:00
8838a1b54c docs: edit copy and example in hierarchical injectors guide (#32501)
Fixes #32461

PR Close #32501
2019-09-06 18:28:42 -04:00
e742edca78 docs: add akita to the list of data libraries (#32505)
PR Close #32505
2019-09-06 14:58:16 -04:00
8304343e94 docs: expand abbreviation in providers guide (#32400)
The intro paragraph currently uses the DI abbreviation,
but it is clearer with DI written out and linked to the DI guide.

PR Close #32400
2019-09-05 18:59:56 -04:00
2ec91443e9 ci: re-run flaky docs examples e2e tests in test_docs_examples[_ivy] jobs (#32497)
The docs examples e2e tests have been quite flaky recently. This causes
the `test_docs_examples` and `test_docs_examples_ivy` CircleCI jobs to
often fail (and block PRs) without a real reason.

This commit adds support for re-running failed docs examples e2e tests
and configures the `test_docs_examples` and `test_docs_examples_ivy`
jobs to try running each test that fails a second time, before giving up
and marking it as failed.

Closes #31841
Closes #31842

PR Close #32497
2019-09-05 18:10:31 -04:00
be30f25da6 docs: update default path for xi18n (#32480)
PR Close #32480
2019-09-05 13:34:19 -04:00
c426a2595f docs: add Alexey Zuev to GDE resources (#32440)
PR Close #32440
2019-09-05 13:34:02 -04:00
896a8a441e docs: added note in animation keyframe offset (#32350)
Not mentioned in the docs.
Whenever offset property is used inside a keyframe's step at least once, then it must be defined to all the steps.
When read the first time, I supposed that the API automatically sets an even offset to the remaining not defined offsets, which is not

PR Close #32350
2019-09-05 13:33:27 -04:00
b1e7f4c952 fix(docs-infra): do not include GitHub links in Table of Content (#32418)
The docs template for cli commands ([cli-command.template.html][1])
includes an `h2` element with GitHub links for [long description][2].
Since the content of `h2` elements is replicated in the auto-generated
Table of Contents, the GitHub links were replicated as well (which is
undesirable).

This commit fixes it by explicitly excluding `.github-links` elements,
when extracting the content for the ToC (in
[TocService#extractHeadingSafeHtml()][3]). This is similar to what we do
for the auto-generated `.header-link` anchors.

[1]: https://github.com/angular/angular/blob/1537791f0/aio/tools/transforms/templates/cli/cli-command.template.html
[2]: https://github.com/angular/angular/blob/1537791f0/aio/tools/transforms/templates/cli/cli-command.template.html#L18
[3]: https://github.com/angular/angular/blob/1537791f0/aio/src/app/shared/toc.service.ts#L56

PR Close #32418
2019-09-05 13:33:07 -04:00
d3ee9e3926 fix(docs-infra): exclude heading anchor icon text from ToC tooltips (#32418)
The Table of Contents (ToC) is auto-generated based on the content of
heading elements on the page. At the same time, anchor links are
auto-generated and added to each heading element. Note that the Material
Icons used for the anchor icon make use of ligatures, which means that
the icons are specified by using their textual name as text content of
the icon element. As a result, the name of the icon is included in the
parent element's `textContent`.

Previously, the `TocService` used to strip off these anchor elements
when generating the content of ToC items, but not when generating the
content of their tooltips. Thus, tooltips for ToC items would
confusingly include a `link` suffix (`link` is the textual name of the
icon used in heading anchor links).

This commit fixes this by deriving the tooltip content from the
transformed text content (which already has anchor links stripped off),
instead of from the original heading content.

PR Close #32418
2019-09-05 13:33:07 -04:00
2b7116a4f3 release: cut the v8.2.5 release 2019-09-04 14:57:38 -07:00
8be20f3a3e build: fix incorrect formating which caused a broken build 2019-09-04 13:42:39 -07:00
5112669d29 refactor(benchpress): remove two mutable exports from largetable/util.ts (#32425)
Mutable exports, i.e. using this pattern

```
export let x = 0;
export function f() {
  x += 1;
}
```

is problematic to transpile to CommonJS and Goog.module systems, we are
working on banning it google internal codebase.

The workaround is adding an explcit getter function.

PR Close #32425
2019-09-04 11:44:18 -07:00
3d453fe6df docs: fix typo in structural directive example (#32459)
Fixes #32458

PR Close #32459
2019-09-04 11:36:03 -07:00
32a6972cdc docs: add app-shell production reference (#32471)
PR Close #32471
2019-09-04 11:34:17 -07:00
2cd5d4c64b docs: correct @ngtools/webpack url (#32407)
Fixes #32385

PR Close #32407
2019-09-03 12:00:20 -07:00
3248fe865f ci: re-enable chrome mobile tests on android (#32447)
With 63dff9c888, we temporarily disabled
the chrome mobile tests on Android because the launched browsers weren't
able to load the karma page through the tunnel.

The Saucelabs support responded to a ticket that we opened and said that
there were issues with those browsers which are now resolved.

PR Close #32447
2019-09-03 11:58:31 -07:00
b3ea6981cd feat(common): HttpParams fromObject accepts ReadonlyArray<string> (#31072)
Fixes #28452

PR Close #31072
2019-08-30 12:55:03 -07:00
f698a6bd73 ci: update codeowners for docs guides/examples/images (#32360)
Based on the output of `node aio\scripts\verify-docs-codeownership`, the
following guides still have no owners:

- accessibility.md
- angular-compiler-options.md
- aot-metadata-errors.md
- bazel.md
- cli-builder.md
- static-query-migration.md

PR Close #32360
2019-08-30 12:48:25 -07:00
97d2673eae test(docs-infra): expand select glob patterns in verify-docs-codeownership.js (#32360)
This allows the script to recognise some matches that it would miss
before and avoid listing them as missing.

Ideally, the script should be able to understand the globs in
`CODEOWNERS` and correctly find matching file-system paths.However, for
the limited purposes of the script (and for just a couple of relevant
globs), implementing this would be an overkill.

Implemented the "manual expansion" instead.
(We might revisit, if the needs change.)

PR Close #32360
2019-08-30 12:48:25 -07:00
4e93c4f87a test(docs-infra): modify verify-guide-codeownership.js to also check API docs examples (#32360)
This script can be used for manually checking that all docs
guides/examples/images have owners in `.github/CODEOWNERS`.

This commit adds support for also checking codeownership of API docs
examples (in `packages/examples/*`). The script is also renamed to the
more generic (and accurate) `verify-docs-codeownership.js`.

PR Close #32360
2019-08-30 12:48:25 -07:00
b5f85638f7 fix(zone.js): a path traversal attack in test (#32392)
`simple-server.js` is vulnerable to a trivial path traversal attack, i.e. an
attacker can supply a path like `../../etc/passwd` to read arbitrary files on
the server. This change fixes the issue by properly resolving the path, and then
only serving files under the current directory (as intended).

This is not really a security issue, given the code is not part of Angular, but
rather just testing infrastructure for Angular itself, and the CI servers are
not expected to contain confidential information, but still worth fixing for
code hygiene.

PR Close #32392
2019-08-30 12:44:47 -07:00
efd13d31fc build(docs-infra): upgrade cli command docs sources to 6734efe52 (#32414)
Updating [angular#8.2.x](https://github.com/angular/angular/tree/8.2.x) from [cli-builds#8.3.x](https://github.com/angular/cli-builds/tree/8.3.x).

##
Relevant changes in [commit range](ea386e045...6734efe52):

**Modified**
- help/e2e.json

##

PR Close #32414
2019-08-30 13:54:31 -04:00
3a45bef0e7 docs: add clarification regarding development in older browsers in Deployment guide (#32210)
Fixes #32199

PR Close #32210
2019-08-30 13:53:12 -04:00
5b105544fc build: mention where to find the invalid commit message, when validation fails (#32420)
Whenever someone tries to commit (by running `git commit` directly or
indirectly), a `commit-msg` git hook is run to validate the commit
message. If the validation fails, an error message is printed and the
commit is aborted.

Occasionally, people may have written a non-trivial commit message which
could turn out to be invalid (due a small typo for example). In that
case, it is frustrating to "lose" the whole message and have to write it
all over again (from memory). This is frustrating and has happened to me
enough times to finally seek a solution.

Fortunately, it turns out that git stores the last commit message in
`.git/COMMIT_EDITMSG`, so it is easy to get it back (as long as you know
where to look for it). This commit mentions this info in the validation
error to help people that might not know about it.

(This issue is probably mostly relevant for people using git from the
command-line and not through a UI, but it won't hurt in either case.)

PR Close #32420
2019-08-30 13:52:54 -04:00
4c5cfecc56 fix: update all files/directories owned by DevInfra to new DevInfra Framework team alias (#32247)
PR Close #32247
2019-08-29 12:36:18 -07:00
9d2348b9af docs: fix typo in compiler options guide (#32348)
PR Close #32348
2019-08-29 12:35:26 -07:00
e7bca0751c build: update ibazel to version that supports windows (#32390)
The `bazel-watcher` (also known as `ibazel`) currently does not work on windows. This
is because all versions before `v0.10.0` did not have official windows support. This
commit updates `ibazel` to the latest version which also comes with windows support.

PR Close #32390
2019-08-29 12:34:10 -07:00
45c909a237 ci: temporarily disable chrome mobile tests on android (#32403)
Temporarily disables saucelabs tests for Chrome Mobile on
android devices. This is because the browsers constantly do not
capture in Karma due to some connectivity issue where the
browsers are not able to load the karma page.

PR Close #32403
2019-08-29 12:29:54 -07:00
5b76b939af build: bump yarn requirement to 1.17.3 (#32344)
PR Close #32344
2019-08-28 17:14:44 -07:00
261593aab1 docs: update release notes for 8.2.4 to indicate a docs only release 2019-08-28 12:01:33 -07:00
c9ce735675 release: cut the v8.2.4 release 2019-08-28 11:00:34 -07:00
b7f95bec04 build(docs-infra): add empty codeGenApi JSDoc tag definition (#32207)
This avoids warning such as the following ([example][1]):

```
warn: Invalid tags found -
  doc "platform-browser/ɵBROWSER_SANITIZATION_PROVIDERS__POST_R3__" (const)
  from file "platform-browser/src/browser.ts"
```

[1]: https://circleci.com/gh/angular/angular/427064

PR Close #32207
2019-08-28 09:41:22 -07:00
d02573d05f docs: fix a minor typo in the HTTP guide (#32359)
"of typed" should be "of type"
PR Close #32359
2019-08-28 09:40:09 -07:00
8ff6ed6aa3 docs: fix callout header (#32325)
PR Close #32325
2019-08-28 09:06:08 -07:00
6aaf4eac89 docs(docs-infra): add note about setting up examples on Windows (#32355)
Closes #32321

PR Close #32355
2019-08-28 09:04:39 -07:00
1d0c93622d docs(service-worker): add example app for SwPush API docs (#32139)
Previously, the `SwPush` API docs were using hard-coded code snippets.

This commit switches to using code snippets from an actual example app,
which ensures that the code shown in the docs will at least continue to
compile successfully.

PR Close #32139
2019-08-27 16:18:54 -07:00
acd6c195a0 docs: add push notification usage to api doc (#32139)
PR Close #32139
2019-08-27 16:18:54 -07:00
53a9a28ec0 docs: add detail to router event doc (#32140)
PR Close #32140
2019-08-27 16:17:07 -07:00
aa8dd74176 docs: clean up formats in template syntax guide (#32197)
PR Close #32197
2019-08-27 16:14:25 -07:00
ed6dcce13b docs: update marketing resources.json with ExtAngular (#32126)
PR Close #32126
2019-08-27 16:12:32 -07:00
d170e45784 docs: change lite-server baseDir path to output folder (#32164)
In lite-server baseDir, path should be the output folder path, So need to change `baseDir="dist"` to `baseDir="dist/project-name"`

PR Close #32164
2019-08-27 15:53:38 -07:00
7033e7eb22 docs: Use ngOnInit to fetch data from services in the getting started guide (#32273)
Call data services inside ngOnInit interface implementation of components.

closes #32048

PR Close #32273
2019-08-27 09:08:26 -07:00
893123936b docs: Fix typo in singleton-services.md page (#32330)
There is a typo in the first sentence of the singleton-service.md documentation page.
PR Close #32330
2019-08-27 09:07:19 -07:00
31fcb9e036 style: align i18n angular config (#32334)
PR Close #32334
2019-08-27 09:06:52 -07:00
c303d44df6 docs: update i18n docs sample to cater for latest raw-loader version (#32334)
`raw-loader` version 2+ which is used in the CLI version 8 introduced a breaking change and now uses `export default` instead of `module.exports`.

See: https://github.com/webpack-contrib/raw-loader/blob/master/CHANGELOG.md#200-2019-03-18

Closes #32333

PR Close #32334
2019-08-27 09:06:52 -07:00
73dd43170b build: remove the deprecated aio commit message scope (#32341)
The `aio` commit message scope was renamed to `docs-infra` (which is
more descriptive) in #24295. Although it has been removed from the
documentation, the legacy `aio` scope was kept in the [list of valid
scopes][1] to cater for in-flight PRs that already used it. As a result,
it still shows up as a recommended, valid scope in the error message
shown when commit message validation fails during `git commit`. This is
misleading, especially for new contributors.

Since we have been "manually" discouraging people from using `aio`,
there should be no open PRs by now (and if there are, they should be
changed to `docs-infra`), so it is safe to remove it from the list of
allowed scopes.

Related discussion:
https://github.com/angular/angular/pull/32273#pullrequestreview-279767931

[1]: https://github.com/angular/angular/blob/3df54be9e/tools/validate-commit-message/commit-message.json#L16

PR Close #32341
2019-08-27 09:06:36 -07:00
514271ba9c docs: reference articles specifically (#32221)
PR Close #32221
2019-08-26 15:03:05 -07:00
8d18b49899 docs: add links to web.dev sw articles (#32221)
resolves issue 32218

PR Close #32221
2019-08-26 15:03:05 -07:00
6b0b7d01bf docs: fix typo in compiler options guide (#32312)
PR Close #32312
2019-08-26 11:47:40 -07:00
079773f54e ci: remove unused artifact uploads from test job (#32322)
These were initally added to allow for CircleCI to provide a better failure UI using junit data.
This information is not currently being created for bazel tests and once it is created it will
be available on the cloud status pages created by the BEP for each bazel execution.

PR Close #32322
2019-08-26 11:45:43 -07:00
b5cb120db0 docs: Update the aria-valuemax attr of the sample (#32261)
In order to be the same value as the one use here : https://stackblitz.com/edit/angular-kn5jdi?file=src%2Fapp%2Fprogress-bar.ts
PR Close #32261
2019-08-26 10:21:09 -07:00
0fb78d6c94 build(docs-infra): upgrade cli command docs sources to ea386e045 (#32298)
Updating [angular#8.2.x](https://github.com/angular/angular/tree/8.2.x) from [cli-builds#8.3.x](https://github.com/angular/cli-builds/tree/8.3.x).

##
Relevant changes in [commit range](166cd1501...ea386e045):

**Modified**
- help/generate.json

##

PR Close #32298
2019-08-26 09:33:34 -07:00
a80a8636ba docs: fix animations reference links to api pages (#32267)
The automated links for state() and group() are currently going to the
wrong api pages. Edit directs them to the correct animations api pages.

PR Close #32267
2019-08-26 09:31:26 -07:00
0878d67757 docs: fix wrong HttpEventType of HttpResponse class (#32296)
PR Close #32296
2019-08-26 09:28:57 -07:00
5e0890b3af build(docs-infra): upgrade cli command docs sources to 166cd1501 (#32286)
Updating [angular#8.2.x](https://github.com/angular/angular/tree/8.2.x) from [cli-builds#8.3.x](https://github.com/angular/cli-builds/tree/8.3.x).

##
Relevant changes in [commit range](e0055d293...166cd1501):

**Modified**
- help/add.json
- help/deploy.json

##

PR Close #32286
2019-08-23 11:03:12 -07:00
43bac21301 docs: fix http example to use correct property (#32288)
Fixes #31814

PR Close #32288
2019-08-23 09:02:06 -07:00
4df415060b docs: add information about running clang-format with Vim (#32254)
A clang-format plugin for Vim must point to the npm-installed
clang-format command. Add docs for this.

PR Close #32254
2019-08-22 15:59:14 -07:00
039d70efec docs: improve structure (#32227)
PR Close #32227
2019-08-22 13:29:49 -07:00
2a71496791 docs: fix typo (#32227)
PR Close #32227
2019-08-22 13:29:49 -07:00
617a329c24 docs: restructure the ng deploy section (#32227)
PR Close #32227
2019-08-22 13:29:49 -07:00
a00eae0b62 docs: address comments in the ng deploy guide (#32227)
PR Close #32227
2019-08-22 13:29:49 -07:00
e54dd741ef docs: fix broken links to deployment packages (#32227)
PR Close #32227
2019-08-22 13:29:48 -07:00
7b4c1cdbe4 docs: add ng deploy to the deployment guide (#32227)
PR Close #32227
2019-08-22 13:29:48 -07:00
5e4babeaa9 docs: update http guide (#32045)
PR Close #32045
2019-08-22 06:39:56 -07:00
f661f460bb docs(upgrade): position old setup guide as legacy until it can be removed (#32193)
PR Close #32193
2019-08-21 15:20:48 -07:00
44f233c02c docs: edit and organize aot doc (#32028)
PR Close #32028
2019-08-21 15:19:30 -07:00
31e8a52722 release: cut the v8.2.3 release 2019-08-21 13:28:20 -07:00
e3c9f9d794 ci: update material-unit-tests commit [patch] (#32244)
Updates the SHA that will be tested against in the `material-unit-tests` job
to the latest commit in the components repository. SHA 18b9ef3f5529f0fa8f034944681486447af7b879
is needed in order to make the newly introduced material-ci test blocklist effective.

Patch version of #32243.

PR Close #32244
2019-08-21 11:49:43 -07:00
e7c4e94c9a docs: update collaborators page (#32229)
PR Close #32229
2019-08-21 08:26:44 -07:00
26dc826821 docs: change to global approvers (#31940)
PR Close #31940
2019-08-20 16:47:16 -07:00
287247ef05 ci: update material commit we use to run integration tests (#32224)
PR Close #32224
2019-08-20 14:37:38 -07:00
af170d2ae9 ci: exclude the upstream g3 branch from building on CI (#32202)
We don't need to build this branch as it's informative for the purposes of figuring out
the diff between the master and what's synced into google3.

PR Close #32202
2019-08-20 09:55:56 -07:00
a01ed0d7b4 refactor(core): remove disabled injectable-pipe migration (#32184) (#32206)
Initially the plan was to have a migration that adds `@Injectable()` to
all pipes in a CLI project so that the pipes can be injected in Ivy
similarly to how it worked in view engine.

Due to the planned refactorings which ensure that `@Directive`, `@Component`
and `@Pipe` also have a factory definition, this migration is no longer
needed for Ivy. Additionally since it is already disabled (due to
572b54967c) and we have a more generic
migration (known as `missing-injectable)` that could do the same as
`injectable-pipe`, we remove the migration from the code-base.

PR Close #32184

PR Close #32206
2019-08-20 09:48:10 -07:00
a7b94783b5 fix(bazel): pin @microsoft/api-extractor (#32187)
The API of `@microsoft/api-extractor` changed in a minor version which is causes an error when using dts flattening downstream.

API wil be updated on master https://github.com/angular/angular/pull/32185

PR Close #32187
2019-08-19 15:42:45 -07:00
789dd6a0da docs(service-worker): mention that dataGroups only cache non-mutating requests (#32142)
Fixes #28988

PR Close #32142
2019-08-19 10:11:28 -07:00
e5b18e810c build(docs-infra): upgrade cli command docs sources to e0055d293 (#32175)
Updating [angular#8.2.x](https://github.com/angular/angular/tree/8.2.x) from [cli-builds#8.3.x](https://github.com/angular/cli-builds/tree/8.3.x).

##
Relevant changes in [commit range](43fc440c0...e0055d293):

**Added**
- help/deploy.json

**Modified**
- help/generate.json
- help/new.json
- help/serve.json

##

PR Close #32175
2019-08-19 10:09:09 -07:00
b8f86ad7d5 ci: move bazel saucelabs execution to script to be used across all Angular repos (#32141)
PR Close #32141
2019-08-16 09:57:23 -07:00
6f2e8afaed docs: fix typo of Typescript to TypeScript (#32153)
PR Close #32153
2019-08-15 12:44:42 -07:00
699c705a8d docs: clarify hierarchical injectors (#28700)
PR Close #28700
2019-08-15 12:43:51 -07:00
adc869ff88 build: add ngcc as a valid commit message scope (#32144)
PR Close #32144
2019-08-15 10:33:37 -07:00
46f2dcc470 build(docs-infra): upgrade cli command docs sources to 43fc440c0 (#32148)
Updating [angular#8.2.x](https://github.com/angular/angular/tree/8.2.x) from [cli-builds#8.2.x](https://github.com/angular/cli-builds/tree/8.2.x).

##
Relevant changes in [commit range](de49294bf...43fc440c0):

**Modified**
- help/serve.json

##

PR Close #32148
2019-08-15 09:54:24 -07:00
2d9c4c1d82 docs(router): fix router description (#32136)
PR Close #32136
2019-08-14 14:09:02 -07:00
0757702d63 docs: add guide to reproduce material-unit-test failures locally (#32138)
Adds a new guide that can be used to reproduce failures
reported in the `material-unit-tests` job locally.

The document should live in the framework repository as
the package building scripts are local to the framework
repository.

PR Close #32138
2019-08-14 12:02:13 -07:00
174777443d ci: remove material-unit-tests failure blocklist (#32138)
Initially when the `material-unit-tests` job got wired up,
Ivy was not really backwards-compatible and a few bugs caused
test failures when running the Angular Material test suites w/ Ivy.

These bugs got fixed progressively and eventually the test
blocklist became empty. At this point we don't want to regress
in the future and the blocklist should never have new items.

Additionally since we switched the unit-tests job to run against
Angular Material `master` with Bazel, the blocklist is no
longer respected. Therefore we can safely remove the blocklist.

PR Close #32138
2019-08-14 12:02:13 -07:00
baf2d9ddbc fix(docs-infra): fix broken toc ul styles (#32124)
Fixes #32027

PR Close #32124
2019-08-14 12:01:18 -07:00
da444984a8 docs: add info about reviewing PRs from code owners (#32108)
PR Close #32108
2019-08-14 11:59:14 -07:00
84a3daf609 docs: doc browser support for service workers (#32046)
PR Close #32046
2019-08-14 11:58:21 -07:00
c88cdea9ac build(core): add missing tsconfig-build.json dependency (#31943)
For some reason (on OS/X) this transitive dependency is not being passed
through to the final TS builds that rely on this rule, so the build fails
with a missing file error:

```
The specified path does not exist:
'/.../sandbox/darwin-sandbox/451/execroot/angular/packages/tsconfig-build.json'.
```

PR Close #31943
2019-08-14 11:56:14 -07:00
7b3bd219f7 build: ensure schematics are built with typescript strict flag (#31967)
Follow-up to #30993 where we build all Angular packages with
the TypeScript `--strict` flag. The flag improves overall code
health and also helps us catch issues easier.

PR Close #31967
2019-08-13 11:39:01 -07:00
dc76c14e31 docs: edit location doc (#32042)
PR Close #32042
2019-08-13 11:37:14 -07:00
0ffc1d0d21 docs: update marketing resources with Angular UI Toolkit (#31969)
PR Close #31969
2019-08-13 11:36:37 -07:00
3d1b82be67 docs: correct description of animation example (#32009)
PR Close #32009
2019-08-13 11:16:32 -07:00
dec7e5286f ci: use local strategy for AngularTemplateCompile and TypescriptCompile on CI (#32112)
PR Close #32112
2019-08-13 09:57:51 -07:00
2f812f31d5 docs: update events page and fix ordering (#32106)
PR Close #32106
2019-08-13 09:57:28 -07:00
18bac15ddd ci: add ivy commits to generated CHANGELOG (#32114)
Historically, we've cleaned Ivy commits out of the CHANGELOG because
Ivy was not available except as a preview. Given that Ivy will soon
be the default in 9.0.0, it no longer makes sense to remove the Ivy
commits from the log. This changes the gulp changelog task so that
Ivy commits are included by default.

PR Close #32114
2019-08-12 16:03:37 -07:00
a1fe52b41c docs: format currency api (#32107)
PR Close #32107
2019-08-12 15:16:15 -07:00
193 changed files with 21241 additions and 8187 deletions

View File

@ -36,22 +36,6 @@ build --incompatible_strict_action_env
run --incompatible_strict_action_env
test --incompatible_strict_action_env
###############################
# Saucelabs support #
# Turn on these settings with #
# --config=saucelabs #
###############################
# Expose SauceLabs environment to actions
# These environment variables are needed by
# web_test_karma to run on Saucelabs
test:saucelabs --action_env=SAUCE_USERNAME
test:saucelabs --action_env=SAUCE_ACCESS_KEY
test:saucelabs --action_env=SAUCE_READY_FILE
test:saucelabs --action_env=SAUCE_PID_FILE
test:saucelabs --action_env=SAUCE_TUNNEL_IDENTIFIER
test:saucelabs --define=KARMA_WEB_TEST_MODE=SL_REQUIRED
###############################
# Release support #
# Turn on these settings with #

View File

@ -28,14 +28,3 @@ test --flaky_test_attempts=2
# More details on failures
build --verbose_failures=true
# We have seen some flakiness in using TS workers on CircleCI
# https://angular-team.slack.com/archives/C07DT5M6V/p1562693245183400
# > failures like `ERROR: /home/circleci/ng/packages/core/test/BUILD.bazel:5:1:
# > Compiling TypeScript (devmode) //packages/core/test:test_lib failed: Worker process did not return a WorkResponse:`
# > I saw that issue a couple times today.
# > Example job: https://circleci.com/gh/angular/angular/385517
# We expect that TypeScript compilations will parallelize wider than the number of local cores anyway
# so we should saturate remote workers with TS compilations
build --strategy=TypeScriptCompile=standalone
build --strategy=AngularTemplateCompile=standalone

View File

@ -11,12 +11,14 @@
# needed for jobs that run tests without Bazel. Bazel runs tests with browsers that will be
# fetched by the Webtesting rules. Therefore for jobs that run tests with Bazel, we don't need a
# docker image with browsers pre-installed.
# **NOTE 1**: If you change the version of the `*-browsers` docker image, make sure the
# **NOTE 1**: Pin to exact images using an ID (SHA). See https://circleci.com/docs/2.0/circleci-images/#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version.
# (Using the tag in not necessary when pinning by ID, but include it anyway for documentation purposes.)
# **NOTE 2**: If you change the version of the docker images, also change the `cache_key` suffix.
# **NOTE 3**: If you change the version of the `*-browsers` docker image, make sure the
# `CI_CHROMEDRIVER_VERSION_ARG` env var (in `.circleci/env.sh`) points to a ChromeDriver
# version that is compatible with the Chrome version in the image.
# **NOTE 2**: If you change the version of the docker images, also change the `cache_key` suffix.
var_1: &default_docker_image circleci/node:10.16
var_2: &browsers_docker_image circleci/node:10.16-browsers
var_1: &default_docker_image circleci/node:10.16@sha256:75c05084fff4afa3683a03c5a04a4a3ad95c536ff2439d8fe14e7e1f5c58b09a
var_2: &browsers_docker_image circleci/node:10.16-browsers@sha256:d2a96fe1cbef51257ee626b5f645e64dade3e886f00ba9cb7e8ea65b4efe8db1
# We don't want to include the current branch name in the cache key because that would prevent
# PRs from being able to restore the cache since the branch names are always different for PRs.
# The cache key should only consist of dynamic values that change whenever something in the
@ -35,7 +37,7 @@ var_4: &init_environment
# Overwrite the yarn installed in the docker container with our own version.
command: |
./.circleci/env.sh
ourYarn=$(realpath ./third_party/github.com/yarnpkg/yarn/releases/download/v1.13.0/bin/yarn.js)
ourYarn=$(realpath ./third_party/github.com/yarnpkg/yarn/releases/download/v1.17.3/bin/yarn.js)
sudo chmod a+x $ourYarn
sudo ln -fs $ourYarn /usr/local/bin/yarn
echo "Yarn version: $(yarn --version)"
@ -143,7 +145,7 @@ var_14: &notify_dev_infra_on_fail
# Cache key for the Material unit tests job. **Note** when updating the SHA in the cache keys,
# also update the SHA for the "MATERIAL_REPO_COMMIT" environment variable.
var_15: &material_unit_tests_cache_key v4-angular-material-701302dc482d7e4b77990b24e3b5ab330bbf1aa5
var_15: &material_unit_tests_cache_key v4-angular-material-18b9ef3f5529f0fa8f034944681486447af7b879
var_16: &material_unit_tests_cache_key_short v4-angular-material
version: 2
@ -187,6 +189,7 @@ jobs:
(echo -e "\n.bzl files have lint errors. Please run ''yarn bazel:lint-fix''"; exit 1)'
- run: yarn gulp lint
- run: node tools/verify-codeownership
test:
<<: *job_defaults
@ -198,13 +201,6 @@ jobs:
# Setup remote execution and run RBE-compatible tests.
- *setup_bazel_remote_execution
- run: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only
- run: mkdir ~/testlogs
- run: cp -Lr dist/testlogs/* ~/testlogs
- store_test_results:
# Bazel always writes test.xml files under this directory
path: ~/testlogs
- store_artifacts:
path: ~/testlogs
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_aot:
@ -255,24 +251,21 @@ jobs:
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- *setup_bazel_remote_execution
- run:
name: Preparing environment for running tests on Saucelabs.
command: setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
- run:
name: Starting Saucelabs tunnel
command: ./scripts/saucelabs/start-tunnel.sh
background: true
# Waits for the Saucelabs tunnel to be ready. This ensures that we don't run tests
# too early without Saucelabs not being ready.
- run: ./scripts/saucelabs/wait-for-tunnel.sh
name: Run Bazel tests in saucelabs
# All web tests are contained within a single //:test_web_all target for Saucelabs
# as running each set of tests as a separate target will attempt to acquire too
# many browsers on Saucelabs (7 per target currently) and some tests will always
# fail to acquire browsers. For example:
# 14 02 2019 19:52:33.170:WARN [launcher]: chrome beta on SauceLabs have not captured in 180000 ms, killing.
# //packages/forms/test:web_test_sauce TIMEOUT in 315.0s
- run: yarn bazel test --config=saucelabs //:test_web_all
- run: ./scripts/saucelabs/stop-tunnel.sh
command: |
./scripts/saucelabs/run-bazel-via-tunnel.sh \
--tunnel-id angular-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_INDEX} \
--username $SAUCE_USERNAME \
--key $(echo $SAUCE_ACCESS_KEY | rev) \
yarn bazel test //:test_web_all
- *notify_dev_infra_on_fail
test_aio:
@ -377,7 +370,7 @@ jobs:
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
# Since the parallelism is set to "3", there will be three parallel CircleCI containers
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
- run: yarn --cwd aio example-e2e --setup --local --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
- run: yarn --cwd aio example-e2e --setup --local --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL} --retry 2
test_docs_examples_ivy:
<<: *job_defaults
@ -403,7 +396,7 @@ jobs:
# Run examples tests with ivy. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
# Since the parallelism is set to "3", there will be three parallel CircleCI containers
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
- run: yarn --cwd aio example-e2e --setup --local --ivy --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
- run: yarn --cwd aio example-e2e --setup --local --ivy --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL} --retry 2
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
aio_preview:
@ -673,7 +666,10 @@ workflows:
version: 2
default_workflow:
jobs:
- setup
- setup:
filters:
branches:
ignore: g3
- lint:
requires:
- setup
@ -784,9 +780,3 @@ workflows:
branches:
only:
- master
# TODO:
# - don't build the g3 branch
# - verify that we are bootstrapping with the right yarn version coming from the docker image
# - check local chrome version pulled from docker image
# - remove /tools/ngcontainer

View File

@ -19,16 +19,20 @@ setPublicVar PROJECT_ROOT "$projectDir";
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
# This is the branch being built; e.g. `pull/12345` for PR builds.
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
setPublicVar CI_BUILD_URL "$CIRCLE_BUILD_URL";
# ChromeDriver version compatible with the Chrome version included in the docker image used in
# `.circleci/config.yml`. See http://chromedriver.chromium.org/downloads for a list of versions.
# This variable is intended to be passed as an arg to the `webdriver-manager update` command (e.g.
# `"postinstall": "webdriver-manager update $CI_CHROMEDRIVER_VERSION_ARG"`).
setPublicVar CI_CHROMEDRIVER_VERSION_ARG "--versions.chrome 75.0.3770.90";
setPublicVar CI_COMMIT "$CIRCLE_SHA1";
# `CI_COMMIT_RANGE` will only be available when `CIRCLE_COMPARE_URL` is also available (or can be
# retrieved via `get-compare-url.js`), i.e. on push builds (a.k.a. non-PR, non-scheduled builds and
# rerun workflows of such builds). That is fine, since we only need it in push builds.
setPublicVar CI_COMMIT_RANGE "`[[ ${CIRCLE_PR_NUMBER:-false} != false ]] && echo "" || node $getCommitRangePath "$CIRCLE_BUILD_NUM" "$CIRCLE_COMPARE_URL"`";
# `CI_COMMIT_RANGE` is only used on push builds (a.k.a. non-PR, non-scheduled builds and rerun
# workflows of such builds).
# NOTE: With [CircleCI Pipelines](https://circleci.com/docs/2.0/build-processing) enabled,
# `CIRCLE_COMPARE_URL` is no longer available and the commit range cannot be reliably
# detected. Fall back to only considering the last commit (which is accurate in the majority
# of cases for push builds).
setPublicVar CI_COMMIT_RANGE "`[[ ${CIRCLE_PR_NUMBER:-false} != false ]] && echo "" || echo "$CIRCLE_SHA1~1...$CIRCLE_SHA1"`";
setPublicVar CI_PULL_REQUEST "${CIRCLE_PR_NUMBER:-false}";
setPublicVar CI_REPO_NAME "$CIRCLE_PROJECT_REPONAME";
setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
@ -61,6 +65,7 @@ else
setPublicVar SAUCE_USERNAME "angular-ci";
setSecretVar SAUCE_ACCESS_KEY "9b988f434ff8-fbca-8aa4-4ae3-35442987";
fi
# TODO(josephperrott): Remove environment variables once all saucelabs tests are via bazel method.
setPublicVar SAUCE_LOG_FILE /tmp/angular/sauce-connect.log
setPublicVar SAUCE_READY_FILE /tmp/angular/sauce-connect-ready-file.lock
setPublicVar SAUCE_PID_FILE /tmp/angular/sauce-connect-pid-file.lock
@ -79,7 +84,7 @@ setPublicVar MATERIAL_REPO_TMP_DIR "/tmp/material2"
setPublicVar MATERIAL_REPO_URL "https://github.com/angular/material2.git"
setPublicVar MATERIAL_REPO_BRANCH "master"
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI "config.yml".
setPublicVar MATERIAL_REPO_COMMIT "701302dc482d7e4b77990b24e3b5ab330bbf1aa5"
setPublicVar MATERIAL_REPO_COMMIT "18b9ef3f5529f0fa8f034944681486447af7b879"
# Source `$BASH_ENV` to make the variables available immediately.
source $BASH_ENV;

View File

@ -10,6 +10,13 @@
* format of the `CIRCLE_COMPARE_URL` environment variable, or by retrieving the equivalent of
* `CIRCLE_COMPARE_URL` for jobs that are part of a rerun workflow and extracting it from there.
*
* > !!! WARNING !!!
* > !!
* > !! When [CircleCI Pipelines](https://circleci.com/docs/2.0/build-processing) is enabled, the
* > !! `CIRCLE_COMPARE_URL` environment variable is not available at all and this script does not
* > !! work.
* > !!!!!!!!!!!!!!!
*
* **Context:**
* CircleCI sets the `CIRCLE_COMPARE_URL` environment variable (from which we can extract the commit
* range) on push builds (a.k.a. non-PR, non-scheduled builds). Yet, when a workflow is rerun
@ -21,7 +28,7 @@
* (undocumented) fact that the workspace ID happens to be the same as the workflow ID that first
* created it.
*
* For example, for a job on push build workflow, the CircleCI API will return data that look like:
* For example, for a job on push build workflows, the CircleCI API will return data that look like:
* ```js
* {
* compare: 'THE_COMPARE_URL_WE_ARE_LOOKING_FOR',

155
.github/CODEOWNERS vendored
View File

@ -44,23 +44,19 @@
# alxhub - Alex Rickabaugh
# AndrewKushnir - Andrew Kushnir
# andrewseguin - Andrew Seguin
# benlesh - Ben Lesh
# brandonroberts - Brandon Roberts
# atscott - Andrew Scott
# devversion - Paul Gschwendtner
# filipesilva - Filipe Silva
# gkalpak - George Kalpakas
# hansl - Hans Larsen
# IgorMinar - Igor Minar
# jasonaden - Jason Aden
# jenniferfell - Jennifer Fell
# JiaLiPassion - Jia Li
# josephperrott - Joey Perrott
# kapunahelewong - Kapunahele Wong
# kara - Kara Erickson
# kyliau - Keen Yee Liau
# matsko - Matias Niemelä
# mgechev - Minko Gechev
# mhevery - Misko Hevery
# ocombe - Olivier Combe
# petebacondarwin - Pete Bacon Darwin
# pkozlowski-opensource - Pawel Kozlowski
# robwormald - Rob Wormald
@ -88,9 +84,9 @@
# (secret team to avoid review requests, it also doesn't inherit from @angular/framework because nested teams can't be secret)
#
# - IgorMinar
# - josephperrott
# - kara
# - mhevery
# - alexeagle
# ===========================================================
@ -99,9 +95,8 @@
# Used for approving minor documentation-only changes that don't require engineering review.
# (secret team to avoid review requests, it also doesn't inherit from @angular/framework because nested teams can't be secret)
#
# - brandonroberts
# - gkalpak
# - jenniferfell
# - kapunahelewong
# - petebacondarwin
@ -126,10 +121,9 @@
# @angular/tools-cli
# ===========================================================
#
# - alexeagle
# - filipesilva
# - hansl
# - mgechev
# - vikerman
# ===========================================================
@ -180,8 +174,7 @@
# @angular/fw-forms
# ===========================================================
#
# - kara
# - jasonaden
# - AndrewKushnir
# ===========================================================
@ -203,7 +196,7 @@
# @angular/fw-router
# ===========================================================
#
# - jasonaden
# - atscott
# ===========================================================
@ -221,7 +214,6 @@
#
# - gkalpak
# - petebacondarwin
# - jasonaden
# ===========================================================
@ -237,7 +229,7 @@
#
# - AndrewKushnir
# - mhevery
# - ocombe
# - petebacondarwin
# - vikerman
@ -269,8 +261,8 @@
# @angular/fw-integration
# ===========================================================
#
# - alexeagle
# - IgorMinar
# - josephperrott
# - mhevery
@ -278,7 +270,6 @@
# @angular/docs-infra
# ===========================================================
#
# - brandonroberts
# - gkalpak
# - IgorMinar
# - petebacondarwin
@ -288,8 +279,6 @@
# @angular/fw-docs-intro
# ===========================================================
#
# - jenniferfell
# - brandonroberts
# - IgorMinar
# - stephenfluin
@ -298,16 +287,15 @@
# @angular/fw-docs-observables
# ===========================================================
#
# - benlesh
# - jasonaden
# - alxhub
# ===========================================================
# @angular/fw-docs-packaging
# ===========================================================
#
# - alexeagle
# - IgorMinar
# - vikerman
# ===========================================================
@ -315,10 +303,9 @@
# ===========================================================
#
# - alan-agius4
# - alexeagle
# - hansl
# - IgorMinar
# - mgechev
# - vikerman
# ===========================================================
@ -326,11 +313,9 @@
# ===========================================================
#
# - alan-agius4
# - alexeagle
# - hansl
# - IgorMinar
# - mgechev
# - vikerman
# ===========================================================
@ -349,10 +334,9 @@
# ===========================================================
# @angular/fw-dev-infra
# @angular/dev-infra-framework
# ===========================================================
#
# - alexeagle
# - devversion
# - filipesilva
# - gkalpak
@ -410,6 +394,7 @@
# ================================================
/packages/bazel/** @angular/tools-bazel @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/bazel.md @angular/tools-bazel @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -419,8 +404,11 @@
# ================================================
/packages/compiler/** @angular/fw-compiler @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/examples/compiler/** @angular/fw-compiler @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/compiler-cli/** @angular/fw-compiler @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/angular-compiler-options.md @angular/fw-compiler @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/aot-compiler.md @angular/fw-compiler @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/aot-metadata-errors.md @angular/fw-compiler @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -439,6 +427,7 @@
# ================================================
/packages/compiler-cli/src/ngtools/** @angular/tools-cli @angular/framework-global-approvers
/aio/content/guide/cli-builder.md @angular/tools-cli @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/ivy.md @angular/tools-cli @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/web-worker.md @angular/tools-cli @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -454,12 +443,18 @@
# ================================================
/packages/core/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/examples/core/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/common/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/platform-browser/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/examples/platform-browser/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/platform-browser-dynamic/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/platform-webworker/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/platform-webworker-dynamic/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/examples/common/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/docs/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/accessibility.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/accessibility/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/architecture-components.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/architecture-modules.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -516,6 +511,8 @@
/aio/content/guide/hierarchical-dependency-injection.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/hierarchical-dependency-injection/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/providers-viewproviders/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/resolution-modifiers/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/lazy-loading-ngmodules.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/lazy-loading-ngmodules/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -550,11 +547,12 @@
/aio/content/examples/attribute-binding/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/two-way-binding/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/built-in-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/built-in-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/template-reference-variables/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/inputs-outputs/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/inputs-outputs/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/template-expression-operators/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/pipes.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/pipes/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/pipes/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -587,6 +585,7 @@
/packages/common/http/** @angular/fw-http @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/http/** @angular/fw-http @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/examples/http/** @angular/fw-http @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/http.md @angular/fw-http @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/http/** @angular/fw-http @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/http/** @angular/fw-http @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -609,6 +608,7 @@
# ================================================
/packages/forms/** @angular/fw-forms @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/examples/forms/** @angular/fw-forms @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/forms.md @angular/fw-forms @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/forms/** @angular/fw-forms @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/forms/** @angular/fw-forms @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -652,6 +652,7 @@
# ================================================
/packages/router/** @angular/fw-router @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/examples/router/** @angular/fw-router @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/router.md @angular/fw-router @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/router/** @angular/fw-router @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/router/** @angular/fw-router @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -663,6 +664,7 @@
# ================================================
/packages/service-worker/** @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/packages/examples/service-worker/** @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/service-worker-getting-started.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/service-worker-getting-started/** @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/app-shell.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -689,6 +691,7 @@
/aio/content/examples/upgrade-phonecat-2-hybrid/** @angular/fw-upgrade @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/upgrade-phonecat-3-final/** @angular/fw-upgrade @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/upgrade-performance.md @angular/fw-upgrade @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/upgrade-setup.md @angular/fw-upgrade @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/ajs-quick-reference.md @angular/fw-upgrade @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/ajs-quick-reference/** @angular/fw-upgrade @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -726,7 +729,6 @@ testing/** @angular/fw-test
/aio/content/examples/i18n/** @angular/fw-i18n @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
# ================================================
# @angular security
# ================================================
@ -777,7 +779,6 @@ testing/** @angular/fw-test
/aio/tools/** @angular/docs-infra @angular/framework-global-approvers
# Hidden docs
/aio/content/guide/change-log.md @angular/docs-infra @angular/framework-global-approvers
/aio/content/guide/docs-style-guide.md @angular/docs-infra @angular/framework-global-approvers
/aio/content/examples/docs-style-guide/** @angular/docs-infra @angular/framework-global-approvers
/aio/content/images/guide/docs-style-guide/** @angular/docs-infra @angular/framework-global-approvers
@ -790,9 +791,8 @@ testing/** @angular/fw-test
# Docs: getting started & tutorial
# ================================================
/aio/content/guide/quickstart.md @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/cli-quickstart/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/cli-quickstart/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/setup-local.md @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/setup-local/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/tutorial/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/toh/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/toh-pt0/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -804,8 +804,8 @@ testing/** @angular/fw-test
/aio/content/examples/toh-pt6/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/getting-started-v0/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/getting-started/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/getting-started/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/getting-started/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/start/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/start/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
# ================================================
@ -831,17 +831,18 @@ testing/** @angular/fw-test
/aio/content/guide/npm-packages.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/browser-support.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/typescript-configuration.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/setup.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/setup/** @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/build.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/build/** @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/deployment.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/guide/deployment/** @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/file-structure.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/releases.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/updating.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/workspace-config.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/deprecations.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/migration-renderer.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/migration-undecorated-classes.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
# ================================================
@ -878,44 +879,38 @@ testing/** @angular/fw-test
# ================================================
# Build & CI Owners
# Build, CI & Dev-infra Owners
# ================================================
/* @angular/fw-dev-infra
/.buildkite/** @angular/fw-dev-infra
/.circleci/** @angular/fw-dev-infra
/.devcontainer/** @angular/fw-dev-infra
/.github/** @angular/fw-dev-infra
/.vscode/** @angular/fw-dev-infra
/docs/BAZEL.md @angular/fw-dev-infra
/packages/* @angular/fw-dev-infra
/scripts/** @angular/fw-dev-infra
/third_party/** @angular/fw-dev-infra
/tools/build/** @angular/fw-dev-infra
/tools/cjs-jasmine/** @angular/fw-dev-infra
/tools/gulp-tasks/** @angular/fw-dev-infra
/tools/ngcontainer/** @angular/fw-dev-infra
/tools/npm/** @angular/fw-dev-infra
/tools/npm_workspace/** @angular/fw-dev-infra
/tools/public_api_guard/** @angular/fw-dev-infra
/tools/rxjs/** @angular/fw-dev-infra
/tools/source-map-test/** @angular/fw-dev-infra
/tools/symbol-extractor/** @angular/fw-dev-infra
/tools/testing/** @angular/fw-dev-infra
/tools/ts-api-guardian/** @angular/fw-dev-infra
/tools/tslint/** @angular/fw-dev-infra
/tools/validate-commit-message/** @angular/fw-dev-infra
/tools/yarn/** @angular/fw-dev-infra
/tools/*
*.bzl @angular/fw-dev-infra
# ================================================
# Material CI
# ================================================
/tools/material-ci/** @angular/fw-core @angular/framework-global-approvers
/* @angular/dev-infra-framework
/.buildkite/** @angular/dev-infra-framework
/.circleci/** @angular/dev-infra-framework
/.devcontainer/** @angular/dev-infra-framework
/.github/** @angular/dev-infra-framework
/.vscode/** @angular/dev-infra-framework
/docs/BAZEL.md @angular/dev-infra-framework
/packages/* @angular/dev-infra-framework
/packages/examples/test-utils/** @angular/dev-infra-framework
/packages/private/** @angular/dev-infra-framework
/scripts/** @angular/dev-infra-framework
/third_party/** @angular/dev-infra-framework
/tools/build/** @angular/dev-infra-framework
/tools/cjs-jasmine/** @angular/dev-infra-framework
/tools/gulp-tasks/** @angular/dev-infra-framework
/tools/ngcontainer/** @angular/dev-infra-framework
/tools/npm/** @angular/dev-infra-framework
/tools/npm_workspace/** @angular/dev-infra-framework
/tools/public_api_guard/** @angular/dev-infra-framework
/tools/rxjs/** @angular/dev-infra-framework
/tools/source-map-test/** @angular/dev-infra-framework
/tools/symbol-extractor/** @angular/dev-infra-framework
/tools/testing/** @angular/dev-infra-framework
/tools/ts-api-guardian/** @angular/dev-infra-framework
/tools/tslint/** @angular/dev-infra-framework
/tools/validate-commit-message/** @angular/dev-infra-framework
/tools/yarn/** @angular/dev-infra-framework
/tools/* @angular/dev-infra-framework
*.bzl @angular/dev-infra-framework
@ -931,6 +926,14 @@ testing/** @angular/fw-test
# ================================================
# Special cases
# ================================================
/aio/content/guide/static-query-migration.md @kara @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
# ================================================
# CODEOWNERS Owners owners ...
# ================================================

View File

@ -1,3 +1,49 @@
<a name="8.2.7"></a>
## [8.2.7](https://github.com/angular/angular/compare/8.2.6...8.2.7) (2019-09-18)
### Bug Fixes
* **bazel:** ng_package(data) should support non-text files ([#32721](https://github.com/angular/angular/issues/32721)) ([ba1ef6b](https://github.com/angular/angular/commit/ba1ef6b))
* **compiler-cli:** fix typo in diagnostic template info. ([#32684](https://github.com/angular/angular/issues/32684)) ([947c076](https://github.com/angular/angular/commit/947c076)), closes [#32662](https://github.com/angular/angular/issues/32662)
* **language-service:** cache module resolution ([#32483](https://github.com/angular/angular/issues/32483)) ([1c5b157](https://github.com/angular/angular/commit/1c5b157))
<a name="8.2.6"></a>
## [8.2.6](https://github.com/angular/angular/compare/8.2.5...8.2.6) (2019-09-11)
This release contains various API docs improvements.
<a name="8.2.5"></a>
## [8.2.5](https://github.com/angular/angular/compare/8.2.4...8.2.5) (2019-09-04)
### Bug Fixes
* **common:** HttpParams fromObject accepts ReadonlyArray<string> ([#31072](https://github.com/angular/angular/issues/31072)) ([b3ea698](https://github.com/angular/angular/commit/b3ea698)), closes [#28452](https://github.com/angular/angular/issues/28452)
<a name="8.2.4"></a>
## [8.2.4](https://github.com/angular/angular/compare/8.2.3...8.2.4) (2019-08-28)
This release contains various API docs improvements.
<a name="8.2.3"></a>
## [8.2.3](https://github.com/angular/angular/compare/8.2.2...8.2.3) (2019-08-21)
### Bug Fixes
* **bazel:** pin `[@microsoft](https://github.com/microsoft)/api-extractor` ([#32187](https://github.com/angular/angular/issues/32187)) ([a7b9478](https://github.com/angular/angular/commit/a7b9478))
<a name="8.2.2"></a>
## [8.2.2](https://github.com/angular/angular/compare/8.2.1...8.2.2) (2019-08-12)

View File

@ -233,6 +233,7 @@ There are currently a few exceptions to the "use package name" rule:
* **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
repo
* **ivy**: used for changes to the [Ivy renderer](https://github.com/angular/angular/issues/21706).
* **ngcc**: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all
packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a
specific package (e.g. `docs: fix typo in tutorial`).

View File

@ -6,7 +6,7 @@
# Angular
Angular is a development platform for building mobile and desktop web applications using Typescript/JavaScript and other languages.
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.
## Quickstart

View File

@ -65,6 +65,9 @@ node_repositories(
},
node_version = "10.16.0",
package_json = ["//:package.json"],
yarn_repositories = {
"1.17.3": ("yarn-v1.17.3.tar.gz", "yarn-v1.17.3", "e3835194409f1b3afa1c62ca82f561f1c29d26580c9e220c36866317e043c6f3"),
},
# yarn 1.13.0 under Bazel has a regression on Windows that causes build errors on rebuilds:
# ```
# ERROR: Source forest creation failed: C:/.../fyuc5c3n/execroot/angular/external (Directory not empty)
@ -73,7 +76,7 @@ node_repositories(
# It possible that versions of yarn past 1.13.0 do not have this issue, however, before
# advancing this version we need to test manually on Windows that the above error does not
# happen as the issue is not caught by CI.
yarn_version = "1.12.1",
yarn_version = "1.17.3",
)
yarn_install(

View File

@ -46,6 +46,15 @@ Here are the most important tasks you might need to use:
- `yarn example-e2e --filter=foo` - limit e2e tests to those containing the word "foo"
- `yarn example-e2e --setup --local` - run e2e tests with the local version of Angular contained in the "dist" folder
> **Note for Windows users**
>
> Setting up the examples involves creating some [symbolic links](https://en.wikipedia.org/wiki/Symbolic_link) (see [here](./tools/examples/README.md#symlinked-node_modules) for details). On Windows, this requires to either have [Developer Mode enabled](https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10) (supported on Windows 10 or newer) or run the setup commands as administrator.
>
> The affected commands are:
> - `yarn setup` / `yarn setup-*`
> - `yarn build` / `yarn build-*`
> - `yarn boilerplate:add`
> - `yarn example-e2e --setup`
## Using ServiceWorker locally

View File

@ -0,0 +1,21 @@
'use strict'; // necessary for es6 output in node
import { browser, element, by } from 'protractor';
describe('Accessibility example e2e tests', () => {
beforeEach(() => {
browser.get('');
});
it('should display Accessibility Example', function () {
expect(element(by.css('h1')).getText()).toEqual('Accessibility Example');
});
it('should take a number and change progressbar width', function () {
element(by.css('input')).sendKeys('16');
expect(element(by.css('input')).getAttribute('value')).toEqual('016');
expect(element(by.css('app-example-progressbar div')).getCssValue('width')).toBe('48px');
});
});

View File

@ -0,0 +1,13 @@
<h1>Accessibility Example</h1>
<!-- #docregion template -->
<label>
Enter an example progress value
<input type="number" min="0" max="100"
[value]="progress" (input)="progress = $event.target.value">
</label>
<!-- The user of the progressbar sets an aria-label to communicate what the progress means. -->
<app-example-progressbar [value]="progress" aria-label="Example of a progress bar">
</app-example-progressbar>
<!-- #enddocregion template -->

View File

@ -0,0 +1,10 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
progress = 0;
}

View File

@ -0,0 +1,12 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ExampleProgressbarComponent } from './progress-bar.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent, ExampleProgressbarComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -0,0 +1,12 @@
:host {
display: block;
width: 300px;
height: 25px;
border: 1px solid black;
margin-top: 16px;
}
.bar {
background: blue;
height: 100%;
}

View File

@ -0,0 +1,28 @@
// #docregion progressbar-component
import { Component, Input } from '@angular/core';
/**
* Example progressbar component.
*/
@Component({
selector: 'app-example-progressbar',
template: `<div class="bar" [style.width.%]="value"></div>`,
styleUrls: ['./progress-bar.component.css'],
host: {
// Sets the role for this component to "progressbar"
role: 'progressbar',
// Sets the minimum and maximum values for the progressbar role.
'aria-valuemin': '0',
'aria-valuemax': '100',
// Binding that updates the current value of the progressbar.
'[attr.aria-valuenow]': 'value',
}
})
export class ExampleProgressbarComponent {
/** Current value of the progressbar. */
@Input() value = 0;
}
// #enddocregion progressbar-component

View File

@ -0,0 +1,14 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Accessibility Example</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root>Loading...</app-root>
</body>
</html>

View File

@ -0,0 +1,11 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -0,0 +1,10 @@
{
"description": "Accessibility",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1,2].*"
],
"file": "src/app/app.component.ts",
"tags": ["Accessibility"]
}

View File

@ -1,6 +1,6 @@
// #docplaster
// #docregion imports
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { CartService } from '../cart.service';
// #enddocregion imports
@ -10,12 +10,14 @@ import { CartService } from '../cart.service';
styleUrls: ['./cart.component.css']
})
// #docregion props-services, submit
export class CartComponent {
export class CartComponent implements OnInit {
items;
constructor(
private cartService: CartService
) {
) { }
ngOnInit() {
this.items = this.cartService.getItems();
}
}

View File

@ -1,6 +1,6 @@
// #docplaster
// #docregion imports
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { CartService } from '../cart.service';
// #enddocregion
@ -11,7 +11,7 @@ import { CartService } from '../cart.service';
styleUrls: ['./shipping.component.css']
})
// #docregion props, ctor
export class ShippingComponent {
export class ShippingComponent implements OnInit {
shippingCosts;
// #enddocregion props
@ -19,10 +19,12 @@ export class ShippingComponent {
constructor(
private cartService: CartService
) {
// #enddocregion inject-cart-service
this.shippingCosts = this.cartService.getShippingPrices();
// #docregion inject-cart-service
}
// #enddocregion inject-cart-service
ngOnInit() {
this.shippingCosts = this.cartService.getShippingPrices();
}
// #docregion props
}

View File

@ -1,6 +1,6 @@
<h1>HTTP Sample</h1>
<div>
<input type="checkbox" id="heroes" [checked]="toggleHeroes" (click)="toggleHeroes()">
<input type="checkbox" id="heroes" [checked]="showHeroes" (click)="toggleHeroes()">
<label for="heroes">Heroes</label>
<input type="checkbox" id="config" [checked]="showConfig" (click)="toggleConfig()">

View File

@ -12,7 +12,7 @@ if (environment.production) {
// use the require method provided by webpack
declare const require;
// we use the webpack raw-loader to return the content as a string
const translations = require(`raw-loader!./locale/messages.fr.xlf`);
const translations = require('raw-loader!./locale/messages.fr.xlf').default;
platformBrowserDynamic().bootstrapModule(AppModule, {
providers: [

View File

@ -0,0 +1,24 @@
import { browser, element, by } from 'protractor';
import { logging } from 'selenium-webdriver';
describe('Providers and ViewProviders', function () {
beforeEach(() => {
browser.get('');
});
it('shows basic flower emoji', function() {
expect(element.all(by.css('p')).get(0).getText()).toContain('🌺');
});
it('shows whale emoji', function() {
expect(element.all(by.css('p')).get(1).getText()).toContain('🐳');
});
it('shows sunflower from FlowerService', function() {
expect(element.all(by.css('p')).get(8).getText()).toContain('🌻');
});
});

View File

@ -0,0 +1,10 @@
// #docregion animal-service
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AnimalService {
emoji = '🐳';
}
// #enddocregion animal-service

View File

@ -0,0 +1,15 @@
import { Component } from '@angular/core';
import { FlowerService } from './flower.service';
import { AnimalService } from './animal.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
// #docregion injection
export class AppComponent {
constructor(public flower: FlowerService) {}
}
// #enddocregion injection

View File

@ -0,0 +1,15 @@
<h2>From AppComponent:</h2>
<!-- #docregion binding-flower -->
<p>Emoji from FlowerService: {{flower.emoji}}</p>
<!-- #enddocregion binding-flower -->
<!-- #docregion binding-animal -->
<p>Emoji from AnimalService: {{animal.emoji}}</p>
<!-- #enddocregion binding-animal -->
<hr />
<h2>From ChildComponent:</h2>
<!-- #docregion content-projection -->
<app-child><app-inspector></app-inspector></app-child>
<!-- #enddocregion content-projection -->

View File

@ -0,0 +1,31 @@
import { Component } from '@angular/core';
import { FlowerService } from './flower.service';
import { AnimalService } from './animal.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
// #docregion inject-animal-service
export class AppComponent {
constructor(public flower: FlowerService, public animal: AnimalService) {}
}
// #enddocregion inject-animal-service
// When using @Host() together with @SkipSelf() in
// child.component.ts for the AnimalService, add the
// following viewProviders array to the @Component metadata:
// viewProviders: [{ provide: AnimalService, useValue: { emoji: '🦔' } }]
// So, the entire @ChildComponent() decorator and its
// metadata should be as follows:
// @Component({
// selector: 'app-root',
// templateUrl: './app.component.html',
// styleUrls: [ './app.component.css' ],
// viewProviders: [{ provide: AnimalService, useValue: { emoji: '🦔' } }]
// })

View File

@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { ChildComponent } from './child/child.component';
import { InspectorComponent } from './inspector/inspector.component';
// #docregion appmodule
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent, ChildComponent, InspectorComponent ],
bootstrap: [ AppComponent ],
providers: []
})
export class AppModule { }
// #enddocregion appmodule

View File

@ -0,0 +1,19 @@
import { Component, OnInit, Host, SkipSelf, Optional } from '@angular/core';
import { FlowerService } from '../flower.service';
// #docregion flowerservice
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
// use the providers array to provide a service
providers: [{ provide: FlowerService, useValue: { emoji: '🌻' } }]
})
export class ChildComponent {
// inject the service
constructor( public flower: FlowerService) { }
}
// #enddocregion flowerservice

View File

@ -0,0 +1,4 @@
.container {
border: 1px solid darkblue;
padding: 1rem;
}

View File

@ -0,0 +1,24 @@
<!-- #docplaster -->
<!-- #docregion child-component -->
<!-- #docregion flower-binding -->
<p>Emoji from FlowerService: {{flower.emoji}}</p>
<!-- #enddocregion flower-binding -->
<!-- #docregion animal-binding -->
<p>Emoji from AnimalService: {{animal.emoji}}</p>
<!-- #enddocregion animal-binding -->
<div class="container">
<h3>Content projection</h3>
<!-- #enddocregion child-component -->
<p>The following is coming from content. It doesn't get to see the puppy because the puppy is declared inside the view only.</p>
<!-- #docregion child-component -->
<ng-content></ng-content>
</div>
<h3>Inside the view</h3>
<!-- #enddocregion child-component -->
<p>The following is inside the view so it does see the puppy.</p>
<!-- #docregion child-component -->
<app-inspector></app-inspector>
<!-- #enddocregion child-component -->

View File

@ -0,0 +1,44 @@
// #docplaster
import { Component, OnInit, Host, SkipSelf, Optional } from '@angular/core';
import { FlowerService } from '../flower.service';
import { AnimalService } from '../animal.service';
// #docregion provide-animal-service
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
// provide services
providers: [{ provide: FlowerService, useValue: { emoji: '🌻' } }],
viewProviders: [{ provide: AnimalService, useValue: { emoji: '🐶' } }]
})
export class ChildComponent {
// inject service
constructor( public flower: FlowerService, public animal: AnimalService) { }
// #enddocregion provide-animal-service
// viewProviders ensures that only the view gets to see this.
// With the AnimalService in the viewProviders, the
// InspectorComponent doesn't get to see it because the
// inspector is in the content.
// constructor( public flower: FlowerService, @Optional() @Host() public animal: AnimalService) { }
// Comment out the above constructor and alternately
// uncomment the two following constructors to see the
// effects of @Host() and @Host() + @SkipSelf().
// constructor(
// @Host() public animal : AnimalService,
// @Host() @Optional() public flower : FlowerService) { }
// constructor(
// @SkipSelf() @Host() public animal : AnimalService,
// @SkipSelf() @Host() @Optional() public flower : FlowerService) { }
// #docregion provide-animal-service
}
// #enddocregion provide-animal-service

View File

@ -0,0 +1,11 @@
import { Injectable } from '@angular/core';
// #docregion flowerservice
@Injectable({
providedIn: 'root'
})
export class FlowerService {
emoji = '🌺';
}
// #enddocregion flowerservice

View File

@ -0,0 +1,4 @@
<!-- #docregion binding -->
<p>Emoji from FlowerService: {{flower.emoji}}</p>
<p>Emoji from AnimalService: {{animal.emoji}}</p>
<!-- #enddocregion binding -->

View File

@ -0,0 +1,14 @@
import { Component } from '@angular/core';
import { FlowerService } from '../flower.service';
import { AnimalService } from '../animal.service';
@Component({
selector: 'app-inspector',
templateUrl: './inspector.component.html',
styleUrls: ['./inspector.component.css']
})
// #docregion injection
export class InspectorComponent {
constructor(public flower: FlowerService, public animal: AnimalService) { }
}
// #enddocregion injection

View File

@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>providers vs. viewProviders</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>

View File

@ -0,0 +1,12 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));

View File

@ -0,0 +1,10 @@
{
"description": "Inputs and Outputs",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1,2].*"
],
"file": "src/app/app.component.ts",
"tags": ["Inputs and Outputs"]
}

View File

@ -0,0 +1,21 @@
import { browser, element, by } from 'protractor';
describe('Resolution-modifiers-example', function () {
beforeAll(function () {
browser.get('');
});
it('shows basic flower emoji', function() {
expect(element.all(by.css('p')).get(0).getText()).toContain('🌸');
});
it('shows basic leaf emoji', function() {
expect(element.all(by.css('p')).get(1).getText()).toContain('🌿');
});
it('shows yellow flower in host child', function() {
expect(element.all(by.css('p')).get(9).getText()).toContain('🌼');
});
});

View File

@ -0,0 +1,14 @@
<h1>DI resolution modifiers</h1>
<p>Basic flower service: {{flower.emoji}}</p>
<p>Basic leaf service: {{leaf.emoji}}</p>
<app-optional></app-optional>
<app-self></app-self>
<app-self-no-data></app-self-no-data>
<app-skipself></app-skipself>
<app-host-parent></app-host-parent>

View File

@ -0,0 +1,13 @@
import { Component } from '@angular/core';
import { LeafService } from './leaf.service';
import { FlowerService } from './flower.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
constructor(public flower: FlowerService, public leaf: LeafService) {}
}

View File

@ -0,0 +1,33 @@
;
import { OptionalComponent } from './optional/optional.component';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { SelfNoDataComponent } from './self-no-data/self-no-data.component';
import { HostComponent } from './host/host.component';
import { SelfComponent } from './self/self.component';
import { SkipselfComponent } from './skipself/skipself.component';
import { HostParentComponent } from './host-parent/host-parent.component';
import { HostChildComponent } from './host-child/host-child.component';
@NgModule({
imports: [
BrowserModule,
FormsModule
],
declarations: [
AppComponent,
OptionalComponent,
SelfComponent,
SelfNoDataComponent,
HostComponent,
SkipselfComponent,
HostParentComponent,
HostChildComponent
],
bootstrap: [AppComponent],
providers: []
})
export class AppModule { }

View File

@ -0,0 +1,9 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // provide this service in the root ModuleInjector
})
export class FlowerService {
emoji = '🌸';
}

View File

@ -0,0 +1,5 @@
.section {
border: 2px solid #369;
padding: 1rem;
margin: 1rem 0;
}

View File

@ -0,0 +1,4 @@
<div class="section">
<h2>Child of @Host() Component</h2>
<p>Flower emoji: {{flower.emoji}}</p>
</div>

View File

@ -0,0 +1,11 @@
import { Component } from '@angular/core';
import { FlowerService } from '../flower.service';
@Component({
selector: 'app-host-child',
templateUrl: './host-child.component.html',
styleUrls: ['./host-child.component.css']
})
export class HostChildComponent {
constructor(public flower: FlowerService) { }
}

View File

@ -0,0 +1,5 @@
.section {
border: 2px solid #369;
padding: 1rem;
margin: 1rem 0;
}

View File

@ -0,0 +1,5 @@
<div class="section">
<h2>Parent of @Host() Component</h2>
<p>Flower emoji: {{flower.emoji}}</p>
<app-host></app-host>
</div>

View File

@ -0,0 +1,16 @@
import { Component } from '@angular/core';
import { FlowerService } from '../flower.service';
@Component({
selector: 'app-host-parent',
templateUrl: './host-parent.component.html',
styleUrls: ['./host-parent.component.css'],
providers: [{ provide: FlowerService, useValue: { emoji: '🌺' } }]
})
export class HostParentComponent {
constructor(public flower: FlowerService) { }
}

View File

@ -0,0 +1,5 @@
.section {
border: 2px solid #369;
padding: 1rem;
margin: 1rem 0;
}

View File

@ -0,0 +1,6 @@
<div class="section">
<h2>@Host() Component</h2>
<p>Flower emoji: {{flower.emoji}}</p>
<p><i>(@Host() stops it here)</i></p>
<app-host-child></app-host-child>
</div>

View File

@ -0,0 +1,21 @@
import { Component, Host, Optional } from '@angular/core';
import { FlowerService } from '../flower.service';
// #docregion host-component
@Component({
selector: 'app-host',
templateUrl: './host.component.html',
styleUrls: ['./host.component.css'],
// provide the service
providers: [{ provide: FlowerService, useValue: { emoji: '🌼' } }]
})
export class HostComponent {
// use @Host() in the constructor when injecting the service
constructor(@Host() @Optional() public flower: FlowerService) { }
}
// #enddocregion host-component
// if you take out @Host() and the providers array, flower will be red hibiscus

View File

@ -0,0 +1,11 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
// #docregion leafservice
export class LeafService {
emoji = '🌿';
}
// #enddocregion leafservice

View File

@ -0,0 +1,7 @@
import { Injectable } from '@angular/core';
@Injectable()
export class OptionalService {
}
// This service isn't provided anywhere.

View File

@ -0,0 +1,5 @@
.section {
border: 2px solid #369;
padding: 1rem;
margin: 1rem 0;
}

View File

@ -0,0 +1,4 @@
<div class="section">
<h2>@Optional() Component</h2>
<p>This component still works even though the OptionalService (notice @Optional() in the consturctor isn't provided or configured anywhere. Angular goes through tree and visibilty rules, and if it doesn't find the requested service, returns null.</p>
</div>

View File

@ -0,0 +1,21 @@
import { Component, Optional } from '@angular/core';
import { OptionalService } from '../optional.service';
@Component({
selector: 'app-optional',
templateUrl: './optional.component.html',
styleUrls: ['./optional.component.css']
})
// #docregion optional-component
export class OptionalComponent {
constructor(@Optional() public optional: OptionalService) {}
}
// #enddocregion optional-component
// The OptionalService isn't provided here, in the @Injectable()
// providers array, or in the NgModule. If you remove @Optional()
// from the constructor, you'll get an error.

View File

@ -0,0 +1,5 @@
.section {
border: 2px solid #369;
padding: 1rem;
margin: 1rem 0;
}

View File

@ -0,0 +1,4 @@
<div class="section">
<h2>@Self() Component (without a provider)</h2>
<p>Leaf emoji: {{leaf?.emoji}}</p>
</div>

View File

@ -0,0 +1,18 @@
import { Component, Self, Optional } from '@angular/core';
import { LeafService } from '../leaf.service';
// #docregion self-no-data-component
@Component({
selector: 'app-self-no-data',
templateUrl: './self-no-data.component.html',
styleUrls: ['./self-no-data.component.css']
})
export class SelfNoDataComponent {
constructor(@Self() @Optional() public leaf: LeafService) { }
}
// #enddocregion self-no-data-component
// The app doesn't break because the value being available at self is optional.
// If you remove @Optional(), the app breaks.

View File

@ -0,0 +1,5 @@
.section {
border: 2px solid #369;
padding: 1rem;
margin: 1rem 0;
}

View File

@ -0,0 +1,4 @@
<div class="section">
<h2>@Self() Component</h2>
<p>Flower emoji: {{flower?.emoji}}</p>
</div>

View File

@ -0,0 +1,19 @@
import { Component, Self } from '@angular/core';
import { FlowerService } from '../flower.service';
// #docregion self-component
@Component({
selector: 'app-self',
templateUrl: './self.component.html',
styleUrls: ['./self.component.css'],
providers: [{ provide: FlowerService, useValue: { emoji: '🌼' } }]
})
export class SelfComponent {
constructor(@Self() public flower: FlowerService) {}
}
// #enddocregion self-component
// This component provides the FlowerService so the injector
// doesn't have to look further up the injector tree

View File

@ -0,0 +1,5 @@
.section {
border: 2px solid #369;
padding: 1rem;
margin: 1rem 0;
}

View File

@ -0,0 +1,4 @@
<div class="section">
<h2>@SkipSelf() Component</h2>
<p>Leaf emoji: {{leaf.emoji}}</p>
</div>

View File

@ -0,0 +1,18 @@
import { Component, SkipSelf } from '@angular/core';
import { LeafService } from '../leaf.service';
// #docregion skipself-component
@Component({
selector: 'app-skipself',
templateUrl: './skipself.component.html',
styleUrls: ['./skipself.component.css'],
// Angular would ignore this LeafService instance
providers: [{ provide: LeafService, useValue: { emoji: '🍁' } }]
})
export class SkipselfComponent {
// Use @SkipSelf() in the constructor
constructor(@SkipSelf() public leaf: LeafService) { }
}
// #enddocregion skipself-component
// @SkipSelf(): Specifies that the dependency resolution should start from the parent injector, not here.

View File

@ -0,0 +1,14 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>DI Resolution Modifiers Example</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root>Loading...</app-root>
</body>
</html>

View File

@ -0,0 +1,11 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -0,0 +1,10 @@
{
"description": "NgModules",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1,2].*"
],
"file": "src/app/app.component.ts",
"tags": ["NgModules"]
}

View File

@ -12,7 +12,7 @@ import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
* then the templated elements are removed removed from the DOM,
* the templated elements are (re)inserted into the DOM.
*
* <div *ngUnless="errorCount" class="success">
* <div *appUnless="errorCount" class="success">
* Congrats! Everything is great!
* </div>
*

View File

@ -84,48 +84,15 @@ The following example shows how to make a simple progress bar accessible by usin
* The component defines an accessibility-enabled element with both the standard HTML attribute `role`, and ARIA attributes. The ARIA attribute `aria-valuenow` is bound to the user's input.
```ts
import { Component, Input } from '@angular/core';
/**
* Example progressbar component.
*/
@Component({
selector: 'example-progressbar',
template: `<div class="bar" [style.width.%]="value"></div>`,
styleUrls: ['./progress-bar.css'],
host: {
// Sets the role for this component to "progressbar"
role: 'progressbar',
<code-example path="accessibility/src/app/progress-bar.component.ts" header="src/app/progress-bar.component.ts" region="progressbar-component"></code-example>
// Sets the minimum and maximum values for the progressbar role.
'aria-valuemin': '0',
'aria-valuemax': '0',
// Binding that updates the current value of the progressbar.
'[attr.aria-valuenow]': 'value',
}
})
export class ExampleProgressbar {
/** Current value of the progressbar. */
@Input() value: number = 0;
}
```
* In the template, the `aria-label` attribute ensures that the control is accessible to screen readers.
```html
<label>
Enter an example progress value
<input type="number" min="0" max="100"
[value]="progress" (input)="progress = $event.target.value">
</label>
<code-example path="accessibility/src/app/app.component.html" header="src/app/app.component.html" region="template"></code-example>
<!-- The user of the progressbar sets an aria-label to communicate what the progress means. -->
<example-progressbar [value]="progress" aria-label="Example of a progress bar">
</example-progressbar>
```
[See the full example in StackBlitz](https://stackblitz.com/edit/angular-kn5jdi?file=src%2Fapp%2Fapp.component.html).
To see the progress bar in a working example app, refer to the <live-example></live-example>.
## Routing and focus management

View File

@ -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 `tsconfig.json` [TypeScript configuration file](guide/typescript-configuration).
When you use [AoT compilation](guide/aot-compiler), you can control how your application is compiled by specifying *template* compiler options in the `tsconfig.json` [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.
@ -17,7 +17,38 @@ The template options object, `angularCompilerOptions`, is a sibling to the `comp
}
}
```
This page describes the available Angular template compiler options.
{@a tsconfig-extends}
## Configuration inheritance with extends
Like the TypeScript compiler, The Angular AoT compiler also supports `extends` in the `angularCompilerOptions` section of the TypeScript configuration file, `tsconfig.json`.
The `extends` property is at the top level, parallel to `compilerOptions` and `angularCompilerOptions`.
A TypeScript configuration can inherit settings from another file using the `extends` property.
The configuration options from the base file are loaded first, then overridden by those in the inheriting `tsconfig` file.
For example:
```json
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true,
...
}
}
```
For more informaton, see the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).
## Template options
The following options are available for configuring the AoT template compiler.
### `allowEmptyCodegenFiles`
@ -29,7 +60,7 @@ Modifies how Angular-specific annotations are emitted to improve tree-shaking. N
* 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. TypeScript emits calls to the` __decorate` helper. Use `--emitDecoratorMetadata` for runtime reflection (but note taht the resulting code will not properly tree-shake.
* The `decorators` value leaves the decorators in place, which makes compilation faster. TypeScript emits calls to the` __decorate` helper. Use `--emitDecoratorMetadata` for runtime reflection (but note that the resulting code will not properly tree-shake.
### `annotateForClosureCompiler`
@ -57,7 +88,7 @@ When enabled, the `.js` output of `ngc` does not include any lazy-loaded templat
### `enableLegacyTemplate`
When true, enables use of the `<template>` element, which was deprecated in Angular 4.0, in favor of `<ng-template>` (to avoid colliding with the DOM's element of the same name). Default is false. Might be required by some third-party Angular libraries. |
When true, enables use of the `<template>` element, which was deprecated in Angular 4.0, in favor of `<ng-template>` (to avoid colliding with the DOM's element of the same name). Default is false. Might be required by some third-party Angular libraries.
### `flatModuleId`

View File

@ -260,7 +260,7 @@ What it does
</tr>
<tr>
<td><code>state()</code></td>
<td><code><a href="api/animations/state" class="code-anchor">state()</a></code></td>
<td>Creates a named set of CSS styles that should be applied on successful transition to a given state. The state can then be referenced by name within other animation functions.</td>
</tr>
@ -280,7 +280,7 @@ What it does
</tr>
<tr>
<td><code>group()</code></td>
<td><code><a href="api/animations/group" class="code-anchor">group()</a></code></td>
<td>Specifies a group of animation steps (<em>inner animations</em>) to be run in parallel. Animation continues only after all inner animation steps have completed. Used within <code>sequence()</code> or <code>transition().</code></td>
</tr>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,540 @@
# AoT metadata errors
The following are metadata errors you may encounter, with explanations and suggested corrections.
[Expression form not supported](#expression-form-not-supported)<br>
[Reference to a local (non-exported) symbol](#reference-to-a-local-symbol)<br>
[Only initialized variables and constants](#only-initialized-variables)<br>
[Reference to a non-exported class](#reference-to-a-non-exported-class)<br>
[Reference to a non-exported function](#reference-to-a-non-exported-function)<br>
[Function calls are not supported](#function-calls-not-supported)<br>
[Destructured variable or constant not supported](#destructured-variable-not-supported)<br>
[Could not resolve type](#could-not-resolve-type)<br>
[Name expected](#name-expected)<br>
[Unsupported enum member name](#unsupported-enum-member-name)<br>
[Tagged template expressions are not supported](#tagged-template-expressions-not-supported)<br>
[Symbol reference expected](#symbol-reference-expected)<br>
<hr>
{@a expression-form-not-supported}
## Expression form not supported
<div class="alert is-helpful">
*The compiler encountered an expression it didn't understand while evaluating Angular metadata.*
</div>
Language features outside of the compiler's [restricted expression syntax](guide/aot-compiler#expression-syntax)
can produce this error, as seen in the following example:
```ts
// ERROR
export class Fooish { ... }
...
const prop = typeof Fooish; // typeof is not valid in metadata
...
// bracket notation is not valid in metadata
{ provide: 'token', useValue: { [prop]: 'value' } };
...
```
You can use `typeof` and bracket notation in normal application code.
You just can't use those features within expressions that define Angular metadata.
Avoid this error by sticking to the compiler's [restricted expression syntax](guide/aot-compiler#expression-syntax)
when writing Angular metadata
and be wary of new or unusual TypeScript features.
<hr>
{@a reference-to-a-local-symbol}
## Reference to a local (non-exported) symbol
<div class="alert is-helpful">
_Reference to a local (non-exported) symbol 'symbol name'. Consider exporting the symbol._
</div>
The compiler encountered a referenced to a locally defined symbol that either wasn't exported or wasn't initialized.
Here's a `provider` example of the problem.
```ts
// ERROR
let foo: number; // neither exported nor initialized
@Component({
selector: 'my-component',
template: ... ,
providers: [
{ provide: Foo, useValue: foo }
]
})
export class MyComponent {}
```
The compiler generates the component factory, which includes the `useValue` provider code, in a separate module. _That_ factory module can't reach back to _this_ source module to access the local (non-exported) `foo` variable.
You could fix the problem by initializing `foo`.
```ts
let foo = 42; // initialized
```
The compiler will [fold](guide/aot-compiler#code-folding) the expression into the provider as if you had written this.
```ts
providers: [
{ provide: Foo, useValue: 42 }
]
```
Alternatively, you can fix it by exporting `foo` with the expectation that `foo` will be assigned at runtime when you actually know its value.
```ts
// CORRECTED
export let foo: number; // exported
@Component({
selector: 'my-component',
template: ... ,
providers: [
{ provide: Foo, useValue: foo }
]
})
export class MyComponent {}
```
Adding `export` often works for variables referenced in metadata such as `providers` and `animations` because the compiler can generate _references_ to the exported variables in these expressions. It doesn't need the _values_ of those variables.
Adding `export` doesn't work when the compiler needs the _actual value_
in order to generate code.
For example, it doesn't work for the `template` property.
```ts
// ERROR
export let someTemplate: string; // exported but not initialized
@Component({
selector: 'my-component',
template: someTemplate
})
export class MyComponent {}
```
The compiler needs the value of the `template` property _right now_ to generate the component factory.
The variable reference alone is insufficient.
Prefixing the declaration with `export` merely produces a new error, "[`Only initialized variables and constants can be referenced`](#only-initialized-variables)".
<hr>
{@a only-initialized-variables}
## Only initialized variables and constants
<div class="alert is-helpful">
_Only initialized variables and constants can be referenced because the value of this variable is needed by the template compiler._
</div>
The compiler found a reference to an exported variable or static field that wasn't initialized.
It needs the value of that variable to generate code.
The following example tries to set the component's `template` property to the value of
the exported `someTemplate` variable which is declared but _unassigned_.
```ts
// ERROR
export let someTemplate: string;
@Component({
selector: 'my-component',
template: someTemplate
})
export class MyComponent {}
```
You'd also get this error if you imported `someTemplate` from some other module and neglected to initialize it there.
```ts
// ERROR - not initialized there either
import { someTemplate } from './config';
@Component({
selector: 'my-component',
template: someTemplate
})
export class MyComponent {}
```
The compiler cannot wait until runtime to get the template information.
It must statically derive the value of the `someTemplate` variable from the source code
so that it can generate the component factory, which includes
instructions for building the element based on the template.
To correct this error, provide the initial value of the variable in an initializer clause _on the same line_.
```ts
// CORRECTED
export let someTemplate = '<h1>Greetings from Angular</h1>';
@Component({
selector: 'my-component',
template: someTemplate
})
export class MyComponent {}
```
<hr>
{@a reference-to-a-non-exported-class}
## Reference to a non-exported class
<div class="alert is-helpful">
_Reference to a non-exported class <class name>. Consider exporting the class._
</div>
Metadata referenced a class that wasn't exported.
For example, you may have defined a class and used it as an injection token in a providers array
but neglected to export that class.
```ts
// ERROR
abstract class MyStrategy { }
...
providers: [
{ provide: MyStrategy, useValue: ... }
]
...
```
Angular generates a class factory in a separate module and that
factory [can only access exported classes](guide/aot-compiler#exported-symbols).
To correct this error, export the referenced class.
```ts
// CORRECTED
export abstract class MyStrategy { }
...
providers: [
{ provide: MyStrategy, useValue: ... }
]
...
```
<hr>
{@a reference-to-a-non-exported-function}
## Reference to a non-exported function
<div class="alert is-helpful">
*Metadata referenced a function that wasn't exported.*
</div>
For example, you may have set a providers `useFactory` property to a locally defined function that you neglected to export.
```ts
// ERROR
function myStrategy() { ... }
...
providers: [
{ provide: MyStrategy, useFactory: myStrategy }
]
...
```
Angular generates a class factory in a separate module and that
factory [can only access exported functions](guide/aot-compiler#exported-symbols).
To correct this error, export the function.
```ts
// CORRECTED
export function myStrategy() { ... }
...
providers: [
{ provide: MyStrategy, useFactory: myStrategy }
]
...
```
<hr>
{@a function-calls-not-supported}
## Function calls are not supported
<div class="alert is-helpful">
_Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function._
</div>
The compiler does not currently support [function expressions or lambda functions](guide/aot-compiler#function-expression).
For example, you cannot set a provider's `useFactory` to an anonymous function or arrow function like this.
```ts
// ERROR
...
providers: [
{ provide: MyStrategy, useFactory: function() { ... } },
{ provide: OtherStrategy, useFactory: () => { ... } }
]
...
```
You also get this error if you call a function or method in a provider's `useValue`.
```ts
// ERROR
import { calculateValue } from './utilities';
...
providers: [
{ provide: SomeValue, useValue: calculateValue() }
]
...
```
To correct this error, export a function from the module and refer to the function in a `useFactory` provider instead.
```ts
// CORRECTED
import { calculateValue } from './utilities';
export function myStrategy() { ... }
export function otherStrategy() { ... }
export function someValueFactory() {
return calculateValue();
}
...
providers: [
{ provide: MyStrategy, useFactory: myStrategy },
{ provide: OtherStrategy, useFactory: otherStrategy },
{ provide: SomeValue, useFactory: someValueFactory }
]
...
```
<hr>
{@a destructured-variable-not-supported}
## Destructured variable or constant not supported
<div class="alert is-helpful">
_Referencing an exported destructured variable or constant is not supported by the template compiler. Consider simplifying this to avoid destructuring._
</div>
The compiler does not support references to variables assigned by [destructuring](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#destructuring).
For example, you cannot write something like this:
```ts
// ERROR
import { configuration } from './configuration';
// destructured assignment to foo and bar
const {foo, bar} = configuration;
...
providers: [
{provide: Foo, useValue: foo},
{provide: Bar, useValue: bar},
]
...
```
To correct this error, refer to non-destructured values.
```ts
// CORRECTED
import { configuration } from './configuration';
...
providers: [
{provide: Foo, useValue: configuration.foo},
{provide: Bar, useValue: configuration.bar},
]
...
```
<hr>
{@a could-not-resolve-type}
## Could not resolve type
<div class="alert is-helpful">
*The compiler encountered a type and can't determine which module exports that type.*
</div>
This can happen if you refer to an ambient type.
For example, the `Window` type is an ambient type declared in the global `.d.ts` file.
You'll get an error if you reference it in the component constructor,
which the compiler must statically analyze.
```ts
// ERROR
@Component({ })
export class MyComponent {
constructor (private win: Window) { ... }
}
```
TypeScript understands ambient types so you don't import them.
The Angular compiler does not understand a type that you neglect to export or import.
In this case, the compiler doesn't understand how to inject something with the `Window` token.
Do not refer to ambient types in metadata expressions.
If you must inject an instance of an ambient type,
you can finesse the problem in four steps:
1. Create an injection token for an instance of the ambient type.
1. Create a factory function that returns that instance.
1. Add a `useFactory` provider with that factory function.
1. Use `@Inject` to inject the instance.
Here's an illustrative example.
```ts
// CORRECTED
import { Inject } from '@angular/core';
export const WINDOW = new InjectionToken('Window');
export function _window() { return window; }
@Component({
...
providers: [
{ provide: WINDOW, useFactory: _window }
]
})
export class MyComponent {
constructor (@Inject(WINDOW) private win: Window) { ... }
}
```
The `Window` type in the constructor is no longer a problem for the compiler because it
uses the `@Inject(WINDOW)` to generate the injection code.
Angular does something similar with the `DOCUMENT` token so you can inject the browser's `document` object (or an abstraction of it, depending upon the platform in which the application runs).
```ts
import { Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
@Component({ ... })
export class MyComponent {
constructor (@Inject(DOCUMENT) private doc: Document) { ... }
}
```
<hr>
{@a name-expected}
## Name expected
<div class="alert is-helpful">
*The compiler expected a name in an expression it was evaluating.*
</div>
This can happen if you use a number as a property name as in the following example.
```ts
// ERROR
provider: [{ provide: Foo, useValue: { 0: 'test' } }]
```
Change the name of the property to something non-numeric.
```ts
// CORRECTED
provider: [{ provide: Foo, useValue: { '0': 'test' } }]
```
<hr>
{@a unsupported-enum-member-name}
## Unsupported enum member name
<div class="alert is-helpful">
*Angular couldn't determine the value of the [enum member](https://www.typescriptlang.org/docs/handbook/enums.html) that you referenced in metadata.*
</div>
The compiler can understand simple enum values but not complex values such as those derived from computed properties.
```ts
// ERROR
enum Colors {
Red = 1,
White,
Blue = "Blue".length // computed
}
...
providers: [
{ provide: BaseColor, useValue: Colors.White } // ok
{ provide: DangerColor, useValue: Colors.Red } // ok
{ provide: StrongColor, useValue: Colors.Blue } // bad
]
...
```
Avoid referring to enums with complicated initializers or computed properties.
<hr>
{@a tagged-template-expressions-not-supported}
## Tagged template expressions are not supported
<div class="alert is-helpful">
_Tagged template expressions are not supported in metadata._
</div>
The compiler encountered a JavaScript ES2015 [tagged template expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals) such as the following.
```ts
// ERROR
const expression = 'funky';
const raw = String.raw`A tagged template ${expression} string`;
...
template: '<div>' + raw + '</div>'
...
```
[`String.raw()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw)
is a _tag function_ native to JavaScript ES2015.
The AoT compiler does not support tagged template expressions; avoid them in metadata expressions.
<hr>
{@a symbol-reference-expected}
## Symbol reference expected
<div class="alert is-helpful">
*The compiler expected a reference to a symbol at the location specified in the error message.*
</div>
This error can occur if you use an expression in the `extends` clause of a class.
<!--
Chuck: After reviewing your PR comment I'm still at a loss. See [comment there](https://github.com/angular/angular/pull/17712#discussion_r132025495).
-->

View File

@ -44,6 +44,12 @@ After running this command you will notice that the `angular.json` configuration
"browserTarget": "my-app:build",
"serverTarget": "my-app:server",
"route": "shell"
},
"configurations": {
"production": {
"browserTarget": "my-app:build:production",
"serverTarget": "my-app:server:production"
}
}
}
</code-example>
@ -56,4 +62,12 @@ Use the CLI to build the `app-shell` target.
ng run my-app:app-shell
</code-example>
Or to use the production configuration.
<code-example language="bash">
ng run my-app:app-shell:production
</code-example>
To verify the build output, open `dist/my-app/index.html`. Look for default text `app-shell works!` to show that the app shell route was rendered as part of the output.

View File

@ -8,13 +8,7 @@ This page discusses build-specific configuration options for Angular projects.
You can define different named build configurations for your project, such as *stage* and *production*, with different defaults.
Each named build configuration can have defaults for any of the options that apply to the various build targets, such as `build`, `serve`, and `test`. The [Angular CLI](cli) `build`, `serve`, and `test` commands can then replace files with appropriate versions for your intended target environment.
The following figure shows how a project has multiple build targets, which can be executed using the named configurations that you define.
<figure>
<img src="generated/images/guide/build/build-config-targets.gif" alt="build configurations and targets">
</figure>
Each named configuration can have defaults for any of the options that apply to the various [builder targets](guide/glossary#target), such as `build`, `serve`, and `test`. The [Angular CLI](cli) `build`, `serve`, and `test` commands can then replace files with appropriate versions for your intended target environment.
### Configure environment-specific defaults
@ -170,8 +164,9 @@ You can also configure the `serve` command to use the targeted build configurati
```
{@a size-budgets}
{@a configure-size-budgets}
## Configure size budgets
## Configuring size budgets
As applications grow in functionality, they also grow in size.
The CLI allows you to set size thresholds in your configuration to ensure that parts of your application stay within size boundaries that you define.
@ -296,10 +291,9 @@ Autoprefixer looks for the `browserslist` configuration when it prefixes your CS
See the [browserslist repo](https://github.com/browserslist/browserslist) for more examples of how to target specific browsers and versions.
<div class="alert is-helpful">
Backward compatibility
### Backward compatibility with Lighthouse
If you want to produce a progressive web app and are using [Lighthouse](https://developers.google.com/web/tools/lighthouse/) to grade the project, add the following browserslist entry to your `package.json` file, in order to eliminate the [old flexbox](https://developers.google.com/web/tools/lighthouse/audits/old-flexbox) prefixes:
If you want to produce a progressive web app and are using [Lighthouse](https://developers.google.com/web/tools/lighthouse/) to grade the project, add the following `browserslist` entry to your `package.json` file, in order to eliminate the [old flexbox](https://developers.google.com/web/tools/lighthouse/audits/old-flexbox) prefixes:
```
"browserslist": [
@ -309,7 +303,23 @@ If you want to produce a progressive web app and are using [Lighthouse](https://
]
```
</div>
### Backward compatibility with CSS grid
CSS grid layout support in Autoprefixer, which was previously on by default, is off by default in Angular 8 and higher.
To use CSS grid with IE10/11, you must explicitly enable it using the `autoplace` option.
To do this, add the following to the top of the global styles file (or within a specific css selector scope):
```
/* autoprefixer grid: autoplace /
```
or
```
/ autoprefixer grid: no-autoplace */
```
For more information, see [Autoprefixer documentation](https://autoprefixer.github.io/).
{@a proxy}

View File

@ -30,7 +30,7 @@ The Filter/Stagger tab in the live example shows a list of heroes with an introd
The following example demonstrates how to use `query()` and `stagger()` functions on the entry of an animated element.
* Use `query()` to look for any element entering or leaving the page. The query specifies elements meeting certain CSS class criteria.
* Use `query()` to look for an element entering the page that meets certain criteria.
* For each of these elements, use `style()` to set the same initial style for the element. Make it invisible and use `transform` to move it out of position so that it can slide into place.

View File

@ -134,7 +134,7 @@ The `@NgModule()` and `@Component()` decorators have the `providers` metadata op
Components are directives, and the `providers` option is inherited from `@Directive()`. You can also configure providers for directives and pipes at the same level as the component.
Learn more about [where to configure providers](guide/hierarchical-dependency-injection#where-to-register).
Learn more about [where to configure providers](guide/hierarchical-dependency-injection).
</div>

View File

@ -8,7 +8,7 @@ When you are ready to deploy your Angular application to a remote server, you ha
## Simple deployment options
Before fully deploying your application, you can test the process, build configuration, and deployed behavior by using one of these interim techniques
Before fully deploying your application, you can test the process, build configuration, and deployed behavior by using one of these interim techniques.
### Building and serving from disk
@ -41,7 +41,7 @@ You will need two terminals to get the live-reload experience.
<code-example language="none" class="code-shell">
lite-server --baseDir="dist"
lite-server --baseDir="dist/project-name"
</code-example>
@ -53,6 +53,35 @@ This method is for development and testing only, and is not a supported or secur
</div>
### Automatic deployment with the CLI
The Angular CLI command `ng deploy` (introduced in version 8.3.0) executes the `deploy` [CLI builder](https://angular.io/guide/cli-builder) associated with your project. A number of third-party builders implement deployment capabilities to different platforms. You can add any of them to your project by running `ng add [package name]`.
When you add a package with deployment capability, it'll automatically update your workspace configuration (`angular.json` file) with a `deploy` section for the selected project. You can then use the `ng deploy` command to deploy that project.
For example, the following command automatically deploys a project to Firebase.
<code-example language="none" class="code-shell">
ng add @angular/fire
ng deploy
</code-example>
The command is interactive. In this case, you must have or create a Firebase account, and authenticate using that account. The command prompts you to select a Firebase project for deployment
After the command produces an optimal build of your application (equivalent to `ng deploy --prod`), it'll upload the production assets to Firebase.
In the table below, you can find a list of packages which implement deployment functionality to different platforms. The `deploy` command for each package may require different command line options. You can read more by following the links associated with the package names below:
| Deployment to | Package |
|---------------------------------------------------------------|--------------------------------------------------------------------------------|
| [Firebase hosting](https://firebase.google.com/docs/hosting) | [`@angular/fire`](https://npmjs.org/package/@angular/fire) |
| [Azure](https://azure.microsoft.com/en-us/) | [`@azure/ng-deploy`](https://npmjs.org/package/@azure/ng-deploy) |
| [Now](https://zeit.co/now) | [`@zeit/ng-deploy`](https://npmjs.org/package/@zeit/ng-deploy) |
| [Netlify](https://www.netlify.com/) | [`@netlify-builder/deploy`](https://npmjs.org/package/@netlify-builder/deploy) |
| [GitHub pages](https://pages.github.com/) | [`angular-cli-ghpages`](https://npmjs.org/package/angular-cli-ghpages) |
If you're deploying to a self-managed server or there's no builder for your favorite cloud platform, you can either create a builder that allows you to use the `ng deploy` command, or read through this guide to learn how to manually deploy your app.
### Basic deployment to a remote server
For the simplest deployment, create a production build and copy the output directory to a web server.
@ -589,14 +618,14 @@ In `angular.json` add two new configuration sections under the `build` and `serv
...
},
"es5": {
"browserTarget": "app:build:es5"
"browserTarget": "<app-name>:build:es5"
}
}
},
</code-example>
You can then run the serve with this configuration.
You can then run the `ng serve` command with this configuration. Make sure to replace `<app-name>` (in `"<app-name>:build:es5"`) with the actual name of the app, as it appears under `projects` in `angular.json`. For example, if your app name is `myAngularApp` the config will become `"browserTarget": "myAngularApp:build:es5"`.
<code-example language="none" class="code-shell">
@ -651,7 +680,7 @@ Create an [ES5 serve configuration](guide/deployment#configuring-serve-for-es5)
<code-example language="json">
"test": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
...
@ -661,14 +690,14 @@ Create an [ES5 serve configuration](guide/deployment#configuring-serve-for-es5)
...
},
"es5": {
"devServerTarget": "app:serve:es5"
"devServerTarget": "<app-name>:serve:es5"
}
}
},
</code-example>
You can then run the e2e's with this configuration
You can then run the `ng e2e` command with this configuration. Make sure to replace `<app-name>` (in `"<app-name>:serve:es5"`) with the actual name of the app, as it appears under `projects` in `angular.json`. For example, if your app name is `myAngularApp` the config will become `"devServerTarget": "myAngularApp:serve:es5"`.
<code-example language="none" class="code-shell">

View File

@ -321,7 +321,7 @@ In a typical Angular project, the polyfill is not used in production builds, so
{@a static-query-resolution}
### `@ViewChild()` / `@ContentChild()` static resolution as the default
See our [dedicated migration guide for static queries](guide/static-query-migration).
See the [dedicated migration guide for static queries](guide/static-query-migration).
{@a contentchild-input-together}
### `@ContentChild()` / `@Input()` used together
@ -389,6 +389,18 @@ As of Angular version 8, all `platform-webworker` APIs are deprecated.
This includes both packages: `@angular/platform-webworker` and
`@angular/platform-webworker-dynamic`.
## Angular version 9 schematics
{@a renderer-to-renderer2}
### Migrating from `Renderer` to `Renderer2`
See the [dedicated migration guide for Renderer](guide/migration-renderer).
{@a undecorated-classes}
### Migrating undecorated classes
See the [dedicated migration guide for undecorated classes](guide/migration-undecorated-classes).
{@a removed}
## Removed APIs
@ -396,9 +408,9 @@ The following APIs have been removed starting with version 8.0.0:
| Package | API | Replacement | Notes |
| ------- | -------------- | ----------- | ----- |
| [`@angular/http`](https://v7.angular.io/api/http) | All exports | [`@angular/common/http`](https://v7.angular.io/api/common/http) | See [below](#http). |
[`@angular/http/testing`](https://v7.angular.io/api/http/testing) | All exports | [`@angular/common/http/testing`](https://v7.angular.io/api/common/http/testing) | See [below](#http). |
| `@angular/platform-browser` | [`DOCUMENT`](https://v7.angular.io/api/platform-browser/DOCUMENT) | [`DOCUMENT` in `@angular/common`](https://v7.angular.io/api/common/DOCUMENT) | Updating to version 8 with [`ng update`](cli/update) changes this automatically. |
| [`@angular/http`](https://v7.angular.io/api/http) | All exports | [`@angular/common/http`](api/common/http) | See [below](#http). |
[`@angular/http/testing`](https://v7.angular.io/api/http/testing) | All exports | [`@angular/common/http/testing`](api/common/http/testing) | See [below](#http). |
| `@angular/platform-browser` | [`DOCUMENT`](https://v7.angular.io/api/platform-browser/DOCUMENT) | [`DOCUMENT` in `@angular/common`](api/common/DOCUMENT) | Updating to version 8 with [`ng update`](cli/update) changes this automatically. |
| `@angular/core/testing` | [`TestBed.deprecatedOverrideProvider()`](https://v7.angular.io/api/core/testing/TestBed#deprecatedoverrideprovider) | [`TestBed.overrideProvider()`](api/core/testing/TestBed#overrideprovider) | none |
| `@angular/core/testing` | [`TestBedStatic.deprecatedOverrideProvider()`](https://v7.angular.io/api/core/testing/TestBedStatic#deprecatedoverrideprovider) | [`TestBedStatic.overrideProvider()`](api/core/testing/TestBedStatic#overrideprovider) | none |
@ -464,100 +476,3 @@ For more information about using `@angular/common/http`, see the [HttpClient gui
| --------------------- | ------------------------------------------- |
| `MockBackend` | [`HttpTestingController`](/api/common/http/testing/HttpTestingController) |
| `MockConnection` | [`HttpTestingController`](/api/common/http/testing/HttpTestingController) |
## Renderer to Renderer2 migration
### Migration Overview
The `Renderer` class has been marked as deprecated since Angular version 4. This section provides guidance on migrating from this deprecated API to the newer `Renderer2` API and what it means for your app.
### Why should I migrate to Renderer2?
The deprecated `Renderer` class has been removed in version 9 of Angular, so it's necessary to migrate to a supported API. Using `Renderer2` is the recommended strategy because it supports a similar set of functionality to `Renderer`. The API surface is quite large (with 19 methods), but the schematic should simplify this process for your applications.
### Is there action required on my end?
No. The schematic should handle most cases with the exception of `Renderer.animate()` and `Renderer.setDebugInfo()`, which already arent supported.
### What are the `__ngRendererX` methods? Why are they necessary?
Some methods either don't have exact equivalents in `Renderer2`, or they correspond to more than one expression. For example, both renderers have a `createElement()` method, but they're not equal because a call such as `renderer.createElement(parentNode, namespaceAndName)` in the `Renderer` corresponds to the following block of code in `Renderer2`:
```ts
const [namespace, name] = splitNamespace(namespaceAndName);
const el = renderer.createElement(name, namespace);
if (parentNode) {
renderer.appendChild(parentNode, el);
}
return el;
```
Migration has to guarantee that the return values of functions and types of variables stay the same. To handle the majority of cases safely, the schematic declares helper functions at the bottom of the user's file. These helpers encapsulate your own logic and keep the replacements inside your code down to a single function call. Here's an example of how the `createElement()` migration looks:
**Before:**
```ts
public createAndAppendElement() {
const el = this.renderer.createElement('span');
el.textContent = 'hello world';
return el;
}
```
**After:**
<code-example>
public createAndAppendElement() {
const el = __ngRendererCreateElement(this.renderer, this.element, 'span');
el.textContent = 'hello world';
return el;
}
// Generated code at the bottom of the file
__ngRendererCreateElement(renderer: any, parentNode: any, nameAndNamespace: any) {
const [namespace, name] = __ngRendererSplitNamespace(namespaceAndName);
const el = renderer.createElement(name, namespace);
if (parentNode) {
renderer.appendChild(parentNode, el);
}
return el;
}
__ngRendererSplitNamespace(nameAndNamespace: any) {
// returns the split name and namespace
}
</code-example>
When implementing these helper functions, the schematic ensures that they're only declared once per file and that their names are unique enough that there's a small chance of colliding with pre-existing functions in your code. The schematic also keeps their parameter types as `any` so that it doesn't have to insert extra logic that ensures that their values have the correct type.
### Im a library author. Should I run this migration?
**Library authors should definitely use this migration to move away from the `Renderer`. Otherwise, the libraries won't work with applications built with version 9.**
### Full list of method migrations
The following table shows all methods that the migration maps from `Renderer` to `Renderer2`.
|Renderer|Renderer2|
|---|---|
|`listen(renderElement, name, callback)`|`listen(renderElement, name, callback)`|
|`setElementProperty(renderElement, propertyName, propertyValue)`|`setProperty(renderElement, propertyName, propertyValue)`|
|`setText(renderNode, text)`|`setValue(renderNode, text)`|
|`listenGlobal(target, name, callback)`|`listen(target, name, callback)`|
|`selectRootElement(selectorOrNode, debugInfo?)`|`selectRootElement(selectorOrNode)`|
|`createElement(parentElement, name, debugInfo?)`|`appendChild(parentElement, createElement(name))`|
|`setElementStyle(el, style, value?)`|`value == null ? removeStyle(el, style) : setStyle(el, style, value)`
|`setElementAttribute(el, name, value?)`|`attributeValue == null ? removeAttribute(el, name) : setAttribute(el, name, value)`
|`createText(parentElement, value, debugInfo?)`|`appendChild(parentElement, createText(value))`|
|`createTemplateAnchor(parentElement)`|`appendChild(parentElement, createComment(''))`|
|`setElementClass(renderElement, className, isAdd)`|`isAdd ? addClass(renderElement, className) : removeClass(renderElement, className)`|
|`projectNodes(parentElement, nodes)`|`for (let i = 0; i < nodes.length; i<ins></ins>) { appendChild(parentElement, nodes<i>); }`|
|`attachViewAfter(node, viewRootNodes)`|`const parentElement = parentNode(node); const nextSibling = nextSibling(node); for (let i = 0; i < viewRootNodes.length; i<ins></ins>) { insertBefore(parentElement, viewRootNodes<i>, nextSibling);}`|
|`detachView(viewRootNodes)`|`for (let i = 0; i < viewRootNodes.length; i<ins></ins>) {const node = viewRootNodes<i>; const parentElement = parentNode(node); removeChild(parentElement, node);}`|
|`destroyView(hostElement, viewAllNodes)`|`for (let i = 0; i < viewAllNodes.length; i<ins></ins>) { destroyNode(viewAllNodes<i>); }`|
|`setBindingDebugInfo()`|This function is a noop in `Renderer2`.|
|`createViewRoot(hostElement)`|Should be replaced with a reference to `hostElement`|
|`invokeElementMethod(renderElement, methodName, args?)`|`(renderElement as any)<methodName>.apply(renderElement, args);`|
|`animate(element, startingStyles, keyframes, duration, delay, easing, previousPlayers?)`|Throws an error (same behavior as `Renderer.animate()`)|

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@ into an application class as shown in the following `ConfigService` example.
header="app/config/config.service.ts (excerpt)">
</code-example>
## Getting JSON data
## Requesting data from server
Applications often request JSON data from the server.
For example, the app might need a configuration file on the server, `config.json`,
@ -73,45 +73,37 @@ the component **subscribes** to the method's return value.
The subscription callback copies the data fields into the component's `config` object,
which is data-bound in the component template for display.
### Why write a service
<div class="callout is-helpful">
<header>Why write a service?</header>
This example is so simple that it is tempting to write the `Http.get()` inside the
component itself and skip the service.
However, data access rarely stays this simple.
You typically post-process the data, add error handling, and maybe some retry logic to
In practice, however, data access rarely stays this simple.
You typically need to post-process the data, add error handling, and maybe some retry logic to
cope with intermittent connectivity.
The component quickly becomes cluttered with data access minutia.
The component becomes harder to understand, harder to test, and the data access logic can't be re-used or standardized.
That's why it is a best practice to separate presentation of data from data access by
That's why it's a best practice to separate presentation of data from data access by
encapsulating data access in a separate service and delegating to that service in
the component, even in simple cases like this one.
</div>
### Type-checking the response
### Requesting a typed response
The subscribe callback above requires bracket notation to extract the data values.
You can structure your `HttpClient` request to declare the type of the response object, to make consuming the output easier and more obvious.
Specifying the response type acts as a type assertion during the compile time.
<code-example
path="http/src/app/config/config.component.ts"
region="v1_callback">
</code-example>
You can't write `data.heroesUrl` because TypeScript correctly complains that the `data` object from the service does not have a `heroesUrl` property.
The `HttpClient.get()` method parsed the JSON server response into the anonymous `Object` type. It doesn't know what the shape of that object is.
You can tell `HttpClient` the type of the response to make consuming the output easier and more obvious.
First, define an interface with the correct shape:
To specify the response object type, first define an interface with the required properties.
(Use an interface rather than a class; a response cannot be automatically converted to an instance of a class.)
<code-example
path="http/src/app/config/config.service.ts"
region="config-interface">
</code-example>
Then, specify that interface as the `HttpClient.get()` call's type parameter in the service:
Next, specify that interface as the `HttpClient.get()` call's type parameter in the service.
<code-example
path="http/src/app/config/config.service.ts"
@ -119,6 +111,12 @@ Then, specify that interface as the `HttpClient.get()` call's type parameter in
header="app/config/config.service.ts (getConfig v.2)">
</code-example>
<div class="alert is-helpful">
When you pass an interface as a type parameter to the `HttpClient.get()` method, use the RxJS `map` operator to transform the response data as needed by the UI. You can then pass the transformed data to the [async pipe](api/common/AsyncPipe).
</div>
The callback in the updated component method receives a typed data object, which is
easier and safer to consume:
@ -128,6 +126,24 @@ easier and safer to consume:
header="app/config/config.component.ts (showConfig v.2)">
</code-example>
<div class="alert is-important">
Specifying the response type is a declaration to TypeScript that it should expect your response to be of the given type.
This is a build-time check and doesn't guarantee that the server will actually respond with an object of this type. It is up to the server to ensure that the type specified by the server API is returned.
</div>
To access properties that are defined in an interface, you must explicitly convert the Object you get from the JSON to the required response type.
For example, the following `subscribe` callback receives `data` as an Object, and then type-casts it in order to access the properties.
<code-example>
.subscribe(data => this.config = {
heroesUrl: (data as any).heroesUrl,
textfile: (data as any).textfile,
});
</code-example>
### Reading the full response
The response body doesn't return all the data you may need. Sometimes servers return special headers or status codes to indicate certain conditions that are important to the application workflow.
@ -139,7 +155,7 @@ Tell `HttpClient` that you want the full response with the `observe` option:
region="getConfigResponse">
</code-example>
Now `HttpClient.get()` returns an `Observable` of typed `HttpResponse` rather than just the JSON data.
Now `HttpClient.get()` returns an `Observable` of type `HttpResponse` rather than just the JSON data.
The component's `showConfigResponse()` method displays the response headers as well as the configuration:
@ -152,6 +168,54 @@ The component's `showConfigResponse()` method displays the response headers as w
As you can see, the response object has a `body` property of the correct type.
### Making a JSONP request
Apps can use the the `HttpClient` to make [JSONP](https://en.wikipedia.org/wiki/JSONP) requests across domains when the server doesn't support [CORS protocol](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
Angular JSONP requests return an `Observable`.
Follow the pattern for subscribing to observables and use the RxJS `map` operator to transform the response before using the [async pipe](api/common/AsyncPipe) to manage the results.
In Angular, use JSONP by including `HttpClientJsonpModule` in the `NgModule` imports.
In the following example, the `searchHeroes()` method uses a JSONP request to query for heroes whose names contain the search term.
```ts
/* GET heroes whose name contains search term */
searchHeroes(term: string): Observable {
term = term.trim();
let heroesURL = `${this.heroesURL}?${term}`;
return this.http.jsonp(heroesUrl, 'callback').pipe(
catchError(this.handleError('searchHeroes', []) // then handle the error
);
};
```
This request passes the `heroesURL` as the first parameter and the callback function name as the second parameter.
The response is wrapped in the callback function, which takes the observables returned by the JSONP method and pipes them through to the error handler.
### Requesting non-JSON data
Not all APIs return JSON data.
In this next example, a `DownloaderService` method reads a text file from the server and logs the file contents, before returning those contents to the caller as an `Observable<string>`.
<code-example
path="http/src/app/downloader/downloader.service.ts"
region="getTextFile"
header="app/downloader/downloader.service.ts (getTextFile)" linenums="false">
</code-example>
`HttpClient.get()` returns a string rather than the default JSON because of the `responseType` option.
The RxJS `tap` operator (as in "wiretap") lets the code inspect both success and error values passing through the observable without disturbing them.
A `download()` method in the `DownloaderComponent` initiates the request by subscribing to the service method.
<code-example
path="http/src/app/downloader/downloader.component.ts"
region="download"
header="app/downloader/downloader.component.ts (download)" linenums="false">
</code-example>
## Error handling
What happens if the request fails on the server, or if a poor network connection prevents it from even reaching the server? `HttpClient` will return an _error_ object instead of a successful response.
@ -204,7 +268,7 @@ and _pipe them through_ to the error handler.
header="app/config/config.service.ts (getConfig v.3 with error handler)">
</code-example>
### `retry()`
### Retrying
Sometimes the error is transient and will go away automatically if you try again.
For example, network interruptions are common in mobile scenarios, and trying again
@ -242,29 +306,34 @@ If you're following along with these code snippets, note that you must import th
header="app/config/config.service.ts (RxJS imports)">
</code-example>
## Requesting non-JSON data
## HTTP headers
Not all APIs return JSON data. In this next example,
a `DownloaderService` method reads a text file from the server
and logs the file contents, before returning those contents to the caller
as an `Observable<string>`.
Many servers require extra headers for save operations.
For example, they may require a "Content-Type" header to explicitly declare the MIME type of the request body; or the server may require an authorization token.
### Adding headers
The `HeroesService` defines such headers in an `httpOptions` object that will be passed
to every `HttpClient` save method.
<code-example
path="http/src/app/downloader/downloader.service.ts"
region="getTextFile"
header="app/downloader/downloader.service.ts (getTextFile)">
path="http/src/app/heroes/heroes.service.ts"
region="http-options"
header="app/heroes/heroes.service.ts (httpOptions)">
</code-example>
`HttpClient.get()` returns a string rather than the default JSON because of the `responseType` option.
### Updating headers
The RxJS `tap` operator (as in "wiretap") lets the code inspect good and error values passing through the observable without disturbing them.
You can't directly modify the existing headers within the previous options
object because instances of the `HttpHeaders` class are immutable.
A `download()` method in the `DownloaderComponent` initiates the request by subscribing to the service method.
Use the `set()` method instead, to return a clone of the current instance with the new changes applied.
Here's how you might update the authorization header (after the old token expired) before making the next request.
<code-example
path="http/src/app/downloader/downloader.component.ts"
region="download"
header="app/downloader/downloader.component.ts (download)">
path="http/src/app/heroes/heroes.service.ts"
region="update-headers" linenums="false">
</code-example>
## Sending data to the server
@ -276,22 +345,6 @@ that fetches heroes and enables users to add, delete, and update them.
The following sections excerpt methods of the sample's `HeroesService`.
### Adding headers
Many servers require extra headers for save operations.
For example, they may require a "Content-Type" header to explicitly declare
the MIME type of the request body.
Or perhaps the server requires an authorization token.
The `HeroesService` defines such headers in an `httpOptions` object that will be passed
to every `HttpClient` save method.
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="http-options"
header="app/heroes/heroes.service.ts (httpOptions)">
</code-example>
### Making a POST request
Apps often POST data to a server. They POST when submitting a form.
@ -413,118 +466,8 @@ in order to initiate the request.
We have discussed the basic HTTP functionality in `@angular/common/http`, but sometimes you need to do more than make simple requests and get data back.
### Configuring the request
Other aspects of an outgoing request can be configured via the options object
passed as the last argument to the `HttpClient` method.
You [saw earlier](#adding-headers) that the `HeroesService` sets the default headers by
passing an options object (`httpOptions`) to its save methods.
You can do more.
#### Update headers
You can't directly modify the existing headers within the previous options
object because instances of the `HttpHeaders` class are immutable.
Use the `set()` method instead.
It returns a clone of the current instance with the new changes applied.
Here's how you might update the authorization header (after the old token expired)
before making the next request.
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="update-headers">
</code-example>
#### URL Parameters
Adding URL search parameters works a similar way.
Here is a `searchHeroes` method that queries for heroes whose names contain the search term.
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="searchHeroes">
</code-example>
If there is a search term, the code constructs an options object with an HTML URL-encoded search parameter. If the term were "foo", the GET request URL would be `api/heroes/?name=foo`.
The `HttpParams` are immutable so you'll have to use the `set()` method to update the options.
### Debouncing requests
The sample includes an _npm package search_ feature.
When the user enters a name in a search-box, the `PackageSearchComponent` sends
a search request for a package with that name to the NPM web API.
Here's a pertinent excerpt from the template:
<code-example
path="http/src/app/package-search/package-search.component.html"
region="search"
header="app/package-search/package-search.component.html (search)">
</code-example>
The `(keyup)` event binding sends every keystroke to the component's `search()` method.
Sending a request for every keystroke could be expensive.
It's better to wait until the user stops typing and then send a request.
That's easy to implement with RxJS operators, as shown in this excerpt.
<code-example
path="http/src/app/package-search/package-search.component.ts"
region="debounce"
header="app/package-search/package-search.component.ts (excerpt)">
</code-example>
The `searchText$` is the sequence of search-box values coming from the user.
It's defined as an RxJS `Subject`, which means it is a multicasting `Observable`
that can also produce values for itself by calling `next(value)`,
as happens in the `search()` method.
Rather than forward every `searchText` value directly to the injected `PackageSearchService`,
the code in `ngOnInit()` _pipes_ search values through three operators:
1. `debounceTime(500)` - wait for the user to stop typing (1/2 second in this case).
1. `distinctUntilChanged()` - wait until the search text changes.
1. `switchMap()` - send the search request to the service.
The code sets `packages$` to this re-composed `Observable` of search results.
The template subscribes to `packages$` with the [AsyncPipe](api/common/AsyncPipe)
and displays search results as they arrive.
A search value reaches the service only if it's a new value and the user has stopped typing.
<div class="alert is-helpful">
The `withRefresh` option is explained [below](#cache-refresh).
</div>
#### _switchMap()_
The `switchMap()` operator has three important characteristics.
1. It takes a function argument that returns an `Observable`.
`PackageSearchService.search` returns an `Observable`, as other data service methods do.
2. If a previous search request is still _in-flight_ (as when the connection is poor),
it cancels that request and sends a new one.
3. It returns service responses in their original request order, even if the
server returns them out of order.
<div class="alert is-helpful">
If you think you'll reuse this debouncing logic,
consider moving it to a utility function or into the `PackageSearchService` itself.
</div>
### Intercepting requests and responses
{@a intercepting-requests-and-responses }
### HTTP interceptors
_HTTP Interception_ is a major feature of `@angular/common/http`.
With interception, you declare _interceptors_ that inspect and transform HTTP requests from your application to the server.
@ -642,7 +585,7 @@ You may have expected the `intercept()` and `handle()` methods to return observa
Instead they return observables of `HttpEvent<any>`.
That's because interceptors work at a lower level than those `HttpClient` methods. A single HTTP request can generate multiple _events_, including upload and download progress events. The `HttpResponse` class itself is actually an event, whose type is `HttpEventType.HttpResponseEvent`.
That's because interceptors work at a lower level than those `HttpClient` methods. A single HTTP request can generate multiple _events_, including upload and download progress events. The `HttpResponse` class itself is actually an event, whose type is `HttpEventType.Response`.
Many interceptors are only concerned with the outgoing request and simply return the event stream from `next.handle()` without modifying it.
@ -845,6 +788,117 @@ the cached response first (and immediately), followed later
by the response from the server.
Subscribers see a sequence of _two_ responses.
### Configuring the request
Other aspects of an outgoing request can be configured via the options object
passed as the last argument to the `HttpClient` method.
In [Adding headers](#adding-headers), the `HeroesService` set the default headers by
passing an options object (`httpOptions`) to its save methods.
You can do more.
#### URL query strings
In this section, you will see how to use the `HttpParams` class to add URL query strings in your `HttpRequest`.
The following `searchHeroes` method queries for heroes whose names contain the search term.
Start by importing `HttpParams` class.
<code-example hideCopy language="typescript">
import {HttpParams} from "@angular/common/http";
</code-example>
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="searchHeroes" linenums="false">
</code-example>
If there is a search term, the code constructs an options object with an HTML URL-encoded search parameter.
If the term were "foo", the GET request URL would be `api/heroes?name=foo`.
The `HttpParams` are immutable so you'll have to save the returned value of the `.set()` method in order to update the options.
#### Use `fromString` to create HttpParams
You can also create HTTP parameters directly from a query string by using the `fromString` variable:
<code-example hideCopy language="typescript">
const params = new HttpParams({fromString: 'name=foo'});
</code-example>
### Debouncing requests
The sample includes an _npm package search_ feature.
When the user enters a name in a search-box, the `PackageSearchComponent` sends
a search request for a package with that name to the NPM web API.
Here's a pertinent excerpt from the template:
<code-example
path="http/src/app/package-search/package-search.component.html"
region="search"
header="app/package-search/package-search.component.html (search)">
</code-example>
The `keyup` event binding sends every keystroke to the component's `search()` method.
Sending a request for every keystroke could be expensive.
It's better to wait until the user stops typing and then send a request.
That's easy to implement with RxJS operators, as shown in this excerpt.
<code-example
path="http/src/app/package-search/package-search.component.ts"
region="debounce"
header="app/package-search/package-search.component.ts (excerpt)">
</code-example>
The `searchText$` is the sequence of search-box values coming from the user.
It's defined as an RxJS `Subject`, which means it is a multicasting `Observable`
that can also emit values for itself by calling `next(value)`,
as happens in the `search()` method.
Rather than forward every `searchText` value directly to the injected `PackageSearchService`,
the code in `ngOnInit()` _pipes_ search values through three operators:
1. `debounceTime(500)` - wait for the user to stop typing (1/2 second in this case).
2. `distinctUntilChanged()` - wait until the search text changes.
3. `switchMap()` - send the search request to the service.
The code sets `packages$` to this re-composed `Observable` of search results.
The template subscribes to `packages$` with the [AsyncPipe](api/common/AsyncPipe)
and displays search results as they arrive.
A search value reaches the service only if it's a new value and the user has stopped typing.
<div class="alert is-helpful">
The `withRefresh` option is explained [below](#cache-refresh).
</div>
#### _switchMap()_
The `switchMap()` operator has three important characteristics.
1. It takes a function argument that returns an `Observable`.
`PackageSearchService.search` returns an `Observable`, as other data service methods do.
2. If a previous search request is still _in-flight_ (as when the network connection is poor),
it cancels that request and sends a new one.
3. It returns service responses in their original request order, even if the
server returns them out of order.
<div class="alert is-helpful">
If you think you'll reuse this debouncing logic,
consider moving it to a utility function or into the `PackageSearchService` itself.
</div>
### Listening to progress events
Sometimes applications transfer large amounts of data and those transfers can take a long time.
@ -895,22 +949,26 @@ by returning an observable of simulated events.
</div>
## Security: XSRF Protection
## Security: XSRF protection
[Cross-Site Request Forgery (XSRF)](https://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by which the attacker can trick an authenticated user into unknowingly executing actions on your website. `HttpClient` supports a [common mechanism](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-Header_Token) used to prevent XSRF attacks. When performing HTTP requests, an interceptor reads a token from a cookie, by default `XSRF-TOKEN`, and sets it as an HTTP header, `X-XSRF-TOKEN`. Since only code that runs on your domain could read the cookie, the backend can be certain that the HTTP request came from your client application and not an attacker.
[Cross-Site Request Forgery (XSRF)](https://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by which the attacker can trick an authenticated user into unknowingly executing actions on your website.
`HttpClient` supports a [common mechanism](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-Header_Token) used to prevent XSRF attacks.
When performing HTTP requests, an interceptor reads a token from a cookie, by default `XSRF-TOKEN`, and sets it as an HTTP header, `X-XSRF-TOKEN`.
Since only code that runs on your domain could read the cookie, the backend can be certain that the HTTP request came from your client application and not an attacker.
By default, an interceptor sends this header on all mutating requests (POST, etc.)
to relative URLs but not on GET/HEAD requests or
on requests with an absolute URL.
By default, an interceptor sends this header on all mutating requests (such as POST)
to relative URLs, but not on GET/HEAD requests or on requests with an absolute URL.
To take advantage of this, your server needs to set a token in a JavaScript readable session cookie called `XSRF-TOKEN` on either the page load or the first GET request. On subsequent requests the server can verify that the cookie matches the `X-XSRF-TOKEN` HTTP header, and therefore be sure that only code running on your domain could have sent the request. The token must be unique for each user and must be verifiable by the server; this prevents the client from making up its own tokens. Set the token to a digest of your site's authentication
cookie with a salt for added security.
To take advantage of this, your server needs to set a token in a JavaScript readable session cookie called `XSRF-TOKEN` on either the page load or the first GET request.
On subsequent requests the server can verify that the cookie matches the `X-XSRF-TOKEN` HTTP header, and therefore be sure that only code running on your domain could have sent the request.
The token must be unique for each user and must be verifiable by the server; this prevents the client from making up its own tokens.
Set the token to a digest of your site's authentication cookie with a salt for added security.
In order to prevent collisions in environments where multiple Angular apps share the same domain or subdomain, give each application a unique cookie name.
<div class="alert is-important">
*Note that `HttpClient` supports only the client half of the XSRF protection scheme.*
*`HttpClient` supports only the client half of the XSRF protection scheme.*
Your backend service must be configured to set the cookie for your page, and to verify that
the header is present on all eligible requests.
If not, Angular's default protection will be ineffective.
@ -929,19 +987,13 @@ use `HttpClientXsrfModule.withOptions()` to override the defaults.
## Testing HTTP requests
Like any external dependency, the HTTP backend needs to be mocked
so your tests can simulate interaction with a remote server.
The `@angular/common/http/testing` library makes
setting up such mocking straightforward.
As for any external dependency, you must mock the HTTP backend so your tests can simulate interaction with a remote server.
The `@angular/common/http/testing` library makes it straightforward to set up such mocking .
### Mocking philosophy
Angular's HTTP testing library is designed for a pattern of testing wherein
the app executes code and makes requests first.
Then a test expects that certain requests have or have not been made,
Angular's HTTP testing library is designed for a pattern of testing in which the app executes code and makes requests first.
The test then expects that certain requests have or have not been made,
performs assertions against those requests,
and finally provide responses by "flushing" each expected request.
and finally provides responses by "flushing" each expected request.
At the end, tests may verify that the app has made no unexpected requests.

View File

@ -193,7 +193,7 @@ text messages with different descriptions (not different meanings), then they ar
The angular i18n extractor tool generates a file with a translation unit entry for each `i18n`
attribute in a template. By default, it assigns each translation unit a unique id such as this one:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="generated-id"></code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" header="messages.fr.xlf.html" region="generated-id"></code-example>
When you change the translatable text, the extractor tool generates a new id for that translation unit.
You must then update the translation file with the new id.
@ -206,7 +206,7 @@ The example below defines the custom id `introductionHeader`:
When you specify a custom id, the extractor tool and compiler generate a translation unit with that
custom id.
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="custom-id"></code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" header="messages.fr.xlf.html" region="custom-id"></code-example>
The custom id is persistent. The extractor tool does not change it when the translatable text changes.
Therefore, you do not need to update the translation. This approach makes maintenance easier.
@ -379,7 +379,7 @@ Open a terminal window at the root of the app project and run the CLI command `x
ng xi18n
</code-example>
By default, the command creates a file named `messages.xlf` in your `src/` folder.
By default, the command creates a file named `messages.xlf` in your project's root directory.
<div class="alert is-helpful">
@ -388,7 +388,7 @@ If you don't use the CLI, you have two options:
For more information, see the [`ng xi18n` command documentation](cli/xi18n).
* You can use the CLI Webpack plugin `AngularCompilerPlugin` from the `@ngtools/webpack` package.
Set the parameters `i18nOutFile` and `i18nOutFormat` to trigger the extraction.
For more information, see the [Angular Ahead-of-Time Webpack Plugin documentation](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack).
For more information, see the [Angular Ahead-of-Time Webpack Plugin documentation](https://github.com/angular/angular-cli/tree/master/packages/ngtools/webpack).
</div>
@ -645,9 +645,9 @@ ready-to-run application package, typically for production.
When you internationalize with the AOT compiler, you must pre-build a separate application
package for each language and serve the appropriate package based on either server-side language
detection or url parameters.
detection or URL parameters.
To instruct the AOT compiler to use your translation configuration, set the three "i18n" build configuration options in your `angular.json` file.
To instruct the AOT compiler to use your translation configuration, set the three "i18n" build configuration options in your CLI configuration file, `angular.json`.
* `i18nFile`: the path to the translation file.
* `i18nFormat`: the format of the translation file.
@ -707,7 +707,9 @@ the CLI configuration file, `angular.json`.
"i18nLocale": "fr",
"i18nMissingTranslation": "error",
}
// ...
}
},
...
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
@ -721,8 +723,8 @@ the CLI configuration file, `angular.json`.
"browserTarget": "my-project:build:fr"
}
}
},
}
}
```
The same configuration options can also be provided through the CLI with your existing `production` configuration.
@ -761,6 +763,7 @@ Then provide the `LOCALE_ID` in the main module:
{@a missing-translation}
### Report missing translations
By default, when a translation is missing, the build succeeds but generates a warning such as
`Missing translation for message "foo"`. You can configure the level of warning that is generated by
the Angular compiler:
@ -770,7 +773,7 @@ compilation, the app will fail to load.
* Warning (default): show a 'Missing translation' warning in the console or shell.
* Ignore: do nothing.
You specify the warning level in the `configurations` section your Angular CLI build configuration. The example below shows how to set the warning level to error:
You specify the warning level in the `configurations` section of your Angular CLI configuration file, `angular.json`. The example below shows how to set the warning level to error.
```
"configurations": {
@ -784,7 +787,7 @@ You specify the warning level in the `configurations` section your Angular CLI b
If you use the JIT compiler, specify the warning level in the compiler config at bootstrap by adding
the 'MissingTranslationStrategy' property. The example below shows how to set the warning level to
error:
error.
<code-example path="i18n/doc-files/main.3.ts" header="src/main.ts">
</code-example>

View File

@ -5,13 +5,13 @@
By default, NgModules are eagerly loaded, which means that as soon as the app loads, so do all the NgModules, whether or not they are immediately necessary. For large apps with lots of routes, consider lazy loading&mdash;a design pattern that loads NgModules as needed. Lazy loading helps keep initial
bundle sizes smaller, which in turn helps decrease load times.
For the final sample app with two lazy loaded modules that this page describes, see the
For the final sample app with two lazy-loaded modules that this page describes, see the
<live-example></live-example>.
There are three main steps to setting up a lazy loaded feature module:
There are three main steps to setting up a lazy-loaded feature module:
1. Create the feature module.
1. Create the feature modules routing module.
1. Create the feature module with the CLI, using the `--route` flag.
1. Create the feature modules component.
1. Configure the routes.
## Set up an app
@ -21,9 +21,9 @@ create one with the CLI. If you do already have an app, skip to
[Configure the routes](#config-routes). Enter the following command
where `customer-app` is the name of your app:
```sh
<code-example language="bash">
ng new customer-app --routing
```
</code-example>
This creates an app called `customer-app` and the `--routing` flag
generates a file called `app-routing.module.ts`, which is one of
@ -32,71 +32,63 @@ Navigate into the project by issuing the command `cd customer-app`.
## Create a feature module with routing
Next, youll need a feature module to route to. To make one, enter
the following command at the terminal window prompt where `customers` is the name of the module:
Next, youll need a feature module with a component to route to.
To make one, enter the following command in the terminal, where `customers` is the name of the feature module, and `customer-list` is the route path for loading the `customers` component:
```sh
ng generate module customers --routing
```
<code-example language="bash">
ng generate module customers --route customer-list --module app.module
</code-example>
This creates a customers folder with two files inside; `CustomersModule`
and `CustomersRoutingModule`. `CustomersModule` will act as the gatekeeper
for anything that concerns customers. `CustomersRoutingModule` will handle
any customer-related routing. This keeps the apps structure organized as
the app grows and allows you to reuse this module while easily keeping its routing intact.
This creates a `customers` folder with the new lazy-loadable module `CustomersModule` defined in the file `customers.module.ts`. The command automatically adds the `CustomerComponent` to the new feature module.
The CLI imports the `CustomersRoutingModule` into the `CustomersModule` by
adding a JavaScript import statement at the top of the file and adding
`CustomersRoutingModule` to the `@NgModule` `imports` array.
Because the new module is meant to be lazy-loaded, the command does NOT add a reference for the new feature module to the root application's module file, `app.module.ts`.
Instead, it adds the declared route, `customer-list` to the `Routes` array declared in the module provided as the `--module` option.
## Add a component to the feature module
<code-example language="typescript" header="src/app/app-routing.module.ts">
const routes: Routes = [
{ path: 'customer-list',
loadChildren: () => import('./customers/customers.module').then(m => m.CustomersModule) }
];
</code-example>
In order to see the module being lazy loaded in the browser, create a component to render some HTML when the app loads `CustomersModule`. At the command line, enter the following:
Notice that the lazy-loading syntax uses `loadChildren` followed by a function that uses the browser's built-in `import('...')` syntax for dynamic imports.
The import path is the relative path to the module.
```sh
ng generate component customers/customer-list
```
### Add another feature module
This creates a folder inside of `customers` called `customer-list`
with the four files that make up the component.
Use the same command to create a second lazy-loaded feature module with routing, along with its stub component.
Just like with the routing module, the CLI imports the
`CustomerListComponent` into the `CustomersModule`.
<code-example language="bash">
ng generate module orders --route order-list --module app.module
</code-example>
This creates a new folder called `orders` containing an `OrdersModule` and `OrdersRoutingModule`, along with the new `OrderComponent` source files.
The `order-list` route is added to the `Routes` array in `app-routing.module.ts`, using the lazy-loading syntax.
## Add another feature module
For another place to route to, create a second feature module with routing:
```sh
ng generate module orders --routing
```
This makes a new folder called `orders` containing an `OrdersModule` and an `OrdersRoutingModule`.
Now, just like with the `CustomersModule`, give it some content:
```sh
ng generate component orders/order-list
```
<code-example language="typescript" header="src/app/app-routing.module.ts">
const routes: Routes = [
{ path: 'customer-list',
loadChildren: () => import('./customers/customers.module').then(m => m.CustomersModule) },
{ path: 'order-list',
loadChildren: () => import('./orders/orders.module').then(m => m.OrdersModule) }
];
</code-example>
## Set up the UI
Though you can type the URL into the address bar, a nav
is easier for the user and more common. Replace the default
placeholder markup in `app.component.html` with a custom nav
Though you can type the URL into the address bar, a navigation UI is easier for the user and more common.
Replace the default placeholder markup in `app.component.html` with a custom nav
so you can easily navigate to your modules in the browser:
<code-example path="lazy-loading-ngmodules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
<code-example path="lazy-loading-ngmodules/src/app/app.component.html" header="app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
To see your app in the browser so far, enter the following command in the terminal window:
```sh
<code-example language="bash">
ng serve
```
</code-example>
Then go to `localhost:4200` where you should see “app works!” and three buttons.
@ -104,59 +96,42 @@ Then go to `localhost:4200` where you should see “app works!” and three butt
<img src="generated/images/guide/lazy-loading-ngmodules/three-buttons.png" width="300" alt="three buttons in the browser">
</figure>
To make the buttons work, you need to configure the routing modules.
These buttons work, because the CLI automatically added the routes to the feature modules to the `routes` array in `app.module.ts`.
{@a config-routes}
## Configure the routes
The two feature modules, `OrdersModule` and `CustomersModule`, have to be
wired up to the `AppRoutingModule` so the router knows about them. The structure is as follows:
<figure>
<img src="generated/images/guide/lazy-loading-ngmodules/lazy-load-relationship.jpg" width="400" alt="lazy loaded modules diagram">
</figure>
Each feature module acts as a doorway via the router. In the `AppRoutingModule`, you configure the routes to the feature modules, in this case `OrdersModule` and `CustomersModule`. This way, the router knows to go to the feature module. The feature module then connects the `AppRoutingModule` to the `CustomersRoutingModule` or the `OrdersRoutingModule`. Those routing modules tell the router where to go to load relevant components.
### Routes at the app level
## Imports and route configuration
The CLI automatically added each feature module to the routes map at the application level.
Finish this off by adding the default route.
In `AppRoutingModule`, update the `routes` array with the following:
<code-example path="lazy-loading-ngmodules/src/app/app-routing.module.ts" id="app-routing.module.ts" region="const-routes" header="src/app/app-routing.module.ts"></code-example>
<code-example path="lazy-loading-ngmodules/src/app/app-routing.module.ts" region="const-routes" header="src/app/app-routing.module.ts"></code-example>
The first two paths are the routes to the `CustomersModule` and the `OrdersModule`.
The final entry defines a default route. The empty path matches everything that doesn't match an earlier path.
The import statements stay the same. The first two paths are the routes to the `CustomersModule` and the `OrdersModule` respectively. Notice that the lazy loading syntax uses `loadChildren` followed by a function that uses the browser's built-in `import('...')` syntax for dynamic imports. The import path is the relative path to the module.
### Inside the feature module
Next, take a look at `customers.module.ts`. If youre using the CLI and following the steps outlined in this page, you dont have to do anything here. The feature module is like a connector between the `AppRoutingModule` and the feature routing module. The `AppRoutingModule` imports the feature module, `CustomersModule`, and `CustomersModule` in turn imports the `CustomersRoutingModule`.
<code-example path="lazy-loading-ngmodules/src/app/customers/customers.module.ts" region="customers-module" header="src/app/customers/customers.module.ts"></code-example>
Next, take a look at `customers.module.ts`. If youre using the CLI and following the steps outlined in this page, you dont have to do anything here.
<code-example path="lazy-loading-ngmodules/src/app/customers/customers.module.ts" id="customers.module.ts" region="customers-module" header="src/app/customers/customers.module.ts"></code-example>
The `customers.module.ts` file imports the `CustomersRoutingModule` and `CustomerListComponent` so the `CustomersModule` class can have access to them. `CustomersRoutingModule` is then listed in the `@NgModule` `imports` array giving `CustomersModule` access to its own routing module, and `CustomerListComponent` is in the `declarations` array, which means `CustomerListComponent` belongs to the `CustomersModule`.
### Configure the feature modules routes
The feature module has its own routing module, `customers-routing.module.ts`. The `AppRoutingModule` imports the feature module, `CustomersModule`, and `CustomersModule` in turn imports the `CustomersRoutingModule`.
The next step is in `customers-routing.module.ts`. First, import the component at the top of the file with the other JavaScript import statements. Then, add the route to `CustomerListComponent`.
<code-example path="lazy-loading-ngmodules/src/app/customers/customers-routing.module.ts" region="customers-routing-module" header="src/app/customers/customers-routing.module.ts"></code-example>
The feature-specific routing module imports its own feature component, `CustomerListComponent`, along with the other JavaScript import statements. It also adds the route to its own component.
<code-example path="lazy-loading-ngmodules/src/app/customers/customers-routing.module.ts" id="customers-routing.module.ts" region="customers-routing-module" header="src/app/customers/customers-routing.module.ts"></code-example>
Notice that the `path` is set to an empty string. This is because the path in `AppRoutingModule` is already set to `customers`, so this route in the `CustomersRoutingModule`, is already within the `customers` context. Every route in this routing module is a child route.
Repeat this last step of importing the `OrdersListComponent` and configuring the Routes array for the `orders-routing.module.ts`:
The other feature module's routing module is configured similarly.
<code-example path="lazy-loading-ngmodules/src/app/orders/orders-routing.module.ts" region="orders-routing-module-detail" header="src/app/orders/orders-routing.module.ts (excerpt)"></code-example>
Now, if you view the app in the browser, the three buttons take you to each module.
<code-example path="lazy-loading-ngmodules/src/app/orders/orders-routing.module.ts" id="orders-routing.module.ts" region="orders-routing-module-detail" header="src/app/orders/orders-routing.module.ts (excerpt)"></code-example>
## Confirm its working
@ -167,7 +142,7 @@ You can check to see that a module is indeed being lazy loaded with the Chrome d
</figure>
Click on the Orders or Customers button. If you see a chunk appear, youve wired everything up properly and the feature module is being lazy loaded. A chunk should appear for Orders and for Customers but will only appear once for each.
Click on the Orders or Customers button. If you see a chunk appear, everything is wired up properly and the feature module is being lazy loaded. A chunk should appear for Orders and for Customers but will only appear once for each.
<figure>
@ -186,17 +161,17 @@ Then reload with `Cmd+r` or `Ctrl+r`, depending on your platform.
## `forRoot()` and `forChild()`
You might have noticed that the CLI adds `RouterModule.forRoot(routes)` to the `app-routing.module.ts` `imports` array. This lets Angular know that this module,
`AppRoutingModule`, is a routing module and `forRoot()` specifies that this is the root
routing module. It configures all the
routes you pass to it, gives you access to the router directives, and registers the `RouterService`.
You might have noticed that the CLI adds `RouterModule.forRoot(routes)` to the `app-routing.module.ts` `imports` array.
This lets Angular know that this module, `AppRoutingModule`, is a routing module and `forRoot()` specifies that this is the root routing module.
It configures all the routes you pass to it, gives you access to the router directives, and registers the `RouterService`.
Use `forRoot()` in the `AppRoutingModule`&mdash;that is, one time in the app at the root level.
The CLI also adds `RouterModule.forChild(routes)` to feature routing modules. This way, Angular
knows that the route list is only responsible for providing additional routes and is intended for feature modules. You can use `forChild()` in multiple modules.
`forRoot()` contains injector configuration which is global; such as configuring the Router. `forChild()` has no injector configuration, only directives such as `RouterOutlet` and `RouterLink`.
The CLI also adds `RouterModule.forChild(routes)` to feature routing modules.
This way, Angular knows that the route list is only responsible for providing additional routes and is intended for feature modules.
You can use `forChild()` in multiple modules.
The `forRoot()` method takes care of the *global* injector configuration for the Router.
The `forChild()` method has no injector configuration. It uses directives such as `RouterOutlet` and `RouterLink`.
For more information, see the [`forRoot()` pattern](guide/singleton-services#forRoot) section of the [Singleton Services](guide/singleton-services) guide.
<hr>
@ -209,4 +184,3 @@ You may also be interested in the following:
* [Types of Feature Modules](guide/module-types).
* [Route-level code-splitting in Angular](https://web.dev/route-level-code-splitting-in-angular/)
* [Route preloading strategies in Angular](https://web.dev/route-preloading-in-angular/)

View File

@ -0,0 +1,96 @@
# `Renderer` to `Renderer2` migration
## Migration Overview
The `Renderer` class has been marked as deprecated since Angular version 4. This section provides guidance on migrating from this deprecated API to the newer `Renderer2` API and what it means for your app.
## Why should I migrate to Renderer2?
The deprecated `Renderer` class has been removed in version 9 of Angular, so it's necessary to migrate to a supported API. Using `Renderer2` is the recommended strategy because it supports a similar set of functionality to `Renderer`. The API surface is quite large (with 19 methods), but the schematic should simplify this process for your applications.
## Is there action required on my end?
No. The schematic should handle most cases with the exception of `Renderer.animate()` and `Renderer.setDebugInfo()`, which already arent supported.
## What are the `__ngRendererX` methods? Why are they necessary?
Some methods either don't have exact equivalents in `Renderer2`, or they correspond to more than one expression. For example, both renderers have a `createElement()` method, but they're not equal because a call such as `renderer.createElement(parentNode, namespaceAndName)` in the `Renderer` corresponds to the following block of code in `Renderer2`:
```ts
const [namespace, name] = splitNamespace(namespaceAndName);
const el = renderer.createElement(name, namespace);
if (parentNode) {
renderer.appendChild(parentNode, el);
}
return el;
```
Migration has to guarantee that the return values of functions and types of variables stay the same. To handle the majority of cases safely, the schematic declares helper functions at the bottom of the user's file. These helpers encapsulate your own logic and keep the replacements inside your code down to a single function call. Here's an example of how the `createElement()` migration looks:
**Before:**
```ts
public createAndAppendElement() {
const el = this.renderer.createElement('span');
el.textContent = 'hello world';
return el;
}
```
**After:**
<code-example>
public createAndAppendElement() {
const el = __ngRendererCreateElement(this.renderer, this.element, 'span');
el.textContent = 'hello world';
return el;
}
// Generated code at the bottom of the file
__ngRendererCreateElement(renderer: any, parentNode: any, nameAndNamespace: any) {
const [namespace, name] = __ngRendererSplitNamespace(namespaceAndName);
const el = renderer.createElement(name, namespace);
if (parentNode) {
renderer.appendChild(parentNode, el);
}
return el;
}
__ngRendererSplitNamespace(nameAndNamespace: any) {
// returns the split name and namespace
}
</code-example>
When implementing these helper functions, the schematic ensures that they're only declared once per file and that their names are unique enough that there's a small chance of colliding with pre-existing functions in your code. The schematic also keeps their parameter types as `any` so that it doesn't have to insert extra logic that ensures that their values have the correct type.
### Im a library author. Should I run this migration?
**Library authors should definitely use this migration to move away from the `Renderer`. Otherwise, the libraries won't work with applications built with version 9.**
### Full list of method migrations
The following table shows all methods that the migration maps from `Renderer` to `Renderer2`.
|Renderer|Renderer2|
|---|---|
|`listen(renderElement, name, callback)`|`listen(renderElement, name, callback)`|
|`setElementProperty(renderElement, propertyName, propertyValue)`|`setProperty(renderElement, propertyName, propertyValue)`|
|`setText(renderNode, text)`|`setValue(renderNode, text)`|
|`listenGlobal(target, name, callback)`|`listen(target, name, callback)`|
|`selectRootElement(selectorOrNode, debugInfo?)`|`selectRootElement(selectorOrNode)`|
|`createElement(parentElement, name, debugInfo?)`|`appendChild(parentElement, createElement(name))`|
|`setElementStyle(el, style, value?)`|`value == null ? removeStyle(el, style) : setStyle(el, style, value)`
|`setElementAttribute(el, name, value?)`|`attributeValue == null ? removeAttribute(el, name) : setAttribute(el, name, value)`
|`createText(parentElement, value, debugInfo?)`|`appendChild(parentElement, createText(value))`|
|`createTemplateAnchor(parentElement)`|`appendChild(parentElement, createComment(''))`|
|`setElementClass(renderElement, className, isAdd)`|`isAdd ? addClass(renderElement, className) : removeClass(renderElement, className)`|
|`projectNodes(parentElement, nodes)`|`for (let i = 0; i < nodes.length; i<ins></ins>) { appendChild(parentElement, nodes<i>); }`|
|`attachViewAfter(node, viewRootNodes)`|`const parentElement = parentNode(node); const nextSibling = nextSibling(node); for (let i = 0; i < viewRootNodes.length; i<ins></ins>) { insertBefore(parentElement, viewRootNodes<i>, nextSibling);}`|
|`detachView(viewRootNodes)`|`for (let i = 0; i < viewRootNodes.length; i<ins></ins>) {const node = viewRootNodes<i>; const parentElement = parentNode(node); removeChild(parentElement, node);}`|
|`destroyView(hostElement, viewAllNodes)`|`for (let i = 0; i < viewAllNodes.length; i<ins></ins>) { destroyNode(viewAllNodes<i>); }`|
|`setBindingDebugInfo()`|This function is a noop in `Renderer2`.|
|`createViewRoot(hostElement)`|Should be replaced with a reference to `hostElement`|
|`invokeElementMethod(renderElement, methodName, args?)`|`(renderElement as any)<methodName>.apply(renderElement, args);`|
|`animate(element, startingStyles, keyframes, duration, delay, easing, previousPlayers?)`|Throws an error (same behavior as `Renderer.animate()`)|

View File

@ -0,0 +1,138 @@
# Undecorated classes migration (DI)
This section discusses an Angular version 9 schematic that migrates
two inheritance patterns that need to be updated to work with Ivy.
## What does this migration do?
This migration adds an empty `@Directive()` decorator to undecorated
base classes that are extended by either directives or components.
Before:
```ts
export class BaseMenu {
constructor(private vcr: ViewContainerRef) {}
}
@Directive({selector: '[settingsMenu]'})
export class SettingsMenu extends BaseMenu {}
```
After:
```ts
@Directive()
export class BaseMenu {
constructor(private vcr: ViewContainerRef) {}
}
@Directive({selector: '[settingsMenu]'})
export class SettingsMenu extends BaseMenu {}
```
The schematic also copies any inherited directive or component metadata to the derived class.
Before:
```ts
@Component({
selector: 'base-menu',
template: '<div></div>'
})
class BaseMenu {}
export class SettingsMenu extends BaseMenu {}
```
After:
```ts
@Component({
selector: 'base-menu',
template: '<div></div>'
})
class BaseMenu {}
@Component({
selector: 'settings-menu',
template: '<div></div>'
})
export class SettingsMenu extends BaseMenu {}
```
## Why is this migration necessary?
When a class has a `@Directive()` or `@Component()` decorator,
the Angular compiler generates extra code to inject dependencies into
the constructor. When using inheritance, Ivy needs both the parent class
and the child class to apply a decorator to generate the correct code.
You can think of this change as two cases: a parent class is missing a
decorator or a child class is missing a decorator. In both scenarios,
Angular's run-time needs additional information from the compiler.
This additional information comes from adding decorators.
### Decorator missing from parent class
When the decorator is missing from the parent class,
the subclass will inherit a constructor from a class for
which the compiler did not generate special constructor
info (because it was not decorated as a directive).
When Angular then tries to create the subclass,
it doesn't have the correct info
to create it.
In View Engine, the compiler has global knowledge, so it
can look up the missing data. However, the Ivy compiler
only processes each directive in isolation. This means that
compilation can be faster, but the compiler can't
automatically infer the same
information as before. Adding the `@Directive()` explicitly
provides this information.
In the future, add `@Directive()` to base classes that
do not already have decorators and are extended by directives.
### Decorator missing from child class
When the child class is missing the decorator, the
child class inherits from the
parent class yet has no decorators of its own.
Without a decorator, the compiler has no way of knowing
that the class is a `@Directive` or `@Component`, so
it doesn't generate the proper instructions for the directive.
## What does it mean to have a `@Directive()` decorator with no metadata inside of it?
The presence of the `@Directive` decorator causes Angular to generate
extra code for the affected class. If that decorator includes no
properties (metadata),
the directive won't be matched to elements or instantiated
directly, but other classes that _extend_ the
directive class will inherit this generated code. You can think of
this as an "abstract" directive.
Adding an abstract directive to an `NgModule` will cause an error.
A directive must have a `selector` property defined in order to match some element in a template.
## When do I need a `@Directive()` decorator without a selector?
If you're using dependency injection, or any Angular-specific
feature, such as `@HostBinding()`, `@ViewChild()`, or `@Input()`, you need a
`@Directive()` or `@Component()` decorator.
The decorator lets the compiler know to generate the correct
instructions to create that class and any classes that extend it.
If you don't want to use that base class as a directive directly, leave
the selector blank. If you do want it to be usable independently,
fill in the metadata as usual.
Classes that don't use Angular features don't need an Angular decorator.
## I'm a library author. Should I add the `@Directive()` decorator to base classes?
As support for selectorless decorators is introduced in
Angular version 9, if you want to support Angular version 8 and earlier, you
shouldn't add a selectorless `@Directive()` decorator.
You can either add `@Directive()` with a selector or
add an explicit constructor to affected subclasses.

View File

@ -1,6 +1,6 @@
# Providers
A provider is an instruction to the DI system on how to obtain a value for a dependency. Most of the time, these dependencies are services that you create and provide.
A provider is an instruction to the [Dependency Injection](/guide/dependency-injection) system on how to obtain a value for a dependency. Most of the time, these dependencies are services that you create and provide.
For the final sample app using the provider that this page describes,
see the <live-example></live-example>.

View File

@ -519,7 +519,8 @@ During each navigation, the `Router` emits navigation events through the `Router
<td>
An [event](api/router/NavigationCancel) triggered when navigation is canceled.
This is due to a [Route Guard](#guards) returning false during navigation.
This can happen when a [Route Guard](#guards) returns false during navigation,
or redirects by returning a `UrlTree`.
</td>
</tr>

View File

@ -137,8 +137,9 @@ export interface DataGroup {
Similar to `assetGroups`, every data group has a `name` which uniquely identifies it.
### `urls`
A list of URL patterns. URLs that match these patterns will be cached according to this data group's policy.<br>
_(Negative glob patterns are not supported and `?` will be matched literally; i.e. it will not match any character other than `?`.)_
A list of URL patterns. URLs that match these patterns are cached according to this data group's policy. Only non-mutating requests (GET and HEAD) are cached.
* Negative glob patterns are not supported.
* `?` is matched literally; that is, it matches *only* the character `?`.
### `version`
Occasionally APIs change formats in a way that is not backward-compatible. A new version of the app may not be compatible with the old API format and thus may not be compatible with existing cached resources from that API.

View File

@ -31,22 +31,54 @@ Installing the Angular service worker is as simple as including an `NgModule`. I
## Prerequisites
Your application must run in a web browser that supports service workers. Currently, service workers are supported in the latest versions of Chrome, Firefox, Edge, Safari, Opera, UC Browser (Android version) and Samsung Internet. Browsers like IE and Opera Mini do not provide the support. To learn more about other browsers that are service worker ready, see the [Can I Use](https://caniuse.com/#feat=serviceworkers) page and [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API).
To make use of all the features of Angular service worker, use the latest versions of Angular and the Angular CLI.
In addition, in order for service workers to be registered, the app must be accessed over HTTPS, not HTTP. Browsers will ignore service workers on pages that are served over an insecure connection. The reason is that service workers are quite powerful, so extra care needs to be taken to ensure the service worker script has not been tampered with.
In order for service workers to be registered, the app must be accessed over HTTPS, not HTTP.
Browsers ignore service workers on pages that are served over an insecure connection.
The reason is that service workers are quite powerful, so extra care needs to be taken to ensure the service worker script has not been tampered with.
There is one exception to this rule: to make local development easier, browsers do _not_ require a secure connection when accessing an app on `localhost`.
### Browser support
To benefit from the Angular service worker, your app must run in a web browser that supports service workers in general.
Currently, service workers are supported in the latest versions of Chrome, Firefox, Edge, Safari, Opera, UC Browser (Android version) and Samsung Internet.
Browsers like IE and Opera Mini do not support service workers.
If the user is accessing your app via a browser that does not support service workers, the service worker is not registered and related behavior such as offline cache management and push notifications does not happen.
More specifically:
* The browser does not download the service worker script and `ngsw.json` manifest file.
* Active attempts to interact with the service worker, such as calling `SwUpdate.checkForUpdate()`, return rejected promises.
* The observable events of related services, such as `SwUpdate.available`, are not triggered.
It is highly recommended that you ensure that your app works even without service worker support in the browser.
Although an unsupported browser ignores service worker caching, it will still report errors if the app attempts to interact with the service worker.
For example, calling `SwUpdate.checkForUpdate()` will return rejected promises.
To avoid such an error, you can check whether the Angular service worker is enabled using `SwUpdate.isEnabled()`.
To learn more about other browsers that are service worker ready, see the [Can I Use](https://caniuse.com/#feat=serviceworkers) page and [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API).
There is one exception to this rule: To make local development easier, browsers do _not_ require a secure connection when accessing an app on `localhost`.
## Related resources
The rest of the articles in this section specifically address the Angular implementation of service workers.
* [App Shell](guide/app-shell)
* [Service Worker Communication](guide/service-worker-communications)
* [Service Worker in Production](guide/service-worker-devops)
* [Service Worker Configuration](guide/service-worker-config)
For more information about service workers in general, see [Service Workers: an Introduction](https://developers.google.com/web/fundamentals/primers/service-workers/).
For more information about browser support, see the [browser support](https://developers.google.com/web/fundamentals/primers/service-workers/#browser_support) section of [Service Workers: an Introduction](https://developers.google.com/web/fundamentals/primers/service-workers/), Jake Archibald's [Is Serviceworker ready?](https://jakearchibald.github.io/isserviceworkerready/), and
[Can I Use](http://caniuse.com/#feat=serviceworkers).
The remainder of this Angular documentation specifically addresses the Angular implementation of service workers.
For additional recommendations and examples, see:
## More on Angular service workers
* [Precaching with Angular Service Worker](https://web.dev/precaching-with-the-angular-service-worker/)
* [Creating a PWA with Angular CLI](https://web.dev/creating-pwa-with-angular-cli/)
You may also be interested in the following:
* [Getting Started with service workers](guide/service-worker-getting-started).
## Next steps
To begin using Angular service workers, see [Getting Started with service workers](guide/service-worker-getting-started).

Some files were not shown because too many files have changed in this diff Show More