Compare commits

..

391 Commits

Author SHA1 Message Date
79fb9d449c build(docs-infra): use pinned dependencies when possible in ng-packages-installer (#28510)
Previously, `ng-packages-installer` would replace the version ranges for
all dependencies that were peer dependencies of an Angular package with
the version range used in the Angular package. This effectively meant
that the pinned version (from `yarn.lock`) for that dependency was
ignored (even if the pinned version satisfied the new version range).

This commit reduces non-determinism in CI jobs using the locally built
Angular packages by always using pinned versions of dependencies for
Angular package peer dependencies if possible.

For example, assuming the following versions for the RxJS dependency:

- **aio/package.json**: `rxjs: ^6.3.0`
- **aio/yarn.lock**: `rxjs@^6.3.0: 6.3.3`
- **@angular/core#peerDependencies**: `rxjs: ^6.0.0`

...the following versions would be used with `ng-packages-installer`:

- Before this commit:
  - **aio/package.json**: `rxjs: ^6.0.0`
  - **node_modules/rxjs/**: `6.4.0` (latest version satisfying `^6.0.0`)
- After this commit:
  - **aio/package.json**: `rxjs: ^6.3.0`
  - **node_modules/rxjs/**: `6.3.3` (because it satisfies `^6.0.0`)

PR Close #28510
2019-03-06 15:03:43 -08:00
73a93d3ab6 build(docs-infra): keep other dependencies pinned when installing local Angular packages (#28510)
`ng-packages-installer` can be used to replace Angular packages with
locally built ones (from `dist/packages-dist/`) along with their peer
dependencies.

Previously, in order to achieve this, `yarn install` was called with the
`--no-lockfile` option, which resulted in installing the latest versions
of all dependencies (including transitive ones) permitted by the
corresponding version ranges in `package.json` files. As a result, newly
released versions would be picked, resulting in unexpected,
non-deterministic breakages in CI.

This commit calls `yarn install` with the `--pure-lockfile` option
instead. As a result, only the Angular packages (for which the locally
built ones are used) and their peer dependencies are unpinned; the
pinned versions from `yarn.lock` are used for all other (direct and
transitive) dependencies.

While this does not eliminate non-determinism across builds, it
significantly reduces it.

PR Close #28510
2019-03-06 15:03:37 -08:00
8eda5a152b perf(docs-infra): avoid unnecessary I/O operation in ng-packages-installer (#28510)
PR Close #28510
2019-03-06 15:03:29 -08:00
7b82ce0c67 refactor(docs-infra): format package.json for readability in ng-packages-installer (#28510)
PR Close #28510
2019-03-06 15:03:19 -08:00
2eb5fe699f build(docs-infra): remove unnecessary workaround for RxJS in ng-packages-installer (#28510)
Since b43f8bc7d, RxJS does not need to be patched any more in the
top-level `node_modules/`, so we don't need to special-case RxJS in
`ng-package-installer` and use `node_modules/rxjs/`.

PR Close #28510
2019-03-06 15:03:12 -08:00
f99febcdf9 ci(docs-infra): fix deployment to Firebase
This is a backport of f1a860fbf to 6.1.x.
Related to #29029.
2019-03-06 15:03:00 -08:00
36cbfb1771 build(compiler-cli): upgrade chokidar to latest version
This is a backport of 745c9c5ca to 6.1.x.
Related to #28771.
2019-02-28 18:54:13 +02:00
1f5315f6f7 build(docs-infra): upgrade npm-run-all to latest version for security
This is a backport of f45aedcbf to 6.2.x.
See the original commit for details.
2019-02-28 18:54:13 +02:00
eeebe621fe docs: Indicate that PRs should have an associated issue (#25436)
PR Close #25436
2018-10-15 16:51:46 -07:00
05f279df49 test(docs-infra): improve logging output in test-pwa-score[-localhost] (#26459)
PR Close #26459
2018-10-15 15:23:37 -07:00
485d67bfed build(docs-infra): upgrade lighthouse to 3.2.1 (#26459)
PR Close #26459
2018-10-15 15:23:37 -07:00
a1592f5a20 ci(docs-infra): reduce flakyness (#26459)
PR Close #26459
2018-10-15 15:23:37 -07:00
a251374ecd docs: update process for cli tool and restructure doc (#25752)
PR Close #25752
2018-10-15 11:22:18 -07:00
2b00c17091 docs: minor wording correction. "use" to "user". (#26452)
PR Close #26452
2018-10-15 11:19:47 -07:00
81724f5790 ci(docs-infra): allow aio_local builds to fail on Travis
This job is flaky (up to 50%!) so let's allow it to fail while
we investigate the reason.
2018-10-15 10:28:09 -07:00
1f06b6c99b build: upgrade @types/jasminewd2 to 2.0.4 (#26432)
This commit also removes the extra jasminewd2 typings, since the
changes have been merged in the official typings with
DefinitelyTyped/DefinitelyTyped#28957.
2018-10-13 21:09:41 -07:00
6790709b93 fix(docs-infra): prevent unnecessary SideNav scrollbar (#26416)
Fixes #21508

PR Close #26416
2018-10-12 14:09:09 -07:00
9f7f67121c build(docs-infra): only show name in 'inherited from' section (#26387)
Closes #26181

PR Close #26387
2018-10-12 09:13:02 -07:00
db49beae15 build(docs-infra): upgrade @angular/material to 7.0.0-rc.1 (#26394)
PR Close #26394
2018-10-12 08:57:50 -07:00
97609daea9 build(docs-infra): upgrade @angular/* to 7.0.0-rc.1 (#26394)
PR Close #26394
2018-10-12 08:57:50 -07:00
abcb03cb82 build(docs-infra): upgrade @angular/cli to 7.0.0-rc.2 (#26394)
PR Close #26394
2018-10-12 08:57:47 -07:00
4f09f7db73 fix(upgrade): properly destroy upgraded component elements and descendants (#26209)
Fixes #26208

PR Close #26209
2018-10-11 21:07:49 -07:00
f1e14a3224 docs: add angularmix to events page (#26374)
PR Close #26374
2018-10-11 14:16:02 -07:00
50de03a83a docs: fix transpiles link in dependency injection (#26250)
fixed a double bracket that broke the link

PR Close #26250
2018-10-11 14:11:46 -07:00
65555fe35d Revert "fix(upgrade): properly destroy upgraded component elements and descendants (#26209)"
This reverts commit 6da3867d63. Revert is needed due to compilation failures due to this PR inside Google.
2018-10-10 14:46:20 -07:00
6da3867d63 fix(upgrade): properly destroy upgraded component elements and descendants (#26209)
Fixes #26208

PR Close #26209
2018-10-10 14:19:01 -07:00
c9488b5432 release: cut the v6.1.10 release 2018-10-10 11:23:23 -07:00
b22c376123 Revert "fix(upgrade): properly destroy upgraded component elements and descendants (#26209)"
This reverts commit 623adbbdf7.
2018-10-08 14:36:59 -07:00
8a6f3723ca build(docs-infra): upgrade Angular to 7.0.0-rc.0 and TypeScript to 3.1.1 (#26306)
PR Close #26306
2018-10-08 13:44:15 -07:00
ccb0ec9c35 build(docs-infra): upgrade webpack-cli to 3.1.2 (#26306)
This is necessary to avoid webpack/webpack#8082, when installing
dependencies without taking the lockfile into account (e.g. with
`yarn aio-use-local` - locally or on CI).

PR Close #26306
2018-10-08 13:44:15 -07:00
0c9a087809 ci(docs-infra): run tests against local Angular packages too (#26306)
PR Close #26306
2018-10-08 13:44:15 -07:00
2515ff660b test(docs-infra): fix tests (#26306)
PR Close #26306
2018-10-08 13:44:15 -07:00
70c79cb969 ci(docs-infra): remove unnecessary command (#26306)
This was accidentally merged with 4d506acba and 87f60bccf.
The build script is called in `scripts/ci/build.sh` (if necessary).

PR Close #26306
2018-10-08 13:44:15 -07:00
ed04e99c95 docs: update docs to reflect the changes in RxJS 6 (#26238)
PR Close #26238
2018-10-08 13:43:12 -07:00
623adbbdf7 fix(upgrade): properly destroy upgraded component elements and descendants (#26209)
Fixes #26208

PR Close #26209
2018-10-08 12:06:13 -07:00
3660ff80b7 ci(docs-infra): re-use env variable (#26138)
PR Close #26138
2018-10-08 11:56:53 -07:00
3b4d9dc576 fix(platform-browser): fix #22155, destroy hammer manager when off (#22156)
PR Close #22156
2018-10-05 15:44:06 -07:00
8c6c2fc80d docs: add fakeAsync test new feature document (#23117)
PR Close #23117
2018-10-05 15:43:37 -07:00
3886bfadb0 docs: Rename 'QuickStart' into 'Getting Started' (#25762)
Delete symlink

docs: Undo unwanted changes

docs: Rename 'QuickStart' into 'Getting Started'

Revert symlink commit
PR Close #25762
2018-10-05 15:43:17 -07:00
b35ab4f0e6 docs: clarify CurrencyPipe display property (#25852)
Clarify how to suppress the currency/code in the CurrencyPipe by passing an empty string.

PR Close #25852
2018-10-05 15:42:57 -07:00
39d979c5fa docs: add package doc files (#26047)
PR Close #26047
2018-10-05 15:42:14 -07:00
ff980032e7 fix(docs-infra): fix positioning of message for disabled JavaScript (#26198)
PR Close #26198
2018-10-05 15:39:23 -07:00
2fe401dfbb ci(docs-infra): show custom 404 page on preview server (for consistency) (#26199)
PR Close #26199
2018-10-05 15:39:02 -07:00
b4421bb96b docs: fix wording (#26207)
fix wording to sound better
PR Close #26207
2018-10-05 14:19:08 -07:00
ecb28bf5aa docs: fix spelling errors (#26213)
PR Close #26213
2018-10-05 14:17:22 -07:00
5c5164b6e7 docs: typo fixes (#26247)
PR Close #26247
2018-10-05 14:00:21 -07:00
b8a081a8a5 docs(service-worker): improve API docs for SwPush/SwUpdate (#23138)
PR Close #23138
2018-10-05 13:48:14 -07:00
59d80c471a refactor(service-worker): simplify/improve NgswCommChannel typings (#23138)
PR Close #23138
2018-10-05 13:48:14 -07:00
9e5b0794c5 docs(service-worker): add UpdateActivated/AvailableEvent to the public API (#23138)
PR Close #23138
2018-10-05 13:48:14 -07:00
1c1fd98591 docs: add Suguru Inatomi to GDE resources (#26219)
PR Close #26219
2018-10-04 10:10:52 -07:00
d815e4137f build(docs-infra): upgrade @angular/cli to 6.2.3 (#26145) (#25997)
PR Close #26145

PR Close #25997
2018-10-03 13:26:32 -07:00
fe0c5bfdb3 build(docs-infra): upgrade @angular/* to 7.0.0-beta.7 (#26145) (#25997)
PR Close #26145

PR Close #25997
2018-10-03 13:26:32 -07:00
1975c0a4d2 build(docs-infra): update payload size limits to reflect current status (#26145) (#25997)
PR Close #26145

PR Close #25997
2018-10-03 13:26:32 -07:00
efde073ab9 fix(docs-infra): configure Firebase to strip off the .html extension (#25999) (#25997)
Firebase used to do it automatically (with `cleanUrls: true`), but it
stopped doing it unless the resulting URL corresponds to an existing
file (which is not always the case in angular.io; e.g. the resulting URL
might be matched by a new redirect rule).
This change in Firebase hosting behavior resulted in some URLs not being
correctly redirected (e.g. URLs to the archived v2 site, or `.html`
suffixed URLs from 3rd-party sites).

This commit fixes it, by configuring Firebase hosting to strip off the
`.html` extension and redirect (if no other redirect rule matched).

PR Close #25999

PR Close #25997
2018-10-03 13:26:32 -07:00
a68c29da4b build(docs-infra): update size limits (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
becb775d08 fix(docs-infra): ignore server-side redirected URLs in the SW (#25997)
This allows URLs to be passed through to the server (where they are
properly redirected), instead of serving `index.html` from the SW.

Known issue:
`/docs/` will be passed through to the server. `/docs` (without the
trailing slash) will be correctly treated as a navigation URL and
handled by the SW.
We don't link to `/docs/` from within the app, but if there are external
links to `/docs/` they will require a round-trip to the server and will
not work in offline mode.

PR Close #25997
2018-10-03 13:26:32 -07:00
a273491be0 build(docs-infra): downgrade @angular-devkit/build-angular to 0.6.7 (#25997)
The is a bug in versions 0.6.8+ that breaks when trying to use Jasmine's
mock clock.

Related to angular/angular-cli#11626.

PR Close #25997
2018-10-03 13:26:32 -07:00
7d45386262 build(docs-infra): upgrade @angular/* to 6.1.0-rc.3 and rxjs to 6.2.2 (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
82fcb325a1 build(docs-infra): upgrade @angular/cli to 6.1.0-rc.3 and @angular-devkit/build-angular to 0.7.0-rc.3 (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
115c874779 build(docs-infra): upgrade @angular/material to 6.0.2 (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
8cbebc673d build(docs-infra): upgrade @angular/* to 6.0.2 and rxjs to 6.1.0 (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
94b2673c1f build(docs-infra): upgrade @angular/cli to 6.0.3 (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
bc73dcb448 build(docs-infra): remove unused dependencies (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
fefa171d83 build(docs-infra): remove the dependency on rxjs-compat (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
5c84b91543 build(docs-infra): enable ServiceWorker in cli config (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
00b37310e1 fix(docs-infra): correctly show icon for fetch error when offline (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
bc27b95771 refactor(docs-infra): move concept icons to more appropriate location (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
31f352c043 refactor(docs-infra): remove unused images (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
ad62eaa612 feat(docs-infra): Convert AIO to use the new Service Worker 5.0.0. (#25997)
AIO is currently using a beta version of @angular/service-worker.
Since that was implemented, the SW has been rewritten and released
as part of Angular 5.0.0. This commit updates AIO to use the latest
implementation, with an appropriate configuration file that caches
the various AIO assets in useful ways.

PR Close #25997
2018-10-03 13:26:31 -07:00
66c2d089f0 ci(docs-infra): run the script in the correct folder 2018-10-01 13:08:05 -07:00
c1bf82adb9 fix(docs-infra): remove unnecessary margin on short descriptions (#25768)
(This was added in 405d97431f but it is
not clear the reasoning. It looks better to remove it now.)

PR Close #25768
2018-10-01 09:36:37 -07:00
c05d24e0fe build(docs-infra): fix formatting of entry point export table (#25768)
Now that `list-table` cells are `pre` formatterd we must be careful
of what whitespace appears in text nodes.

PR Close #25768
2018-10-01 09:36:37 -07:00
adbb920ae8 build(docs-infra): simplify property syntax rendering (#25768)
PR Close #25768
2018-10-01 09:36:37 -07:00
f871fecf66 build(docs-infra): remove unused property table heading (#25768)
PR Close #25768
2018-10-01 09:36:37 -07:00
9f919f762a build(docs-infra): add short description "See more" link (#25768)
If there is additional (non-short) description then add in a
link to the short description to take the reader there.

PR Close #25768
2018-10-01 09:36:37 -07:00
6df45a6d47 build(docs-infra): pluralize NgModule(s) heading as appropriate (#25768)
PR Close #25768
2018-10-01 09:36:37 -07:00
71128e2392 build(docs-infra): improve directive selector rendering (#25768)
`:not(...)` blocks are now rendered as italic, while the
rest of the selector is bold.

PR Close #25768
2018-10-01 09:36:36 -07:00
38980f1813 build(docs-infra): move directive macros into memberHelpers.html (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
76f30524be build(docs-infra): include directives etc in class descendants lists (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
721343349b build(docs-infra): display inherited members on directives (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
4c19a2dba9 build(docs-infra): directive inputs and outputs (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
4aacbbe04b build(docs-infra): rename example template variable in directive pages (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
19c2d5b3d4 build(docs-infra): remove class overview from directive pages (#25768)
PR Close #25768
2018-10-01 09:36:35 -07:00
2f79aab084 build(docs-infra): improve directive selector rendering (#25768)
If the documentation contains a `@selectors` tag then the content of that
is used to describe the selectors of a directive.

Otherwise the selector string is split and each selector is listed as
a list item in an unordered list.

PR Close #25768
2018-10-01 09:36:35 -07:00
63b178ec3d build(docs-infra): improve directive API doc templates (#25768)
Closes #22790
Closes #25530

PR Close #25768
2018-10-01 09:36:35 -07:00
a48bf0bdb6 docs: fix a typo in the Universal guide (#25853)
line 39: `highly-interactive` is the pre-qualifier of `Angular application`, which is the subject so the comma is not necessary (I think). I think this will make it easier for non-native speakers.

PR Close #25853
2018-09-28 09:36:10 -07:00
22dc8adae5 build: use separate tags for ivy builds in publish-build-artifacts.sh (#26159)
PR Close #26159
2018-09-28 09:35:33 -07:00
04a023c31a build: pass stripExportPattern as an array of RegExp (#26012)
This is a workaround for https://github.com/bazelbuild/rules_nodejs/issues/317

PR Close #26012
2018-09-27 12:07:04 -07:00
c12e553ff1 fix(docs-infra): use correct parameters for paginated requests to GitHub (#25671)
As it turns out, in GitHub API paginated requests, page numbering is
1-based. (https://developer.github.com/v3/#pagination)

Starting at page 0 (which returns the first page), results in making the
same request twice and logging incorrect numbers (since the first 100
items are listed twice).

PR Close #25671
2018-09-26 15:26:25 -07:00
c8eb6182bc fix(docs-infra): fix preview server periodic clean-up (#25671)
Includes the following fixes:

- Fix cron entry format for clean-up script.
  Crontabs in `/etc` should not have a user field. No idea why it used
  to work before, but it started giving errors recently:
  `/bin/sh: root: not found`.

- Set required env variable in clean-up script. (Broken in cc6f36a9d.)
  This was producing the following error:
  `ERROR: Missing required environment variable 'AIO_CIRCLE_CI_TOKEN'!`

- Use the correct path for downloads to be removed. (Broken in cc6f36a9d.)

PR Close #25671
2018-09-26 15:26:25 -07:00
0a7a542edd test(docs-infra): remove unnecessary test helpers (#25671)
`supertest.Request` extends `Promise` and can be used directly without
"promisifying".

PR Close #25671
2018-09-26 15:26:25 -07:00
9d7ad34873 docs(docs-infra): update preview server docs to account for recent changes (#25671)
Mostly (but not exclusively) a follow-up to #23576.

PR Close #25671
2018-09-26 15:26:25 -07:00
63c2a2a74a ci(docs-infra): test PR previews on CI (#25671)
The deployment of PR previews is triggered by the notification webhook
of the `aio_preview` CircleCI job (which creates and stores the build
artifacts).

This commit adds a new job (`test_aio_preview`), which waits for the
preview to be deployed (for PRs that do have a preview) and then runs
some tests against it (currently only PWA tests).

Fixes #23818

PR Close #25671
2018-09-26 15:26:25 -07:00
2e0de01372 feat(docs-infra): add API endpoint for checking if PR can have preview (#25671)
There several reasons why PRs cannot have (public) previews:
- The PR did not affect any relevant files (e.g. non-spec files in
  `aio/` or `packages/`).
- The PR cannot be automatically verified as "trusted" (based on its
  author or labels).

Note:
The endpoint does not check whether there currently is a (public)
preview for the specified PR; only whether there can be one.

PR Close #25671
2018-09-26 15:26:25 -07:00
88e080003d fix(docs-infra): correctly check PR files on preview server (#25671)
According to the docs, the response of GitHub's [PR files API][1]
_"includes a maximum of 300 files"_. This means that if a PR contains
more files, it is possible that not all files are retrieved (which
could, for example, give a false negative for the "significant files
touched" check - not likely but possible).

This commit fixes it by using paginated requests to retrieve all changed
files.

[1]: https://developer.github.com/v3/pulls/#list-pull-requests-files

PR Close #25671
2018-09-26 15:26:25 -07:00
8a62f0a36c test(docs-infra): fix test for preview server's GithubPullRequests (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
6c8863aa09 test(docs-infra): fix test for preview server's BuildCleaner completing prematurely (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
fe92614c91 test(docs-infra): fix preview server unit tests on Windows (#25671)
Some tests where comparing actual with expected paths, without taking
into account that paths will be different on Windows.

This commit uses `path.resolve()` to convert expected paths to their
OS-specific form.

PR Close #25671
2018-09-26 15:26:25 -07:00
166bb8e048 test(docs-infra): add support for source-maps in preview server tests (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
c7da5d8cfd refactor(docs-infra): use mockable logger (#25671)
Related discussion:
https://github.com/angular/angular/pull/23576#discussion_r187925949.

PR Close #25671
2018-09-26 15:26:25 -07:00
153738dce9 refactor(docs-infra): fix method name (getPrfromBranch --> getPrFromBranch) (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
ce4aa5cb93 build(docs-infra): upgrade preview server dependencies (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
0647582292 build(docs-infra): replace concurrently with npm-run-all for preview server dev (#25671)
`npm-run-all` works just as well, but is better at handling termination on Windows.

PR Close #25671
2018-09-26 15:26:25 -07:00
c5620d1c7a build(docs-infra): do not exit preview server dev script when build fails (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
e3a73dff45 build(docs-infra): avoid race condition in aio-builds-setup/ npm scripts (#25671)
Previously, due to multiple scripts re-building during `yarn dev`
initialization, there could be race conditions that led to errors.

This commit fixes it by ensuring `yarn build` is run once (before
the main `yarn dev` script).

PR Close #25671
2018-09-26 15:26:25 -07:00
5881f34787 docs: firefox web components info (#26118)
PR Close #26118
2018-09-26 15:25:46 -07:00
acffa22a35 release: cut the v6.1.9 release 2018-09-26 12:02:03 -07:00
159e8b4fda docs: update routing integration section based on feedback (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
d52dd0a8d1 docs: add section on router integration (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
05252769bf docs: clean up providedIn: 'root' syntax for router examples (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
9c36a3520d docs: router guide review feedback changes (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
1b282c278f docs: Update router guide to use Angular CLI (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
c9fece997c docs: Refresh content on routable animations for router guide (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
c8817f39a9 docs: cleanup minor changes for forms overview (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
2f1aec4744 docs: remove unused properties from forms overview example (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
e55127906a docs: fix typos from review feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
789ff49bcf docs: update with forms overview review feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
df02d6dd86 docs: more overview feedback changes (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
fb8028a130 docs: update nav descriptions based on feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
29647bb815 docs: add updated reactive forms data flow image (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
2911e99baf docs: updates from review feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
3952367bf3 docs: add updated forms overview images (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
ea6aade4ce docs: integrate forms diagrams into overview (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
26baf15b12 docs: add final thoughts to forms overview (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
25c5cba7b3 docs: incorporated forms overview review feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
fb06037392 docs: forms overview review changes (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
90f8a1622e docs: add forms overview example for snippets (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
8c9edb8484 docs: more form overview edits (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
52cd20d4fe docs: incorporated forms overview feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
c7567b65f2 docs(forms): add package overview for forms (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
0fdd1bb929 docs: add forms overview guide (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
559c647db7 docs: fix issues related to tutorial. (#24445)
PR Close #24445
2018-09-25 18:45:21 -07:00
42e2e7cf57 build: remove obsolete comment in env.sh (#25819)
The comment is no longer true since #25602.

PR Close #25819
2018-09-25 11:04:34 -07:00
adad1706e0 docs: fix a typo (#26074)
PR Close #26074
2018-09-24 13:48:26 -07:00
a169743324 fix(service-worker): do not blow up when caches are unwritable (#26042)
In some cases, example when the user clears the caches in DevTools but
the SW remains active on another tab and keeps references to the deleted
caches, trying to write to the cache throws errors (e.g.
`Entry was not found`).

When this happens, the SW can no longer work correctly and should enter
a degraded mode allowing requests to be served from the network.

Possibly related:
- https://github.com/GoogleChrome/workbox/issues/792
- https://bugs.chromium.org/p/chromium/issues/detail?id=639034

This commits remedies this situation, by ensuring the SW can enter the
degraded `EXISTING_CLIENTS_ONLY` mode and forward requests to the
network.

PR Close #26042
2018-09-24 09:53:41 -07:00
cea7fbe93f docs: Fixes typo in FormArray (#26031)
PR Close #26031
2018-09-24 09:14:08 -07:00
b907e5a2bc docs: correct path reference in upgrade guide (#26072)
The incorrect path is referenced, this is confusing to users following the "Upgrading from AngularJS" guide.

PR Close #26072
2018-09-24 09:13:27 -07:00
77d2cbda4a docs: fix Sajee info in contributors (#26063)
PR Close #26063
2018-09-24 09:12:47 -07:00
a730fc703f build(docs-infra): fail doc-gen if a content rule fails (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
af26914ba9 build(docs-infra): allow usage notes on decorator option properties (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
7f7bc64186 docs(core): remove usage notes from ReflexiveInjector.parent property (#26039)
Properties are not allowed usage notes, and in this case the example
is so simple it didn't warrant moving it to the overall class documentation.

PR Close #26039
2018-09-24 09:11:05 -07:00
33af76929f docs(core): move headings to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
edbf3d2fe3 docs(common): move KeyValuePipe example to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
a39445fe09 docs(forms): move extended text to @usageNotes (#26039)
Headings are not allowed in the basic description block.

PR Close #26039
2018-09-24 09:11:05 -07:00
0b05448a7d docs(http): move examples to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
852a73ef82 docs(platform-browser): move examples to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
b8bfc03875 docs(router): move examples to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
c4887ab10a docs(upgrade): move examples etc into @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
1abd3977be docs(common): move KeyValuePipe example to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
98961e3d44 build(docs-infra): remove legacy jsdoc tag processing (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
3f89d3094b docs(common): remove legacy @whatItDoes tag (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
484d3d9a64 build(docs-infra): add @nocollapse tag-def to prevent warning (#26039)
See https://github.com/angular/angular/blob/master/packages/compiler-cli/src/transformers/nocollapse_hack.ts

PR Close #26039
2018-09-24 09:11:05 -07:00
37f3b92ff5 build(docs-infra): sort NgModule exports by id (#26051)
PR Close #26051
2018-09-21 17:00:04 -07:00
50cd655c6c build(docs-infra): sort package exports by id (#26051)
Closes #26046

PR Close #26051
2018-09-21 17:00:04 -07:00
05d1b84f52 fix(docs-infra): ensure that only search is removed from URL on click (#26056)
When we have navigated to the site via a URL that contains a search
query param, the site shows the search results.

We want to remove that query param from the URL when the search
results are closed, but the current implementation is also removing
other query params unnecessarily.

Now only the search param is removed when the search results are
closed.

See https://github.com/angular/angular/pull/25479/files#r219497804
for more context.

PR Close #26056
2018-09-21 10:29:26 -07:00
69452231df build(docs-infra): expose deprecated status on items more clearly (#25750)
PR Close #25750
2018-09-21 10:26:51 -07:00
4f6bef5b32 fix(docs-infra): render security risk labels (#25750)
PR Close #25750
2018-09-21 10:26:51 -07:00
ec96332559 build(docs-infra): improve search quality (#25750)
PR Close #25750
2018-09-21 10:26:51 -07:00
ee9f0b5d9a build(docs-infra): do not include license comment in first API doc (#26050)
The default dgeni config is to concatenate leading comments in front of API items.

In the case that you have an API item that starts a file with no import statements,
the license comment at the top of the file was being added to the front of the
API item's comment. SInce the license comment includes the `@license` tag
and the API item's comment did not start with `@description` the content of
the API item's comment was being put inside the `@license` tag, and no
description was being extracted from the API item's comment.

This commit updates to a version of dgeni-packages that has a switch to turn off
this concatenation, and then also configures this switch.

Closes #26045

PR Close #26050
2018-09-21 10:25:46 -07:00
a135f48b6d docs: add Sajee to contributors (#26028)
PR Close #26028
2018-09-21 10:24:22 -07:00
61b4c26893 ci: correct github robot size check configuration (#26057)
PR Close #26057
2018-09-21 10:21:31 -07:00
f1cb46081c ci: only run aio_preview job on PR builds (#26030)
There can be no preview on non-PR builds, so there is no point in
running the job.

PR Close #26030
2018-09-20 09:32:46 -07:00
0ec925bd2f docs: copy-edit (#25732)
PR Close #25732
2018-09-19 18:22:47 -07:00
5f1b861525 docs: integrate material from cli wiki (#25732)
PR Close #25732
2018-09-19 18:22:47 -07:00
f0d70545e8 fix(forms): remove forms file from patch (#26025)
PR Close #26025
2018-09-19 17:18:31 -07:00
26341c7fd4 docs: add missing @ngModule tags (#25734)
PR Close #25734
2018-09-19 16:23:04 -07:00
e9f4f1b416 build(docs-infra): process and render ngmodule exports (#25734)
All directives and pipes must now be tagged with one ore more
public NgModule, from which they are exported.

If an item is exported transitively via a re-exported internal NgModule
then it may be that the item appears to be exported from more than
one public NgModule. For example, there are shared directives that
are exported in this way from `FormsModule` and `ReactiveFormsModule`.

The doc-gen will error and fail if a directive or pipe is not tagged correctly.

NgModule pages now list all the directives and pipes that are exported from it.
Directive and Pipe pages now list any NgModule from which they are exported.
Packages also now list any NgModules that are contained - previously they were
missed.

PR Close #25734
2018-09-19 16:21:02 -07:00
9cd534bd63 build(docs-infra): separate NgModules from Classes in API docs (#25734)
PR Close #25734
2018-09-19 16:20:56 -07:00
2f8e1fbab8 build(docs-infra): remove unused info-bar API template (#25734)
PR Close #25734
2018-09-19 16:20:48 -07:00
c7a6adc771 docs(forms): update form apis based on review feedback (#25724)
PR Close #25724
2018-09-19 16:09:03 -07:00
8fb2b473ca docs(forms): update API reference for forms interfaces and abstract classes (#25724)
PR Close #25724
2018-09-19 16:09:03 -07:00
5886090d50 feat(docs-infra): Add opensearch description (#25479)
Enables Chrome users to search angular.io and its subdomains from the browsers navigation bar.
Not sure if compatible with Firefox yet.
The queried term in the URL is removed after closing the search-results.

PR Close #25479
2018-09-19 15:33:28 -07:00
3988ebf432 release: cut the v6.1.8 release 2018-09-19 14:07:10 -07:00
5099b79545 docs: copy edit (#25582)
PR Close #25582
2018-09-19 10:43:07 -07:00
038d06d2e9 docs: clean up formats, add detail (#25582)
PR Close #25582
2018-09-19 10:43:07 -07:00
9e1aff9fe6 docs: update view-related api doc (#25582)
PR Close #25582
2018-09-19 10:43:07 -07:00
a41f331cb4 docs: add ngmodule api doc (#25618)
PR Close #25618
2018-09-19 10:40:59 -07:00
71628f1837 docs(animations): updated animation docs (#24206)
PR Close #24206
2018-09-19 10:37:31 -07:00
df878a6b60 docs: delete extra sentence (#25984)
PR Close #25984
2018-09-19 09:42:12 -07:00
48d7f4e8b5 fix(bazel): move bazel managed runtime deps for downstream usage (#25690)
PR Close #25690
2018-09-18 15:09:50 -07:00
66f5d27e50 build(bazel): fix typos in comments (#25172)
PR Close #25172
2018-09-18 15:05:29 -07:00
91dd160b21 fix(bazel): correct type concatenated to devmode_js (#25467)
PR Close #25467
2018-09-18 15:04:40 -07:00
1c44b71fd2 feat(ivy): enable .ngfactory.js generation in g3 only (#25392)
This turns on generation of ngfactory.js files when compiling in Ivy
mode in g3. They're not turned on for Bazel users as there appears to
be a strange interaction with the way our tests run in Bazel mode.

PR Close #25392
2018-09-18 15:04:31 -07:00
a5e0ae501d docs(bazel): add skydoc generation (#23544)
PR Close #23544
2018-09-18 15:04:26 -07:00
2d0e642dbe fix(bazel): allow compile_strategy to be (privately) imported (#25080)
compile_strategy() is used to decide whether to build Angular code
using ngc (legacy) or ngtsc (local). In order for g3 BUILD rules
to switch properly and allow testing of Ivy in g3, they need to
import this function.

This commit removes the _ prefix which allows the function to be
imported.

PR Close #25080
2018-09-18 15:00:32 -07:00
9ea656f20e build: use nodejs public api (#25940)
`nodejs_binary` and `nodejs_test` from `@build_bazel_rules_nodejs//:defs.bzl` and `@build_bazel_rules_nodejs//internal/node:node.bzl` are different as the first one uses a macro https://github.com/bazelbuild/rules_nodejs/blob/master/internal/node/node.bzl#L229 to wrap the `nodejs_binary` and `nodejs_test` as an `.exe` for Windows.

PR Close #25940
2018-09-18 14:47:43 -07:00
97ae7aed41 feat(bazel): add additional parameters to ts_api_guardian_test def (#25694)
Added `strip_export_pattern` and `allow_module_identifiers` so that these can be passed from downstream

PR Close #25694
2018-09-18 14:47:35 -07:00
678b4209c8 fix(bazel): specify the package and lock files using the workspace (#25694)
PR Close #25694
2018-09-18 14:47:30 -07:00
b7be4f55be build: add support for running builds outside of sandbox on Mac. (#25870)
Add following to your `~/.bazelrc`. This will run the build faster locally
(outside of sandbox), but continue running the builds with sandboxing
on CI.

```
build --spawn_strategy=standalone --strategy=ESM5=sandboxed
```
PR Close #25870
2018-09-18 14:43:39 -07:00
e7c72ab556 style: reformat bzl files on patch branch to match master 2018-09-18 14:43:05 -07:00
af785f9e91 ci: enforce formatting of .bzl files (#23544)
These are now enforced in google3 so we want to match, so that PRs don't get held up when we sync

PR Close #23544
2018-09-18 14:40:59 -07:00
1ac5d68827 build: bump the com_github_bazelbuild_buildtools version to 0.12.0 (#25917)
This is a preliminary fix to make buildifier work with Bazel 0.16.

See alexeagle/angular-bazel-example/issues/173

PR Close #25917
2018-09-18 14:36:38 -07:00
2c987625ae build(bazel): update to rules_typescript 0.17.0 & rules_nodejs 0.13.4 (#25920)
PR Close #25920
2018-09-18 14:36:28 -07:00
a77f567403 ci: update to bazel 0.17 (#25967)
this includes support for @ character in labels, which we need for fine-grained deps

PR Close #25967
2018-09-18 14:32:34 -07:00
110c81f359 build: ignore aio/docs-infra commits in changelog gulp task (#25838)
PR Close #25838
2018-09-18 13:23:06 -07:00
ef4b5c7e59 build: update conventional-changelog and simplify changelog gulp task (#25838)
The version prefix issue has been fixed with
conventional-changelog/conventional-changelog#179.

PR Close #25838
2018-09-18 13:23:00 -07:00
c69362442d build: update .nvmrc file to correct node version (#25992)
The version was updated in 34ec9244a6
but this file got missed.
PR Close #25992
2018-09-18 13:11:58 -07:00
6c8791ee32 docs(forms): change documentation of the FormGroup patchValue method (#25901)
Improve the grammar of the description to make it more readable.
PR Close #25901
2018-09-18 13:08:06 -07:00
274dc1e972 build(bazel): update to rules_typescript 0.17.0 & rules_nodejs 0.13.4 (#25977)
PR Close #25977
2018-09-18 13:03:37 -07:00
d9bd86050b docs: fix typo in bootstrapping guide (#25939)
Fixes #25938

PR Close #25939
2018-09-14 16:38:18 -07:00
076374ba4f docs: delete old comments from example (#25931)
PR Close #25931
2018-09-13 15:33:33 -07:00
e117b1ffd2 fix(router): mount correct component if router outlet was not instantiated and if using a route reuse strategy (#25313) (#25314)
This unsets 'attachRef' on outlet context if no route is to be reused in route activation.

Closes #25313

PR Close #25314
2018-09-11 16:26:42 -07:00
8d7fbb614b docs(router): change description of parameter usage for navigation functions (#21840)
PR Close #21840
2018-09-11 16:24:23 -07:00
a31cfc521c fix(compiler): Fix look up of entryComponents in AOT Summaries (#24892)
Previously, when you attempted to bootstrap a component that had a
router-outlet using ngsummaries, it would complain that the component
was not provided by any module even if it was. This commit fixes a
mistake (AFAICT) which caused the lookup of the component in the AOT
summaries to fail.

I believe this change is safe. I've run the affected tests within Google
and there were no breakages caused by this change.

PR Close #24892
2018-09-11 16:23:17 -07:00
55a1ce7adf docs: add disableTypeScriptVersionCheck documentation (#25537)
PR Close #25537
2018-09-11 12:25:55 -07:00
9f3da659aa docs(aio): add ng-sq-ui to resources (#25874)
PR Close #25874
2018-09-10 10:31:11 -07:00
8f9aeaaa67 docs: move compiler options to last section of the page (#22353)
PR Close #22353
2018-09-10 10:30:01 -07:00
b9a5ce1c06 docs(service-worker): update http-server command (#25845)
PR Close #25845
2018-09-06 14:59:51 -07:00
f67229efa3 build(docs-infra): ensure any stale generated content is deleted (#25841)
Since `aio/src/generated/` is git-ignored, it is easy for stale content
(e.g. removed images, examples, zips, etc.) to remain there on local
clones and then get copied into the `dist/` directory.

This commit ensures `aio/src/generated/` is cleaned up before generating
the new content.

PR Close #25841
2018-09-06 14:59:29 -07:00
f707f545aa build: update to Node 10 (#25822)
PR Close #25822
2018-09-06 14:58:30 -07:00
62f4ea5f0f test(docs-infra): fix double-slash in URL of aio_monitoring test (#25641) (#25820)
As part of the tests run in the CircleCI `aio_monitoring` job, we need
to retrieve `sitemap.xml` from the site under test. Previously, the URL
used to retrieve that contained a double-slash (`//`). At some point,
Firebase (which is used for hosting the site) stopped normalizing
double-slashes to a single slash, causing the test to fail.

This commit fixes the problem by ensuring that the constructed URLs do
not contain double-slashes.

PR Close #25641

PR Close #25820
2018-09-06 14:58:09 -07:00
ecc3406ca6 test(docs-infra): correctly extract sitemap URLs (#19795) (#25820)
`%%DEPLOYMENT_HOST%%` has been assumed to be the host prefix for sitemap
URLs since bf29936af, but afaict this was never the case.

PR Close #19795

PR Close #25820
2018-09-06 14:58:09 -07:00
e244b5180e build(bazel): update bazel integration to build angular from source (#25774)
PR Close #25774
2018-09-06 14:56:53 -07:00
f85d3d7857 build(bazel): make resolveTypeReferenceDirectives override work with both ts 2.9 & ts 3.0 (#25774)
PR Close #25774
2018-09-06 14:56:53 -07:00
b404d47b16 build(bazel): fix bazel types reference directive resolves (#25774)
PR Close #25774
2018-09-06 14:56:53 -07:00
815d1ffa19 release: cut the v6.1.7 release 2018-09-05 20:49:37 -07:00
d1063c62b3 build(docs-infra): restore correct dependency versions in package.json (#25827)
Accidentally broken in 46de203f8 (while cherry-picking #25806 into
6.1.x).
2018-09-05 17:57:27 -07:00
3a0b7355e5 build: upgrade Chromium and ChromeDriver to latest versions (#25602) (#25669)
PR Close #25602

PR Close #25669
2018-09-05 11:40:30 -07:00
3bdd4e249f build: check for latest Chromium version (#25602) (#25669)
Now that https://omahaproxy.appspot.com/all is back up, we can restore
the check for newer available version of Chromium.

Fixes #22231

PR Close #25602

PR Close #25669
2018-09-05 11:40:30 -07:00
2c1f55069f build: update ngcontainer to node 10.9.0 (#25812)
PR Close #25812
2018-09-05 11:37:26 -07:00
e72f741e78 docs: update event page (#25799)
docs: change reactiveconf event location
PR Close #25799
2018-09-05 11:37:03 -07:00
f0bcfd0e78 docs: fix showcase address truly-ui (#25757)
PR Close #25757
2018-09-05 11:36:39 -07:00
82e06766b8 fix(upgrade): trigger $destroy event on upgraded component element (#25357)
Fixes #25334

PR Close #25357
2018-09-05 11:35:15 -07:00
eea1600a38 refactor(upgrade): share code for destroying upgraded components between dynamic and static (#25357)
PR Close #25357
2018-09-05 11:35:14 -07:00
8f8c390c75 test: remove deprecated Buffer usage in sourcemap test (#25805)
PR Close #25805
2018-09-05 09:38:49 -07:00
23a96dca2d feat(router): warn if navigation triggered outside Angular zone (#24959)
closes #15770, closes #15946, closes #24728

PR Close #24959
2018-09-05 09:35:14 -07:00
6f7df8a1fa feat(docs-infra): disable "status" selector in API list when displaying only packages (#25718)
Closes #25708

PR Close #25718
2018-09-05 09:28:29 -07:00
92298e5271 build(docs-infra): do not render internals in package API pages (#25723)
Closes #24493

PR Close #25723
2018-09-05 09:28:06 -07:00
27f0817000 docs(changelog): fix version 6.1.5 typo (#25760)
PR Close #25760
2018-09-05 09:27:16 -07:00
4596fc0217 refactor(docs-infra): bump polyfills payload limit (#25806)
PR Close #25806
2018-09-05 09:26:10 -07:00
46de203f85 refactor(docs-infra): simplify custom-element polyfill setup (#25806)
PR Close #25806
2018-09-05 09:24:12 -07:00
d752a8907b build(docs-infra): ensure root node_modules exists (#25811)
Now that the doc-gen parses the imports of TS source
files we need to ensure that the root node_modules
exists. Otherwise running `yarn docs` produces an
obscure error:

```
Error: No SourceFile found with path node_modules/@types/jasmine/index.d.ts
```

Closes #25759

PR Close #25811
2018-09-05 09:22:46 -07:00
4fe369e188 docs: add pwa keyword to service worker page (#25725)
PR Close #25725
2018-09-04 12:09:56 -07:00
d8930bbdc2 docs: correct misspellings and add missing punctuation in tutorial (#25676)
PR Close #25676
2018-09-04 12:08:53 -07:00
ad7be5087c ci: ensure build-packages-dist works on OS/X bash (#25591)
PR Close #25591
2018-09-04 12:08:25 -07:00
a4405d7c6f docs(forms): update API reference for reactive and template-driven forms modules (#25687)
PR Close #25687
2018-08-31 13:39:24 -07:00
88f7ddb27d build: fix bad merge onto patch branch (#25729) 2018-08-31 09:51:21 -07:00
98f5acebdb test(docs-infra): test that the "suggest edit" buttons are visible where expected (#24378)
PR Close #24378
2018-08-31 09:42:11 -07:00
ff78149ec2 refactor(docs-infra): refactor templates (#24378)
PR Close #24378
2018-08-31 09:42:11 -07:00
66b7870da7 fix(docs-infra): show "suggest edits" only for /guide and /tutorial dirs (#24378)
PR Close #24378
2018-08-31 09:42:11 -07:00
82088a8489 feat(docs-infra): add "suggest edits" feature to all docs (#24378)
PR Close #24378
2018-08-31 09:42:11 -07:00
ebcf762132 fix(core): size regression with closure compiler (#25531)
By pulling in `compiler` into `core` the `compiler` was not
100% tree-shakable and about  8KB of code was retained
when tree-shaken with closure.

PR Close #25531
2018-08-30 21:32:10 -07:00
ed6b68babf fix(bazel): protractor rule should include *.e2e-spec.js (#25701)
PR Close #25701
2018-08-30 21:21:28 -07:00
2e09115c0c docs: edit and organize di guide (#21915)
PR Close #21915
2018-08-30 13:15:47 -04:00
4a8d56a820 release: cut the v6.1.6 release 2018-08-29 15:38:51 -07:00
0a3dd872e3 build: fix bad merge onto patch branch (#25729)
PR Close #25729
2018-08-29 18:34:22 -04:00
3e690e0062 fix(bazel): Cache fileNameToModuleName lookups (#25731)
This saves expensive re-parsing of the file when not run as a Bazel worker

PR Close #25731
2018-08-29 17:39:22 -04:00
7f8d6c1066 release: cut the v6.1.5 release 2018-08-28 21:39:18 -07:00
c6d502f7f8 docs: clarification of hero selection in routing section (#25634)
PR Close #25634
2018-08-28 22:16:18 -04:00
7aff3641a1 fix(bazel): only lookup amd module-name tags in .d.ts files (#25710)
PR Close #25710
2018-08-28 21:07:15 -04:00
2194b5a5c3 ci: remove vicb from pullapprove.yml (#25702)
PR Close #25702
2018-08-28 11:15:54 -07:00
8a35290686 build: update Bazel to 0.16 (#25646)
PR Close #25646
2018-08-27 18:20:32 -04:00
e40519c32a build(docs-infra): render all overloads if they are abstract (#25670)
In an overloaded method, the overload with the function body is the
actual method doc, and this doc is not included in the list of "additional"
overloads.

Moreover, the logic (all in dgeni-packages) is that if none of the items
has a body then we use the first overload as the actual method doc.

In the case of abstract methods, none of the methods have a body. So we
have a situation where the overloads collection does not contain the first
abstract method, even though it is not the "implementation" of the method.
Therefore we need to still render it.

Closes #25610

PR Close #25670
2018-08-27 18:19:08 -04:00
b560189c0e build(docs-infra): remove "annotations" section from API pages (#25677)
PR Close #25677
2018-08-27 18:18:42 -04:00
59cfc8a729 build(bazel): use value of /// <amd-module name=“”> directive to convert fileNameToModuleName in ngc-wrapped (#25650)
PR Close #25650
2018-08-27 12:21:19 -04:00
72ed2e90d0 build(bazel): esm5_outputs_aspect to work with targets such as ts_proto_library with no replay_params attribute (#25648)
PR Close #25648
2018-08-24 11:48:04 -04:00
4e82a76998 docs(elements): fix typo (tranformation --> transformation) (#25600)
PR Close #25600
2018-08-23 16:54:49 -04:00
51d5b433d0 fix(aio): show aio-themed 404 page for unknown resources (#23188)
Fixes #23179

PR Close #23188
2018-08-23 15:25:48 -04:00
cc0d0a9d1e fix(docs-infra): fix closure warning issue for improper internal flag (#25628)
PR Close #25628
2018-08-22 21:59:23 -04:00
82f26fe5f5 build(bazel): remove workaround no longer needed for module names for ngfactory & ngsummary files (#25604)
Workaround was added in https://github.com/angular/angular/pull/25335. It was necessary for .ngfactory & .ngsummary files to have proper AMD module names starting with @angular when building angular downstream from source using Bazel. The underlying issue has been resolved in the compiler and these files now get proper AMD module names without the need for this workaround. The workaround had an unexpected consequence https://github.com/angular/angular-cli/issues/11835 which is fixed by its removal.

PR Close #25604
2018-08-22 21:11:18 -04:00
8de57c9887 release: cut the v6.1.4 release 2018-08-22 15:05:02 -07:00
ace4e4ffa5 build: remove NGBUILDS_IO_KEY now that it is not used any more (#25601)
This is a follow-up to #25536.

PR Close #25601
2018-08-22 15:59:14 -04:00
1fa97903a3 docs: Improve docs for downgrading a service (#19371)
PR Close #19371
2018-08-21 10:49:00 -07:00
7e61645b82 fix(router): default scroll position restoration to disabled (#25586)
Fixes #25145
FW-305 #resolve

PR Close #25586
2018-08-21 10:48:14 -07:00
46b0ce9fc6 refactor(bazel): allow and ignore extra args for _ts_expected_outs (#25558)
This is needed to let ts_compile_actions take explicit list of srcs and deps to generate tsc actions from another rule. This is no-op for ngc for now.

PR Close #25558
2018-08-20 16:27:48 -07:00
78750a7fec docs: fix typo in service worker getting started guide (#25512)
PR Close #25512
2018-08-20 11:09:52 -07:00
77d9975eb2 build(aio): update dgeni-packages to 0.26.3 to fix reference types issue (#25528)
PR Close #25528
2018-08-20 11:09:24 -07:00
7eed4ee837 build: refactor ambient node & jasmine types so they are only included where needed (#25528)
PR Close #25528
2018-08-20 11:09:24 -07:00
292b435495 docs: fix typo in reactive forms guide (#25543)
PR Close #25543
2018-08-20 11:08:32 -07:00
5939c420ce docs: copy edit glossary (#25468)
PR Close #25468
2018-08-17 14:33:51 -07:00
a5cc9dbb53 ci: ensure aio_preview job has needed node_modules (#25536)
PR Close #25536
2018-08-17 13:48:27 -07:00
2b810a4e57 docs(docs-infra): the build.sh script was renamed to create-image.sh (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
2acf369664 ci(docs-infra): rename 'upload-server' to 'preview-server' (#25554)
The server no longer has files uploaded to it. Instead it is more
accurate to refer to it as dealing with "previews" of PRs.

PR Close #25554
2018-08-17 13:47:54 -07:00
860b79289f ci(docs-infra): add explicit return types to methods (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
b519d41f42 ci(docs-infra): improve preview-server logging (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
faf184ad63 ci(docs-infra): change AIO preview server stuff to pull builds from CircleCI (#25554)
Previously, Travis pushed the build artitfacts to the preview server.
This required us to use JWT to secure the POST request from Travis, to
ensure we couldn't receive malicious builds.

JWT has been deprecated and we are moving our builds to CircleCI.

This commit rewrites the TypeScript part of the preview server that
handles converting build artifact into hosted previews of the docs.

PR Close #25554
2018-08-17 13:47:54 -07:00
1e0f455855 ci(docs-infra): factor out the aio-builds-setup environment variables (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
ced30982df ci(docs-infra): move the payload-size check to the test job (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
fed429b0cc ci(docs-infra): add helper scripts for running TDD in Docker (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
9cb3107dda docs(docs-infra): update the preview server documentation (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
548a972c2a ci(docs-infra): move AIO preview deployment to CircleCI (#25554)
Now instead of pushing the AIO build artifacts to the preview server
from inside a Travis job, the artifacts are built and hosted on the
CircleCI infrastructure. The preview server will then pull these
down after being triggered by a CircleCI build webhook.

PR Close #25554
2018-08-17 13:47:54 -07:00
20dcc25eed ci(docs-infra): update upload-server to run on node.js v10 (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
620d1402fe docs: add HttpClientModule import code to services tutorial (#24854)
To be able to copy and paste.

PR Close #24854
2018-08-16 13:51:18 -07:00
36fb4f4fdb docs: reactive forms guide copy edits (#25417)
PR Close #25417
2018-08-16 13:50:51 -07:00
ea83445149 release: cut the v6.1.3 release 2018-08-15 14:28:58 -07:00
1319ff4376 fix(service-worker): Cache-Control: no-cache on assets breaks service worker (#25408)
At the moment `cacheAge` can we undefined when having `Cache-Control` set to `no-cache` due the mapping method in `needToRevalidate`

Closes #25442

PR Close #25408
2018-08-14 16:40:15 -07:00
9c1311c801 docs(core): Correct spelling error in directives docs (#25377)
Link to life-cycle hooks was spelt as "life-cycle hoooks".
PR Close #25377
2018-08-14 16:39:33 -07:00
2ce93482b9 docs: enable debug tools with current versions of Angular (#25361)
Updating code snippet in docs that shows how to enable debug tools.
PR Close #25361
2018-08-14 16:38:26 -07:00
ed2a47f822 build(bazel): update to rules_typescript 0.16.0 & update to tagged rules_webtesting 0.2.1 (#25486)
PR Close #25486
2018-08-14 16:37:48 -07:00
cdee9add01 build(docs-infra): remove stability labels from API docs (#25453)
PR Close #25453
2018-08-14 13:17:15 -07:00
2f85b1691a build(docs-infra): clean up API package template (#25453)
PR Close #25453
2018-08-14 13:17:15 -07:00
bf441e8b9e build(docs-infra): include packages in API template breadcrumbs (#25453)
PR Close #25453
2018-08-14 13:17:15 -07:00
1c86e9b3b2 build(docs-infra): change breadcrumb delimiter to > (#25453)
PR Close #25453
2018-08-14 13:17:15 -07:00
9d6e869899 docs: add api doc for programmatic animation classes (#24668)
PR Close #24668
2018-08-14 13:15:27 -07:00
e906bf4f31 docs: add Accelebrate to resources (#23204)
PR Close #23204
2018-08-14 11:58:04 -07:00
5f08bdf8b9 ci: github robot should enforce that all requested reviews are submitted (#25336)
See docs in the diff for justification.
PR Close #25336
2018-08-13 21:39:05 -07:00
f1ed022a4d docs: fix typo in Architecture overview page (#25438)
PR Close #25438
2018-08-13 21:38:22 -07:00
151e4b9fcc docs: add link to Yarn in README (#24856)
Remove the code markdown. It is not code, it is a name.

PR Close #24856
2018-08-13 21:36:13 -07:00
d0f089a55d docs(aio): add async validation chapter (#25189)
Closes #22881

PR Close #25189
2018-08-10 09:14:25 -07:00
cb05f9bbe9 docs: fix typo in testing guide (closes #25400) (#25418)
PR Close #25418
2018-08-10 09:11:35 -07:00
fda30cb3e3 build: stop printing source-map-support warning (#25339)
PR Close #25339
2018-08-08 19:02:58 -07:00
2951e721df build(bazel): update to rules_nodejs 0.11.2 and latest rules_typescript (#25365) 2018-08-08 13:19:37 -07:00
3449f1e256 docs: copy edit architecture guide (#25328)
PR Close #25328
2018-08-08 13:12:54 -07:00
6480d1b288 docs: make css multiline in styleguide for consistency (#25300)
PR Close #25300
2018-08-08 13:12:35 -07:00
e76211aa32 docs: add ngrx book to the docs (#23389)
PR Close #23389
2018-08-08 13:11:46 -07:00
a16de8f842 style: fix whitespace and indentation in the testing guide (#21669)
PR Close #21669
2018-08-08 13:11:17 -07:00
24f1dd3b81 docs: add docs for fakeAsync test with custom macroTask in aio (#21669)
PR Close #21669
2018-08-08 13:11:17 -07:00
f39551ce7e docs: Clarify breaking change in minor release (#25393)
The breaking change was in an experimental feature. Update to clarify the wording.

PR Close #25393
2018-08-08 13:06:59 -07:00
3beb7116af release: cut the v6.1.2 release 2018-08-08 11:00:23 -07:00
4b1a825efc Revert "build: update Bazel to 0.16 (#25316)" (#25391)
This reverts commit 4eb8ac6de9 because 0.16 is not
widely available yet (e.g. on Mac) and it is blocking the Angular release.

PR Close #25391
2018-08-08 10:52:25 -07:00
01e62551f5 build(bazel): update to rules_nodejs 0.11.2 and latest rules_typescript (#25365)
PR Close #25365
2018-08-07 21:01:46 -07:00
2f23533a25 docs(aio): Angular course in Portuguese #21836 2018-08-07 12:08:47 -07:00
054fbbe8b8 fix: add mappings for ngfactory & ngsummary files to their module names in aot summary resolver (#25335)
PR Close #25335
2018-08-07 11:13:29 -07:00
155d938e04 docs: refining code of tutorial 7 routing (#22151)
Removed the dead code from hero-detail.component.ts

Fixes #21908

PR Close #22151
2018-08-07 11:08:54 -07:00
94a2ac7884 docs: update resources to include UI-jar (#21200)
PR Close #21200
2018-08-07 11:07:40 -07:00
b75a98522a test(upgrade): reduce flaky-ness by increasing timeout (#24937)
PR Close #24937
2018-08-06 14:52:52 -07:00
d7dc1b5e44 refactor(upgrade): improve internal AngularJS typings (#24937)
PR Close #24937
2018-08-06 14:52:52 -07:00
e075ea7ae7 build(upgrade): use correct sources in BUILD.bazel (#24937)
PR Close #24937
2018-08-06 14:52:52 -07:00
415519acd3 docs: update to 2nd edition of Learning Angular (#20934)
PR Close #20934
2018-08-06 13:44:43 -07:00
8cbb836985 docs: clarify heroes example (#21216)
PR Close #21216
2018-08-06 13:44:18 -07:00
8d0f8bd657 docs: fix table in comparing observables guide (#22485)
PR Close #22485
2018-08-06 13:41:16 -07:00
66547d8fd0 docs(core): clarify supported ViewChild selectors (#22784)
PR Close #22784
2018-08-06 13:40:48 -07:00
6e7d5f0925 docs(core): fix tree-shakable spelling (#24057)
PR Close #24057
2018-08-06 13:40:17 -07:00
29dfa5570a docs: standardize spelling of tree-shakable (#24057)
PR Close #24057
2018-08-06 13:40:17 -07:00
0c028a03ec docs: remove code in universal hero detail component (#25215)
This reverts commit e9cc3dad8f39bc8dfabfb708a825f90fcd2ab697.

PR Close #25215
2018-08-06 13:39:24 -07:00
a54c049051 docs: replace npm with yarn in lockfile readme (#25309)
PR Close #25309
2018-08-06 13:38:15 -07:00
40904ce0c4 docs: add missing word in outputs description. (#25330)
PR Close #25330
2018-08-06 13:36:51 -07:00
88f01f5653 docs: fix typo (#25331)
PR Close #25331
2018-08-06 13:36:10 -07:00
c66794c265 docs: several fixes for NPM package guide (#20186)
PR Close #20186
2018-08-06 11:32:32 -07:00
e4acd83541 docs(http): fixed example unit test for error catching (#25306)
The example unit test should test the service when the backend
application is not available, by providing a mock error response.
Although, the test will
fail as the mock response from the server is valid (it does not simulate
a
error response, but valid response with an error status 404).
This merge request fix this issue by replacing MockResponse with
MockError

This PR resolves 19499 issue

PR Close #25306
2018-08-06 11:31:59 -07:00
a57f8a1301 build: update Bazel to 0.16 (#25316)
PR Close #25316
2018-08-06 11:30:25 -07:00
ae9b4e6fa7 fix(router): take base uri into account in setUpLocationSync() (#20244)
Normalize the full URL (including the base uri) before passing it to
`router.navigateByUrl()`.

Fixes #20061

PR Close #20244
2018-08-06 11:11:08 -07:00
478eca31c7 docs(aio): add Made with Angular (#21297)
PR Close #21297
2018-08-06 09:50:16 -07:00
2e1603938c build: skip ivy builds when not publishing (#25299)
PR Close #25299
2018-08-04 14:17:01 -07:00
0c9c2accc2 refactor(bazel): dont rely on language target to downlevel for loop (#24534)
PR Close #24534
2018-08-03 15:55:19 -07:00
0fb41e5ced test(docs-infra): log docs examples e2e spec paths to aid debugging (#25293)
It seems that occasionally the sharding of docs examples e2e tests gets
messed up resulting in some tests not being run. This can cause CI to be
green on a PR, when they shouldn't (because the failing tests didn't run
at all).

It is unclear under what circumstances this happens, so printing the
paths of found e2e specs will help debug the issue when it comes up
again.

PR Close #25293
2018-08-03 15:30:32 -07:00
3f43dbb642 style(common): fix short param names (#23667)
PR Close #23667
2018-08-03 14:09:29 -07:00
5069c06906 docs(common): fix content errors (#23667)
PR Close #23667
2018-08-03 14:09:29 -07:00
58698d7806 release: cut the v6.1.1 release 2018-08-02 14:02:59 -07:00
e26c25a062 Revert "docs: refactor http module import for style guide app.module (#25001)" (#25263)
This reverts commit 88da8f3d52.

PR Close #25263
2018-08-02 09:20:12 -07:00
0a6434b066 test(common): TokenExtractor should extend HttpXsrfTokenExtractor in xsrf spec (#24649)
PR Close #24649
2018-08-02 08:34:15 -07:00
ff3550c304 test(common): remove unused import in xsrf spec (#24649)
PR Close #24649
2018-08-02 08:34:15 -07:00
6d4a14082c docs(docs-infra): adds note according to Symlink problem (#24714)
docs: adds note according to Symlink problem

Closes #24709
docs(docs-infra): adds section "Developing on Windows"


Merge remote-tracking branch 'origin/aioREADME' into aioREADME


docs(docs-infra): adds information about admin rights


docs(docs-infra): adds hint


docs(docs-infra): Change to link


PR Close #24714
2018-08-02 08:33:24 -07:00
9ddf269c2c docs(elements): add section about custom element typings in elements guide (#25219)
PR Close #25219
2018-08-02 08:32:59 -07:00
25a76a1492 docs(elements): add link to full example in elements guide (#25219)
PR Close #25219
2018-08-02 08:32:59 -07:00
8439a6ec2a docs(elements): remove unnecessary whitespace in elements guide (#25219)
PR Close #25219
2018-08-02 08:32:59 -07:00
1ef2eae3aa feat(docs-infra): support sending Google Analytics events (#25042)
PR Close #25042
2018-08-01 17:04:19 -07:00
d5d034a0ff docs: update reactiveconf 2018 in events (#24739)
PR Close #24739
2018-08-01 16:15:18 -07:00
5ca35b3cd2 docs: Update the link to the Jasmine docs (#25175)
Solves #24462.

Also update the http part of the link to to https.

PR Close #25175
2018-08-01 16:12:44 -07:00
0a6a3f3163 ci: update pullapprove groups and add docs (#25257)
With this update to permissions the docs team can easily identify the technical reviewer for a particular doc, which should streamline the reviews.

I also added Jennifer into all groups that contain docs, so that she can approve changes that contain only editorial changes.

Closes #21692

PR Close #25257
2018-08-01 15:53:41 -07:00
3a601382e6 test(upgrade): run tests against AngularJS v1.7.x as well (#25231)
PR Close #25231
2018-08-01 14:10:21 -07:00
7a1fdde69e build(bazel): entry point file couldn't be resolved [ts-api-guardian] (#25052)
* When using `ts-api-guardian` on Windows, the input file can't be found due to wrong normalized path delimiters.

PR Close #25052
2018-08-01 13:29:27 -07:00
cbc2ea1b1a build: update hello_world__closure to google-closure-compiler 20180716.0.0 (#25236)
PR Close #25236
2018-08-01 13:25:40 -07:00
bdf801b0e8 build: revert yarn.lock rxjs version to 6.0.0 (#25236)
PR Close #25236
2018-08-01 13:23:35 -07:00
fe5e8b7177 docs(aio): update Kendo UI description in resource.json (#24845)
PR Close #24845
2018-08-01 10:59:16 -07:00
11f0f98ad8 docs: fix typos and missing word in tutorial (#20764)
PR Close #20764
2018-08-01 10:56:31 -07:00
801b534421 docs(core): remove experimental tag (#24032)
PR Close #24032
2018-08-01 10:56:07 -07:00
0fc83215e2 docs(core): remove experimental tag (#24032)
Remove experimental note on APP_INITIALIZER.

PR Close #24032
2018-08-01 10:56:07 -07:00
3d3a1a4642 docs(aio): add Kevin Yang to GDE resources (#24791)
Add files via upload
PR Close #24791
2018-08-01 10:55:41 -07:00
32a40ba5de docs: refactor http module import for style guide app.module (#25001)
PR Close #25001
2018-08-01 10:55:17 -07:00
045271230d docs: refactor lazy loading modules example (#25071)
PR Close #25071
2018-08-01 10:54:00 -07:00
ec31f6bf9a docs(router): clarify scroll position wording (#25077)
PR Close #25077
2018-08-01 10:53:35 -07:00
4798d77088 docs(core): replace ReflectiveInjector example with Static Injector example (#25162)
PR Close #25162
2018-08-01 10:52:32 -07:00
08c6762039 docs: replace ReflectiveInjector samples with Injector samples (#25162)
PR Close #25162
2018-08-01 10:52:32 -07:00
26516045e7 refactor(animations): do not use short parameter names (#25198)
PR Close #25198
2018-08-01 10:51:58 -07:00
a83b9f7911 docs(changelog): remove reverted feature entry (#25206)
PR Close #25206
2018-08-01 10:51:28 -07:00
1b7c77e49f docs(changelog): remove duplicate entries (#25206)
PR Close #25206
2018-08-01 10:51:28 -07:00
3ab31a4be6 docs: update to account for CLI changes (#25223)
This should help clarify the use of providedIn and correct the documentation where it was showing the use of a now depreciated CLI command flag.

I am openly looking for feedback on this change to figure out the best wording.

PR Close #25223
2018-08-01 10:51:05 -07:00
43dcf77123 build(bazel): fix typo in protractor test target definition (#25235)
PR Close #25235
2018-08-01 10:50:44 -07:00
d4bf2da3bd refactor(core): remove withBody from public testing API (#25171)
PR Close #25171
2018-07-31 15:09:33 -07:00
fa3882845a docs(aio): add short description for entryComponents (#21360)
PR Close #21360
2018-07-31 13:18:36 -07:00
fa59748e00 build: make postinstall script compatible with Windows (#25232)
PR Close #25232
2018-07-31 13:17:55 -07:00
c38ecb3b5b docs(forms): fix incorrect variables naming in the comments (#25150)
PR Close #25150
2018-07-31 11:42:16 -07:00
875efa8492 docs(docs-infra): fix topnav layout for smaller screens (#25181)
PR Close #25181
2018-07-31 11:41:22 -07:00
74964bde99 docs: fix link to "Override component providers" (#24967)
Closes #24966

PR Close #24967
2018-07-30 21:53:21 -07:00
785fb5cc5a docs(aio): add StrongBrew to the trainer list (#24891)
PR Close #24891
2018-07-30 16:48:17 -07:00
26d9f0278b ci: correctly encode quoted params passed as params to curl
Previously the auth token could have been split into three separate args in bash which resulted
in two bogus requests being sent out for each curl call. These requests had to time out before
the real request was made, but without the token.

I couldn't find a better way to quickly fix this without adding some duplication.
2018-07-30 16:46:50 -07:00
22ebd53c17 docs: update bootstrapping and entry component guide to use httpclient (#25178)
PR Close #25178
2018-07-30 16:00:19 -07:00
a972c039c3 docs: fix typo in dependency injection guide (#24972)
PR Close #24972
2018-07-30 15:56:36 -07:00
f5e18029fa docs: refactor pipe example to use the HttpClient (#22741)
PR Close #22741
2018-07-30 14:40:25 -07:00
317c7087c5 build(compiler-cli): update tsickle dependency to support TypeScript 2.9 (#25152)
The original range (`^0.30.0`) does not match `0.32.1`, which enables support for TypeScript 2.9.

Close #25141

PR Close #25152
2018-07-27 11:25:28 -07:00
39abe7b7c1 test: fix typings for DoneFn (#25163)
This also fixes CI tests, which were accidentally broken in #24663.

PR Close #25163
2018-07-27 11:13:33 -07:00
36a7705a44 feat(docs-infra): allow notification bar to show arbitrary content (#25020)
This change generalises the notification bar rendering to allow
more complex content to be displayed.

Now you must provide the full HTML of the notification message
when using `<aio-notification>`.

Also you can control whether clicking the content triggers the
notification to close or not.

This will support the new notification specified in "Other Items : 3" of
[#24140](https://github.com/angular/angular/issues/24140#issuecomment-397480410)

PR Close #25020
2018-07-27 09:29:40 -07:00
50a21885cf style(docs-infra): remove unnecessary call to console.log() (#25020)
PR Close #25020
2018-07-27 09:29:40 -07:00
e86f3d9a49 docs: refactor feature modules example (#25069)
PR Close #25069
2018-07-27 09:28:13 -07:00
738f2961ba docs: Change unnecessary step in ToH-Tutorial (#25059)
PR Close #25059
2018-07-27 09:25:59 -07:00
f2bf8287ba build(bazel): add comment about angular bazel rules API re-export from /index.bzl (#24663)
PR Close #24663
2018-07-26 17:02:21 -07:00
9d5b34e1e7 build(bazel): add comment for patch-types work-around (#24663)
PR Close #24663
2018-07-26 17:02:21 -07:00
d237f4014a build(bazel): show bazel progress in CircleCI to prevent 10m timeout with no output (#24663)
PR Close #24663
2018-07-26 17:02:21 -07:00
8743a9bfd6 build(bazel): use bazel managed node_modules for downstream angular from source build support (#24663)
PR Close #24663
2018-07-26 17:02:21 -07:00
514d03f2d0 docs(router): Removed unneeded trailing text. (#24894)
PR Close #24894
2018-07-26 17:01:03 -07:00
1379 changed files with 45512 additions and 105792 deletions

View File

@ -1,4 +0,0 @@
node_modules
dist
aio/node_modules
aio/tools/examples/shared/node_modules

View File

@ -13,7 +13,7 @@ a GitHub token that enables publishing snapshots.
To create the github_token file, we take this approach:
- Find the angular-builds:token in http://valentine
- Go inside the CircleCI default docker image so you use the same version of openssl as we will at runtime: `docker run --rm -it circleci/node:10.12`
- Go inside the ngcontainer docker image so you use the same version of openssl as we will at runtime: `docker run --rm -it angular/ngcontainer`
- echo "https://[token]:@github.com" > credentials
- openssl aes-256-cbc -e -in credentials -out .circleci/github_token -k $KEY
- If needed, base64-encode the result so you can copy-paste it out of docker: `base64 github_token`

View File

@ -16,6 +16,22 @@ test --test_tag_filters=-manual
# (e.g. /etc/bazel.bazelrc vs. tools/bazel.rc)
build --announce_rc
# Create dist/bin symlink to $(bazel info bazel-bin)
# We use this when uploading artifacts after the build finishes
build --symlink_prefix=dist/
# Enable experimental CircleCI bazel remote cache proxy
# See remote cache documentation in /docs/BAZEL.md
build --experimental_remote_spawn_cache --remote_rest_cache=http://localhost:7643
# Prevent unstable environment variables from tainting cache keys
build --experimental_strict_action_env
# Save downloaded repositories such as the go toolchain
# This directory can then be included in the CircleCI cache
# It should save time running the first build
build --experimental_repository_cache=/home/circleci/bazel_repository_cache
# Workaround https://github.com/bazelbuild/bazel/issues/3645
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
# Limit Bazel to consuming resources that fit in CircleCI "xlarge" class
@ -24,6 +40,3 @@ build --local_resources=14336,8.0,1.0
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
test --flaky_test_attempts=2
# More details on failures
build --verbose_failures=true

View File

@ -7,120 +7,93 @@
# To validate changes, use an online parser, eg.
# http://yaml-online-parser.appspot.com/
# Note that the browser docker image comes with Chrome and Firefox preinstalled. This is just
# 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**: If you change the version of the docker images, also change the `cache_key` suffix.
var_1: &default_docker_image circleci/node:10.12
var_2: &browsers_docker_image circleci/node:10.12-browsers
var_3: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-node-10.12
# Variables
## IMPORTANT
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.6.0
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.6.0
# Define common ENV vars
var_4: &define_env_vars
run:
name: Define environment variables
command: ./.circleci/env.sh
var_3: &define_env_vars
run: echo "export PROJECT_ROOT=$(pwd)" >> $BASH_ENV
var_5: &setup_bazel_remote_execution
# See remote cache documentation in /docs/BAZEL.md
var_4: &setup-bazel-remote-cache
run:
name: "Setup bazel RBE remote execution"
command: openssl aes-256-cbc -d -in .circleci/gcp_token -k "$CI_REPO_NAME" -out /home/circleci/.gcp_credentials && echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/circleci/.gcp_credentials" >> $BASH_ENV && sudo bash -c "cat .circleci/rbe-bazel.rc >> /etc/bazel.bazelrc"
name: Start up bazel remote cache proxy
command: ~/bazel-remote-proxy -backend circleci://
background: true
# Settings common to each job
var_6: &job_defaults
anchor_1: &job_defaults
working_directory: ~/ng
docker:
- image: *default_docker_image
- image: *docker_image
# After checkout, rebase on top of master.
# Similar to travis behavior, but not quite the same.
# See https://discuss.circleci.com/t/1662
var_7: &post_checkout
post: git pull --ff-only origin "refs/pull/${CI_PULL_REQUEST//*pull\//}/merge"
var_8: &yarn_install
run:
name: Running Yarn install
command: yarn install --frozen-lockfile --non-interactive
var_9: &setup_circleci_bazel_config
run:
name: Setting up CircleCI bazel configuration
command: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
anchor_2: &post_checkout
post: git pull --ff-only origin "refs/pull/${CIRCLE_PULL_REQUEST//*pull\//}/merge"
version: 2
jobs:
lint:
<<: *job_defaults
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- run: 'yarn buildifier -mode=check ||
# Check BUILD.bazel formatting before we have a node_modules directory
# Then we don't need any exclude pattern to avoid checking those files
- run: 'buildifier -mode=check $(find . -type f \( -name "*.bzl" -or -name BUILD.bazel -or -name BUILD \)) ||
(echo "BUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
# Run the skylark linter to check our Bazel rules
- run: 'yarn skylint ||
# deprecated-api is disabled because we use actions.new_file(genfiles_dir)
# which has no replacement, see https://github.com/bazelbuild/bazel/issues/4858
- run: 'find . -type f -name "*.bzl" |
xargs java -jar /usr/local/bin/Skylint_deploy.jar --disable-checks=deprecated-api ||
(echo -e "\n.bzl files have lint errors. Please run ''yarn skylint''"; exit 1)'
- restore_cache:
key: *cache_key
- run: yarn install --frozen-lockfile --non-interactive
- run: ./node_modules/.bin/gulp lint
test:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
# 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,-local
# Now run RBE incompatible tests locally.
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: yarn bazel test //... --build_tag_filters=-ivy-only,local --test_tag_filters=-ivy-only,local
- *setup-bazel-remote-cache
- save_cache:
key: *cache_key
paths:
- "node_modules"
- "~/bazel_repository_cache"
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_aot:
<<: *job_defaults
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
# We need to explicitly specify the --symlink_prefix option because otherwise we would
# not be able to easily find the output bin directory when uploading artifacts for size
# measurements.
- run: yarn test-ivy-aot //... --symlink_prefix=dist/
- run: ls /home/circleci/bazel_repository_cache || true
- run: bazel info release
- run: bazel run @nodejs//:yarn
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
# This avoids waiting for the slowest build target to finish before running the first test
# See https://github.com/bazelbuild/bazel/issues/4257
# NOTE: Angular developers should typically just bazel build //packages/... or bazel test //packages/...
- run: bazel query --output=label //... | xargs bazel test --build_tag_filters=-ivy-only --test_tag_filters=-manual,-ivy-only
# Publish bundle artifacts which will be used to calculate the size change. **Note**: Make
# sure that the size plugin from the Angular robot fetches the artifacts from this CircleCI
# job (see .github/angular-robot.yml). Additionally any artifacts need to be stored with the
# following path format: "{projectName}/{context}/{fileName}". This format is necessary
# because otherwise the bot is not able to pick up the artifacts from CircleCI. See:
# https://github.com/angular/github-robot/blob/master/functions/src/plugins/size.ts#L392-L394
# CircleCI will allow us to go back and view/download these artifacts from past builds.
# Also we can use a service like https://buildsize.org/ to automatically track binary size of these artifacts.
# The destination keys need be format {projectName}/{context}/{fileName} so that the github-robot can process them for size calculations
# projectName should remain consistant to group files
# context and fileName can be almost anything (within usual URI rules)
# There should only be exactly 2 forward slashes in the path
# This is so they're backwards compatiable with the existing data we have on bundle sizes
- store_artifacts:
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js
destination: core/hello_world/bundle
@ -133,131 +106,49 @@ jobs:
- store_artifacts:
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js.br
destination: core/todo/bundle.br
test_aio:
- save_cache:
key: *cache_key
paths:
- "node_modules"
- "~/bazel_repository_cache"
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_jit:
<<: *job_defaults
docker:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- restore_cache:
key: *cache_key
- *define_env_vars
# Build aio
- run: yarn --cwd aio build --progress=false
# Lint the code
- run: yarn --cwd aio lint
# Run PWA-score tests
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Check the bundle sizes.
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
- run: yarn --cwd aio payload-size
# Run unit tests
- run: yarn --cwd aio test --watch=false
# Run e2e tests
- run: yarn --cwd aio e2e
# Run unit tests for Firebase redirects
- run: yarn --cwd aio redirects-test
deploy_aio:
- run: bazel run @yarn//:yarn
- run: bazel query --output=label //... | xargs bazel test --define=compile=jit --build_tag_filters=ivy-jit --test_tag_filters=-manual,ivy-jit
test_ivy_aot:
<<: *job_defaults
docker:
# Needed because before deploying the deploy-production script runs the PWA score tests.
- image: *browsers_docker_image
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- restore_cache:
key: *cache_key
- *define_env_vars
# Deploy angular.io to production (if necessary)
- run: setPublicVar CI_STABLE_BRANCH "$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')"
- run: yarn --cwd aio deploy-production
test_aio_local:
<<: *job_defaults
docker:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Build aio (with local Angular packages)
- run: yarn --cwd aio build-local --progress=false
# Run PWA-score tests
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Run unit tests
- run: yarn --cwd aio test --watch=false
# Run e2e tests
- run: yarn --cwd aio e2e
- run: bazel run @yarn//:yarn
- run: bazel query --output=label //... | xargs bazel test --define=compile=local --build_tag_filters=ivy-local --test_tag_filters=-manual,ivy-local
test_aio_tools:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Install
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
- run: yarn --cwd aio extract-cli-command-docs
# Run tools tests
- run: yarn --cwd aio tools-test
- run: ./aio/aio-builds-setup/scripts/test.sh
test_docs_examples_0:
<<: *job_defaults
docker:
# Needed because the example e2e tests depend on Chrome.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Install root
- *yarn_install
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Run examples tests
- run: yarn --cwd aio example-e2e --setup --local --shard=0/2
test_docs_examples_1:
<<: *job_defaults
docker:
# Needed because the example e2e tests depend on Chrome.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Install root
- *yarn_install
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Run examples tests
- run: yarn --cwd aio example-e2e --setup --local --shard=1/2
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
# This job should only be run on PR builds, where `CIRCLE_PR_NUMBER` is defined.
aio_preview:
<<: *job_defaults
environment:
@ -267,31 +158,28 @@ jobs:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *yarn_install
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CI_PULL_REQUEST $CI_COMMIT
- run: yarn install --frozen-lockfile --non-interactive
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CIRCLE_PR_NUMBER $CIRCLE_SHA1
- store_artifacts:
path: *aio_preview_artifact_path
# The `destination` needs to be kept in synch with the value of
# `AIO_ARTIFACT_PATH` in `aio/aio-builds-setup/Dockerfile`
destination: aio/dist/aio-snapshot.tgz
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
# This job should only be run on PR builds, where `CIRCLE_PR_NUMBER` is defined.
test_aio_preview:
<<: *job_defaults
docker:
# Needed because the test-preview script runs e2e tests and the PWA score test with Chrome.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- run: yarn install --cwd aio --frozen-lockfile --non-interactive
- run:
name: Wait for preview and run tests
command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
command: |
source "./scripts/ci/env.sh" print
xvfb-run --auto-servernum node aio/scripts/test-preview.js $CIRCLE_PR_NUMBER $CIRCLE_SHA1 $AIO_MIN_PWA_SCORE
# This job exists only for backwards-compatibility with old scripts and tests
# that rely on the pre-Bazel dist/packages-dist layout.
@ -304,15 +192,15 @@ jobs:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- run: bazel run @nodejs//:yarn
- run: scripts/build-packages-dist.sh
# Save the npm packages from //packages/... for other workflow jobs to read
@ -321,7 +209,8 @@ jobs:
root: dist
paths:
- packages-dist
- packages-dist-ivy-aot
- packages-dist-ivy-jit
- packages-dist-ivy-local
# We run the integration tests outside of Bazel for now.
# They are a separate workflow job so that they can be easily re-run.
@ -331,41 +220,35 @@ jobs:
# See comments inside the integration/run_tests.sh script.
integration_test:
<<: *job_defaults
docker:
# Needed because the integration tests expect Chrome to be installed (e.g cli-hello-world)
- image: *browsers_docker_image
# Note: we run Bazel in one of the integration tests, and it can consume >2G
# of memory. Together with the system under test, this can exhaust the RAM
# on a 4G worker so we use a larger machine here too.
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
- run: ./integration/run_tests.sh
- run: xvfb-run --auto-servernum ./integration/run_tests.sh
# This job updates the content of repos like github.com/angular/core-builds
# for every green build on angular/angular.
publish_snapshot:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- *define_env_vars
# See below - ideally this job should not trigger for non-upstream builds.
# But since it does, we have to check this condition.
- run:
name: Skip this job for Pull Requests and Fork builds
# Note, `|| true` on the end makes this step always exit 0
command: '[[
"$CI_PULL_REQUEST" != "false"
|| "$CI_REPO_OWNER" != "angular"
|| "$CI_REPO_NAME" != "angular"
-v CIRCLE_PR_NUMBER
|| "$CIRCLE_PROJECT_USERNAME" != "angular"
|| "$CIRCLE_PROJECT_REPONAME" != "angular"
]] && circleci step halt || true'
- checkout:
<<: *post_checkout
- attach_workspace:
at: dist
# CircleCI has a config setting to force SSH for all github connections
@ -379,23 +262,16 @@ jobs:
aio_monitoring:
<<: *job_defaults
docker:
# This job needs Chrome to be globally installed because the tests run with Protractor
# which does not load the browser through the Bazel webtesting rules.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- run:
name: Run tests against the deployed apps
command: ./aio/scripts/test-production.sh $CI_AIO_MIN_PWA_SCORE
- run:
name: Notify caretaker about failure
command: 'curl --request POST --header "Content-Type: application/json" --data "{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}" $CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL'
when: on_fail
command: |
source "./scripts/ci/env.sh" print
xvfb-run --auto-servernum ./aio/scripts/test-production.sh $AIO_MIN_PWA_SCORE
workflows:
version: 2
@ -403,24 +279,9 @@ workflows:
jobs:
- lint
- test
- test_ivy_jit
- test_ivy_aot
- build-packages-dist
- test_aio
- deploy_aio:
requires:
- test_aio
- test_aio_local:
requires:
- build-packages-dist
- test_aio_tools:
requires:
- build-packages-dist
- test_docs_examples_0:
requires:
- build-packages-dist
- test_docs_examples_1:
requires:
- build-packages-dist
- aio_preview:
# Only run on PR builds. (There can be no previews for non-PR builds.)
filters:
@ -440,12 +301,9 @@ workflows:
requires:
# Only publish if tests and integration tests pass
- test
- test_ivy_jit
- test_ivy_aot
- integration_test
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
- test_aio_local
- test_docs_examples_0
- test_docs_examples_1
# Get the artifacts to publish from the build-packages-dist job
# since the publishing script expects the legacy outputs layout.
- build-packages-dist
@ -463,4 +321,4 @@ workflows:
notify:
webhooks:
- url: https://ngbuilds.io/circle-build
- url: https://ngbuilds.io/circle-build

View File

@ -1,38 +0,0 @@
####################################################################################################
# Helpers for defining environment variables for CircleCI.
#
# In CircleCI, each step runs in a new shell. The way to share ENV variables across steps is to
# export them from `$BASH_ENV`, which is automatically sourced at the beginning of every step (for
# the default `bash` shell).
#
# See also https://circleci.com/docs/2.0/env-vars/#using-bash_env-to-set-environment-variables.
####################################################################################################
# Set and print an environment variable.
#
# Use this function for setting environment variables that are public, i.e. it is OK for them to be
# visible to anyone through the CI logs.
#
# Usage: `setPublicVar <name> <value>`
function setPublicVar() {
setSecretVar $1 $2;
echo "$1=$2";
}
# Set (without printing) an environment variable.
#
# Use this function for setting environment variables that are secret, i.e. should not be visible to
# everyone through the CI logs.
#
# Usage: `setSecretVar <name> <value>`
function setSecretVar() {
# WARNING: Secrets (e.g. passwords, access tokens) should NOT be printed.
# (Keep original shell options to restore at the end.)
local -r originalShellOptions=$(set +o);
set +x -eu -o pipefail;
echo "export $1=\"${2:-}\";" >> $BASH_ENV;
# Restore original shell options.
eval "$originalShellOptions";
}

View File

@ -1,35 +0,0 @@
#!/usr/bin/env bash
# Load helpers and make them available everywhere (through `$BASH_ENV`).
readonly envHelpersPath="`dirname $0`/env-helpers.inc.sh";
source $envHelpersPath;
echo "source $envHelpersPath;" >> $BASH_ENV;
####################################################################################################
# Define PUBLIC environment variables for CircleCI.
####################################################################################################
setPublicVar PROJECT_ROOT "$(pwd)";
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_COMMIT "$CIRCLE_SHA1";
# `CI_COMMIT_RANGE` will only be available when `CIRCLE_COMPARE_URL` is also available,
# i.e. on push builds (a.k.a. non-PR builds). That is fine, since we only need it in push builds.
setPublicVar CI_COMMIT_RANGE "$(sed -r 's|^.*/([0-9a-f]+\.\.\.[0-9a-f]+)$|\1|i' <<< ${CIRCLE_COMPARE_URL:-})";
setPublicVar CI_PULL_REQUEST "${CIRCLE_PR_NUMBER:-false}";
setPublicVar CI_REPO_NAME "$CIRCLE_PROJECT_REPONAME";
setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
####################################################################################################
# Define SECRET environment variables for CircleCI.
####################################################################################################
setSecretVar CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN "$AIO_DEPLOY_TOKEN";
setSecretVar CI_SECRET_PAYLOAD_FIREBASE_TOKEN "$ANGULAR_PAYLOAD_TOKEN";
# Defined in https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
setSecretVar CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL "$SLACK_CARETAKER_WEBHOOK_URL";
# Source `$BASH_ENV` to make the variables available immediately.
source $BASH_ENV;

Binary file not shown.

Binary file not shown.

View File

@ -1,77 +0,0 @@
# These options are enabled when running on CI with Remote Build Execution.
################################################################
# Toolchain related flags for remote build execution. #
################################################################
# Remote Build Execution requires a strong hash function, such as SHA256.
startup --host_jvm_args=-Dbazel.DigestFunction=SHA256
# Depending on how many machines are in the remote execution instance, setting
# this higher can make builds faster by allowing more jobs to run in parallel.
# Setting it too high can result in jobs that timeout, however, while waiting
# for a remote machine to execute them.
build --jobs=150
# Set several flags related to specifying the platform, toolchain and java
# properties.
# These flags are duplicated rather than imported from (for example)
# %workspace%/configs/ubuntu16_04_clang/1.0/toolchain.bazelrc to make this
# bazelrc a standalone file that can be copied more easily.
# These flags should only be used as is for the rbe-ubuntu16-04 container
# and need to be adapted to work with other toolchain containers.
build --host_javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.0:jdk8
build --javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.0:jdk8
build --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build --java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.0/bazel_0.15.0/default:toolchain
build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
# Platform flags:
# The toolchain container used for execution is defined in the target indicated
# by "extra_execution_platforms", "host_platform" and "platforms".
# If you are using your own toolchain container, you need to create a platform
# target with "constraint_values" that allow for the toolchain specified with
# "extra_toolchains" to be selected (given constraints defined in
# "exec_compatible_with").
# More about platforms: https://docs.bazel.build/versions/master/platforms.html
build --extra_toolchains=@bazel_toolchains//configs/ubuntu16_04_clang/1.0/bazel_0.15.0/cpp:cc-toolchain-clang-x86_64-default
build --extra_execution_platforms=//tools:rbe_ubuntu1604-angular
build --host_platform=//tools:rbe_ubuntu1604-angular
build --platforms=//tools:rbe_ubuntu1604-angular
# Set various strategies so that all actions execute remotely. Mixing remote
# and local execution will lead to errors unless the toolchain and remote
# machine exactly match the host machine.
build --spawn_strategy=remote
build --strategy=Javac=remote
build --strategy=Closure=remote
build --genrule_strategy=remote
build --define=EXECUTOR=remote
# Enable the remote cache so action results can be shared across machines,
# developers, and workspaces.
build --remote_cache=remotebuildexecution.googleapis.com
# Enable remote execution so actions are performed on the remote systems.
build --remote_executor=remotebuildexecution.googleapis.com
# Remote instance.
build --remote_instance_name=projects/internal-200822/instances/default_instance
# Enable encryption.
build --tls_enabled=true
# Enforce stricter environment rules, which eliminates some non-hermetic
# behavior and therefore improves both the remote cache hit rate and the
# correctness and repeatability of the build.
build --experimental_strict_action_env=true
# Set a higher timeout value, just in case.
build --remote_timeout=3600
# Enable authentication. This will pick up application default credentials by
# default. You can use --auth_credentials=some_file.json to use a service
# account credential instead.
build --auth_enabled=true
# Do not accept remote cache.
build --remote_accept_cached=false

View File

@ -1,10 +1,59 @@
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
<!--
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
Please help us process issues more efficiently by filing an
issue using one of the following templates:
ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.
-->
https://github.com/angular/angular/issues/new/choose
## I'm submitting a...
<!-- Check one of the following options with "x" -->
<pre><code>
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report <!-- Please search GitHub for a similar issue or PR before submitting -->
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:
</code></pre>
Thank you!
## Current behavior
<!-- Describe how the issue manifests. -->
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
## Expected behavior
<!-- Describe what the desired behavior would be. -->
## Minimal reproduction of the problem with instructions
<!--
For bug reports please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
https://stackblitz.com or similar (you can use this template as a starting point: https://stackblitz.com/fork/angular-gitter).
-->
## What is the motivation / use case for changing the behavior?
<!-- Describe the motivation or the concrete use case. -->
## Environment
<pre><code>
Angular version: X.Y.Z
<!-- Check whether this is still an issue in the most recent Angular version -->
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX <!-- run `node --version` -->
- Platform: <!-- Mac, Linux, Windows -->
Others:
<!-- Anything else relevant? Operating system version, IDE, package manager, HTTP server, ... -->
</code></pre>

View File

@ -1,63 +0,0 @@
---
name: "\U0001F41EBug report"
about: Report a bug in the Angular Framework
---
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
Oh hi there! 😄
To expedite issue processing please search open and closed issues before submitting a new one.
Existing issues often contain information about workarounds, resolution, or progress updates.
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
# 🐞 bug report
### Affected Package
<!-- Can you pin-point one or more @angular/* packages as the source of the bug? -->
<!-- ✍edit: --> The issue is caused by package @angular/....
### Is this a regression?
<!-- Did this behavior use to work in the previous version? -->
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
### Description
<!-- ✍️--> A clear and concise description of the problem...
## 🔬 Minimal Reproduction
<!--
Please create and share minimal reproduction of the issue starting with this template: https://stackblitz.com/fork/angular-issue-repro2
-->
<!-- ✍️--> https://stackblitz.com/...
<!--
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue. Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
-->
## 🔥 Exception or Error
<pre><code>
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
<!-- ✍️-->
</code></pre>
## 🌍 Your Environment
**Angular Version:**
<pre><code>
<!-- run `ng version` and paste output below -->
<!-- ✍️-->
</code></pre>
**Anything else relevant?**
<!-- ✍Is this a browser specific issue? If so, please specify the browser and version. -->
<!-- ✍Do any of these matter: operating system, IDE, package manager, HTTP server, ...? If so, please mention it below. -->

View File

@ -1,32 +0,0 @@
---
name: "\U0001F680Feature request"
about: Suggest a feature for Angular Framework
---
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
Oh hi there! 😄
To expedite issue processing please search open and closed issues before submitting a new one.
Existing issues often contain information about workarounds, resolution, or progress updates.
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
# 🚀 feature request
### Relevant Package
<!-- Can you pin-point one or more @angular/* packages the are relevant for this feature request? -->
<!-- ✍edit: --> This feature request is for @angular/....
### Description
<!-- ✍️--> A clear and concise description of the problem or missing capability...
### Describe the solution you'd like
<!-- ✍️--> If you have a solution in mind, please describe it.
### Describe alternatives you've considered
<!-- ✍️--> Have you considered any alternative solutions or workarounds?

View File

@ -1,55 +0,0 @@
---
name: "📚 Docs or angular.io issue report"
about: Report an issue in Angular's documentation or angular.io application
---
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
Oh hi there! 😄
To expedite issue processing please search open and closed issues before submitting a new one.
Existing issues often contain information about workarounds, resolution, or progress updates.
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
# 📚 Docs or angular.io bug report
### Description
<!-- ✍edit:--> A clear and concise description of the problem...
## 🔬 Minimal Reproduction
### What's the affected URL?**
<!-- ✍edit:--> https://angular.io/...
### Reproduction Steps**
<!-- If applicable please list the steps to take to reproduce the issue -->
<!-- ✍edit:-->
### Expected vs Actual Behavior**
<!-- If applicable please describe the difference between the expected and actual behavior after following the repro steps. -->
<!-- ✍edit:-->
## 📷Screenshot
<!-- Often a screenshot can help to capture the issue better than a long description. -->
<!-- ✍upload a screenshot:-->
## 🔥 Exception or Error
<pre><code>
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
<!-- ✍️-->
</code></pre>
## 🌍 Your Environment
### Browser info
<!-- ✍Is this a browser specific issue? If so, please specify the device, browser, and version. -->
### Anything else relevant?
<!-- ✍Please provide additional info if necessary. -->

View File

@ -1,11 +0,0 @@
---
name: ⚠️ Security issue disclosure
about: Report a security issue in Angular Framework, Material, or CLI
---
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
Please read https://angular.io/guide/security#report-issues on how to disclose security related issues.
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

View File

@ -1,16 +0,0 @@
---
name: "❓Support request"
about: Questions and requests for support
---
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
Please do not file questions or support requests on the GitHub issues tracker.
You can get your questions answered using other communication channels. Please see:
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Thank you!
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

View File

@ -1,13 +0,0 @@
---
name: "\U0001F6E0Angular CLI"
about: Issues and feature requests for Angular CLI
---
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
Please file any Angular CLI issues at: https://github.com/angular/angular-cli/issues/new
For the time being, we keep Angular CLI issues in a separate repository.
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

View File

@ -1,13 +0,0 @@
---
name: "\U0001F48EAngular Material"
about: Issues and feature requests for Angular Material
---
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
Please file any Angular Material issues at: https://github.com/angular/material2/issues/new
For the time being, we keep Angular Material issues in a separate repository.
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

View File

@ -10,17 +10,17 @@ Please check if your PR fulfills the following requirements:
What kind of change does this PR introduce?
<!-- Please check the one that applies to this PR using "x". -->
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Documentation content changes
- [ ] angular.io application / infrastructure changes
- [ ] Other... Please describe:
```
[ ] Bugfix
[ ] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] angular.io application / infrastructure changes
[ ] Other... Please describe:
```
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
@ -32,10 +32,10 @@ Issue Number: N/A
## Does this PR introduce a breaking change?
- [ ] Yes
- [ ] No
```
[ ] Yes
[ ] No
```
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->

View File

@ -4,7 +4,7 @@
size:
disabled: false
maxSizeIncrease: 2000
circleCiStatusName: "ci/circleci: test_ivy_aot"
circleCiStatusName: "ci/circleci: test"
# options for the merge plugin
merge:
@ -39,7 +39,6 @@ merge:
- "packages/**"
# list of patterns to ignore for the files changed by the PR
exclude:
- "packages/bazel/*.bzl"
- "packages/language-service/**"
- "**/.gitignore"
- "**/.gitkeep"
@ -50,7 +49,6 @@ merge:
- "**/BUILD.bazel"
- "packages/**/integrationtest/**"
- "packages/**/test/**"
- "packages/compiler-cli/src/ngcc/**"
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.
@ -126,23 +124,3 @@ triage:
-
- "type: RFC / Discussion / question"
- "comp: *"
# options for the triage PR plugin
triagePR:
# set to true to disable
disabled: false
# number of the milestone to apply when the PR has not been triaged yet
needsTriageMilestone: 83,
# number of the milestone to apply when the PR is triaged
defaultMilestone: 82,
# arrays of labels that determine if a PR has been triaged by the caretaker
l1TriageLabels:
-
- "comp: *"
# arrays of labels that determine if a PR has been fully triaged
l2TriageLabels:
-
- "type: *"
- "effort*"
- "risk*"
- "comp: *"

3
.gitignore vendored
View File

@ -1,7 +1,7 @@
.DS_STORE
/dist/
/bazel-*
bazel-*
e2e_test.*
node_modules
bower_components
@ -14,6 +14,7 @@ pubspec.lock
.settings/
*.swo
modules/.settings
.bazelrc
.vscode
modules/.vscode

View File

@ -87,10 +87,10 @@ groups:
files:
include:
- "WORKSPACE"
- ".bazel*"
- "*.bazel"
- "*.bzl"
- "packages/bazel/*"
- "tools/bazel.rc"
- "/docs/BAZEL.md"
users:
- alexeagle #primary
@ -108,9 +108,9 @@ groups:
- "*.lock"
- "tools/*"
exclude:
- "aio/*"
- "packages/core/test/bundling/*"
- "tools/bazel.rc"
- "tools/public_api_guard/*"
- "aio/*"
users:
- IgorMinar #primary
- alexeagle
@ -277,9 +277,6 @@ groups:
- "aio/content/guide/forms.md"
- "aio/content/examples/forms/*"
- "aio/content/images/guide/forms/*"
- "aio/content/guide/forms-overview.md"
- "aio/content/examples/forms-overview/*"
- "aio/content/images/guide/forms-overview/*"
- "aio/content/guide/form-validation.md"
- "aio/content/examples/form-validation/*"
- "aio/content/images/guide/form-validation/*"

View File

@ -30,6 +30,14 @@ env:
# GITHUB_TOKEN_ANGULAR=<github token, a personal access token of the angular-builds account, account access in valentine>
# This is needed for the e2e Travis matrix task to publish packages to github for continuous packages delivery.
- secure: "aCdHveZuY8AT4Jr1JoJB4LxZsnGWRe/KseZh1YXYe5UtufFCtTVHvUcLn0j2aLBF0KpdyS+hWf0i4np9jthKu2xPKriefoPgCMpisYeC0MFkwbmv+XlgkUbgkgVZMGiVyX7DCYXVahxIoOUjVMEDCbNiHTIrfEuyq24U3ok2tHc="
# FIREBASE_TOKEN
# This is needed for publishing builds to the "aio-staging" and "angular-io" firebase projects.
# This token was generated using the aio-deploy@angular.io account using `firebase login:ci` and password from valentine
- secure: "L5CyQmpwWtoR4Qi4xlWQh/cL1M6ZeJL4W4QAr4HdKFMgYt9h+Whqkymyh2NxwmCbPvWa7yUd+OiLQUDCY7L2VIg16hTwoe2CgYDyQA0BEwLzxtRrJXl93TfwMlrUx5JSIzAccD6D4sjtz8kSFMomK2Nls33xOXOukwyhVMjd0Cg="
# ANGULAR_PAYLOAD_FIREBASE_TOKEN
# This is for payload size data to "angular-payload-size" firebase project
# This token was generated using the payload@angular.io account using `firebase login:ci` and password from valentine
- secure: "SxotP/ymNy6uWAVbfwM9BlwETPEBpkRvU/F7fCtQDDic99WfQHzzUSQqHTk8eKk3GrGAOSL09vT0WfStQYEIGEoS5UHWNgOnelxhw+d5EnaoB8vQ0dKQBTK092hQg4feFprr+B/tCasyMV6mVwpUzZMbIJNn/Rx7H5g1bp+Gkfg="
matrix:
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
- CI_MODE=e2e
@ -39,10 +47,16 @@ env:
# - CI_MODE=browserstack_required
- CI_MODE=saucelabs_optional
- CI_MODE=browserstack_optional
- CI_MODE=aio_tools_test
- CI_MODE=aio
- CI_MODE=aio_local
- CI_MODE=aio_e2e AIO_SHARD=0
- CI_MODE=aio_e2e AIO_SHARD=1
matrix:
fast_finish: true
allow_failures:
- env: "CI_MODE=aio_local"
- env: "CI_MODE=saucelabs_optional"
- env: "CI_MODE=browserstack_optional"
@ -56,6 +70,8 @@ install:
script:
- ./scripts/ci/build.sh
- ./scripts/ci/test.sh
# deploy is part of 'script' and not 'after_success' so that we fail the build if the deployment fails
- ./scripts/ci/deploy.sh
- ./scripts/ci/angular.sh
# all the scripts under this line will not quickly abort in case ${TRAVIS_TEST_RESULT} is 1 (job failure)
- ./scripts/ci/cleanup.sh

View File

@ -8,14 +8,26 @@ exports_files([
"protractor-perf.conf.js",
])
# Developers should always run `bazel run :install`
# This ensures that package.json in subdirectories get installed as well.
alias(
name = "install",
actual = "@nodejs//:yarn",
)
alias(
name = "node_modules",
actual = "@angular_deps//:node_modules",
)
filegroup(
name = "web_test_bootstrap_scripts",
# do not sort
srcs = [
"@ngdeps//node_modules/reflect-metadata:Reflect.js",
"@ngdeps//node_modules/zone.js:dist/zone.js",
"@ngdeps//node_modules/zone.js:dist/zone-testing.js",
"@ngdeps//node_modules/zone.js:dist/task-tracking.js",
"@angular_deps//:node_modules/reflect-metadata/Reflect.js",
"@angular_deps//:node_modules/zone.js/dist/zone.js",
"@angular_deps//:node_modules/zone.js/dist/zone-testing.js",
"@angular_deps//:node_modules/zone.js/dist/task-tracking.js",
"//:test-events.js",
],
)
@ -23,29 +35,11 @@ filegroup(
filegroup(
name = "angularjs_scripts",
srcs = [
"@ngdeps//node_modules/angular:angular.js",
"@ngdeps//node_modules/angular-1.5:angular.js",
"@ngdeps//node_modules/angular-1.6:angular.js",
"@ngdeps//node_modules/angular-mocks:angular-mocks.js",
"@ngdeps//node_modules/angular-mocks-1.5:angular-mocks.js",
"@ngdeps//node_modules/angular-mocks-1.6:angular-mocks.js",
"@angular_deps//:node_modules/angular-1.5/angular.js",
"@angular_deps//:node_modules/angular-1.6/angular.js",
"@angular_deps//:node_modules/angular-mocks-1.5/angular-mocks.js",
"@angular_deps//:node_modules/angular-mocks-1.6/angular-mocks.js",
"@angular_deps//:node_modules/angular-mocks/angular-mocks.js",
"@angular_deps//:node_modules/angular/angular.js",
],
)
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
# A nodejs_binary for @angular/bazel/ngc-wrapped to use by default in
# ng_module that depends on @npm//@angular/bazel instead of the
# output of the //packages/bazel/src/ngc-wrapped ts_library rule. This
# default is for downstream users that depend on the @angular/bazel npm
# package. The generated @npm//@angular/bazel/ngc-wrapped target
# does not work because it does not have the node `--expose-gc` flag
# set which is required to support the call to `global.gc()`.
nodejs_binary(
name = "@angular/bazel/ngc-wrapped",
configuration_env_vars = ["compile"],
data = ["@npm//@angular/bazel"],
entry_point = "@angular/bazel/src/ngc-wrapped/index.js",
install_source_map_support = False,
templated_args = ["--node_options=--expose-gc"],
)

View File

@ -1,252 +1,3 @@
<a name="7.2.0-beta.0"></a>
# [7.2.0-beta.0](https://github.com/angular/angular/compare/7.1.0...7.2.0-beta.0) (2018-11-28)
### Bug Fixes
* **common:** expose request url in network error ([#27143](https://github.com/angular/angular/issues/27143)) ([1db53da](https://github.com/angular/angular/commit/1db53da)), closes [#27029](https://github.com/angular/angular/issues/27029)
* **upgrade:** don't rely upon the runtime to resolve forward refs ([#27132](https://github.com/angular/angular/issues/27132)) ([a4462c2](https://github.com/angular/angular/commit/a4462c2))
<a name="7.1.1"></a>
## [7.1.1](https://github.com/angular/angular/compare/7.1.0...7.1.1) (2018-11-28)
### Bug Fixes
* **core:** export a value for InjectFlags ([#27279](https://github.com/angular/angular/issues/27279)) ([bdf5f3e](https://github.com/angular/angular/commit/bdf5f3e)), closes [#27251](https://github.com/angular/angular/issues/27251)
<a name="7.1.0"></a>
# [7.1.0](https://github.com/angular/angular/compare/7.1.0-rc.0...7.1.0) (2018-11-21)
### Bug Fixes
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([496372d](https://github.com/angular/angular/commit/496372d)), closes [#18253](https://github.com/angular/angular/issues/18253)
* **service-worker:** add typing to public api guard and fix lint errors ([#25860](https://github.com/angular/angular/issues/25860)) ([1061875](https://github.com/angular/angular/commit/1061875))
* **upgrade:** improve downgrading-related error messages ([#26217](https://github.com/angular/angular/issues/26217)) ([7dbc103](https://github.com/angular/angular/commit/7dbc103))
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([64647af](https://github.com/angular/angular/commit/64647af)), closes [#26420](https://github.com/angular/angular/issues/26420)
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([c31e78f](https://github.com/angular/angular/commit/c31e78f))
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([0ada23a](https://github.com/angular/angular/commit/0ada23a))
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([a752971](https://github.com/angular/angular/commit/a752971)), closes [#26983](https://github.com/angular/angular/issues/26983)
### Features
* **bazel:** Bazel workspace schematics ([#26971](https://github.com/angular/angular/issues/26971)) ([b07bd30](https://github.com/angular/angular/commit/b07bd30))
* **router:** add prioritizedGuardValue operator optimization and allowing UrlTree return from guard ([#26478](https://github.com/angular/angular/issues/26478)) ([fdfedce](https://github.com/angular/angular/commit/fdfedce))
* **compiler:** ability to mark an InvokeFunctionExpr as pure ([#26860](https://github.com/angular/angular/issues/26860)) ([4dfa71f](https://github.com/angular/angular/commit/4dfa71f))
* **forms:** add updateOn option to FormBuilder ([#24599](https://github.com/angular/angular/issues/24599)) ([e9e804f](https://github.com/angular/angular/commit/e9e804f))
* **router:** allow guards to return UrlTree as well as boolean ([#26521](https://github.com/angular/angular/issues/26521)) ([081f95c](https://github.com/angular/angular/commit/081f95c))
* **router:** allow redirect from guards by returning UrlTree ([#26521](https://github.com/angular/angular/issues/26521)) ([152ca66](https://github.com/angular/angular/commit/152ca66))
* **router:** guard returning UrlTree cancels current navigation and redirects ([#26521](https://github.com/angular/angular/issues/26521)) ([4e9f2e5](https://github.com/angular/angular/commit/4e9f2e5)), closes [#24618](https://github.com/angular/angular/issues/24618)
* **service-worker:** add typing for messagesClicked in SwPush service ([#25860](https://github.com/angular/angular/issues/25860)) ([c78c221](https://github.com/angular/angular/commit/c78c221))
* **service-worker:** close notifications and focus window on click ([#25860](https://github.com/angular/angular/issues/25860)) ([f5d5a3d](https://github.com/angular/angular/commit/f5d5a3d))
* **service-worker:** handle 'notificationclick' events ([#25860](https://github.com/angular/angular/issues/25860)) ([cf6ea28](https://github.com/angular/angular/commit/cf6ea28)), closes [#20956](https://github.com/angular/angular/issues/20956) [#22311](https://github.com/angular/angular/issues/22311)
* **upgrade:** support downgrading multiple modules ([#26217](https://github.com/angular/angular/issues/26217)) ([93837e9](https://github.com/angular/angular/commit/93837e9)), closes [#26062](https://github.com/angular/angular/issues/26062)
* **router:** add pathParamsChange mode for runGuardsAndResolvers ([#26861](https://github.com/angular/angular/issues/26861)) ([bf6ac6c](https://github.com/angular/angular/commit/bf6ac6c)), closes [#18253](https://github.com/angular/angular/issues/18253)
<a name="7.1.0-rc.0"></a>
# [7.1.0-rc.0](https://github.com/angular/angular/compare/7.1.0-beta.2...7.1.0-rc.0) (2018-11-14)
### Bug Fixes
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([c31e78f](https://github.com/angular/angular/commit/c31e78f))
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([0ada23a](https://github.com/angular/angular/commit/0ada23a))
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([a752971](https://github.com/angular/angular/commit/a752971)), closes [#26983](https://github.com/angular/angular/issues/26983)
### Features
* **router:** add pathParamsChange mode for runGuardsAndResolvers ([#26861](https://github.com/angular/angular/issues/26861)) ([bf6ac6c](https://github.com/angular/angular/commit/bf6ac6c)), closes [#18253](https://github.com/angular/angular/issues/18253)
<a name="7.0.4"></a>
## [7.0.4](https://github.com/angular/angular/compare/7.0.3...7.0.4) (2018-11-14)
### Bug Fixes
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([4348c47](https://github.com/angular/angular/commit/4348c47))
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([188e9ce](https://github.com/angular/angular/commit/188e9ce))
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([d304427](https://github.com/angular/angular/commit/d304427)), closes [#26983](https://github.com/angular/angular/issues/26983)
<a name="7.1.0-beta.2"></a>
# [7.1.0-beta.2](https://github.com/angular/angular/compare/7.1.0-beta.1...7.1.0-beta.2) (2018-11-07)
### Bug Fixes
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([496372d](https://github.com/angular/angular/commit/496372d)), closes [#18253](https://github.com/angular/angular/issues/18253)
* **service-worker:** add typing to public api guard and fix lint errors ([#25860](https://github.com/angular/angular/issues/25860)) ([1061875](https://github.com/angular/angular/commit/1061875))
* **upgrade:** improve downgrading-related error messages ([#26217](https://github.com/angular/angular/issues/26217)) ([7dbc103](https://github.com/angular/angular/commit/7dbc103))
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([64647af](https://github.com/angular/angular/commit/64647af)), closes [#26420](https://github.com/angular/angular/issues/26420)
### Features
* **compiler:** ability to mark an InvokeFunctionExpr as pure ([#26860](https://github.com/angular/angular/issues/26860)) ([4dfa71f](https://github.com/angular/angular/commit/4dfa71f))
* **forms:** add updateOn option to FormBuilder ([#24599](https://github.com/angular/angular/issues/24599)) ([e9e804f](https://github.com/angular/angular/commit/e9e804f))
* **router:** allow guards to return UrlTree as well as boolean ([#26521](https://github.com/angular/angular/issues/26521)) ([081f95c](https://github.com/angular/angular/commit/081f95c))
* **router:** allow redirect from guards by returning UrlTree ([#26521](https://github.com/angular/angular/issues/26521)) ([152ca66](https://github.com/angular/angular/commit/152ca66))
* **router:** guard returning UrlTree cancels current navigation and redirects ([#26521](https://github.com/angular/angular/issues/26521)) ([4e9f2e5](https://github.com/angular/angular/commit/4e9f2e5)), closes [#24618](https://github.com/angular/angular/issues/24618)
* **service-worker:** add typing for messagesClicked in SwPush service ([#25860](https://github.com/angular/angular/issues/25860)) ([c78c221](https://github.com/angular/angular/commit/c78c221))
* **service-worker:** close notifications and focus window on click ([#25860](https://github.com/angular/angular/issues/25860)) ([f5d5a3d](https://github.com/angular/angular/commit/f5d5a3d))
* **service-worker:** handle 'notificationclick' events ([#25860](https://github.com/angular/angular/issues/25860)) ([cf6ea28](https://github.com/angular/angular/commit/cf6ea28)), closes [#20956](https://github.com/angular/angular/issues/20956) [#22311](https://github.com/angular/angular/issues/22311)
* **upgrade:** support downgrading multiple modules ([#26217](https://github.com/angular/angular/issues/26217)) ([93837e9](https://github.com/angular/angular/commit/93837e9)), closes [#26062](https://github.com/angular/angular/issues/26062)
<a name="7.0.3"></a>
## [7.0.3](https://github.com/angular/angular/compare/7.0.2...7.0.3) (2018-11-07)
### Bug Fixes
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([4d532df](https://github.com/angular/angular/commit/4d532df))
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([dc05385](https://github.com/angular/angular/commit/dc05385)), closes [#18253](https://github.com/angular/angular/issues/18253)
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([315d95c](https://github.com/angular/angular/commit/315d95c)), closes [#26420](https://github.com/angular/angular/issues/26420)
<a name="7.1.0-beta.1"></a>
# [7.1.0-beta.1](https://github.com/angular/angular/compare/7.1.0-beta.0...7.1.0-beta.1) (2018-10-31)
### Bug Fixes
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
<a name="7.0.2"></a>
## [7.0.2](https://github.com/angular/angular/compare/7.0.1...7.0.2) (2018-10-31)
### Bug Fixes
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([c01f340](https://github.com/angular/angular/commit/c01f340))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([#26879](https://github.com/angular/angular/issues/26879)) ([257ac83](https://github.com/angular/angular/commit/257ac83))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([b3c6409](https://github.com/angular/angular/commit/b3c6409))
<a name="7.1.0-beta.0"></a>
# [7.1.0-beta.0](https://github.com/angular/angular/compare/7.0.0-rc.1...7.1.0-beta.0) (2018-10-24)
### Bug Fixes
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
### Features
* **router:** add prioritizedGuardValue operator optimization and allowing UrlTree return from guard ([#26478](https://github.com/angular/angular/issues/26478)) ([fdfedce](https://github.com/angular/angular/commit/fdfedce))
<a name="7.0.1"></a>
## [7.0.1](https://github.com/angular/angular/compare/7.0.0...7.0.1) (2018-10-24)
<a name="7.0.0"></a>
# [7.0.0](https://github.com/angular/angular/compare/7.0.0-rc.1...7.0.0) (2018-10-18)
### Release Highlights & Update instructions
To learn about the release highlights and our new CLI-powered update workflow for your projects please check out the [v7 release announcement](https://blog.angular.io/version-7-of-angular-cli-prompts-virtual-scroll-drag-and-drop-and-more-c594e22e7b8c).
### Dependency updates
* @angular/core now depends on
* TypeScript 3.1
* RxJS 6.3
* @angular/platform-server now depends on Domino 2.1
### Features
* **core:** add DoBootstrap interface. ([#24558](https://github.com/angular/angular/issues/24558)) ([732026c](https://github.com/angular/angular/commit/732026c)), closes [#24557](https://github.com/angular/angular/issues/24557)
* **compiler:** add "original" placeholder value on extracted XMB ([#25079](https://github.com/angular/angular/issues/25079)) ([e99d860](https://github.com/angular/angular/commit/e99d860))
* **compiler-cli:** add support to extend `angularCompilerOptions` ([#22717](https://github.com/angular/angular/issues/22717)) ([d7e5bbf](https://github.com/angular/angular/commit/d7e5bbf)), closes [#22684](https://github.com/angular/angular/issues/22684)
* **bazel:** add additional parameters to `ts_api_guardian_test` def ([#25694](https://github.com/angular/angular/issues/25694)) ([2a21ca0](https://github.com/angular/angular/commit/2a21ca0))
* **elements:** enable Shadow DOM v1 and slots ([#24861](https://github.com/angular/angular/issues/24861)) ([c9844a2](https://github.com/angular/angular/commit/c9844a2))
* **platform-server:** update domino to v2.1.0 ([#25564](https://github.com/angular/angular/issues/25564)) ([3fb0da2](https://github.com/angular/angular/commit/3fb0da2))
* **router:** warn if navigation triggered outside Angular zone ([#24959](https://github.com/angular/angular/issues/24959)) ([010e35d](https://github.com/angular/angular/commit/010e35d)), closes [#15770](https://github.com/angular/angular/issues/15770) [#15946](https://github.com/angular/angular/issues/15946) [#24728](https://github.com/angular/angular/issues/24728)
* **router:** add UrlSegment[] to CanLoad interface ([#13127](https://github.com/angular/angular/issues/13127)) ([07d8d39](https://github.com/angular/angular/commit/07d8d39)), closes [#12411](https://github.com/angular/angular/issues/12411)
### Bug Fixes
* add mappings for ngfactory & ngsummary files to their module names in aot summary resolver ([#25335](https://github.com/angular/angular/issues/25335)) ([02e201a](https://github.com/angular/angular/commit/02e201a))
* **bazel:** Cache fileNameToModuleName lookups ([#25731](https://github.com/angular/angular/issues/25731)) ([f394ba0](https://github.com/angular/angular/commit/f394ba0))
* **bazel:** allow compile_strategy to be (privately) imported ([#25080](https://github.com/angular/angular/issues/25080)) ([0d1d589](https://github.com/angular/angular/commit/0d1d589))
* **bazel:** correct type concatenated to devmode_js ([#25467](https://github.com/angular/angular/issues/25467)) ([fb2c524](https://github.com/angular/angular/commit/fb2c524))
* **bazel:** move bazel managed runtime deps for downstream usage ([#25690](https://github.com/angular/angular/issues/25690)) ([6ed7993](https://github.com/angular/angular/commit/6ed7993))
* **bazel:** only lookup amd module-name tags in .d.ts files ([#25710](https://github.com/angular/angular/issues/25710)) ([42072c4](https://github.com/angular/angular/commit/42072c4))
* **bazel:** protractor rule should include *.e2e-spec.js ([#25701](https://github.com/angular/angular/issues/25701)) ([3809e0f](https://github.com/angular/angular/commit/3809e0f))
* **bazel:** specify the package and lock files using the workspace ([#25694](https://github.com/angular/angular/issues/25694)) ([ddc1335](https://github.com/angular/angular/commit/ddc1335))
* **benchpress:** Use performance.mark() instead of console.time() ([#24114](https://github.com/angular/angular/issues/24114)) ([06d0400](https://github.com/angular/angular/commit/06d0400))
* **common:** register locale data for all equivalent closure locales ([#25867](https://github.com/angular/angular/issues/25867)) ([d83f9d4](https://github.com/angular/angular/commit/d83f9d4))
* **compiler-cli:** correct realPath to realpath. ([#25023](https://github.com/angular/angular/issues/25023)) ([01e6dab](https://github.com/angular/angular/commit/01e6dab))
* **compiler-cli:** use the oldProgram option in watch mode ([#21364](https://github.com/angular/angular/issues/21364)) ([c6e5b97](https://github.com/angular/angular/commit/c6e5b97)), closes [#21361](https://github.com/angular/angular/issues/21361)
* **compiler:** Fix look up of entryComponents in AOT Summaries ([#24892](https://github.com/angular/angular/issues/24892)) ([00d3666](https://github.com/angular/angular/commit/00d3666))
* **compiler:** add hostVars and support pure functions in host bindings ([#25626](https://github.com/angular/angular/issues/25626)) ([b424b31](https://github.com/angular/angular/commit/b424b31))
* **compiler:** update compiler to flatten nested template fns ([#24943](https://github.com/angular/angular/issues/24943)) ([fe14f18](https://github.com/angular/angular/commit/fe14f18))
* **compiler:** update compiler to generate new slot allocations ([#25607](https://github.com/angular/angular/issues/25607)) ([27e2039](https://github.com/angular/angular/commit/27e2039))
* **core:** In Testability.whenStable update callback, pass more complete ([#25010](https://github.com/angular/angular/issues/25010)) ([16c03c0](https://github.com/angular/angular/commit/16c03c0))
* **core:** add missing `peerDependency ` to `[@angular](https://github.com/angular)/compiler` ([#26033](https://github.com/angular/angular/issues/26033)) ([549de1e](https://github.com/angular/angular/commit/549de1e)), closes [/github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e#diff-58563046c4439699f2e6a89187099a54](https://github.com//github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e/issues/diff-58563046c4439699f2e6a89187099a54)
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
* **core:** do not clear element content when using shadow dom ([#24861](https://github.com/angular/angular/issues/24861)) ([6e828bb](https://github.com/angular/angular/commit/6e828bb))
* **core:** size regression with closure compiler ([#25531](https://github.com/angular/angular/issues/25531)) ([1f59f2f](https://github.com/angular/angular/commit/1f59f2f))
* **core:** throw error message when @Output not initialized ([#19116](https://github.com/angular/angular/issues/19116)) ([adf510f](https://github.com/angular/angular/commit/adf510f)), closes [#3664](https://github.com/angular/angular/issues/3664)
* **elements:** add compiler dependency ([#24861](https://github.com/angular/angular/issues/24861)) ([6143da6](https://github.com/angular/angular/commit/6143da6))
* **elements:** add compiler to integration ([#24861](https://github.com/angular/angular/issues/24861)) ([a080ffc](https://github.com/angular/angular/commit/a080ffc))
* **elements:** strict null checks ([#24861](https://github.com/angular/angular/issues/24861)) ([a8210d0](https://github.com/angular/angular/commit/a8210d0))
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
* **router:** mount correct component if router outlet was not instantiated and if using a route reuse strategy ([#25313](https://github.com/angular/angular/issues/25313)) ([#25314](https://github.com/angular/angular/issues/25314)) ([8dc2b11](https://github.com/angular/angular/commit/8dc2b11))
* **router:** take base uri into account in `setUpLocationSync()` ([#20244](https://github.com/angular/angular/issues/20244)) ([ba1e25f](https://github.com/angular/angular/commit/ba1e25f)), closes [#20061](https://github.com/angular/angular/issues/20061)
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([00b5c7b](https://github.com/angular/angular/commit/00b5c7b))
* **service-worker:** do not blow up when caches are unwritable ([#26042](https://github.com/angular/angular/issues/26042)) ([2bd767c](https://github.com/angular/angular/commit/2bd767c))
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
* **upgrade:** trigger `$destroy` event on upgraded component element ([#25357](https://github.com/angular/angular/issues/25357)) ([2a672a9](https://github.com/angular/angular/commit/2a672a9)), closes [#25334](https://github.com/angular/angular/issues/25334)
<a name="6.1.10"></a>
## [6.1.10](https://github.com/angular/angular/compare/6.1.9...6.1.10) (2018-10-10)
@ -258,11 +9,35 @@ To learn about the release highlights and our new CLI-powered update workflow fo
<a name="6.1.9"></a>
## [6.1.9](https://github.com/angular/angular/compare/6.1.8...6.1.9) (2018-09-26)
### Bug Fixes
* **service-worker:** do not blow up when caches are unwritable ([#26042](https://github.com/angular/angular/issues/26042)) ([a169743](https://github.com/angular/angular/commit/a169743))
<a name="6.1.8"></a>
## [6.1.8](https://github.com/angular/angular/compare/6.1.7...6.1.8) (2018-09-19)
### Bug Fixes
* **bazel:** allow compile_strategy to be (privately) imported ([#25080](https://github.com/angular/angular/issues/25080)) ([2d0e642](https://github.com/angular/angular/commit/2d0e642))
* **bazel:** correct type concatenated to devmode_js ([#25467](https://github.com/angular/angular/issues/25467)) ([91dd160](https://github.com/angular/angular/commit/91dd160))
* **bazel:** move bazel managed runtime deps for downstream usage ([#25690](https://github.com/angular/angular/issues/25690)) ([48d7f4e](https://github.com/angular/angular/commit/48d7f4e))
* **bazel:** specify the package and lock files using the workspace ([#25694](https://github.com/angular/angular/issues/25694)) ([678b420](https://github.com/angular/angular/commit/678b420))
* **compiler:** Fix look up of entryComponents in AOT Summaries ([#24892](https://github.com/angular/angular/issues/24892)) ([a31cfc5](https://github.com/angular/angular/commit/a31cfc5))
* **router:** mount correct component if router outlet was not instantiated and if using a route reuse strategy ([#25313](https://github.com/angular/angular/issues/25313)) ([#25314](https://github.com/angular/angular/issues/25314)) ([e117b1f](https://github.com/angular/angular/commit/e117b1f))
### Features
* **bazel:** add additional parameters to `ts_api_guardian_test` def ([#25694](https://github.com/angular/angular/issues/25694)) ([97ae7ae](https://github.com/angular/angular/commit/97ae7ae))
* **ivy:** enable .ngfactory.js generation in g3 only ([#25392](https://github.com/angular/angular/issues/25392)) ([1c44b71](https://github.com/angular/angular/commit/1c44b71))
<a name="6.1.7"></a>
@ -291,8 +66,6 @@ To learn about the release highlights and our new CLI-powered update workflow fo
Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6 instead. sorry! :-)
<a name="6.1.4"></a>
## [6.1.4](https://github.com/angular/angular/compare/6.1.3...6.1.4) (2018-08-22)
@ -327,6 +100,9 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
<a name="6.1.1"></a>
## [6.1.1](https://github.com/angular/angular/compare/6.1.0...6.1.1) (2018-08-02)
### Bug Fixes
* **compiler-cli:** correct tsickle dependency version to fix typescript 2.9 compatibility ([fec29fa](https://github.com/angular/angular/commit/317c7087c56b72aa74cd6d6a8f719e6e7fec29fa))

View File

@ -13,10 +13,12 @@ Angular is a development platform for building mobile and desktop web applicatio
[Get started in 5 minutes][quickstart].
## Changelog
[Learn about the latest improvements][changelog].
## Want to help?
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our

117
WORKSPACE
View File

@ -1,34 +1,89 @@
workspace(name = "angular")
load(
"//packages/bazel:package.bzl",
"rules_angular_dependencies",
"rules_angular_dev_dependencies",
#
# Download Bazel toolchain dependencies as needed by build actions
#
http_archive(
name = "build_bazel_rules_typescript",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.17.0.zip",
strip_prefix = "rules_typescript-0.17.0",
sha256 = "1626ee2cc9770af6950bfc77dffa027f9aedf330fe2ea2ee7e504428927bd95d",
)
load("@build_bazel_rules_typescript//:package.bzl", "rules_typescript_dependencies")
rules_typescript_dependencies()
http_archive(
name = "bazel_toolchains",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/5124557861ebf4c0b67f98180bff1f8551e0b421.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/5124557861ebf4c0b67f98180bff1f8551e0b421.tar.gz",
],
strip_prefix = "bazel-toolchains-5124557861ebf4c0b67f98180bff1f8551e0b421",
sha256 = "c3b08805602cd1d2b67ebe96407c1e8c6ed3d4ce55236ae2efe2f1948f38168d",
)
# Uncomment for local bazel rules development
#local_repository(
# name = "build_bazel_rules_nodejs",
# path = "../rules_nodejs",
#)
#local_repository(
# name = "build_bazel_rules_typescript",
# path = "../rules_typescript",
#)
http_archive(
name = "io_bazel_rules_sass",
url = "https://github.com/bazelbuild/rules_sass/archive/1.11.0.zip",
strip_prefix = "rules_sass-1.11.0",
sha256 = "dbe9fb97d5a7833b2a733eebc78c9c1e3880f676ac8af16e58ccf2139cbcad03",
)
# Angular Bazel users will call this function
rules_angular_dependencies()
# These are the dependencies only for us
rules_angular_dev_dependencies()
# This commit matches the version of buildifier in angular/ngcontainer
# If you change this, also check if it matches the version in the angular/ngcontainer
# version in /.circleci/config.yml
BAZEL_BUILDTOOLS_VERSION = "49a6c199e3fbf5d94534b2771868677d3f9c6de9"
http_archive(
name = "com_github_bazelbuild_buildtools",
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
sha256 = "edf39af5fc257521e4af4c40829fffe8fba6d0ebff9f4dd69a6f8f1223ae047b",
)
# Fetching the Bazel source code allows us to compile the Skylark linter
http_archive(
name = "io_bazel",
url = "https://github.com/bazelbuild/bazel/archive/0.17.1.zip",
strip_prefix = "bazel-0.17.1",
sha256 = "ace8cced3b21e64a8fdad68508e9b0644201ec848ad583651719841d567fc66d",
)
http_archive(
name = "io_bazel_skydoc",
# TODO: switch to upstream when https://github.com/bazelbuild/skydoc/pull/103 is merged
url = "https://github.com/alexeagle/skydoc/archive/fe2e9f888d28e567fef62ec9d4a93c425526d701.zip",
strip_prefix = "skydoc-fe2e9f888d28e567fef62ec9d4a93c425526d701",
sha256 = "7bfb5545f59792a2745f2523b9eef363f9c3e7274791c030885e7069f8116016",
)
# We have a source dependency on the Devkit repository, because it's built with
# Bazel.
# This allows us to edit sources and have the effect appear immediately without
# re-packaging or "npm link"ing.
# Even better, things like aspects will visit the entire graph including
# ts_library rules in the devkit repository.
http_archive(
name = "angular_cli",
url = "https://github.com/angular/angular-cli/archive/v6.1.0-rc.0.zip",
strip_prefix = "angular-cli-6.1.0-rc.0",
sha256 = "8cf320ea58c321e103f39087376feea502f20eaf79c61a4fdb05c7286c8684fd",
)
http_archive(
name = "org_brotli",
url = "https://github.com/google/brotli/archive/v1.0.5.zip",
strip_prefix = "brotli-1.0.5",
sha256 = "774b893a0700b0692a76e2e5b7e7610dbbe330ffbe3fe864b4b52ca718061d5a",
)
#
# Point Bazel to WORKSPACEs that live in subdirectories
#
http_archive(
local_repository(
name = "rxjs",
url = "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz",
strip_prefix = "package/src",
sha256 = "72b0b4e517f43358f554c125e40e39f67688cd2738a8998b4a266981ed32f403",
path = "node_modules/rxjs/src",
)
# Point to the integration test workspace just so that Bazel doesn't descend into it
@ -41,37 +96,29 @@ local_repository(
#
# Load and install our dependencies downloaded above.
#
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
check_bazel_version("0.18.0", """
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
check_bazel_version("0.17.0", """
If you are on a Mac and using Homebrew, there is a breaking change to the installation in Bazel 0.16
See https://blog.bazel.build/2018/08/22/bazel-homebrew.html
""")
node_repositories(
node_version = "10.9.0",
package_json = ["//:package.json"],
preserve_symlinks = True,
yarn_version = "1.12.1",
)
yarn_install(
name = "npm",
package_json = "//tools:npm/package.json",
yarn_lock = "//tools:npm/yarn.lock",
node_version = "10.9.0",
yarn_version = "1.9.2",
)
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()
load("@io_bazel_rules_webtesting//web:repositories.bzl", "browser_repositories", "web_test_repositories")
web_test_repositories()
browser_repositories(
chromium = True,
firefox = True,
@ -89,9 +136,7 @@ ng_setup_workspace()
# Skylark documentation generation
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
sass_repositories()
load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories")
skydoc_repositories()

View File

@ -384,7 +384,7 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1:
chalk@^2.0.1, chalk@^2.3.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
dependencies:
@ -392,6 +392,15 @@ chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^2.4.1:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
check-error@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"

View File

@ -3,7 +3,7 @@
TODO (gkalpak): Add docs. Mention:
- Testing on CI.
Relevant files: `aio/aio-builds-setup/scripts/test.sh`
Relevant files: `scripts/ci/test-aio.sh`, `aio/aio-builds-setup/scripts/test.sh`
- Deploying from CI.
Relevant files: `.circleci/config.yml`, `scripts/ci/deploy.sh`, `aio/scripts/build-artifacts.sh`,
`aio/scripts/deploy-to-firebase.sh`

View File

@ -1,3 +0,0 @@
/node_modules
package.json
yarn.lock

View File

@ -1,100 +0,0 @@
<h1 class="no-toc">CLI Command Reference</h1>
The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications. You can use the tool directly in a command shell, or indirectly through an interactive UI such as [Angular Console](https://angularconsole.com).
## Installing Angular CLI
Major versions of Angular CLI follow the supported major version of Angular, but minor versions can be released separately.
Install the CLI using the `npm` package manager:
<code-example format="." language="bash">
npm install -g @angular/cli
</code-example>
For details about changes between versions, and information about updating from previous releases,
see the Releases tab on GitHub: https://github.com/angular/angular-cli/releases
## Basic workflow
Invoke the tool on the command line through the `ng` executable.
Online help is available on the command line.
Enter the following to list commands or options for a given command (such as [generate](cli/generate)) with a short description.
<code-example format="." language="bash">
ng help
ng generate --help
</code-example>
To create, build, and serve a new, basic Angular project on a development server, go to the parent directory of your new workspace use the following commands:
<code-example format="." language="bash">
ng new my-first-project
cd my-first-project
ng serve
</code-example>
In your browser, open http://localhost:4200/ to see the new app run.
When you use the [ng serve](cli/serve) command to build an app and serve it locally, the server automatically rebuilds the app and reloads the page when you change any of the source files.
## Workspaces and project files
The [ng new](cli/new) command creates an *Angular workspace* folder and generates a new app skeleton.
A workspace can contain multiple apps and libraries.
The initial app created by the [ng new](cli/new) command is at the top level of the workspace.
When you generate an additional app or library in a workspace, it goes into a `projects/` subfolder.
A newly generated app contains the source files for a root module, with a root component and template.
Each app has a `src` folder that contains the logic, data, and assets.
You can edit the generated files directly, or add to and modify them using CLI commands.
Use the [ng generate](cli/generate) command to add new files for additional components and services, and code for new pipes, directives, and so on.
Commands such as [add](cli/add) and [generate](cli/generate), which create or operate on apps and libraries, must be executed from within a workspace or project folder.
* See more about the [Workspace file structure](guide/file-structure).
### Workspace and project configuration
A single workspace configuration file, `angular.json`, is created at the top level of the workspace.
This is where you can set per-project defaults for CLI command options, and specify configurations to use when the CLI builds a project for different targets.
The [ng config](cli/config) command lets you set and retrieve configuration values from the command line, or you can edit the `angular.json` file directly.
Note that option names in the configuration file must use [camelCase](guide/glossary#case-types), while option names supplied to commands can use either camelCase or dash-case.
* See more about [Workspace Configuration](guide/workspace-config).
* See the [complete schema](https://github.com/angular/angular-cli/wiki/angular-workspace) for `angular.json`.
## CLI command-language syntax
Command syntax is shown as follows:
`ng` *commandNameOrAlias* *requiredArg* [*optionalArg*] `[options]`
* Most commands, and some options, have aliases. Aliases are shown in the syntax statement for each command.
* Option names are prefixed with a double dash (--).
Option aliases are prefixed with a single dash (-).
Arguments are not prefixed.
For example: `ng build my-app -c production`
* Typically, the name of a generated artifact can be given as an argument to the command or specified with the --name option.
* Argument and option names can be given in either
[camelCase or dash-case](guide/glossary#case-types).
`--myOptionName` is equivalent to `--my-option-name`.
### Boolean and enumerated options
Boolean options have two forms: `--thisOption` sets the flag, `--noThisOption` clears it.
If neither option is supplied, the flag remains in its default state, as listed in the reference documentation.
Allowed values are given with each enumerated option description, with the default value in **bold**.
### Relative paths
Options that specify files can be given as absolute paths, or as paths relative to the current working directory, which is generally either the workspace or project root.
### Schematics
The [ng generate](cli/generate) and [ng add](cli/add) commands take as an argument the artifact or library to be generated or added to the current project.
In addition to any general options, each artifact or library defines its own options in a *schematic*.
Schematic options are supplied to the command in the same format as immediate command options.

View File

@ -1,6 +1,6 @@
'use strict'; // necessary for es6 output in node
import { browser, ExpectedConditions as EC } from 'protractor';
import { browser } from 'protractor';
import { logging } from 'selenium-webdriver';
import * as openClose from './open-close.po';
import * as statusSlider from './status-slider.po';
@ -25,8 +25,6 @@ describe('Animation Tests', () => {
});
describe('Open/Close Component', () => {
const closedHeight = '100px';
const openHeight = '200px';
beforeAll(async () => {
await openCloseHref.click();
@ -34,37 +32,37 @@ describe('Animation Tests', () => {
});
it('should be open', async () => {
let text = await openClose.getComponentText();
const toggleButton = openClose.getToggleButton();
const container = openClose.getComponentContainer();
let text = await container.getText();
if (text.includes('Closed')) {
await toggleButton.click();
await browser.wait(async () => await container.getCssValue('height') === openHeight, 2000);
sleepFor();
}
text = await container.getText();
text = await openClose.getComponentText();
const containerHeight = await container.getCssValue('height');
expect(text).toContain('The box is now Open!');
expect(containerHeight).toBe(openHeight);
expect(containerHeight).toBe('200px');
});
it('should be closed', async () => {
let text = await openClose.getComponentText();
const toggleButton = openClose.getToggleButton();
const container = openClose.getComponentContainer();
let text = await container.getText();
if (text.includes('Open')) {
await toggleButton.click();
await browser.wait(async () => await container.getCssValue('height') === closedHeight, 2000);
sleepFor();
}
text = await container.getText();
text = await openClose.getComponentText();
const containerHeight = await container.getCssValue('height');
expect(text).toContain('The box is now Closed!');
expect(containerHeight).toBe(closedHeight);
expect(containerHeight).toBe('100px');
});
it('should log animation events', async () => {
@ -74,7 +72,8 @@ describe('Animation Tests', () => {
await toggleButton.click();
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
const animationMessages = logs.filter(({ message }) => message.includes('Animation'));
const animationMessages = logs.filter(({ message }) => message.indexOf('Animation') !== -1 ? true : false);
expect(animationMessages.length).toBeGreaterThan(0);
});
@ -90,16 +89,16 @@ describe('Animation Tests', () => {
});
it('should be inactive with an orange background', async () => {
let text = await statusSlider.getComponentText();
const toggleButton = statusSlider.getToggleButton();
const container = statusSlider.getComponentContainer();
let text = await container.getText();
if (text === 'Active') {
await toggleButton.click();
await browser.wait(async () => await container.getCssValue('backgroundColor') === inactiveColor, 2000);
sleepFor(2000);
}
text = await container.getText();
text = await statusSlider.getComponentText();
const bgColor = await container.getCssValue('backgroundColor');
expect(text).toBe('Inactive');
@ -107,16 +106,16 @@ describe('Animation Tests', () => {
});
it('should be active with a blue background', async () => {
let text = await statusSlider.getComponentText();
const toggleButton = statusSlider.getToggleButton();
const container = statusSlider.getComponentContainer();
let text = await container.getText();
if (text === 'Inactive') {
await toggleButton.click();
await browser.wait(async () => await container.getCssValue('backgroundColor') === activeColor, 2000);
sleepFor(2000);
}
text = await container.getText();
text = await statusSlider.getComponentText();
const bgColor = await container.getCssValue('backgroundColor');
expect(text).toBe('Active');
@ -164,7 +163,10 @@ describe('Animation Tests', () => {
const hero = heroesList.get(0);
await hero.click();
await browser.wait(async () => await heroesList.count() < total, 2000);
await sleepFor(100);
const newTotal = await heroesList.count();
expect(newTotal).toBeLessThan(total);
});
});
@ -188,7 +190,10 @@ describe('Animation Tests', () => {
const hero = heroesList.get(0);
await hero.click();
await browser.wait(async () => await heroesList.count() < total, 2000);
await sleepFor(250);
const newTotal = await heroesList.count();
expect(newTotal).toBeLessThan(total);
});
});
@ -208,14 +213,14 @@ describe('Animation Tests', () => {
it('should filter down the list when a search is performed', async () => {
const heroesList = filterStagger.getHeroesList();
const total = await heroesList.count();
const formInput = filterStagger.getFormInput();
await formInput.sendKeys('Mag');
await browser.wait(async () => await heroesList.count() === 2, 2000);
await sleepFor(500);
const newTotal = await heroesList.count();
expect(newTotal).toBeLessThan(total);
expect(newTotal).toBe(2);
});
});
@ -243,7 +248,10 @@ describe('Animation Tests', () => {
const hero = heroesList.get(0);
await hero.click();
await browser.wait(async () => await heroesList.count() < total, 2000);
await sleepFor(300);
const newTotal = await heroesList.count();
expect(newTotal).toBeLessThan(total);
});
});
});

View File

@ -23,3 +23,11 @@ export function getComponentContainer() {
const findContainer = () => by.css('div');
return locate(getComponent(), findContainer());
}
export async function getComponentText() {
const findContainerText = () => by.css('div');
const contents = locate(getComponent(), findContainerText());
const componentText = await contents.getText();
return componentText;
}

View File

@ -18,3 +18,11 @@ export function getComponentContainer() {
const findContainer = () => by.css('div');
return locate(getComponent(), findContainer());
}
export async function getComponentText() {
const findContainerText = () => by.css('div');
const contents = locate(getComponent(), findContainerText());
const componentText = await contents.getText();
return componentText;
}

View File

@ -2,7 +2,7 @@
import { Component } from '@angular/core';
// #enddocregion import
// #docregion metadata, component
// #docregion metadata
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
@ -13,4 +13,4 @@ import { Component } from '@angular/core';
export class AppComponent {
title = 'My First Angular App!';
}
// #enddocregion title, class, component
// #enddocregion title, class

View File

@ -1,23 +1,12 @@
'use strict'; // necessary for es6 output in node
import { browser, by, element, ElementFinder, ExpectedConditions as EC } from 'protractor';
import { browser, by, element } from 'protractor';
/* tslint:disable:quotemark */
describe('Elements', () => {
const messageInput = element(by.css('input'));
const popupButtons = element.all(by.css('button'));
// Helpers
const click = (elem: ElementFinder) => {
// Waiting for the element to be clickable, makes the tests less flaky.
browser.wait(EC.elementToBeClickable(elem), 5000);
elem.click();
};
const waitForText = (elem: ElementFinder) => {
// Waiting for the element to have some text, makes the tests less flaky.
browser.wait(async () => /\S/.test(await elem.getText()), 5000);
}
beforeEach(() => browser.get(''));
describe('popup component', () => {
@ -28,7 +17,7 @@ describe('Elements', () => {
it('should be displayed on button click', () => {
expect(popupComponent.isPresent()).toBe(false);
click(popupComponentButton);
popupComponentButton.click();
expect(popupComponent.isPresent()).toBe(true);
});
@ -36,9 +25,7 @@ describe('Elements', () => {
messageInput.clear();
messageInput.sendKeys('Angular rocks!');
click(popupComponentButton);
waitForText(popupComponent);
popupComponentButton.click();
expect(popupComponent.getText()).toContain('Popup: Angular rocks!');
});
@ -46,7 +33,7 @@ describe('Elements', () => {
popupComponentButton.click();
expect(popupComponent.isPresent()).toBe(true);
click(closeButton);
closeButton.click();
expect(popupComponent.isPresent()).toBe(false);
});
});
@ -59,7 +46,7 @@ describe('Elements', () => {
it('should be displayed on button click', () => {
expect(popupElement.isPresent()).toBe(false);
click(popupElementButton);
popupElementButton.click();
expect(popupElement.isPresent()).toBe(true);
});
@ -67,9 +54,7 @@ describe('Elements', () => {
messageInput.clear();
messageInput.sendKeys('Angular rocks!');
click(popupElementButton);
waitForText(popupElement);
popupElementButton.click();
expect(popupElement.getText()).toContain('Popup: Angular rocks!');
});
@ -77,7 +62,7 @@ describe('Elements', () => {
popupElementButton.click();
expect(popupElement.isPresent()).toBe(true);
click(closeButton);
closeButton.click();
expect(popupElement.isPresent()).toBe(false);
});
});

View File

@ -72,15 +72,15 @@
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-xs-3">Name</div>
<div class="col-xs-9">{{ model.name }}</div>
<div class="col-xs-9 pull-left">{{ model.name }}</div>
</div>
<div class="row">
<div class="col-xs-3">Alter Ego</div>
<div class="col-xs-9">{{ model.alterEgo }}</div>
<div class="col-xs-9 pull-left">{{ model.alterEgo }}</div>
</div>
<div class="row">
<div class="col-xs-3">Power</div>
<div class="col-xs-9">{{ model.power }}</div>
<div class="col-xs-9 pull-left">{{ model.power }}</div>
</div>
<br>
<button class="btn btn-primary" (click)="submitted=false">Edit</button>

View File

@ -8,11 +8,11 @@ import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [
{
path: 'customers',
loadChildren: './customers/customers.module#CustomersModule'
loadChildren: 'app/customers/customers.module#CustomersModule'
},
{
path: 'orders',
loadChildren: './orders/orders.module#OrdersModule'
loadChildren: 'app/orders/orders.module#OrdersModule'
},
{
path: '',

View File

@ -5,8 +5,8 @@ import { ContactModule } from './contact/contact.module.3';
const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
{ path: 'crisis', loadChildren: './crisis/crisis.module#CrisisModule' },
{ path: 'heroes', loadChildren: './hero/hero.module.3#HeroModule' }
{ path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
{ path: 'heroes', loadChildren: 'app/hero/hero.module.3#HeroModule' }
];
@NgModule({

View File

@ -8,8 +8,8 @@ import { ContactModule } from './contact/contact.module';
const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
// #docregion lazy-routes
{ path: 'crisis', loadChildren: './crisis/crisis.module#CrisisModule' },
{ path: 'heroes', loadChildren: './hero/hero.module#HeroModule' }
{ path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
{ path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule' }
// #enddocregion lazy-routes
];
// #enddocregion routes

View File

@ -3,8 +3,8 @@ import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
{ path: 'items', loadChildren: './items/items.module#ItemsModule' },
{ path: 'customers', loadChildren: './customers/customers.module#CustomersModule' }
{ path: 'items', loadChildren: 'app/items/items.module#ItemsModule' },
{ path: 'customers', loadChildren: 'app/customers/customers.module#CustomersModule' }
];
@NgModule({

View File

@ -35,14 +35,14 @@ describe('Reactive forms', function () {
it('should update the name control when the Update Name button is clicked', async () => {
await nameInput.sendKeys(nameText);
const value1 = await nameInput.getAttribute('value');
const value = await nameInput.getAttribute('value');
expect(value1).toBe(nameText);
expect(value).toBe(nameText);
await updateButton.click();
const value2 = await nameInput.getAttribute('value');
const value = await nameInput.getAttribute('value');
expect(value2).toBe('Nancy');
expect(value).toBe('Nancy');
});
it('should update the displayed control value when the name control updated', async () => {

View File

@ -10,7 +10,7 @@ describe('Security E2E Tests', () => {
expect(interpolated.getText())
.toContain('Template <script>alert("0wned")</script> <b>Syntax</b>');
let bound = element(By.className('e2e-inner-html-bound'));
expect(bound.getText()).toContain('Template Syntax');
expect(bound.getText()).toContain('Template alert("0wned") Syntax');
let bold = element(By.css('.e2e-inner-html-bound b'));
expect(bold.getText()).toContain('Syntax');
});

View File

@ -8,7 +8,7 @@ import { AboutComponent } from './about/about.component';
RouterModule.forRoot([
{ path: '', redirectTo: 'dashboard', pathMatch: 'full'},
{ path: 'about', component: AboutComponent },
{ path: 'heroes', loadChildren: './hero/hero.module#HeroModule'}
{ path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule'}
])
],
exports: [ RouterModule ] // re-export the module declarations

View File

@ -12,7 +12,7 @@ h2, h3 {
body {
margin: 2em;
}
body, input[type="text"], button {
body, input[text], button {
color: #888;
font-family: Cambria, Georgia;
}

View File

@ -2,7 +2,7 @@
<h4>Hero Search</h4>
<!-- #docregion input -->
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<!-- #enddocregion input -->
<ul class="search-result">

View File

@ -40,7 +40,7 @@ export class HeroService {
// #enddocregion getHeroes-1
.pipe(
// #enddocregion getHeroes-2
tap(_ => this.log('fetched heroes')),
tap(heroes => this.log('fetched heroes')),
// #docregion getHeroes-2
catchError(this.handleError('getHeroes', []))
);

View File

@ -1,11 +1,7 @@
// #docregion , init
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { Hero } from './hero';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class InMemoryDataService implements InMemoryDbService {
createDb() {
const heroes = [

View File

@ -1,7 +1,7 @@
<div id="search-component">
<h4>Hero Search</h4>
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<ul class="search-result">
<li *ngFor="let hero of heroes | async" >

View File

@ -1,6 +1,6 @@
'use strict'; // necessary for es6 output in node
import { browser, element, by, ElementArrayFinder, ElementFinder } from 'protractor';
import { browser, element, by, ElementFinder } from 'protractor';
// Angular E2E Testing Guide:
// https://docs.angularjs.org/guide/e2e-testing
@ -20,12 +20,6 @@ describe('PhoneCat Application', function() {
describe('View: Phone list', function() {
// Helpers
const waitForCount = (elems: ElementArrayFinder, count: number) => {
// Wait for the list to stabilize, which may take a while (e.g. due to animations).
browser.wait(() => elems.count().then(c => c === count), 5000);
};
beforeEach(function() {
browser.get('index.html#!/phones');
});
@ -34,16 +28,13 @@ describe('PhoneCat Application', function() {
let phoneList = element.all(by.repeater('phone in $ctrl.phones'));
let query = element(by.model('$ctrl.query'));
waitForCount(phoneList, 20);
expect(phoneList.count()).toBe(20);
query.sendKeys('nexus');
waitForCount(phoneList, 1);
expect(phoneList.count()).toBe(1);
query.clear();
query.sendKeys('motorola');
waitForCount(phoneList, 8);
expect(phoneList.count()).toBe(8);
});
@ -60,7 +51,6 @@ describe('PhoneCat Application', function() {
}
queryField.sendKeys('tablet'); // Let's narrow the dataset to make the assertions shorter
waitForCount(phoneNameColumn, 2);
expect(getNames()).toEqual([
'Motorola XOOM\u2122 with Wi-Fi',
@ -76,16 +66,10 @@ describe('PhoneCat Application', function() {
});
it('should render phone specific links', function() {
let phoneList = element.all(by.repeater('phone in $ctrl.phones'));
let query = element(by.model('$ctrl.query'));
query.sendKeys('nexus');
waitForCount(phoneList, 1);
let nexusPhone = phoneList.first();
let detailLink = nexusPhone.all(by.css('a')).first()
detailLink.click();
element.all(by.css('.phones li a')).first().click();
expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s');
});

View File

@ -202,10 +202,10 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bootstrapping
<code-example hideCopy path="ajs-quick-reference/src/main.ts" header="main.ts" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/main.ts" title="main.ts" linenums="false"></code-example>
<br>
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts" header="app.module.ts" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts" title="app.module.ts" linenums="false"></code-example>
Angular doesn't have a bootstrap directive.

View File

@ -37,7 +37,7 @@ To get started with adding Angular animations to your project, import the animat
Import `BrowserAnimationsModule`, which introduces the animation capabilities into your Angular root application module.
<code-example path="animations/src/app/app.module.1.ts" header="src/app/app.module.ts" language="typescript" linenums="false">
<code-example path="animations/src/app/app.module.1.ts" title="src/app/app.module.ts" language="typescript" linenums="false">
</code-example>
<div class="alert is-helpful">
@ -49,7 +49,7 @@ Import `BrowserAnimationsModule`, which introduces the animation capabilities in
If you plan to use specific animation functions in component files, import those functions from `@angular/animations`.
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="imports" language="typescript">
<code-example path="animations/src/app/app.component.ts" title="src/app/app.component.ts" region="imports" language="typescript">
</code-example>
<div class="alert is-helpful">
@ -61,7 +61,7 @@ If you plan to use specific animation functions in component files, import those
In the component file, add a metadata property called `animations:` within the `@Component()` decorator. You put the trigger that defines an animation within the `animations` metadata property.
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="decorator" language="typescript">
<code-example path="animations/src/app/app.component.ts" title="src/app/app.component.ts" region="decorator" language="typescript">
</code-example>
## Animating a simple transition
@ -82,12 +82,12 @@ Use the `style()` function to define a set of styles to associate with a given s
Let's see how Angular's `state()` function works with the `style­()` function to set CSS style attributes. In this code snippet, multiple style attributes are set at the same time for the state. In the `open` state, the button has a height of 200 pixels, an opacity of 1, and a background color of yellow.
<code-example path="animations/src/app/open-close.component.ts" header="src/app/open-close.component.ts" region="state1" language="typescript">
<code-example path="animations/src/app/open-close.component.ts" title="src/app/open-close.component.ts" region="state1" language="typescript">
</code-example>
In the `closed` state, shown below, the button has a height of 100 pixels, an opacity of 0.5, and a background color of green.
<code-example path="animations/src/app/open-close.component.ts" header="src/app/open-close.component.ts" region="state2" language="typescript">
<code-example path="animations/src/app/open-close.component.ts" title="src/app/open-close.component.ts" region="state2" language="typescript">
</code-example>
### Transitions and timing
@ -134,7 +134,7 @@ The third argument, `easing`, controls how the animation [accelerates and decele
This example provides a state transition from `open` to `closed` with a one second transition between states.
<code-example path="animations/src/app/open-close.component.ts" header="src/app/open-close.component.ts" language="typescript"
<code-example path="animations/src/app/open-close.component.ts" title="src/app/open-close.component.ts" language="typescript"
region="transition1">
</code-example>
@ -142,7 +142,7 @@ In the code snippet above, the `=>` operator indicates unidirectional transition
This example adds a state transition from the `closed` state to the `open` state with a 0.5 second transition animation arc.
<code-example path="animations/src/app/open-close.component.ts" header="src/app/open-close.component.ts" language="typescript"
<code-example path="animations/src/app/open-close.component.ts" title="src/app/open-close.component.ts" language="typescript"
region="transition2">
</code-example>
@ -180,7 +180,7 @@ In this example, we'll name the trigger `openClose`, and attach it to the `butto
Animations are defined in the metadata of the component that controls the HTML element to be animated. Put the code that defines your animations under the `animations:` property within the `@Component()` decorator.
<code-example path="animations/src/app/open-close.component.ts" header="src/app/open-close.component.ts" language="typescript"
<code-example path="animations/src/app/open-close.component.ts" title="src/app/open-close.component.ts" language="typescript"
region="component" linenums="false">
</code-example>
@ -194,7 +194,7 @@ The animation is executed or triggered when the expression value changes to a ne
The following code snippet binds the trigger to the value of the `isOpen` property.
<code-example path="animations/src/app/open-close.component.1.html" header="src/app/open-close.component.html"
<code-example path="animations/src/app/open-close.component.1.html" title="src/app/open-close.component.html"
region="compare">
</code-example>
@ -216,15 +216,15 @@ Here are the code files discussed in the transition example.
<code-tabs>
<code-pane header="src/app/open-close.component.ts" path="animations/src/app/open-close.component.ts" language="typescript"
<code-pane title="src/app/open-close.component.ts" path="animations/src/app/open-close.component.ts" language="typescript"
region="component">
</code-pane>
<code-pane header="src/app/open-close.component.html" path="animations/src/app/open-close.component.1.html"
<code-pane title="src/app/open-close.component.html" path="animations/src/app/open-close.component.1.html"
region="trigger">
</code-pane>
<code-pane header="src/app/open-close.component.css" path="animations/src/app/open-close.component.css">
<code-pane title="src/app/open-close.component.css" path="animations/src/app/open-close.component.css">
</code-pane>
</code-tabs>

View File

@ -8,7 +8,7 @@ This guide explains how to specify metadata and apply available compiler options
<div class="alert is-helpful"
<a href="https://www.youtube.com/watch?v=kW9cJsvcsGo">Watch compiler author Tobias Bosch explain the Angular compiler</a> at AngularConnect 2016.
<a href="https://www.youtube.com/watch?v=kW9cJsvcsGo">Watch compiler author Tobias Bosch explain the Angular Compiler</a> at AngularConnect 2016.
</div>
@ -21,7 +21,7 @@ Angular offers two ways to compile your application:
1. **_Just-in-Time_ (JIT)**, which compiles your app in the browser at runtime.
1. **_Ahead-of-Time_ (AOT)**, which compiles your app at build time.
JIT compilation is the default when you run the [`ng build`](cli/build) (build only) or [`ng serve`](cli/serve) (build and serve locally) CLI commands:
JIT compilation is the default when you run the _build-only_ or the _build-and-serve-locally_ CLI commands:
<code-example language="sh" class="code-shell">
ng build
@ -30,7 +30,7 @@ JIT compilation is the default when you run the [`ng build`](cli/build) (build o
{@a compile}
For AOT compilation, include the `--aot` option with the `ng build` or `ng serve` command:
For AOT compilation, append the `--aot` flags to the _build-only_ or the _build-and-serve-locally_ CLI commands:
<code-example language="sh" class="code-shell">
ng build --aot
@ -41,7 +41,7 @@ For AOT compilation, include the `--aot` option with the `ng build` or `ng serve
The `ng build` command with the `--prod` meta-flag (`ng build --prod`) compiles with AOT by default.
See the [CLI command reference](cli) and [Building and serving Angular apps](guide/build) for more information.
See the [CLI documentation](https://github.com/angular/angular-cli/wiki) for details, especially the [`build` topic](https://github.com/angular/angular-cli/wiki/build).
</div>
@ -1308,28 +1308,6 @@ Chuck: After reviewing your PR comment I'm still at a loss. See [comment there](
}
```
{@a tsconfig-extends}
## Configuration inheritance with extends
Similar to TypeScript Compiler, Angular Compiler also supports `extends` in the `tsconfig.json` on `angularCompilerOptions`. A tsconfig file can inherit configurations from another file using the `extends` property.
The `extends` is a top level property parallel to `compilerOptions` and `angularCompilerOptions`.
The configuration from the base file are loaded first, then overridden by those in the inheriting config file.
Example:
```json
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true,
...
}
}
```
More information about tsconfig extends can be found in the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).
{@a compiler-options}
## Angular template compiler options

View File

@ -15,7 +15,7 @@ Its `selectHero()` method sets a `selectedHero` property when the user clicks to
The component acquires the heroes from a service, which is a TypeScript [parameter property](http://www.typescriptlang.org/docs/handbook/classes.html#parameter-properties) on the constructor.
The service is provided to the component through the dependency injection system.
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" header="src/app/hero-list.component.ts (class)" region="class"></code-example>
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" title="src/app/hero-list.component.ts (class)" region="class"></code-example>
Angular creates, updates, and destroys components as the user moves through the application. Your app can take action at each moment in this lifecycle through optional [lifecycle hooks](guide/lifecycle-hooks), like `ngOnInit()`.
@ -31,7 +31,7 @@ In addition to containing or pointing to the template, the `@Component` metadata
Here's an example of basic metadata for `HeroListComponent`.
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" header="src/app/hero-list.component.ts (metadata)" region="metadata"></code-example>
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" title="src/app/hero-list.component.ts (metadata)" region="metadata"></code-example>
This example shows some of the most useful `@Component` configuration options:
@ -63,7 +63,7 @@ A template looks like regular HTML, except that it also contains Angular [templa
For example, here is a template for the Tutorial's `HeroListComponent`.
<code-example path="architecture/src/app/hero-list.component.html" header="src/app/hero-list.component.html"></code-example>
<code-example path="architecture/src/app/hero-list.component.html" title="src/app/hero-list.component.html"></code-example>
This template uses typical HTML elements like `<h2>` and `<p>`, and also includes Angular template-syntax elements, `*ngFor`, `{{hero.name}}`, `(click)`, `[hero]`, and `<app-hero-detail>`. The template-syntax elements tell Angular how to render the HTML to the screen, using program logic and data.
@ -87,7 +87,7 @@ The following diagram shows the four forms of data binding markup. Each form has
This example from the `HeroListComponent` template uses three of these forms.
<code-example path="architecture/src/app/hero-list.component.1.html" linenums="false" header="src/app/hero-list.component.html (binding)" region="binding"></code-example>
<code-example path="architecture/src/app/hero-list.component.1.html" linenums="false" title="src/app/hero-list.component.html (binding)" region="binding"></code-example>
* The `{{hero.name}}` [*interpolation*](guide/displaying-data#interpolation)
displays the component's `hero.name` property value within the `<li>` element.
@ -101,7 +101,7 @@ Two-way data binding (used mainly in [template-driven forms](guide/forms))
combines property and event binding in a single notation.
Here's an example from the `HeroDetailComponent` template that uses two-way data binding with the `ngModel` directive.
<code-example path="architecture/src/app/hero-detail.component.html" linenums="false" header="src/app/hero-detail.component.html (ngModel)" region="ngModel"></code-example>
<code-example path="architecture/src/app/hero-detail.component.html" linenums="false" title="src/app/hero-detail.component.html (ngModel)" region="ngModel"></code-example>
In two-way binding, a data property value flows to the input box from the component as with property binding.
The user's changes also flow back to the component, resetting the property to the latest value,
@ -164,7 +164,7 @@ Just as for components, the metadata for a directive associates the decorated cl
*Structural directives* alter layout by adding, removing, and replacing elements in the DOM.
The example template uses two built-in structural directives to add application logic to how the view is rendered.
<code-example path="architecture/src/app/hero-list.component.1.html" linenums="false" header="src/app/hero-list.component.html (structural)" region="structural"></code-example>
<code-example path="architecture/src/app/hero-list.component.1.html" linenums="false" title="src/app/hero-list.component.html (structural)" region="structural"></code-example>
* [`*ngFor`](guide/displaying-data#ngFor) is an iterative; it tells Angular to stamp out one `<li>` per hero in the `heroes` list.
* [`*ngIf`](guide/displaying-data#ngIf) is a conditional; it includes the `HeroDetail` component only if a selected hero exists.
@ -176,7 +176,7 @@ In templates they look like regular HTML attributes, hence the name.
The `ngModel` directive, which implements two-way data binding, is an example of an attribute directive. `ngModel` modifies the behavior of an existing element (typically `<input>`) by setting its display value property and responding to change events.
<code-example path="architecture/src/app/hero-detail.component.html" linenums="false" header="src/app/hero-detail.component.html (ngModel)" region="ngModel"></code-example>
<code-example path="architecture/src/app/hero-detail.component.html" linenums="false" title="src/app/hero-detail.component.html (ngModel)" region="ngModel"></code-example>
Angular has more pre-defined directives that either alter the layout structure
(for example, [ngSwitch](guide/template-syntax#ngSwitch))

View File

@ -23,7 +23,7 @@ An NgModule is defined by a class decorated with `@NgModule()`. The `@NgModule()
Here's a simple root NgModule definition.
<code-example path="architecture/src/app/mini-app.ts" region="module" header="src/app/app.module.ts" linenums="false"></code-example>
<code-example path="architecture/src/app/mini-app.ts" region="module" title="src/app/app.module.ts" linenums="false"></code-example>
<div class="alert is-helpful">
@ -56,9 +56,7 @@ A component and its template together define a *view*. A component can contain a
When you create a component, it's associated directly with a single view, called the *host view*. The host view can be the root of a view hierarchy, which can contain *embedded views*, which are in turn the host views of other components. Those components can be in the same NgModule, or can be imported from other NgModules. Views in the tree can be nested to any depth.
<div class="alert is-helpful">
**Note:** The hierarchical structure of views is a key factor in the way Angular detects and responds to changes in the DOM and app data.
**Note:** The hierarchical structure of views is a key factor in the way Angular detects and responds to changes in the DOM and app data.
</div>
## NgModules and JavaScript modules

View File

@ -4,13 +4,13 @@ After you understand the basic Angular building blocks, you can begin to learn m
about the features and tools that are available to help you develop and deliver Angular applications.
Here are some key features.
## Responsive programming
## Responsive programming tools
* [Lifecycle hooks](guide/lifecycle-hooks): Tap into key moments in the lifetime of a component, from its creation to its destruction, by implementing the lifecycle hook interfaces.
* [Observables and event processing](guide/observables): How to use observables with components and services to publish and subscribe to messages of any type, such as user-interaction events and asynchronous operation results.
## Client-server interaction
## Client-server interaction tools
* [HTTP](guide/http): Communicate with a server to get data, save data, and invoke server-side actions with an HTTP client.
@ -28,28 +28,23 @@ without deep knowledge of animation techniques or CSS.
## Support for the development cycle
* [Compilation](guide/aot-compiler): Angular provides just-in-time (JIT) compilation for the development environment, and ahead-of-time (AOT) compilation for the production environment.
* [Testing platform](guide/testing): Run unit tests on your application parts as they interact with the Angular framework.
* [Internationalization](guide/i18n): Make your app available in multiple languages with Angular's internationalization (i18n) tools.
* [Compilation](guide/aot-compiler): Angular provides just-in-time (JIT) compilation for the development environment, and ahead-of-time (AOT) compilation for the production environment.
* [Security guidelines](guide/security): Learn about Angular's built-in protections against common web-app vulnerabilities and attacks such as cross-site scripting attacks.
## Setup, build, and deployment configuration
## Setup and deployment tools
* [CLI Command Reference](cli): The Angular CLI is a command-line tool that you use to create projects, generate application and library code, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
* [Setup for local development](guide/setup): Set up a new project for development with QuickStart.
* [Workspace and File Structure](guide/file-structure): Understand the structure of Angular workspace and project folders.
* [npm Packages](guide/npm-packages): The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm](https://docs.npmjs.com/) packages and distributed via the npm registry. The Angular CLI creates a default `package.json` file, which specifies a starter set of packages that work well together and jointly support many common application scenarios.
* [Installation](guide/npm-packages): The [Angular CLI](https://cli.angular.io/), Angular applications, and Angular itself depend on features and functionality provided by libraries that are available as [npm](https://docs.npmjs.com/) packages.
* [TypeScript configuration](guide/typescript-configuration): TypeScript is the primary language for Angular application development.
* [Browser support](guide/browser-support): Make your apps compatible across a wide range of browsers.
* [Building and Serving](guide/build): Learn to define different build and proxy server configurations for your project, such as development, staging, and production.
* [Deployment](guide/deployment): Learn techniques for deploying your Angular application to a remote server.

View File

@ -28,11 +28,11 @@ available to components through *dependency injection*.
Here's an example of a service class that logs to the browser console.
<code-example path="architecture/src/app/logger.service.ts" linenums="false" header="src/app/logger.service.ts (class)" region="class"></code-example>
<code-example path="architecture/src/app/logger.service.ts" linenums="false" title="src/app/logger.service.ts (class)" region="class"></code-example>
Services can depend on other services. For example, here's a `HeroService` that depends on the `Logger` service, and also uses `BackendService` to get heroes. That service in turn might depend on the `HttpClient` service to fetch heroes asynchronously from a server.
<code-example path="architecture/src/app/hero.service.ts" linenums="false" header="src/app/hero.service.ts (class)" region="class"></code-example>
<code-example path="architecture/src/app/hero.service.ts" linenums="false" title="src/app/hero.service.ts (class)" region="class"></code-example>
## Dependency injection (DI)
@ -48,7 +48,7 @@ Similarly, use the `@Injectable()` decorator to indicate that a component or oth
* An injector creates dependencies, and maintains a *container* of dependency instances that it reuses if possible.
* A *provider* is an object that tells an injector how to obtain or create a dependency.
* A *provider* is an object that tell an injector how to obtain or create a dependency.
For any dependency that you need in your app, you must register a provider with the app's injector,
so that the injector can use the provider to create new instances.
@ -62,7 +62,7 @@ A dependency doesn't have to be a service&mdash;it could be a function, for exam
When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the constructor parameter types. For example, the constructor of `HeroListComponent` needs `HeroService`.
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" header="src/app/hero-list.component.ts (constructor)" region="ctor"></code-example>
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" title="src/app/hero-list.component.ts (constructor)" region="ctor"></code-example>
When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector makes one using the registered provider, and adds it to the injector before returning the service to Angular.
@ -82,7 +82,7 @@ or you can register providers with specific modules or components.
You register providers in the metadata of the service (in the `@Injectable()` decorator),
or in the `@NgModule()` or `@Component()` metadata
* By default, the Angular CLI command [`ng generate service`](cli/generate) registers a provider with the root injector for your service by including provider metadata in the `@Injectable()` decorator. The tutorial uses this method to register the provider of HeroService class definition.
* By default, the Angular CLI command `ng generate service` registers a provider with the root injector for your service by including provider metadata in the `@Injectable()` decorator. The tutorial uses this method to register the provider of HeroService class definition.
```
@Injectable({
@ -111,6 +111,6 @@ or in the `@NgModule()` or `@Component()` metadata
service with each new instance of that component.
At the component level, register a service provider in the `providers` property of the `@Component()` metadata.
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" header="src/app/hero-list.component.ts (component providers)" region="providers"></code-example>
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" title="src/app/hero-list.component.ts (component providers)" region="providers"></code-example>
For more detailed information, see the [Dependency Injection](guide/dependency-injection) section.

View File

@ -37,13 +37,13 @@ This page demonstrates building a simple _appHighlight_ attribute
directive to set an element's background color
when the user hovers over that element. You can apply it like this:
<code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html (applied)" region="applied"></code-example>
<code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" title="src/app/app.component.html (applied)" region="applied"></code-example>
{@a write-directive}
### Write the directive code
Create the directive class file in a terminal window with the CLI command [`ng generate directive`](cli/generate).
Create the directive class file in a terminal window with this CLI command.
<code-example language="sh" class="code-shell">
ng generate directive highlight
@ -59,9 +59,9 @@ _Directives_ must be declared in [Angular Modules](guide/ngmodules) in the same
The generated `src/app/highlight.directive.ts` is as follows:
<code-example path="attribute-directives/src/app/highlight.directive.0.ts" header="src/app/highlight.directive.ts"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.0.ts" title="src/app/highlight.directive.ts"></code-example>
The imported `Directive` symbol provides Angular the `@Directive` decorator.
The imported `Directive` symbol provides the Angular the `@Directive` decorator.
The `@Directive` decorator's lone configuration property specifies the directive's
[CSS attribute selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors), `[appHighlight]`.
@ -92,7 +92,7 @@ Exporting `HighlightDirective` makes the directive accessible.
Now edit the generated `src/app/highlight.directive.ts` to look as follows:
<code-example path="attribute-directives/src/app/highlight.directive.1.ts" header="src/app/highlight.directive.ts"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.1.ts" title="src/app/highlight.directive.ts"></code-example>
The `import` statement specifies an additional `ElementRef` symbol from the Angular `core` library:
@ -111,7 +111,7 @@ This first implementation sets the background color of the host element to yello
To use the new `HighlightDirective`, add a paragraph (`<p>`) element to the template of the root `AppComponent` and apply the directive as an attribute.
<code-example path="attribute-directives/src/app/app.component.1.html" header="src/app/app.component.html" region="applied"></code-example>
<code-example path="attribute-directives/src/app/app.component.1.html" title="src/app/app.component.html" region="applied"></code-example>
Now run the application to see the `HighlightDirective` in action.
@ -136,12 +136,12 @@ and respond by setting or clearing the highlight color.
Begin by adding `HostListener` to the list of imported symbols.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (imports)" region="imports"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" title="src/app/highlight.directive.ts (imports)" region="imports"></code-example>
Then add two eventhandlers that respond when the mouse enters or leaves,
each adorned by the `HostListener` decorator.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (mouse-methods)" region="mouse-methods"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" title="src/app/highlight.directive.ts (mouse-methods)" region="mouse-methods"></code-example>
The `@HostListener` decorator lets you subscribe to events of the DOM
element that hosts an attribute directive, the `<p>` in this case.
@ -162,11 +162,11 @@ The handlers delegate to a helper method that sets the color on the host DOM ele
The helper method, `highlight`, was extracted from the constructor.
The revised constructor simply declares the injected `el: ElementRef`.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (constructor)" region="ctor"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" title="src/app/highlight.directive.ts (constructor)" region="ctor"></code-example>
Here's the updated directive in full:
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" title="src/app/highlight.directive.ts"></code-example>
Run the app and confirm that the background color appears when
the mouse hovers over the `p` and disappears as it moves out.
@ -183,11 +183,11 @@ Currently the highlight color is hard-coded _within_ the directive. That's infle
In this section, you give the developer the power to set the highlight color while applying the directive.
Begin by adding `Input` to the list of symbols imported from `@angular/core`.
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" header="src/app/highlight.directive.ts (imports)" region="imports"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" title="src/app/highlight.directive.ts (imports)" region="imports"></code-example>
Add a `highlightColor` property to the directive class like this:
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (highlightColor)" region="color"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" title="src/app/highlight.directive.ts (highlightColor)" region="color"></code-example>
{@a input}
@ -200,19 +200,19 @@ Without that input metadata, Angular rejects the binding; see [below](guide/attr
Try it by adding the following directive binding variations to the `AppComponent` template:
<code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html (excerpt)" region="color-1"></code-example>
<code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" title="src/app/app.component.html (excerpt)" region="color-1"></code-example>
Add a `color` property to the `AppComponent`.
<code-example path="attribute-directives/src/app/app.component.1.ts" linenums="false" header="src/app/app.component.ts (class)" region="class"></code-example>
<code-example path="attribute-directives/src/app/app.component.1.ts" linenums="false" title="src/app/app.component.ts (class)" region="class"></code-example>
Let it control the highlight color with a property binding.
<code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html (excerpt)" region="color-2"></code-example>
<code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" title="src/app/app.component.html (excerpt)" region="color-2"></code-example>
That's good, but it would be nice to _simultaneously_ apply the directive and set the color _in the same attribute_ like this.
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (color)" region="color"></code-example>
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (color)" region="color"></code-example>
The `[appHighlight]` attribute binding both applies the highlighting directive to the `<p>` element
and sets the directive's highlight color with a property binding.
@ -221,7 +221,7 @@ That's a crisp, compact syntax.
You'll have to rename the directive's `highlightColor` property to `appHighlight` because that's now the color property binding name.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (renamed to match directive selector)" region="color-2"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" title="src/app/highlight.directive.ts (renamed to match directive selector)" region="color-2"></code-example>
This is disagreeable. The word, `appHighlight`, is a terrible property name and it doesn't convey the property's intent.
@ -233,23 +233,23 @@ Fortunately you can name the directive property whatever you want _and_ **_alias
Restore the original property name and specify the selector as the alias in the argument to `@Input`.
<code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" header="src/app/highlight.directive.ts (color property with alias)" region="color"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" title="src/app/highlight.directive.ts (color property with alias)" region="color"></code-example>
_Inside_ the directive the property is known as `highlightColor`.
_Outside_ the directive, where you bind to it, it's known as `appHighlight`.
You get the best of both worlds: the property name you want and the binding syntax you want:
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (color)" region="color"></code-example>
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (color)" region="color"></code-example>
Now that you're binding via the alias to the `highlightColor`, modify the `onMouseEnter()` method to use that property.
If someone neglects to bind to `appHighlightColor`, highlight the host element in red:
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" header="src/app/highlight.directive.ts (mouse enter)" region="mouse-enter"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" title="src/app/highlight.directive.ts (mouse enter)" region="mouse-enter"></code-example>
Here's the latest version of the directive class.
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" header="src/app/highlight.directive.ts (excerpt)"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" title="src/app/highlight.directive.ts (excerpt)"></code-example>
## Write a harness to try it
@ -259,11 +259,11 @@ lets you pick the highlight color with a radio button and bind your color choice
Update <code>app.component.html</code> as follows:
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (v2)" region="v2"></code-example>
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (v2)" region="v2"></code-example>
Revise the `AppComponent.color` so that it has no initial value.
<code-example path="attribute-directives/src/app/app.component.ts" linenums="false" header="src/app/app.component.ts (class)" region="class"></code-example>
<code-example path="attribute-directives/src/app/app.component.ts" linenums="false" title="src/app/app.component.ts (class)" region="class"></code-example>
Here are the harness and directive in action.
@ -283,12 +283,12 @@ Let the template developer set the default color.
Add a second **input** property to `HighlightDirective` called `defaultColor`:
<code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" header="src/app/highlight.directive.ts (defaultColor)" region="defaultColor"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" title="src/app/highlight.directive.ts (defaultColor)" region="defaultColor"></code-example>
Revise the directive's `onMouseEnter` so that it first tries to highlight with the `highlightColor`,
then with the `defaultColor`, and falls back to "red" if both properties are undefined.
<code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" header="src/app/highlight.directive.ts (mouse-enter)" region="mouse-enter"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" title="src/app/highlight.directive.ts (mouse-enter)" region="mouse-enter"></code-example>
How do you bind to a second property when you're already binding to the `appHighlight` attribute name?
@ -296,7 +296,7 @@ As with components, you can add as many directive property bindings as you need
The developer should be able to write the following template HTML to both bind to the `AppComponent.color`
and fall back to "violet" as the default color.
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (defaultColor)" region="defaultColor"></code-example>
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (defaultColor)" region="defaultColor"></code-example>
Angular knows that the `defaultColor` binding belongs to the `HighlightDirective`
because you made it _public_ with the `@Input` decorator.
@ -319,12 +319,12 @@ This page covered how to:
The final source code follows:
<code-tabs>
<code-pane header="app/app.component.ts" path="attribute-directives/src/app/app.component.ts"></code-pane>
<code-pane header="app/app.component.html" path="attribute-directives/src/app/app.component.html"></code-pane>
<code-pane header="app/highlight.directive.ts" path="attribute-directives/src/app/highlight.directive.ts"></code-pane>
<code-pane header="app/app.module.ts" path="attribute-directives/src/app/app.module.ts"></code-pane>
<code-pane header="main.ts" path="attribute-directives/src/main.ts"></code-pane>
<code-pane header="index.html" path="attribute-directives/src/index.html"></code-pane>
<code-pane title="app/app.component.ts" path="attribute-directives/src/app/app.component.ts"></code-pane>
<code-pane title="app/app.component.html" path="attribute-directives/src/app/app.component.html"></code-pane>
<code-pane title="app/highlight.directive.ts" path="attribute-directives/src/app/highlight.directive.ts"></code-pane>
<code-pane title="app/app.module.ts" path="attribute-directives/src/app/app.module.ts"></code-pane>
<code-pane title="main.ts" path="attribute-directives/src/main.ts"></code-pane>
<code-pane title="index.html" path="attribute-directives/src/index.html"></code-pane>
</code-tabs>
@ -338,11 +338,11 @@ You can also experience and download the <live-example title="Attribute Directiv
In this demo, the `highlightColor` property is an ***input*** property of
the `HighlightDirective`. You've seen it applied without an alias:
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" title="src/app/highlight.directive.ts (color)" region="color"></code-example>
You've seen it with an alias:
<code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" title="src/app/highlight.directive.ts (color)" region="color"></code-example>
Either way, the `@Input` decorator tells Angular that this property is
_public_ and available for binding by a parent component.
@ -374,7 +374,7 @@ You can tell if `@Input` is needed by the position of the property name in a bin
Now apply that reasoning to the following example:
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (color)" region="color"></code-example>
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (color)" region="color"></code-example>
* The `color` property in the expression on the right belongs to the template's component.
The template and its component trust each other.

View File

@ -12,7 +12,7 @@ Every application has at least one Angular module, the _root_ module
that you bootstrap to launch the application.
By convention, it is usually called `AppModule`.
If you use the [Angular CLI](cli) to generate an app, the default `AppModule` is as follows:
If you use the CLI to generate an app, the default `AppModule` is as follows:
```typescript
/* JavaScript imports */
@ -52,7 +52,7 @@ The `@NgModule` decorator identifies `AppModule` as an `NgModule` class.
* **_bootstrap_**&mdash;the _root_ component that Angular creates and inserts
into the `index.html` host web page.
The default application created by the Angular CLI only has one component, `AppComponent`, so it
The default CLI application only has one component, `AppComponent`, so it
is in both the `declarations` and the `bootstrap` arrays.
{@a declarations}
@ -106,18 +106,18 @@ To use a directive, component, or pipe in a module, you must do a few things:
Those three steps look like the following. In the file where you create your directive, export it.
The following example, named `ItemDirective` is the default directive structure that the CLI generates in its own file, `item.directive.ts`:
<code-example path="bootstrapping/src/app/item.directive.ts" region="directive" header="src/app/item.directive.ts" linenums="false">
<code-example path="bootstrapping/src/app/item.directive.ts" region="directive" title="src/app/item.directive.ts" linenums="false">
</code-example>
The key point here is that you have to export it so you can import it elsewhere. Next, import it
into the NgModule, in this example `app.module.ts`, with a JavaScript import statement:
<code-example path="bootstrapping/src/app/app.module.ts" region="directive-import" header="src/app/app.module.ts" linenums="false">
<code-example path="bootstrapping/src/app/app.module.ts" region="directive-import" title="src/app/app.module.ts" linenums="false">
</code-example>
And in the same file, add it to the `@NgModule` `declarations` array:
<code-example path="bootstrapping/src/app/app.module.ts" region="declarations" header="src/app/app.module.ts" linenums="false">
<code-example path="bootstrapping/src/app/app.module.ts" region="declarations" title="src/app/app.module.ts" linenums="false">
</code-example>

View File

@ -122,7 +122,7 @@ Note that polyfills cannot magically transform an old, slow browser into a moder
## Enabling polyfills
[Angular CLI](cli) users enable polyfills through the `src/polyfills.ts` file that
[Angular CLI](https://github.com/angular/angular-cli/wiki) users enable polyfills through the `src/polyfills.ts` file that
the CLI created with your project.
This file incorporates the mandatory and many of the optional polyfills as JavaScript `import` statements.
@ -140,7 +140,7 @@ For example, [if you need the web animations polyfill](http://caniuse.com/#feat=
Then open the `polyfills.ts` file and un-comment the corresponding `import` statement as in the following example:
<code-example header="src/polyfills.ts">
<code-example title="src/polyfills.ts">
/**
* Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
@ -553,7 +553,7 @@ computed with the <a href="http://closure-compiler.appspot.com/home">closure com
If you are not using the CLI, you should add your polyfill scripts directly to the host web page (`index.html`), perhaps like this.
<code-example header="src/index.html">
<code-example title="src/index.html">
&lt;!-- pre-zone polyfills -->
&lt;script src="node_modules/core-js/client/shim.min.js">&lt;/script>
&lt;script src="node_modules/web-animations-js/web-animations.min.js">&lt;/script>

View File

@ -1,496 +0,0 @@
# Building and serving Angular apps
This page discusses build-specific configuration options for Angular projects.
{@a app-environments}
## Configuring application environments
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>
### Configure environment-specific defaults
A project's `src/environments/` folder contains the base configuration file, `environment.ts`, which provides a default environment.
You can add override defaults for additional environments, such as production and staging, in target-specific configuration files.
For example:
```
└──myProject/src/environments/
└──environment.ts
└──environment.prod.ts
└──environment.stage.ts
```
The base file `environment.ts`, contains the default environment settings. For example:
```
export const environment = {
production: false
};
```
The `build` command uses this as the build target when no environment is specified.
You can add further variables, either as additional properties on the environment object, or as separate objects.
For example, the following adds a default for a variable to the default environment:
```
export const environment = {
production: false,
apiUrl: 'http://my-api-url'
};
```
You can add target-specific configuration files, such as `environment.prod.ts`.
The following sets content sets default values for the production build target:
```
export const environment = {
production: true
apiUrl: 'http://my-prod-url'
};
```
### Using environment-specific variables in your app
The following application structure configures build targets for production and staging environments:
```
└── src
└── app
├── app.component.html
└── app.component.ts
└── environments
├── environment.prod.ts
├── environment.staging.ts
└── environment.ts
```
To use the environment configurations you have defined, your components must import the original environments file:
```
import { environment } from './../environments/environment';
```
This ensures that the build and serve commands can find the configurations for specific build targets.
The following code in the component file (`app.component.ts`) uses an environment variable defined in the configuration files.
```
import { Component } from '@angular/core';
import { environment } from './../environments/environment';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor() {
console.log(environment.production); // Logs false for default environment
}
title = 'app works!';
}
```
{@a file-replacement}
## Configure target-specific file replacements
The main CLI configuration file, `angular.json`, contains a `fileReplacements` section in the configuration for each build target, which allows you to replace any file with a target-specific version of that file.
This is useful for including target-specific code or variables in a build that targets a specific environment, such as production or staging.
By default no files are replaced.
You can add file replacements for specific build targets.
For example:
```
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
...
```
This means that when you build your production configuration (using `ng build --prod` or `ng build --configuration=production`), the `src/environments/environment.ts` file is replaced with the target-specific version of the file, `src/environments/environment.prod.ts`.
You can add additional configurations as required. To add a staging environment, create a copy of `src/environments/environment.ts` called `src/environments/environment.staging.ts`, then add a `staging` configuration to `angular.json`:
```
"configurations": {
"production": { ... },
"staging": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.staging.ts"
}
]
}
}
```
You can add more configuration options to this target environment as well.
Any option that your build supports can be overridden in a build target configuration.
To build using the staging configuration, run the following command:
<code-example language="sh" class="code-shell">
ng build --configuration=staging
</code-example>
You can also configure the `serve` command to use the targeted build configuration if you add it to the "serve:configurations" section of `angular.json`:
```
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-project-name:build"
},
"configurations": {
"production": {
"browserTarget": "your-project-name:build:production"
},
"staging": {
"browserTarget": "your-project-name:build:staging"
}
}
},
```
{@a size-budgets}
## Configure 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.
Define your size boundaries in the CLI configuration file, `angular.json`, in a `budgets` section for each [configured environment](#app-environments).
```
{
...
"configurations": {
"production": {
...
budgets: []
}
}
}
```
You can specify size budgets for the entire app, and for particular parts.
Each budget entry configures a budget of a given type.
Specify size values in the following formats:
* 123 or 123b: Size in bytes
* 123kb: Size in kilobytes
* 123mb: Size in megabytes
* 12%: Percentage of size relative to baseline. (Not valid for baseline values.)
When you configure a budget, the build system warns or reports and error when a given part of the app reaches or exceeds a boundary size that you set.
Each budget entry is a JSON object with the following properties:
<table>
<tr>
<th>Property</th>
<th>Value</th>
</tr>
<tr>
<td>type</td>
<td>The type of budget. One of:
* bundle - The size of a specific bundle.
* initial - The initial size of the app.
* allScript - The size of all scripts.
* all - The size of the entire app.
* anyScript - The size of any one script.
* any - The size of any file.
</td>
</tr>
<tr>
<td>name</td>
<td>
The name of the bundle (for `type=bundle`).
</td>
</tr>
<tr>
<td>baseline</td>
<td>An absolute baseline size for percentage values. </td>
</tr>
<tr>
<td>maximumWarning</td>
<td>Warns when a size exceeds this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>maximumError</td>
<td>Reports an error when the size exceeds this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>minimumWarning</td>
<td>Warns when the size reaches this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>minimumError</td>
<td>Reports an error when the size reaches this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>warning</td>
<td>Warns when the size ??reaches or exceeds?? this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>error</td>
<td>Reports an error when the size ??reaches or exceeds?? this threshold percentage of the baseline.</td>
</tr>
</table>
{@a browser-compat}
## Configuring browser compatibility
The CLI uses [Autoprefixer](https://github.com/postcss/autoprefixer) to ensure compatibility with different browser and browser versions.
You may find it necessary to target specific browsers or exclude certain browser versions from your build.
Internally, Autoprefixer relies on a library called [Browserslist](https://github.com/browserslist/browserslist) to figure out which browsers to support with prefixing.
Browserlist looks for configuration options in a `browserlist` property of the package configuration file, or in a configuration file named `.browserslistrc`.
Autoprefixer looks for the Browserlist configuration when it prefixes your CSS.
* You can tell Autoprefixer what browsers to target by adding a browserslist property to the package configuration file, `package.json`:
```
"browserslist": [
"> 1%",
"last 2 versions"
]
```
* Alternatively, you can add a new file, `.browserslistrc`, to the project directory, that specifies browsers you want to support:
```
### Supported Browsers
> 1%
last 2 versions
```
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
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": [
"last 2 versions",
"not ie <= 10",
"not ie_mob <= 10"
]
```
</div>
{@a proxy}
## Proxying to a backend server
You can use the [proxying support](https://webpack.js.org/configuration/dev-server/#devserver-proxy) in the `webpack` dev server to divert certain URLs to a backend server, by passing a file to the `--proxy-config` build option.
For example, to divert all calls for `http://localhost:4200/api` to a server running on `http://localhost:3000/api`, take the following steps.
1. Create a file `proxy.conf.json` in the projects `src/` folder, next to `package.json`.
1. Add the following content to the new proxy file:
```
{
"/api": {
"target": "http://localhost:3000",
"secure": false
}
}
```
1. In the CLI configuration file, `angular.json`, add the `proxyConfig` option to the `serve` target:
```
...
"architect": {
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-application-name:build",
"proxyConfig": "src/proxy.conf.json"
},
...
```
1. To run the dev server with this proxy configuration, call `ng serve`.
You can edit the proxy configuration file to add configuration options; some examples are given below.
For a description of all options, see [webpack DevServer documentation](https://webpack.js.org/configuration/dev-server/#devserver-proxy).
Note that if you edit the proxy configuration file, you must relaunch the `ng serve` process to make your changes effective.
### Rewrite the URL path
The `pathRewrite` proxy configuration option lets you rewrite the URL path at run time.
For example, you can specify the following `pathRewrite` value to the proxy configuration to remove "api" from the end of a path.
```
{
"/api": {
"target": "http://localhost:3000",
"secure": false,
"pathRewrite": {
"^/api": ""
}
}
}
```
If you need to access a backend that is not on `localhost`, set the `changeOrigin` option as well. For example:
```
{
"/api": {
"target": "http://npmjs.org",
"secure": false,
"pathRewrite": {
"^/api": ""
},
"changeOrigin": true
}
}
```
To help determine whether your proxy is working as intended, set the `logLevel` option. For example:
```
{
"/api": {
"target": "http://localhost:3000",
"secure": false,
"pathRewrite": {
"^/api": ""
},
"logLevel": "debug"
}
}
```
Proxy log levels are `info` (the default), `debug`, `warn`, `error`, and `silent`.
### Proxy multiple entries
You can proxy multiple entries to the same target by defining the configuration in JavaScript.
Set the proxy configuration file to `proxy.conf.js` (instead of `proxy.conf.json`), and specify configuration files as in the following example.
```
const PROXY_CONFIG = [
{
context: [
"/my",
"/many",
"/endpoints",
"/i",
"/need",
"/to",
"/proxy"
],
target: "http://localhost:3000",
secure: false
}
]
module.exports = PROXY_CONFIG;
```
In the CLI configuration file, `angular.json`, point to the JavaScript proxy configuration file:
```
...
"architect": {
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-application-name:build",
"proxyConfig": "src/proxy.conf.js"
},
...
```
### Bypass the proxy
If you need to optionally bypass the proxy, or dynamically change the request before it's sent, add the bypass option, as shown in this JavaScript example.
```
const PROXY_CONFIG = {
"/api/proxy": {
"target": "http://localhost:3000",
"secure": false,
"bypass": function (req, res, proxyOptions) {
if (req.headers.accept.indexOf("html") !== -1) {
console.log("Skipping proxy for browser request.");
return "/index.html";
}
req.headers["X-Custom-Header"] = "yes";
}
}
}
module.exports = PROXY_CONFIG;
```
### Using corporate proxy
If you work behind a corporate proxy, the cannot directly proxy calls to any URL outside your local network.
In this case, you can configure the backend proxy to redirect calls through your corporate proxy using an agent:
<code-example language="none" class="code-shell">
npm install --save-dev https-proxy-agent
</code-example>
When you define an environment variable `http_proxy` or `HTTP_PROXY`, an agent is automatically added to pass calls through your corporate proxy when running `npm start`.
Use the following content in the JavaScript configuration file.
```
var HttpsProxyAgent = require('https-proxy-agent');
var proxyConfig = [{
context: '/api',
target: 'http://your-remote-server.com:3000',
secure: false
}];
function setupForCorporateProxy(proxyConfig) {
var proxyServer = process.env.http_proxy || process.env.HTTP_PROXY;
if (proxyServer) {
var agent = new HttpsProxyAgent(proxyServer);
console.log('Using corporate proxy server: ' + proxyServer);
proxyConfig.forEach(function(entry) {
entry.agent = agent;
});
}
return proxyConfig;
}
module.exports = setupForCorporateProxy(proxyConfig);
```

View File

@ -38,7 +38,7 @@ The following example demonstrates how to use `query()` and `stagger()` function
* Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it.
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="page-animations" language="typescript" linenums="false"></code-example>
<code-example path="animations/src/app/hero-list-page.component.ts" title="src/app/hero-list-page.component.ts" region="page-animations" language="typescript" linenums="false"></code-example>
## Parallel animation using group() function
@ -51,7 +51,7 @@ You've seen how to add a delay between each successive animation. But you may al
In the following example, using groups on both `:enter` and `:leave` allow for two different timing configurations. They're applied to the same element in parallel, but run independently.
<code-example path="animations/src/app/hero-list-groups.component.ts" region="animationdef" header="src/app/hero-list-groups.component.ts (excerpt)" language="typescript" linenums="false"></code-example>
<code-example path="animations/src/app/hero-list-groups.component.ts" region="animationdef" title="src/app/hero-list-groups.component.ts (excerpt)" language="typescript" linenums="false"></code-example>
## Sequential vs. parallel animations
@ -70,11 +70,11 @@ The filter works in real time as you type. Elements leave the page as you type e
The HTML template contains a trigger called `filterAnimation`.
<code-example path="animations/src/app/hero-list-page.component.html" header="src/app/hero-list-page.component.html" region="filter-animations"></code-example>
<code-example path="animations/src/app/hero-list-page.component.html" title="src/app/hero-list-page.component.html" region="filter-animations"></code-example>
The component file contains three transitions.
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="filter-animations" language="typescript" linenums="false"></code-example>
<code-example path="animations/src/app/hero-list-page.component.ts" title="src/app/hero-list-page.component.ts" region="filter-animations" language="typescript" linenums="false"></code-example>
The animation does the following:

View File

@ -28,7 +28,7 @@ in which two or more components share information.
typically adorned with [@Input decorations](guide/template-syntax#inputs-outputs).
<code-example path="component-interaction/src/app/hero-child.component.ts" header="component-interaction/src/app/hero-child.component.ts">
<code-example path="component-interaction/src/app/hero-child.component.ts" title="component-interaction/src/app/hero-child.component.ts">
</code-example>
@ -41,7 +41,7 @@ binding its `master` string property to the child's `master` alias,
and each iteration's `hero` instance to the child's `hero` property.
<code-example path="component-interaction/src/app/hero-parent.component.ts" header="component-interaction/src/app/hero-parent.component.ts">
<code-example path="component-interaction/src/app/hero-parent.component.ts" title="component-interaction/src/app/hero-parent.component.ts">
</code-example>
@ -61,7 +61,7 @@ The running application displays three heroes:
E2E test that all children were instantiated and displayed as expected:
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="parent-to-child" header="component-interaction/e2e/src/app.e2e-spec.ts">
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="parent-to-child" title="component-interaction/e2e/src/app.e2e-spec.ts">
</code-example>
@ -79,7 +79,7 @@ The setter of the `name` input property in the child `NameChildComponent`
trims the whitespace from a name and replaces an empty value with default text.
<code-example path="component-interaction/src/app/name-child.component.ts" header="component-interaction/src/app/name-child.component.ts">
<code-example path="component-interaction/src/app/name-child.component.ts" title="component-interaction/src/app/name-child.component.ts">
</code-example>
@ -88,7 +88,7 @@ trims the whitespace from a name and replaces an empty value with default text.
Here's the `NameParentComponent` demonstrating name variations including a name with all spaces:
<code-example path="component-interaction/src/app/name-parent.component.ts" header="component-interaction/src/app/name-parent.component.ts">
<code-example path="component-interaction/src/app/name-parent.component.ts" title="component-interaction/src/app/name-parent.component.ts">
</code-example>
@ -105,7 +105,7 @@ Here's the `NameParentComponent` demonstrating name variations including a name
E2E tests of input property setter with empty and non-empty names:
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="parent-to-child-setter" header="component-interaction/e2e/src/app.e2e-spec.ts">
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="parent-to-child-setter" title="component-interaction/e2e/src/app.e2e-spec.ts">
</code-example>
@ -134,7 +134,7 @@ Learn about `ngOnChanges()` in the [LifeCycle Hooks](guide/lifecycle-hooks) chap
This `VersionChildComponent` detects changes to the `major` and `minor` input properties and composes a log message reporting these changes:
<code-example path="component-interaction/src/app/version-child.component.ts" header="component-interaction/src/app/version-child.component.ts">
<code-example path="component-interaction/src/app/version-child.component.ts" title="component-interaction/src/app/version-child.component.ts">
</code-example>
@ -143,7 +143,7 @@ This `VersionChildComponent` detects changes to the `major` and `minor` input pr
The `VersionParentComponent` supplies the `minor` and `major` values and binds buttons to methods that change them.
<code-example path="component-interaction/src/app/version-parent.component.ts" header="component-interaction/src/app/version-parent.component.ts">
<code-example path="component-interaction/src/app/version-parent.component.ts" title="component-interaction/src/app/version-parent.component.ts">
</code-example>
@ -164,7 +164,7 @@ Test that ***both*** input properties are set initially and that button clicks t
the expected `ngOnChanges` calls and values:
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="parent-to-child-onchanges" header="component-interaction/e2e/src/app.e2e-spec.ts">
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="parent-to-child-onchanges" title="component-interaction/e2e/src/app.e2e-spec.ts">
</code-example>
@ -184,7 +184,7 @@ The child's `EventEmitter` property is an ***output property***,
as seen in this `VoterComponent`:
<code-example path="component-interaction/src/app/voter.component.ts" header="component-interaction/src/app/voter.component.ts">
<code-example path="component-interaction/src/app/voter.component.ts" title="component-interaction/src/app/voter.component.ts">
</code-example>
@ -196,7 +196,7 @@ The parent `VoteTakerComponent` binds an event handler called `onVoted()` that r
payload `$event` and updates a counter.
<code-example path="component-interaction/src/app/votetaker.component.ts" header="component-interaction/src/app/votetaker.component.ts">
<code-example path="component-interaction/src/app/votetaker.component.ts" title="component-interaction/src/app/votetaker.component.ts">
</code-example>
@ -217,7 +217,7 @@ and the method processes it:
Test that clicking the *Agree* and *Disagree* buttons update the appropriate counters:
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="child-to-parent" header="component-interaction/e2e/src/app.e2e-spec.ts">
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="child-to-parent" title="component-interaction/e2e/src/app.e2e-spec.ts">
</code-example>
@ -240,7 +240,7 @@ The following is a child `CountdownTimerComponent` that repeatedly counts down t
It has `start` and `stop` methods that control the clock and it displays a
countdown status message in its own template.
<code-example path="component-interaction/src/app/countdown-timer.component.ts" header="component-interaction/src/app/countdown-timer.component.ts">
<code-example path="component-interaction/src/app/countdown-timer.component.ts" title="component-interaction/src/app/countdown-timer.component.ts">
</code-example>
@ -249,7 +249,7 @@ countdown status message in its own template.
The `CountdownLocalVarParentComponent` that hosts the timer component is as follows:
<code-example path="component-interaction/src/app/countdown-parent.component.ts" region="lv" header="component-interaction/src/app/countdown-parent.component.ts">
<code-example path="component-interaction/src/app/countdown-parent.component.ts" region="lv" title="component-interaction/src/app/countdown-parent.component.ts">
</code-example>
@ -284,7 +284,7 @@ match the seconds displayed in the child's status message.
Test also that clicking the *Stop* button pauses the countdown timer:
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="countdown-timer-tests" header="component-interaction/e2e/src/app.e2e-spec.ts">
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="countdown-timer-tests" title="component-interaction/e2e/src/app.e2e-spec.ts">
</code-example>
@ -324,7 +324,7 @@ is solely for the purpose of demonstration.
Here is the parent, `CountdownViewChildParentComponent`:
<code-example path="component-interaction/src/app/countdown-parent.component.ts" region="vc" header="component-interaction/src/app/countdown-parent.component.ts">
<code-example path="component-interaction/src/app/countdown-parent.component.ts" region="vc" title="component-interaction/src/app/countdown-parent.component.ts">
</code-example>
@ -374,7 +374,7 @@ Components outside this component subtree have no access to the service or their
This `MissionService` connects the `MissionControlComponent` to multiple `AstronautComponent` children.
<code-example path="component-interaction/src/app/mission.service.ts" header="component-interaction/src/app/mission.service.ts">
<code-example path="component-interaction/src/app/mission.service.ts" title="component-interaction/src/app/mission.service.ts">
</code-example>
@ -384,7 +384,7 @@ The `MissionControlComponent` both provides the instance of the service that it
(through the `providers` metadata array) and injects that instance into itself through its constructor:
<code-example path="component-interaction/src/app/missioncontrol.component.ts" header="component-interaction/src/app/missioncontrol.component.ts">
<code-example path="component-interaction/src/app/missioncontrol.component.ts" title="component-interaction/src/app/missioncontrol.component.ts">
</code-example>
@ -394,7 +394,7 @@ The `AstronautComponent` also injects the service in its constructor.
Each `AstronautComponent` is a child of the `MissionControlComponent` and therefore receives its parent's service instance:
<code-example path="component-interaction/src/app/astronaut.component.ts" header="component-interaction/src/app/astronaut.component.ts">
<code-example path="component-interaction/src/app/astronaut.component.ts" title="component-interaction/src/app/astronaut.component.ts">
</code-example>
@ -433,7 +433,7 @@ Tests click buttons of both the parent `MissionControlComponent` and the `Astron
and verify that the history meets expectations:
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="bidirectional-service" header="component-interaction/e2e/src/app.e2e-spec.ts">
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="bidirectional-service" title="component-interaction/e2e/src/app.e2e-spec.ts">
</code-example>

View File

@ -21,7 +21,7 @@ One way to do this is to set the `styles` property in the component metadata.
The `styles` property takes an array of strings that contain CSS code.
Usually you give it one string, as in the following example:
<code-example path="component-styles/src/app/hero-app.component.ts" header="src/app/hero-app.component.ts" linenums="false">
<code-example path="component-styles/src/app/hero-app.component.ts" title="src/app/hero-app.component.ts" linenums="false">
</code-example>
## Style scope
@ -71,7 +71,7 @@ Use the `:host` pseudo-class selector to target styles in the element that *host
targeting elements *inside* the component's template).
<code-example path="component-styles/src/app/hero-details.component.css" region="host" header="src/app/hero-details.component.css" linenums="false">
<code-example path="component-styles/src/app/hero-details.component.css" region="host" title="src/app/hero-details.component.css" linenums="false">
</code-example>
The `:host` selector is the only way to target the host element. You can't reach
@ -83,7 +83,7 @@ including another selector inside parentheses after `:host`.
The next example targets the host element again, but only when it also has the `active` CSS class.
<code-example path="component-styles/src/app/hero-details.component.css" region="hostfunction" header="src/app/hero-details.component.css" linenums="false">
<code-example path="component-styles/src/app/hero-details.component.css" region="hostfunction" title="src/app/hero-details.component.css" linenums="false">
</code-example>
### :host-context
@ -99,7 +99,7 @@ up to the document root. The `:host-context()` selector is useful when combined
The following example applies a `background-color` style to all `<h2>` elements *inside* the component, only
if some ancestor element has the CSS class `theme-light`.
<code-example path="component-styles/src/app/hero-details.component.css" region="hostcontext" header="src/app/hero-details.component.css" linenums="false">
<code-example path="component-styles/src/app/hero-details.component.css" region="hostcontext" title="src/app/hero-details.component.css" linenums="false">
</code-example>
### (deprecated) `/deep/`, `>>>`, and `::ng-deep`
@ -114,7 +114,7 @@ children and content children of the component.
The following example targets all `<h3>` elements, from the host element down
through this component to all of its child elements in the DOM.
<code-example path="component-styles/src/app/hero-details.component.css" region="deep" header="src/app/hero-details.component.css" linenums="false">
<code-example path="component-styles/src/app/hero-details.component.css" region="deep" title="src/app/hero-details.component.css" linenums="false">
</code-example>
@ -154,7 +154,7 @@ You can add a `styles` array property to the `@Component` decorator.
Each string in the array defines some CSS for this component.
<code-example path="component-styles/src/app/hero-app.component.ts" header="src/app/hero-app.component.ts (CSS inline)">
<code-example path="component-styles/src/app/hero-app.component.ts" title="src/app/hero-app.component.ts (CSS inline)">
</code-example>
<div class="alert is-critical">
@ -164,7 +164,7 @@ They are _not inherited_ by any components nested within the template nor by any
</div>
The Angular CLI command [`ng generate component`](cli/generate) defines an empty `styles` array when you create the component with the `--inline-style` flag.
The CLI defines an empty `styles` array when you create the component with the `--inline-style` flag.
<code-example language="sh" class="code-shell">
ng generate component hero-app --inline-style
@ -176,8 +176,8 @@ You can load styles from external CSS files by adding a `styleUrls` property
to a component's `@Component` decorator:
<code-tabs>
<code-pane header="src/app/hero-app.component.ts (CSS in file)" path="component-styles/src/app/hero-app.component.1.ts"></code-pane>
<code-pane header="src/app/hero-app.component.css" path="component-styles/src/app/hero-app.component.css"></code-pane>
<code-pane title="src/app/hero-app.component.ts (CSS in file)" path="component-styles/src/app/hero-app.component.1.ts"></code-pane>
<code-pane title="src/app/hero-app.component.css" path="component-styles/src/app/hero-app.component.css"></code-pane>
</code-tabs>
<div class="alert is-critical">
@ -193,7 +193,7 @@ They are _not inherited_ by any components nested within the template nor by any
</div>
When you use the Angular CLI command [`ng generate component`](cli/generate) without the `--inline-style` flag, it creates an empty styles file for you and references that file in the component's generated `styleUrls`.
The CLI creates an empty styles file for you by default and references that file in the component's generated `styleUrls`.
<code-example language="sh" class="code-shell">
ng generate component hero-app
@ -204,20 +204,19 @@ ng generate component hero-app
You can embed CSS styles directly into the HTML template by putting them
inside `<style>` tags.
<code-example path="component-styles/src/app/hero-controls.component.ts" region="inlinestyles" header="src/app/hero-controls.component.ts">
<code-example path="component-styles/src/app/hero-controls.component.ts" region="inlinestyles" title="src/app/hero-controls.component.ts">
</code-example>
### Template link tags
You can also write `<link>` tags into the component's HTML template.
<code-example path="component-styles/src/app/hero-team.component.ts" region="stylelink" header="src/app/hero-team.component.ts">
<code-example path="component-styles/src/app/hero-team.component.ts" region="stylelink" title="src/app/hero-team.component.ts">
</code-example>
<div class="alert is-critical">
When building with the CLI, be sure to include the linked style file among the assets to be copied to the server as described in the [CLI wiki](https://github.com/angular/angular-cli/wiki/stories-asset-configuration).
<!-- 2018-10-16: The link above is still the best source for this information. -->
When building with the CLI, be sure to include the linked style file among the assets to be copied to the server as described in the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-asset-configuration).
Once included, the CLI will include the stylesheet, whether the link tag's href URL is relative to the application root or the component file.
@ -231,7 +230,7 @@ on the [MDN](https://developer.mozilla.org) site.
In this case, the URL is relative to the CSS file into which you're importing.
<code-example path="component-styles/src/app/hero-details.component.css" region="import" header="src/app/hero-details.component.css (excerpt)">
<code-example path="component-styles/src/app/hero-details.component.css" region="import" title="src/app/hero-details.component.css (excerpt)">
</code-example>
### External and global style files
@ -240,9 +239,7 @@ When building with the CLI, you must configure the `angular.json` to include _al
Register **global** style files in the `styles` section which, by default, is pre-configured with the global `styles.css` file.
See the [CLI wiki](https://github.com/angular/angular-cli/wiki/stories-global-styles) to learn more.
<!-- 2018-10-16: The link above is still the best source for this information. -->
See the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-global-styles) to learn more.
### Non-CSS style files
@ -262,10 +259,8 @@ The CLI build process runs the pertinent CSS preprocessor.
When generating a component file with `ng generate component`, the CLI emits an empty CSS styles file (`.css`) by default.
You can configure the CLI to default to your preferred CSS preprocessor
as explained in the [CLI wiki](https://github.com/angular/angular-cli/wiki/stories-css-preprocessors
as explained in the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-css-preprocessors
"CSS Preprocessor integration").
<!-- 2018-10-16: The link above is still the best source for this information. -->
<div class="alert is-important">
@ -303,7 +298,7 @@ Choose from the following modes:
To set the components encapsulation mode, use the `encapsulation` property in the component metadata:
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.native" header="src/app/quest-summary.component.ts" linenums="false">
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.native" title="src/app/quest-summary.component.ts" linenums="false">
</code-example>
`ShadowDom` view encapsulation only works on browsers that have native support

View File

@ -21,7 +21,7 @@ constructor, and lets the framework provide them.
The following example shows that `AppComponent` declares its dependence on `LoggerService` and `UserContext`.
<code-example path="dependency-injection-in-action/src/app/app.component.ts" region="ctor" header="src/app/app.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/app.component.ts" region="ctor" title="src/app/app.component.ts" linenums="false">
</code-example>
@ -30,7 +30,7 @@ The following example shows that `AppComponent` declares its dependence on `Logg
`UserService`, another service that gathers information about a particular user.
<code-example path="dependency-injection-in-action/src/app/user-context.service.ts" region="injectables" header="user-context.service.ts (injection)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/user-context.service.ts" region="injectables" title="user-context.service.ts (injection)" linenums="false">
</code-example>
@ -68,7 +68,7 @@ by providing that service *at the sub-root component for that branch*.
This example shows how to make a different instance of `HeroService` available to `HeroesBaseComponent`
by adding it to the `providers` array of the `@Component()` decorator of the sub-component.
<code-example path="dependency-injection-in-action/src/app/sorted-heroes.component.ts" region="injection" header="src/app/sorted-heroes.component.ts (HeroesBaseComponent excerpt)">
<code-example path="dependency-injection-in-action/src/app/sorted-heroes.component.ts" region="injection" title="src/app/sorted-heroes.component.ts (HeroesBaseComponent excerpt)">
</code-example>
@ -103,7 +103,7 @@ This is called *sandboxing* because each service and component instance has its
In this example, `HeroBiosComponent` presents three instances of `HeroBioComponent`.
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="simple" header="ap/hero-bios.component.ts">
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="simple" title="ap/hero-bios.component.ts">
</code-example>
@ -111,7 +111,7 @@ In this example, `HeroBiosComponent` presents three instances of `HeroBioCompone
Each `HeroBioComponent` can edit a single hero's biography.
`HeroBioComponent` relies on `HeroCacheService` to fetch, cache, and perform other persistence operations on that hero.
<code-example path="dependency-injection-in-action/src/app/hero-cache.service.ts" region="service" header="src/app/hero-cache.service.ts">
<code-example path="dependency-injection-in-action/src/app/hero-cache.service.ts" region="service" title="src/app/hero-cache.service.ts">
</code-example>
@ -122,7 +122,7 @@ as they'd be competing with each other to determine which hero to cache.
Instead, each `HeroBioComponent` gets its *own* `HeroCacheService` instance
by listing `HeroCacheService` in its metadata `providers` array.
<code-example path="dependency-injection-in-action/src/app/hero-bio.component.ts" region="component" header="src/app/hero-bio.component.ts">
<code-example path="dependency-injection-in-action/src/app/hero-bio.component.ts" region="component" title="src/app/hero-bio.component.ts">
</code-example>
@ -179,13 +179,13 @@ that parent component becomes the host. The following example covers this second
These decorators can be used individually or together, as shown in the example.
This `HeroBiosAndContactsComponent` is a revision of `HeroBiosComponent` which you looked at [above](guide/dependency-injection-in-action#hero-bios-component).
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="hero-bios-and-contacts" header="src/app/hero-bios.component.ts (HeroBiosAndContactsComponent)">
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="hero-bios-and-contacts" title="src/app/hero-bios.component.ts (HeroBiosAndContactsComponent)">
</code-example>
Focus on the template:
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="template" header="dependency-injection-in-action/src/app/hero-bios.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="template" title="dependency-injection-in-action/src/app/hero-bios.component.ts" linenums="false">
</code-example>
@ -193,7 +193,7 @@ Now there's a new `<hero-contact>` element between the `<hero-bio>` tags.
Angular *projects*, or *transcludes*, the corresponding `HeroContactComponent` into the `HeroBioComponent` view,
placing it in the `<ng-content>` slot of the `HeroBioComponent` template.
<code-example path="dependency-injection-in-action/src/app/hero-bio.component.ts" region="template" header="src/app/hero-bio.component.ts (template)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/hero-bio.component.ts" region="template" title="src/app/hero-bio.component.ts (template)" linenums="false">
</code-example>
@ -206,13 +206,13 @@ The result is shown below, with the hero's telephone number from `HeroContactCom
Here's `HeroContactComponent`, which demonstrates the qualifying decorators.
<code-example path="dependency-injection-in-action/src/app/hero-contact.component.ts" region="component" header="src/app/hero-contact.component.ts">
<code-example path="dependency-injection-in-action/src/app/hero-contact.component.ts" region="component" title="src/app/hero-contact.component.ts">
</code-example>
Focus on the constructor parameters.
<code-example path="dependency-injection-in-action/src/app/hero-contact.component.ts" region="ctor-params" header="src/app/hero-contact.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/hero-contact.component.ts" region="ctor-params" title="src/app/hero-contact.component.ts" linenums="false">
</code-example>
@ -256,7 +256,7 @@ the app throws an exception when it cannot find the required logger at the host
Using a custom provider allows you to provide a concrete implementation for implicit dependencies, such as built-in browser APIs. The following example uses an `InjectionToken` to provide the [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) browser API as a dependency in the `BrowserStorageService`.
<code-example path="dependency-injection-in-action/src/app/storage.service.ts" header="src/app/storage.service.ts">
<code-example path="dependency-injection-in-action/src/app/storage.service.ts" title="src/app/storage.service.ts">
</code-example>
@ -266,7 +266,7 @@ The `factory` function returns the `localStorage` property that is attached to t
Providers can also be scoped by injector through constructor parameter decorators. The following example overrides the `BROWSER_STORAGE` token in the `Component` class `providers` with the `sessionStorage` browser API. The same `BrowserStorageService` is injected twice in the constructor, decorated with `@Self` and `@SkipSelf` to define which injector handles the provider dependency.
<code-example path="dependency-injection-in-action/src/app/storage.component.ts" header="src/app/storage.component.ts">
<code-example path="dependency-injection-in-action/src/app/storage.component.ts" title="src/app/storage.component.ts">
</code-example>
@ -283,7 +283,7 @@ As a result, you might need to access a component's DOM element.
To illustrate, here's a simplified version of `HighlightDirective` from
the [Attribute Directives](guide/attribute-directives) page.
<code-example path="dependency-injection-in-action/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts">
<code-example path="dependency-injection-in-action/src/app/highlight.directive.ts" title="src/app/highlight.directive.ts">
</code-example>
@ -297,7 +297,7 @@ whose `nativeElement` property exposes the DOM element for the directive to mani
The sample code applies the directive's `myHighlight` attribute to two `<div>` tags,
first without a value (yielding the default color) and then with an assigned color value.
<code-example path="dependency-injection-in-action/src/app/app.component.html" region="highlight" header="src/app/app.component.html (highlight)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/app.component.html" region="highlight" title="src/app/app.component.html (highlight)" linenums="false">
</code-example>
@ -323,7 +323,7 @@ Angular passes this token to the injector and assigns the result to the paramete
The following is a typical example.
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="ctor" header="src/app/hero-bios.component.ts (component constructor injection)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="ctor" title="src/app/hero-bios.component.ts (component constructor injection)" linenums="false">
</code-example>
@ -366,7 +366,7 @@ It's visually simple: a few properties and the logs produced by a logger.
The code behind it customizes how and where the DI framework provides dependencies.
The use cases illustrate different ways to use the [*provide* object literal](guide/dependency-injection-providers#provide) to associate a definition object with a DI token.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="hero-of-the-month" header="hero-of-the-month.component.ts">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="hero-of-the-month" title="hero-of-the-month.component.ts">
</code-example>
@ -384,7 +384,7 @@ You can also use a value provider in a unit test to provide mock data in place o
The `HeroOfTheMonthComponent` example has two value providers.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-value" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-value" title="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
</code-example>
@ -405,7 +405,7 @@ The title string literal is immediately available.
The `someHero` variable in this example was set earlier in the file as shown below.
You can't use a variable whose value will be defined later.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="some-hero" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="some-hero" title="dependency-injection-in-action/src/app/hero-of-the-month.component.ts">
</code-example>
@ -425,7 +425,7 @@ extend the default class, or emulate the behavior of the real class in a test ca
The following code shows two examples in `HeroOfTheMonthComponent`.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-class" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-class" title="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
</code-example>
@ -446,7 +446,7 @@ Components outside the tree continue to receive the original `LoggerService` ins
`DateLoggerService` inherits from `LoggerService`; it appends the current date/time to each message:
<code-example path="dependency-injection-in-action/src/app/date-logger.service.ts" region="date-logger-service" header="src/app/date-logger.service.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/date-logger.service.ts" region="date-logger-service" title="src/app/date-logger.service.ts" linenums="false">
</code-example>
@ -458,7 +458,7 @@ The `useExisting` provider key lets you map one token to another.
In effect, the first token is an *alias* for the service associated with the second token,
creating two ways to access the same service object.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-existing" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-existing" title="dependency-injection-in-action/src/app/hero-of-the-month.component.ts">
</code-example>
@ -470,13 +470,13 @@ You might want to shrink that API surface to just the members you actually need.
In this example, the `MinimalLogger` [class-interface](#class-interface) reduces the API to two members:
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" header="src/app/minimal-logger.service.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" title="src/app/minimal-logger.service.ts" linenums="false">
</code-example>
The following example puts `MinimalLogger` to use in a simplified version of `HeroOfTheMonthComponent`.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.1.ts" header="src/app/hero-of-the-month.component.ts (minimal version)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.1.ts" title="src/app/hero-of-the-month.component.ts (minimal version)" linenums="false">
</code-example>
@ -507,7 +507,7 @@ This is illustrated in the following image, which displays the logging date.
The `useFactory` provider key lets you create a dependency object by calling a factory function,
as in the following example.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-factory" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-factory" title="dependency-injection-in-action/src/app/hero-of-the-month.component.ts">
</code-example>
@ -530,7 +530,7 @@ The `runnersUpFactory()` returns the *provider factory function*, which can use
the passed-in state value and the injected services `Hero` and `HeroService`.
<code-example path="dependency-injection-in-action/src/app/runners-up.ts" region="factory-synopsis" header="runners-up.ts (excerpt)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/runners-up.ts" region="factory-synopsis" title="runners-up.ts (excerpt)" linenums="false">
</code-example>
@ -570,13 +570,13 @@ That's the subject of the next section.
The previous *Hero of the Month* example used the `MinimalLogger` class
as the token for a provider of `LoggerService`.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-existing" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-existing" title="dependency-injection-in-action/src/app/hero-of-the-month.component.ts">
</code-example>
`MinimalLogger` is an abstract class.
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" header="dependency-injection-in-action/src/app/minimal-logger.service.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" title="dependency-injection-in-action/src/app/minimal-logger.service.ts" linenums="false">
</code-example>
@ -604,7 +604,7 @@ Using a class as an interface gives you the characteristics of an interface in a
To minimize memory cost, however, the class should have *no implementation*.
The `MinimalLogger` transpiles to this unoptimized, pre-minified JavaScript for a constructor function.
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" region="minimal-logger-transpiled" header="dependency-injection-in-action/src/app/minimal-logger.service.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" region="minimal-logger-transpiled" title="dependency-injection-in-action/src/app/minimal-logger.service.ts" linenums="false">
</code-example>
@ -633,13 +633,13 @@ another token that happens to have the same name.
You encountered them twice in the *Hero of the Month* example,
in the *title* value provider and in the *runnersUp* factory provider.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="provide-injection-token" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="provide-injection-token" title="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
</code-example>
You created the `TITLE` token like this:
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="injection-token" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="injection-token" title="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
</code-example>
@ -667,7 +667,7 @@ The `HeroesBaseComponent` can stand on its own.
It demands its own instance of `HeroService` to get heroes
and displays them in the order they arrive from the database.
<code-example path="dependency-injection-in-action/src/app/sorted-heroes.component.ts" region="heroes-base" header="src/app/sorted-heroes.component.ts (HeroesBaseComponent)">
<code-example path="dependency-injection-in-action/src/app/sorted-heroes.component.ts" region="heroes-base" title="src/app/sorted-heroes.component.ts (HeroesBaseComponent)">
</code-example>
@ -693,7 +693,7 @@ You must provide the `HeroService` again for *this* component,
then pass it down to the base class inside the constructor.
<code-example path="dependency-injection-in-action/src/app/sorted-heroes.component.ts" region="sorted-heroes" header="src/app/sorted-heroes.component.ts (SortedHeroesComponent)">
<code-example path="dependency-injection-in-action/src/app/sorted-heroes.component.ts" region="sorted-heroes" title="src/app/sorted-heroes.component.ts (SortedHeroesComponent)">
</code-example>
@ -731,7 +731,7 @@ appear *above* the class definition.
Break the circularity with `forwardRef`.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" header="parent-finder.component.ts (AlexComponent providers)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" title="parent-finder.component.ts (AlexComponent providers)" linenums="false">
</code-example>

View File

@ -40,7 +40,7 @@ In the following example, the parent `AlexComponent` has several children includ
{@a alex}
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-1" header="parent-finder.component.ts (AlexComponent v.1)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-1" title="parent-finder.component.ts (AlexComponent v.1)" linenums="false">
</code-example>
@ -49,7 +49,7 @@ In the following example, the parent `AlexComponent` has several children includ
*Cathy* reports whether or not she has access to *Alex*
after injecting an `AlexComponent` into her constructor:
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="cathy" header="parent-finder.component.ts (CathyComponent)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="cathy" title="parent-finder.component.ts (CathyComponent)" linenums="false">
</code-example>
@ -98,7 +98,7 @@ inject its parent via the parent's base class*.
The sample's `CraigComponent` explores this question. [Looking back](#alex),
you see that the `Alex` component *extends* (*inherits*) from a class named `Base`.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-class-signature" header="parent-finder.component.ts (Alex class signature)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-class-signature" title="parent-finder.component.ts (Alex class signature)" linenums="false">
</code-example>
@ -106,7 +106,7 @@ you see that the `Alex` component *extends* (*inherits*) from a class named `Bas
The `CraigComponent` tries to inject `Base` into its `alex` constructor parameter and reports if it succeeded.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="craig" header="parent-finder.component.ts (CraigComponent)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="craig" title="parent-finder.component.ts (CraigComponent)" linenums="false">
</code-example>
@ -138,7 +138,7 @@ and add that provider to the `providers` array of the `@Component()` metadata fo
{@a alex-providers}
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" header="parent-finder.component.ts (AlexComponent providers)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" title="parent-finder.component.ts (AlexComponent providers)" linenums="false">
</code-example>
@ -149,7 +149,7 @@ The [*forwardRef*](guide/dependency-injection-in-action#forwardref) breaks the c
*Carol*, the third of *Alex*'s child components, injects the parent into its `parent` parameter,
the same way you've done it before.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="carol-class" header="parent-finder.component.ts (CarolComponent class)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="carol-class" title="parent-finder.component.ts (CarolComponent class)" linenums="false">
</code-example>
@ -177,7 +177,7 @@ That means he must both *inject* the `Parent` class interface to get *Alice* and
Here's *Barry*.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="barry" header="parent-finder.component.ts (BarryComponent)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="barry" title="parent-finder.component.ts (BarryComponent)" linenums="false">
</code-example>
@ -190,11 +190,11 @@ For now, focus on *Barry*'s constructor.
<code-tabs>
<code-pane header="Barry's constructor" path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="barry-ctor">
<code-pane title="Barry's constructor" path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="barry-ctor">
</code-pane>
<code-pane header="Carol's constructor" path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="carol-ctor">
<code-pane title="Carol's constructor" path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="carol-ctor">
</code-pane>
@ -229,7 +229,7 @@ You [learned earlier](guide/dependency-injection-in-action#class-interface) that
The example defines a `Parent` class interface.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="parent" header="parent-finder.component.ts (Parent class-interface)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="parent" title="parent-finder.component.ts (Parent class-interface)" linenums="false">
</code-example>
@ -241,7 +241,7 @@ Such a narrow interface helps decouple the child component class from its parent
A component that could serve as a parent *should* implement the class interface as the `AliceComponent` does.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alice-class-signature" header="parent-finder.component.ts (AliceComponent class signature)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alice-class-signature" title="parent-finder.component.ts (AliceComponent class signature)" linenums="false">
</code-example>
@ -251,7 +251,7 @@ Doing so adds clarity to the code. But it's not technically necessary.
Although `AlexComponent` has a `name` property, as required by its `Base` class,
its class signature doesn't mention `Parent`.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-class-signature" header="parent-finder.component.ts (AlexComponent class signature)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-class-signature" title="parent-finder.component.ts (AlexComponent class signature)" linenums="false">
</code-example>
@ -277,19 +277,19 @@ It doesn't in this example *only* to demonstrate that the code will compile and
Writing variations of the same parent *alias provider* gets old quickly,
especially this awful mouthful with a [*forwardRef*](guide/dependency-injection-in-action#forwardref).
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" title="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>
You can extract that logic into a helper function like the following.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="provide-the-parent" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="provide-the-parent" title="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>
Now you can add a simpler, more meaningful parent provider to your components.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alice-providers" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alice-providers" title="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>
@ -299,14 +299,14 @@ The application might have a variety of parent types, each with its own class in
Here's a revised version that defaults to `parent` but also accepts an optional second parameter for a different parent class interface.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="provide-parent" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="provide-parent" title="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>
And here's how you could use it with a different parent type.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="beth-providers" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="beth-providers" title="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>

View File

@ -130,7 +130,7 @@ like the title of the application or the address of a web API endpoint.
These configuration objects aren't always instances of a class.
They can be object literals, as shown in the following example.
<code-example path="dependency-injection/src/app/app.config.ts" region="config" header="src/app/app.config.ts (excerpt)" linenums="false">
<code-example path="dependency-injection/src/app/app.config.ts" region="config" title="src/app/app.config.ts (excerpt)" linenums="false">
</code-example>
{@a interface-not-valid-token}
@ -147,7 +147,7 @@ In TypeScript, an interface is a design-time artifact, and doesn't have a runtim
<code-example path="dependency-injection/src/app/providers.component.ts" region="provider-9-ctor-interface" linenums="false">
</code-example>
<div class="alert is-helpful">
<div class="alert-is-helpful">
This might seem strange if you're used to dependency injection in strongly typed languages where an interface is the preferred dependency lookup key.
However, JavaScript, doesn't have interfaces, so when TypeScript is transpiled to JavaScript, the interface disappears.
@ -157,13 +157,13 @@ There is no interface type information left for Angular to find at runtime.
One alternative is to provide and inject the configuration object in an NgModule like `AppModule`.
<code-example path="dependency-injection/src/app/app.module.ts" region="providers" header="src/app/app.module.ts (providers)"></code-example>
<code-example path="dependency-injection/src/app/app.module.ts" region="providers" title="src/app/app.module.ts (providers)"></code-example>
Another solution to choosing a provider token for non-class dependencies is
to define and use an `InjectionToken` object.
The following example shows how to define such a token.
<code-example path="dependency-injection/src/app/app.config.ts" region="token" header="src/app/app.config.ts" linenums="false">
<code-example path="dependency-injection/src/app/app.config.ts" region="token" title="src/app/app.config.ts" linenums="false">
</code-example>
The type parameter, while optional, conveys the dependency's type to developers and tooling.
@ -177,10 +177,10 @@ Register the dependency provider using the `InjectionToken` object:
Now you can inject the configuration object into any constructor that needs it, with
the help of an `@Inject()` parameter decorator.
<code-example path="dependency-injection/src/app/app.component.2.ts" region="ctor" header="src/app/app.component.ts" linenums="false">
<code-example path="dependency-injection/src/app/app.component.2.ts" region="ctor" title="src/app/app.component.ts" linenums="false">
</code-example>
<div class="alert is-helpful">
<div class="alert-is-helpful">
Although the `AppConfig` interface plays no role in dependency injection,
it supports typing of the configuration object within the class.
@ -215,21 +215,21 @@ who is authorized and who isn't.
To resolve this, we give the `HeroService` constructor a boolean flag to control display of secret heroes.
<code-example path="dependency-injection/src/app/heroes/hero.service.ts" region="internals" header="src/app/heroes/hero.service.ts (excerpt)" linenums="false">
<code-example path="dependency-injection/src/app/heroes/hero.service.ts" region="internals" title="src/app/heroes/hero.service.ts (excerpt)" linenums="false">
</code-example>
You can inject `Logger`, but you can't inject the `isAuthorized` flag. Instead, you can use a factory provider to create a new logger instance for `HeroService`.
A factory provider needs a factory function.
<code-example path="dependency-injection/src/app/heroes/hero.service.provider.ts" region="factory" header="src/app/heroes/hero.service.provider.ts (excerpt)" linenums="false">
<code-example path="dependency-injection/src/app/heroes/hero.service.provider.ts" region="factory" title="src/app/heroes/hero.service.provider.ts (excerpt)" linenums="false">
</code-example>
Although `HeroService` has no access to `UserService`, the factory function does.
You inject both `Logger` and `UserService` into the factory provider
and let the injector pass them along to the factory function.
<code-example path="dependency-injection/src/app/heroes/hero.service.provider.ts" region="provider" header="src/app/heroes/hero.service.provider.ts (excerpt)" linenums="false">
<code-example path="dependency-injection/src/app/heroes/hero.service.provider.ts" region="provider" title="src/app/heroes/hero.service.provider.ts (excerpt)" linenums="false">
</code-example>
* The `useFactory` field tells Angular that the provider is a factory function whose implementation is `heroServiceFactory`.
@ -248,10 +248,10 @@ The following shows the new and the old implementations side-by-side.
<code-tabs>
<code-pane header="src/app/heroes/heroes.component (v3)" path="dependency-injection/src/app/heroes/heroes.component.ts">
<code-pane title="src/app/heroes/heroes.component (v3)" path="dependency-injection/src/app/heroes/heroes.component.ts">
</code-pane>
<code-pane header="src/app/heroes/heroes.component (v2)" path="dependency-injection/src/app/heroes/heroes.component.1.ts">
<code-pane title="src/app/heroes/heroes.component (v2)" path="dependency-injection/src/app/heroes/heroes.component.1.ts">
</code-pane>
</code-tabs>
@ -293,7 +293,7 @@ When you provide multiple sets of routes using [RouterModule.forRoot](api/router
and [RouterModule.forChild](api/router/RouterModule#forchild) in a single module,
the [ROUTES](api/router/ROUTES) token combines all the different provided sets of routes into a single value.
<div class="alert is-helpful>
<div class="alert-is-helpful>
Search for [Constants in API documentation](api?type=const) to find more built-in tokens.
@ -309,7 +309,7 @@ When providers are tree-shakable, the Angular compiler removes the associated
services from the final output when it determines that they are not used in your application.
This significantly reduces the size of your bundles.
<div class="alert is-helpful">
<div class="alert-is-helpful">
Ideally, if an application isn't injecting a service, it shouldn't be included in the final output.
However, Angular has to be able to identify at build time whether the service will be required or not.
@ -322,13 +322,13 @@ Thus, services provided at the NgModule or component level are not tree-shakable
The following example of non-tree-shakable providers in Angular configures a service provider for the injector of an NgModule.
<code-example path="dependency-injection/src/app/tree-shaking/service-and-module.ts" header="src/app/tree-shaking/service-and-modules.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/tree-shaking/service-and-module.ts" title="src/app/tree-shaking/service-and-modules.ts" linenums="false"> </code-example>
This module can then be imported into your application module
to make the service available for injection in your app,
as shown in the following example.
<code-example path="dependency-injection/src/app/tree-shaking/app.module.ts" header="src/app/tree-shaking/app.modules.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/tree-shaking/app.module.ts" title="src/app/tree-shaking/app.modules.ts" linenums="false"> </code-example>
When `ngc` runs, it compiles `AppModule` into a module factory, which contains definitions for all the providers declared in all the modules it includes. At runtime, this factory becomes an injector that instantiates these services.
@ -340,13 +340,13 @@ You can make a provider tree-shakable by specifying it in the `@Injectable()` de
The following example shows the tree-shakable equivalent to the `ServiceModule` example above.
<code-example path="dependency-injection/src/app/tree-shaking/service.ts" header="src/app/tree-shaking/service.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/tree-shaking/service.ts" title="src/app/tree-shaking/service.ts" linenums="false"> </code-example>
The service can be instantiated by configuring a factory function, as in the following example.
<code-example path="dependency-injection/src/app/tree-shaking/service.0.ts" header="src/app/tree-shaking/service.0.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/tree-shaking/service.0.ts" title="src/app/tree-shaking/service.0.ts" linenums="false"> </code-example>
<div class="alert is-helpful">
<div class="alert-is-helpful">
To override a tree-shakable provider, configure the injector of a specific NgModule or component with another provider, using the `providers: []` array syntax of the `@NgModule()` or `@Component()` decorator.

View File

@ -9,7 +9,7 @@ DI is a coding pattern in which a class asks for dependencies from external sour
In Angular, the DI framework provides declared dependencies to a class when that class is instantiated. This guide explains how DI works in Angular, and how you use it to make your apps flexible, efficient, and robust, as well as testable and maintainable.
<div class="alert is-helpful">
<div class="alert-is-helpful">
You can run the <live-example></live-example> of the sample app that accompanies this guide.
@ -19,16 +19,16 @@ Start by reviewing this simplified version of the _heroes_ feature
from the [The Tour of Heroes](tutorial/). This simple version doesn't use DI; we'll walk through converting it to do so.
<code-tabs>
<code-pane header="src/app/heroes/heroes.component.ts" path="dependency-injection/src/app/heroes/heroes.component.1.ts" region="v1">
<code-pane title="src/app/heroes/heroes.component.ts" path="dependency-injection/src/app/heroes/heroes.component.1.ts" region="v1">
</code-pane>
<code-pane header="src/app/heroes/hero-list.component.ts" path="dependency-injection/src/app/heroes/hero-list.component.1.ts">
<code-pane title="src/app/heroes/hero-list.component.ts" path="dependency-injection/src/app/heroes/hero-list.component.1.ts">
</code-pane>
<code-pane header="src/app/heroes/hero.ts" path="dependency-injection/src/app/heroes/hero.ts">
<code-pane title="src/app/heroes/hero.ts" path="dependency-injection/src/app/heroes/hero.ts">
</code-pane>
<code-pane header="src/app/heroes/mock-heroes.ts" path="dependency-injection/src/app/heroes/mock-heroes.ts">
<code-pane title="src/app/heroes/mock-heroes.ts" path="dependency-injection/src/app/heroes/mock-heroes.ts">
</code-pane>
</code-tabs>
@ -39,7 +39,7 @@ Its only purpose is to display `HeroListComponent`, which displays a list of her
This version of the `HeroListComponent` gets heroes from the `HEROES` array, an in-memory collection
defined in a separate `mock-heroes` file.
<code-example header="src/app/heroes/hero-list.component.ts (class)" path="dependency-injection/src/app/heroes/hero-list.component.1.ts" region="class">
<code-example title="src/app/heroes/hero-list.component.ts (class)" path="dependency-injection/src/app/heroes/hero-list.component.1.ts" region="class">
</code-example>
This approach works for prototyping, but is not robust or maintainable.
@ -52,7 +52,7 @@ replace every use of the `HEROES` mock data.
The DI framework lets you supply data to a component from an injectable _service_ class, defined in its own file. To demonstrate, we'll create an injectable service class that provides a list of heroes, and register that class as a provider of that service.
<div class="alert is-helpful">
<div class="alert-is-helpful">
Having multiple classes in the same file can be confusing. We generally recommend that you define components and services in separate files.
@ -68,7 +68,7 @@ See an example in the [DI Cookbook](guide/dependency-injection-in-action#forward
### Create an injectable service class
The [Angular CLI](cli) can generate a new `HeroService` class in the `src/app/heroes` folder with this command.
The [**Angular CLI**](https://cli.angular.io/) can generate a new `HeroService` class in the `src/app/heroes` folder with this command.
<code-example language="sh" class="code-shell">
ng generate service heroes/hero
@ -76,12 +76,12 @@ ng generate service heroes/hero
The command creates the following `HeroService` skeleton.
<code-example path="dependency-injection/src/app/heroes/hero.service.0.ts" header="src/app/heroes/hero.service.ts (CLI-generated)">
<code-example path="dependency-injection/src/app/heroes/hero.service.0.ts" title="src/app/heroes/hero.service.ts (CLI-generated)">
</code-example>
The `@Injectable()` is an essential ingredient in every Angular service definition. The rest of the class has been written to expose a `getHeroes` method that returns the same mock data as before. (A real app would probably get its data asynchronously from a remote server, but we'll ignore that to focus on the mechanics of injecting the service.)
<code-example path="dependency-injection/src/app/heroes/hero.service.3.ts" header="src/app/heroes/hero.service.ts">
<code-example path="dependency-injection/src/app/heroes/hero.service.3.ts" title="src/app/heroes/hero.service.ts">
</code-example>
@ -147,7 +147,7 @@ In order for `HeroListComponent` to get heroes from `HeroService`, it needs to a
You can tell Angular to inject a dependency in a component's constructor by specifying a **constructor parameter with the dependency type**. Here's the `HeroListComponent` constructor, asking for the `HeroService` to be injected.
<code-example header="src/app/heroes/hero-list.component (constructor signature)" path="dependency-injection/src/app/heroes/hero-list.component.ts"
<code-example title="src/app/heroes/hero-list.component (constructor signature)" path="dependency-injection/src/app/heroes/hero-list.component.ts"
region="ctor-signature">
</code-example>
@ -155,10 +155,10 @@ Of course, `HeroListComponent` should do something with the injected `HeroServic
Here's the revised component, making use of the injected service, side-by-side with the previous version for comparison.
<code-tabs>
<code-pane header="hero-list.component (with DI)" path="dependency-injection/src/app/heroes/hero-list.component.2.ts">
<code-pane title="hero-list.component (with DI)" path="dependency-injection/src/app/heroes/hero-list.component.2.ts">
</code-pane>
<code-pane header="hero-list.component (without DI)" path="dependency-injection/src/app/heroes/hero-list.component.1.ts">
<code-pane title="hero-list.component (without DI)" path="dependency-injection/src/app/heroes/hero-list.component.1.ts">
</code-pane>
</code-tabs>
@ -197,7 +197,7 @@ Listing dependencies as constructor parameters may be all you need to test appli
For example, you can create a new `HeroListComponent` with a mock service that you can manipulate
under test.
<code-example path="dependency-injection/src/app/test.component.ts" region="spec" header="src/app/test.component.ts" linenums="false">
<code-example path="dependency-injection/src/app/test.component.ts" region="spec" title="src/app/test.component.ts" linenums="false">
</code-example>
<div class="alert is-helpful">
@ -217,13 +217,13 @@ Here is the revised `HeroService` that injects `Logger`, side by side with the p
<code-tabs>
<code-pane header="src/app/heroes/hero.service (v2)" path="dependency-injection/src/app/heroes/hero.service.2.ts">
<code-pane title="src/app/heroes/hero.service (v2)" path="dependency-injection/src/app/heroes/hero.service.2.ts">
</code-pane>
<code-pane header="src/app/heroes/hero.service (v1)" path="dependency-injection/src/app/heroes/hero.service.1.ts">
<code-pane title="src/app/heroes/hero.service (v1)" path="dependency-injection/src/app/heroes/hero.service.1.ts">
</code-pane>
<code-pane header="src/app/logger.service"
<code-pane title="src/app/logger.service"
path="dependency-injection/src/app/logger.service.ts">
</code-pane>
@ -238,7 +238,7 @@ If Angular can't find that parameter information, it throws an error.
Angular can only find the parameter information _if the class has a decorator of some kind_.
The `@Injectable()` decorator is the standard decorator for service classes.
<div class="alert is-helpful">
<div class="alert-is-helpful">
The decorator requirement is imposed by TypeScript. TypeScript normally discards parameter type information when it [transpiles](guide/glossary#transpile) the code to JavaScript. TypeScript preserves this information if the class has a decorator and the `emitDecoratorMetadata` compiler option is set `true` in TypeScript's `tsconfig.json` configuration file. The CLI configures `tsconfig.json` with `emitDecoratorMetadata: true`.
@ -260,14 +260,14 @@ In simple examples, the dependency value is an *instance*, and
the class *type* serves as its own lookup key.
Here you get a `HeroService` directly from the injector by supplying the `HeroService` type as the token:
<code-example path="dependency-injection/src/app/injector.component.ts" region="get-hero-service" header="src/app/injector.component.ts" linenums="false">
<code-example path="dependency-injection/src/app/injector.component.ts" region="get-hero-service" title="src/app/injector.component.ts" linenums="false">
</code-example>
The behavior is similar when you write a constructor that requires an injected class-based dependency.
When you define a constructor parameter with the `HeroService` class type,
Angular knows to inject the service associated with that `HeroService` class token:
<code-example path="dependency-injection/src/app/heroes/hero-list.component.ts" region="ctor-signature" header="src/app/heroes/hero-list.component.ts">
<code-example path="dependency-injection/src/app/heroes/hero-list.component.ts" region="ctor-signature" title="src/app/heroes/hero-list.component.ts">
</code-example>
Many dependency values are provided by classes, but not all. The expanded *provide* object lets you associate different kinds of providers with a DI token.
@ -295,7 +295,7 @@ When using `@Optional()`, your code must be prepared for a null value. If you
don't register a logger provider anywhere, the injector sets the
value of `logger` to null.
<div class="alert is-helpful">
<div class="alert-is-helpful">
`@Inject()` and `@Optional()` are _parameter decorators_. They alter the way the DI framework provides a dependency, by annotating the dependency parameter on the constructor of the class that requires the dependency.

View File

@ -1,192 +1,60 @@
# Deployment
When you are ready to deploy your Angular application to a remote server, you have various options for
deployment.
This page describes techniques for deploying your Angular application to a remote server.
{@a dev-deploy}
{@a copy-files}
## Simplest deployment possible
For the simplest deployment, create a production build and copy the output directory to a web server.
For the simplest deployment, build for development and copy the output directory to a web server.
1. Start with the production build:
1. Start with the development build
<code-example language="none" class="code-shell">
ng build --prod
ng build
</code-example>
2. Copy _everything_ within the output folder (`dist/` by default) to a folder on the server.
3. Configure the server to redirect requests for missing files to `index.html`.
Learn more about server-side redirects [below](#fallback).
This is the simplest production-ready deployment of your application.
3. If you copy the files into a server _sub-folder_, append the build flag, `--base-href` and set the `<base href>` appropriately.<br><br>
{@a deploy-to-github}
For example, if the `index.html` is on the server at `/my/app/index.html`, set the _base href_ to
`<base href="/my/app/">` like this.
## Deploy to GitHub pages
Another simple way to deploy your Angular app is to use [GitHub Pages](https://help.github.com/articles/what-is-github-pages/).
1. You need to [create a GitHub account](https://github.com/join) if you don't have one, and then [create a repository](https://help.github.com/articles/create-a-repo/) for your project.
Make a note of the user name and project name in GitHub.
1. Build your project using Github project name, with the Angular CLI command [`ng build`](cli/build) and the options shown here:
<code-example language="none" class="code-shell">
ng build --prod --output-path docs --base-href <project_name>
</code-example>
1. When the build is complete, make a copy of `docs/index.html` and name it `docs/404.html`.
1. Commit your changes and push.
1. On the GitHub project page, configure it to [publish from the docs folder](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch).
You can see your deployed page at `https://<user_name>.github.io/<project_name>/`.
<div class="alert is-helpful>
Check out [angular-cli-ghpages](https://github.com/angular-buch/angular-cli-ghpages), a full featured package that does all this for you and has extra functionality.
</div>
<hr>
{@a server-configuration}
## Server configuration
This section covers changes you may have make to the server or to files deployed to the server.
{@a fallback}
### Routed apps must fallback to `index.html`
Angular apps are perfect candidates for serving with a simple static HTML server.
You don't need a server-side engine to dynamically compose application pages because
Angular does that on the client-side.
If the app uses the Angular router, you must configure the server
to return the application's host page (`index.html`) when asked for a file that it does not have.
{@a deep-link}
A routed application should support "deep links".
A _deep link_ is a URL that specifies a path to a component inside the app.
For example, `http://www.mysite.com/heroes/42` is a _deep link_ to the hero detail page
that displays the hero with `id: 42`.
There is no issue when the user navigates to that URL from within a running client.
The Angular router interprets the URL and routes to that page and hero.
But clicking a link in an email, entering it in the browser address bar,
or merely refreshing the browser while on the hero detail page &mdash;
all of these actions are handled by the browser itself, _outside_ the running application.
The browser makes a direct request to the server for that URL, bypassing the router.
A static server routinely returns `index.html` when it receives a request for `http://www.mysite.com/`.
But it rejects `http://www.mysite.com/heroes/42` and returns a `404 - Not Found` error *unless* it is
configured to return `index.html` instead.
#### Fallback configuration examples
There is no single configuration that works for every server.
The following sections describe configurations for some of the most popular servers.
The list is by no means exhaustive, but should provide you with a good starting point.
* [Apache](https://httpd.apache.org/): add a
[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to the `.htaccess` file as shown
(https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):
<code-example format=".">
RewriteEngine On
&#35 If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
&#35 If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
<code-example language="none" class="code-shell">
ng build --base-href=/my/app/
</code-example>
* [Nginx](http://nginx.org/): use `try_files`, as described in
[Front Controller Pattern Web Apps](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#front-controller-pattern-web-apps),
modified to serve `index.html`:
<code-example format=".">
try_files $uri $uri/ /index.html;
</code-example>
You'll see that the `<base href>` is set properly in the generated `dist/index.html`.<br><br>
If you copy to the server's root directory, omit this step and leave the `<base href>` alone.<br><br>
Learn more about the role of `<base href>` [below](guide/deployment#base-tag).
* [IIS](https://www.iis.net/): add a rewrite rule to `web.config`, similar to the one shown
[here](http://stackoverflow.com/a/26152011/2116927):
<code-example format='.'>
&lt;system.webServer&gt;
&lt;rewrite&gt;
&lt;rules&gt;
&lt;rule name="Angular Routes" stopProcessing="true"&gt;
&lt;match url=".*" /&gt;
&lt;conditions logicalGrouping="MatchAll"&gt;
&lt;add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&gt;
&lt;add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /&gt;
&lt;/conditions&gt;
&lt;action type="Rewrite" url="/index.html" /&gt;
&lt;/rule&gt;
&lt;/rules&gt;
&lt;/rewrite&gt;
&lt;/system.webServer&gt;
</code-example>
4. Configure the server to redirect requests for missing files to `index.html`.
Learn more about server-side redirects [below](guide/deployment#fallback).
* [GitHub Pages](https://pages.github.com/): you can't
[directly configure](https://github.com/isaacs/github/issues/408)
the GitHub Pages server, but you can add a 404 page.
Copy `index.html` into `404.html`.
It will still be served as the 404 response, but the browser will process that page and load the app properly.
It's also a good idea to
[serve from `docs/` on master](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch)
and to
[create a `.nojekyll` file](https://www.bennadel.com/blog/3181-including-node-modules-and-vendors-folders-in-your-github-pages-site.htm)
* [Firebase hosting](https://firebase.google.com/docs/hosting/): add a
[rewrite rule](https://firebase.google.com/docs/hosting/url-redirects-rewrites#section-rewrites).
<code-example format=".">
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
</code-example>
{@a cors}
### Requesting services from a different server (CORS)
Angular developers may encounter a
<a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing" title="Cross-origin resource sharing">
<i>cross-origin resource sharing</i></a> error when making a service request (typically a data service request)
to a server other than the application's own host server.
Browsers forbid such requests unless the server permits them explicitly.
There isn't anything the client application can do about these errors.
The server must be configured to accept the application's requests.
Read about how to enable CORS for specific servers at
<a href="http://enable-cors.org/server.html" title="Enabling CORS server">enable-cors.org</a>.
<hr>
This is _not_ a production deployment. It's not optimized and it won't be fast for users.
It might be good enough for sharing your progress and ideas internally with managers, teammates, and other stakeholders.
{@a optimize}
## Production optimizations
## Optimize for production
The `--prod` _meta-flag_ engages the following build optimization features.
Although deploying directly from the development environment works,
you can generate an optimized build with additional CLI command line flags,
starting with `--prod`.
### Build with _--prod_
<code-example language="none" class="code-shell">
ng build --prod
</code-example>
The `--prod` _meta-flag_ engages the following optimization features.
* [Ahead-of-Time (AOT) Compilation](guide/aot-compiler): pre-compiles Angular component templates.
* [Production mode](#enable-prod-mode): deploys the production environment which enables _production mode_.
@ -195,22 +63,32 @@ The `--prod` _meta-flag_ engages the following build optimization features.
* Uglification: rewrites code to use short, cryptic variable and function names.
* Dead code elimination: removes unreferenced modules and much unused code.
See [`ng build`](cli/build) for more about CLI build options and what they do.
The remaining [copy deployment steps](#copy-files) are the same as before.
You may further reduce bundle sizes by adding the `build-optimizer` flag.
<code-example language="none" class="code-shell">
ng build --prod --build-optimizer
</code-example>
See the [CLI Documentation](https://github.com/angular/angular-cli/wiki/build)
for details about available build options and what they do.
{@a enable-prod-mode}
### Enable runtime production mode
### Enable production mode
In addition to build optimizations, Angular also has a runtime production mode. Angular apps run in development mode by default, as you can see by the following message on the browser console:
Angular apps run in development mode by default, as you can see by the following message on the browser
console:
<code-example format="nocode">
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
</code-example>
Switching to _production mode_ makes it run faster by disabling development specific checks such as the dual change detection cycles.
Switching to _production mode_ can make it run faster by disabling development specific checks such as the dual change detection cycles.
When you enable production builds via `--prod` command line flag, the runtime production mode is enabled as well.
Building for production (or appending the `--environment=prod` flag) enables _production mode_
Look at the CLI-generated `main.ts` to see how this works.
{@a lazy-loading}
@ -224,24 +102,22 @@ Configure the Angular Router to defer loading of all other modules (and their as
or by [_lazy loading_](guide/router#asynchronous-routing "Lazy loading")
them on demand.
<div class="alert is-helpful>
#### Don't eagerly import something from a lazy loaded module
#### Don't eagerly import something from a lazy-loaded module
If you mean to lazy-load a module, be careful not import it
in a file that's eagerly loaded when the app starts (such as the root `AppModule`).
It's a common mistake.
You've arranged to lazy load a module.
But you unintentionally import it, with a JavaScript `import` statement,
in a file that's eagerly loaded when the app starts, a file such as the root `AppModule`.
If you do that, the module will be loaded immediately.
The bundling configuration must take lazy loading into consideration.
Because lazy-loaded modules aren't imported in JavaScript, bundlers exclude them by default.
Bundlers don't know about the router configuration and can't create separate bundles for lazy-loaded modules.
You would have to create these bundles manually.
Because lazy loaded modules aren't imported in JavaScript (as just noted), bundlers exclude them by default.
Bundlers don't know about the router configuration and won't create separate bundles for lazy loaded modules.
You have to create these bundles manually.
The CLI runs the
[Angular Ahead-of-Time Webpack Plugin](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack)
which automatically recognizes lazy-loaded `NgModules` and creates separate bundles for them.
</div>
which automatically recognizes lazy loaded `NgModules` and creates separate bundles for them.
{@a measure}
@ -327,12 +203,17 @@ the subfolder is `my/app/` and you should add `<base href="/my/app/">` to the se
When the `base` tag is mis-configured, the app fails to load and the browser console displays `404 - Not Found` errors
for the missing files. Look at where it _tried_ to find those files and adjust the base tag appropriately.
## Building and serving for deployment
## _build_ vs. _serve_
When you are designing and developing applications, you typically use `ng serve` to build your app for fast, local, iterative development.
When you are ready to deploy, however, you must use the `ng build` command to build the app and deploy the build artifacts elsewhere.
You'll probably prefer `ng build` for deployments.
Both `ng build` and `ng serve` clear the output folder before they build the project, but only the `ng build` command writes the generated build artifacts to the output folder.
The **ng build** command is intended for building the app and deploying the build artifacts elsewhere.
The **ng serve** command is intended for fast, local, iterative development.
Both `ng build` and `ng serve` **clear the output folder** before they build the project.
The `ng build` command writes generated build artifacts to the output folder.
The `ng serve` command does not.
It serves build artifacts from memory instead for a faster development experience.
<div class="alert is-helpful">
@ -341,13 +222,160 @@ To output to a different folder, change the `outputPath` in `angular.json`.
</div>
The `ng serve` command builds, watches, and serves the application from local memory, using a local development server.
When you have deployed your app to another server, however, you might still want to serve the app so that you can continue to see changes that you make in it.
You can do this by adding the `--watch` option to the `ng build` command.
The `ng serve` command builds, watches, and serves the application from a local CLI development server.
```
ng build --watch
```
Like the `ng serve` command, this regenerates output files when source files change.
The `ng build` command generates output files just once and does not serve them.
The `ng build --watch` command will regenerate output files when source files change.
This `--watch` flag is useful if you're building during development and
are automatically re-deploying changes to another server.
For complete details of the CLI commands, see the [CLI command reference](cli).
See the [CLI `build` topic](https://github.com/angular/angular-cli/wiki/build) for more details and options.
<hr>
{@a server-configuration}
## Server configuration
This section covers changes you may have make to the server or to files deployed to the server.
{@a fallback}
### Routed apps must fallback to `index.html`
Angular apps are perfect candidates for serving with a simple static HTML server.
You don't need a server-side engine to dynamically compose application pages because
Angular does that on the client-side.
If the app uses the Angular router, you must configure the server
to return the application's host page (`index.html`) when asked for a file that it does not have.
{@a deep-link}
A routed application should support "deep links".
A _deep link_ is a URL that specifies a path to a component inside the app.
For example, `http://www.mysite.com/heroes/42` is a _deep link_ to the hero detail page
that displays the hero with `id: 42`.
There is no issue when the user navigates to that URL from within a running client.
The Angular router interprets the URL and routes to that page and hero.
But clicking a link in an email, entering it in the browser address bar,
or merely refreshing the browser while on the hero detail page &mdash;
all of these actions are handled by the browser itself, _outside_ the running application.
The browser makes a direct request to the server for that URL, bypassing the router.
A static server routinely returns `index.html` when it receives a request for `http://www.mysite.com/`.
But it rejects `http://www.mysite.com/heroes/42` and returns a `404 - Not Found` error *unless* it is
configured to return `index.html` instead.
#### Fallback configuration examples
There is no single configuration that works for every server.
The following sections describe configurations for some of the most popular servers.
The list is by no means exhaustive, but should provide you with a good starting point.
#### Development servers
* [Lite-Server](https://github.com/johnpapa/lite-server): the default dev server installed with the
[Quickstart repo](https://github.com/angular/quickstart) is pre-configured to fallback to `index.html`.
* [Webpack-Dev-Server](https://github.com/webpack/webpack-dev-server): setup the
`historyApiFallback` entry in the dev server options as follows:
<code-example>
historyApiFallback: {
disableDotRule: true,
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
}
</code-example>
#### Production servers
* [Apache](https://httpd.apache.org/): add a
[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to the `.htaccess` file as shown
(https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):
<code-example format=".">
RewriteEngine On
&#35 If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
&#35 If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
</code-example>
* [NGinx](http://nginx.org/): use `try_files`, as described in
[Front Controller Pattern Web Apps](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#front-controller-pattern-web-apps),
modified to serve `index.html`:
<code-example format=".">
try_files $uri $uri/ /index.html;
</code-example>
* [IIS](https://www.iis.net/): add a rewrite rule to `web.config`, similar to the one shown
[here](http://stackoverflow.com/a/26152011/2116927):
<code-example format='.'>
&lt;system.webServer&gt;
&lt;rewrite&gt;
&lt;rules&gt;
&lt;rule name="Angular Routes" stopProcessing="true"&gt;
&lt;match url=".*" /&gt;
&lt;conditions logicalGrouping="MatchAll"&gt;
&lt;add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&gt;
&lt;add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /&gt;
&lt;/conditions&gt;
&lt;action type="Rewrite" url="/index.html" /&gt;
&lt;/rule&gt;
&lt;/rules&gt;
&lt;/rewrite&gt;
&lt;/system.webServer&gt;
</code-example>
* [GitHub Pages](https://pages.github.com/): you can't
[directly configure](https://github.com/isaacs/github/issues/408)
the GitHub Pages server, but you can add a 404 page.
Copy `index.html` into `404.html`.
It will still be served as the 404 response, but the browser will process that page and load the app properly.
It's also a good idea to
[serve from `docs/` on master](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch)
and to
[create a `.nojekyll` file](https://www.bennadel.com/blog/3181-including-node-modules-and-vendors-folders-in-your-github-pages-site.htm)
* [Firebase hosting](https://firebase.google.com/docs/hosting/): add a
[rewrite rule](https://firebase.google.com/docs/hosting/url-redirects-rewrites#section-rewrites).
<code-example format=".">
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
</code-example>
{@a cors}
### Requesting services from a different server (CORS)
Angular developers may encounter a
<a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing" title="Cross-origin resource sharing">
<i>cross-origin resource sharing</i></a> error when making a service request (typically a data service request)
to a server other than the application's own host server.
Browsers forbid such requests unless the server permits them explicitly.
There isn't anything the client application can do about these errors.
The server must be configured to accept the application's requests.
Read about how to enable CORS for specific servers at
<a href="http://enable-cors.org/server.html" title="Enabling CORS server">enable-cors.org</a>.

View File

@ -42,7 +42,7 @@ changing the template and the body of the component.
When you're done, it should look like this:
<code-example path="displaying-data/src/app/app.component.1.ts" header="src/app/app.component.ts">
<code-example path="displaying-data/src/app/app.component.1.ts" title="src/app/app.component.ts">
</code-example>
@ -54,7 +54,7 @@ The template displays the two component properties using double curly brace
interpolation:
<code-example path="displaying-data/src/app/app.component.1.ts" linenums="false" header="src/app/app.component.ts (template)" region="template">
<code-example path="displaying-data/src/app/app.component.1.ts" linenums="false" title="src/app/app.component.ts (template)" region="template">
</code-example>
@ -98,7 +98,7 @@ The CSS `selector` in the `@Component` decorator specifies an element named `<ap
That element is a placeholder in the body of your `index.html` file:
<code-example path="displaying-data/src/index.html" linenums="false" header="src/index.html (body)" region="body">
<code-example path="displaying-data/src/index.html" linenums="false" title="src/index.html (body)" region="body">
</code-example>
@ -135,7 +135,7 @@ In either style, the template data bindings have the same access to the componen
<div class="alert is-helpful">
By default, the Angular CLI command [`ng generate component`](cli/generate) generates components with a template file. You can override that with:
By default, the Angular CLI generates components with a template file. You can override that with:
<code-example hideCopy language="sh" class="code-shell">
ng generate component hero -it
@ -164,7 +164,7 @@ This app uses more terse "variable assignment" style simply for brevity.
To display a list of heroes, begin by adding an array of hero names to the component and redefine `myHero` to be the first name in the array.
<code-example path="displaying-data/src/app/app.component.2.ts" linenums="false" header="src/app/app.component.ts (class)" region="class">
<code-example path="displaying-data/src/app/app.component.2.ts" linenums="false" title="src/app/app.component.ts (class)" region="class">
</code-example>
@ -174,7 +174,7 @@ Now use the Angular `ngFor` directive in the template to display
each item in the `heroes` list.
<code-example path="displaying-data/src/app/app.component.2.ts" linenums="false" header="src/app/app.component.ts (template)" region="template">
<code-example path="displaying-data/src/app/app.component.2.ts" linenums="false" title="src/app/app.component.ts (template)" region="template">
</code-example>
@ -185,7 +185,7 @@ in the `<li>` element is the Angular "repeater" directive.
It marks that `<li>` element (and its children) as the "repeater template":
<code-example path="displaying-data/src/app/app.component.2.ts" linenums="false" header="src/app/app.component.ts (li)" region="li">
<code-example path="displaying-data/src/app/app.component.2.ts" linenums="false" title="src/app/app.component.ts (li)" region="li">
</code-example>
@ -252,7 +252,7 @@ of hero names into an array of `Hero` objects. For that you'll need a `Hero` cla
With the following code:
<code-example path="displaying-data/src/app/hero.ts" linenums="false" header="src/app/hero.ts">
<code-example path="displaying-data/src/app/hero.ts" linenums="false" title="src/app/hero.ts">
</code-example>
@ -266,7 +266,7 @@ The declaration of the constructor parameters takes advantage of a TypeScript sh
Consider the first parameter:
<code-example path="displaying-data/src/app/hero.ts" linenums="false" header="src/app/hero.ts (id)" region="id">
<code-example path="displaying-data/src/app/hero.ts" linenums="false" title="src/app/hero.ts (id)" region="id">
</code-example>
@ -286,7 +286,7 @@ After importing the `Hero` class, the `AppComponent.heroes` property can return
of `Hero` objects:
<code-example path="displaying-data/src/app/app.component.3.ts" linenums="false" header="src/app/app.component.ts (heroes)" region="heroes">
<code-example path="displaying-data/src/app/app.component.3.ts" linenums="false" title="src/app/app.component.ts (heroes)" region="heroes">
</code-example>
@ -297,7 +297,7 @@ At the moment it displays the hero's `id` and `name`.
Fix that to display only the hero's `name` property.
<code-example path="displaying-data/src/app/app.component.3.ts" linenums="false" header="src/app/app.component.ts (template)" region="template">
<code-example path="displaying-data/src/app/app.component.3.ts" linenums="false" title="src/app/app.component.ts (template)" region="template">
</code-example>
@ -317,7 +317,7 @@ The Angular `ngIf` directive inserts or removes an element based on a _truthy/fa
To see it in action, add the following paragraph at the bottom of the template:
<code-example path="displaying-data/src/app/app.component.ts" linenums="false" header="src/app/app.component.ts (message)" region="message">
<code-example path="displaying-data/src/app/app.component.ts" linenums="false" title="src/app/app.component.ts (message)" region="message">
</code-example>
@ -357,7 +357,7 @@ big chunks of HTML with many data bindings.
Try it out. Because the array has four items, the message should appear.
Go back into <code>app.component.ts</code> and delete or comment out one of the elements from the hero array.
Go back into <code>app.component.ts"</code> and delete or comment out one of the elements from the hero array.
The browser should refresh automatically and the message should disappear.
@ -375,19 +375,19 @@ Here's the final code:
<code-tabs>
<code-pane header="src/app/app.component.ts" path="displaying-data/src/app/app.component.ts" region="final">
<code-pane title="src/app/app.component.ts" path="displaying-data/src/app/app.component.ts" region="final">
</code-pane>
<code-pane header="src/app/hero.ts" path="displaying-data/src/app/hero.ts">
<code-pane title="src/app/hero.ts" path="displaying-data/src/app/hero.ts">
</code-pane>
<code-pane header="src/app/app.module.ts" path="displaying-data/src/app/app.module.ts">
<code-pane title="src/app/app.module.ts" path="displaying-data/src/app/app.module.ts">
</code-pane>
<code-pane header="main.ts" path="displaying-data/src/main.ts">
<code-pane title="main.ts" path="displaying-data/src/main.ts">
</code-pane>

View File

@ -310,22 +310,22 @@ _This_ "Authors Doc Style Guide" has its own sample application, located in the
The following _code-example_ displays the sample's `app.module.ts`.
<code-example path="docs-style-guide/src/app/app.module.ts" header="src/app/app.module.ts"></code-example>
<code-example path="docs-style-guide/src/app/app.module.ts" title="src/app/app.module.ts"></code-example>
Here's the brief markup that produced that lengthy snippet:
```html
<code-example
path="docs-style-guide/src/app/app.module.ts"
header="src/app/app.module.ts">
title="src/app/app.module.ts">
</code-example>
```
You identified the snippet's source file by setting the `path` attribute to sample folder's location _within_ `content/examples`.
In this example, that path is `docs-style-guide/src/app/app.module.ts`.
You added a header to tell the reader where to find the file by setting the `header` attribute.
Following convention, you set the `header` attribute to the file's location within the sample's root folder.
You added a header to tell the reader where to find the file by setting the `title` attribute.
Following convention, you set the `title` attribute to the file's location within the sample's root folder.
<div class="alert is-helpful">
@ -343,7 +343,7 @@ If you want to include an ignored code file in your project and display it in a
The preferred way to un-ignore a file is to update the `content/examples/.gitignore` like this:
<code-example header="content/examples/.gitignore">
<code-example title="content/examples/.gitignore">
# my-guide
!my-guide/src/something.js
!my-guide/more-javascript*.js
@ -357,7 +357,7 @@ You control the _code-example_ output by setting one or more of its attributes:
* `path`- the path to the file in the `content/examples` folder.
* `header`- the header of the code listing.
* `title`- the header of the code listing.
* `region`- displays the source file fragment with that region name; regions are identified by _docregion_ markup in the source file, as explained [below](#region "Displaying a code fragment").
@ -395,7 +395,7 @@ A couple of observations:
1. The `region` value, `"class"`, is the name of the `#docregion` in the source file. Confirm that by looking at `content/examples/docs-style-guide/src/app/app.module.ts`
1. Omitting the `header` is fine when the source of the fragment is obvious. We just said that this is a fragment of the `app.module.ts` file which was displayed immediately above, in full, with a header.
1. Omitting the `title` is fine when the source of the fragment is obvious. We just said that this is a fragment of the `app.module.ts` file which was displayed immediately above, in full, with a header.
There's no need to repeat the header.
1. The line numbers disappeared. By default, the doc viewer omits line numbers when there are fewer than 10 lines of code; it adds line numbers after that. You can turn line numbers on or off explicitly by setting the `linenums` attribute.
@ -415,11 +415,11 @@ Here's the markup for an "avoid" example in the
<code-example
path="styleguide/src/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts"
region="example"
header="app/heroes/hero-button/hero-button.component.ts">
title="app/heroes/hero-button/hero-button.component.ts">
</code-example>
```
<code-example path="styleguide/src/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" header="app/heroes/hero-button/hero-button.component.ts">
<code-example path="styleguide/src/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" title="app/heroes/hero-button/hero-button.component.ts">
</code-example>
{@a code-tabs}
@ -434,29 +434,29 @@ Code tabs display code much like _code examples_ do. The added advantage is tha
#### Code-pane attributes
* `path` - a file in the content/examples folder
* `header` - seen in the header of a tab
* `title` - seen in the header of a tab
* `linenums` - overrides the `linenums` property at the `code-tabs` level for this particular pane. The value can be `true`, `false` or a number indicating the starting line number. If not specified, line numbers are enabled only when the number of lines of code are greater than 10.
The next example displays multiple code tabs, each with its own header.
The next example displays multiple code tabs, each with its own title.
It demonstrates control over display of line numbers at both the `<code-tabs>` and `<code-pane>` levels.
<code-tabs linenums="false">
<code-pane
header="app.component.html"
title="app.component.html"
path="docs-style-guide/src/app/app.component.html">
</code-pane>
<code-pane
header="app.component.ts"
title="app.component.ts"
path="docs-style-guide/src/app/app.component.ts"
linenums="true">
</code-pane>
<code-pane
header="app.component.css (heroes)"
title="app.component.css (heroes)"
path="docs-style-guide/src/app/app.component.css"
region="heroes">
</code-pane>
<code-pane
header="package.json (scripts)"
title="package.json (scripts)"
path="docs-style-guide/package.1.json">
</code-pane>
</code-tabs>
@ -469,21 +469,21 @@ The `linenums` attribute in the second pane restores line numbering for _itself
```html
<code-tabs linenums="false">
<code-pane
header="app.component.html"
title="app.component.html"
path="docs-style-guide/src/app/app.component.html">
</code-pane>
<code-pane
header="app.component.ts"
title="app.component.ts"
path="docs-style-guide/src/app/app.component.ts"
linenums="true">
</code-pane>
<code-pane
header="app.component.css (heroes)"
title="app.component.css (heroes)"
path="docs-style-guide/src/app/app.component.css"
region="heroes">
</code-pane>
<code-pane
header="package.json (scripts)"
title="package.json (scripts)"
path="docs-style-guide/package.1.json">
</code-pane>
</code-tabs>
@ -548,7 +548,7 @@ The `src/main.ts` is a simple example of a file with a single _#docregion_ at th
<code-example
path="docs-style-guide/src/main.ts"
header="src/main.ts"></code-example>
title="src/main.ts"></code-example>
</div>
@ -622,12 +622,12 @@ Here's are the two corresponding code snippets displayed side-by-side.
<code-tabs>
<code-pane
header="app.component.ts (class)"
title="app.component.ts (class)"
path="docs-style-guide/src/app/app.component.ts"
region="class">
</code-pane>
<code-pane
header="app.component.ts (class-skeleton)"
title="app.component.ts (class-skeleton)"
path="docs-style-guide/src/app/app.component.ts"
region="class-skeleton">
</code-pane>
@ -660,12 +660,12 @@ Here's an example that excerpts certain scripts from `package.json` into a parti
<code-example
path="docs-style-guide/package.1.json"
header="package.json (selected scripts)"></code-example>
title="package.json (selected scripts)"></code-example>
```html
<code-example
path="docs-style-guide/package.1.json"
header="package.json (selected scripts)"></code-example>
title="package.json (selected scripts)"></code-example>
```
#### Partial file naming
@ -689,7 +689,7 @@ Remember to exclude these files from stackblitz by listing them in the `stackbli
<code-example
path="docs-style-guide/stackblitz.json"
header="stackblitz.json"></code-example>
title="stackblitz.json"></code-example>
{@a live-examples}
## Live examples

View File

@ -35,7 +35,7 @@ The ad banner uses a helper directive called `AdDirective` to
mark valid insertion points in the template.
<code-example path="dynamic-component-loader/src/app/ad.directive.ts" header="src/app/ad.directive.ts" linenums="false">
<code-example path="dynamic-component-loader/src/app/ad.directive.ts" title="src/app/ad.directive.ts" linenums="false">
</code-example>
@ -62,7 +62,7 @@ To apply the `AdDirective`, recall the selector from `ad.directive.ts`,
where to dynamically load components.
<code-example path="dynamic-component-loader/src/app/ad-banner.component.ts" region="ad-host" header="src/app/ad-banner.component.ts (template)" linenums="false">
<code-example path="dynamic-component-loader/src/app/ad-banner.component.ts" region="ad-host" title="src/app/ad-banner.component.ts (template)" linenums="false">
</code-example>
@ -91,7 +91,7 @@ With its `getAds()` method, `AdBannerComponent` cycles through the array of `AdI
and loads a new component every 3 seconds by calling `loadComponent()`.
<code-example path="dynamic-component-loader/src/app/ad-banner.component.ts" region="class" header="src/app/ad-banner.component.ts (excerpt)" linenums="false">
<code-example path="dynamic-component-loader/src/app/ad-banner.component.ts" region="class" title="src/app/ad-banner.component.ts (excerpt)" linenums="false">
</code-example>
@ -150,7 +150,7 @@ dynamically loaded components since they load at runtime.
To ensure that the compiler still generates a factory,
add dynamically loaded components to the `NgModule`'s `entryComponents` array:
<code-example path="dynamic-component-loader/src/app/app.module.ts" region="entry-components" header="src/app/app.module.ts (entry components)" linenums="false">
<code-example path="dynamic-component-loader/src/app/app.module.ts" region="entry-components" title="src/app/app.module.ts (entry components)" linenums="false">
</code-example>
@ -169,15 +169,15 @@ Here are two sample components and the `AdComponent` interface for reference:
<code-tabs>
<code-pane header="hero-job-ad.component.ts" path="dynamic-component-loader/src/app/hero-job-ad.component.ts">
<code-pane title="hero-job-ad.component.ts" path="dynamic-component-loader/src/app/hero-job-ad.component.ts">
</code-pane>
<code-pane header="hero-profile.component.ts" path="dynamic-component-loader/src/app/hero-profile.component.ts">
<code-pane title="hero-profile.component.ts" path="dynamic-component-loader/src/app/hero-profile.component.ts">
</code-pane>
<code-pane header="ad.component.ts" path="dynamic-component-loader/src/app/ad.component.ts">
<code-pane title="ad.component.ts" path="dynamic-component-loader/src/app/ad.component.ts">
</code-pane>

View File

@ -40,11 +40,11 @@ Bootstrap the `AppModule` in `main.ts`.
<code-tabs>
<code-pane header="app.module.ts" path="dynamic-form/src/app/app.module.ts">
<code-pane title="app.module.ts" path="dynamic-form/src/app/app.module.ts">
</code-pane>
<code-pane header="main.ts" path="dynamic-form/src/main.ts">
<code-pane title="main.ts" path="dynamic-form/src/main.ts">
</code-pane>
@ -62,7 +62,7 @@ The _question_ is the most fundamental object in the model.
The following `QuestionBase` is a fundamental question class.
<code-example path="dynamic-form/src/app/question-base.ts" header="src/app/question-base.ts">
<code-example path="dynamic-form/src/app/question-base.ts" title="src/app/question-base.ts">
</code-example>
@ -77,7 +77,7 @@ appropriate controls dynamically.
via the `type` property.
<code-example path="dynamic-form/src/app/question-textbox.ts" header="src/app/question-textbox.ts" linenums="false">
<code-example path="dynamic-form/src/app/question-textbox.ts" title="src/app/question-textbox.ts" linenums="false">
</code-example>
@ -86,7 +86,7 @@ via the `type` property.
`DropdownQuestion` presents a list of choices in a select box.
<code-example path="dynamic-form/src/app/question-dropdown.ts" header="src/app/question-dropdown.ts" linenums="false">
<code-example path="dynamic-form/src/app/question-dropdown.ts" title="src/app/question-dropdown.ts" linenums="false">
</code-example>
@ -97,7 +97,7 @@ In a nutshell, the form group consumes the metadata from the question model and
allows you to specify default values and validation rules.
<code-example path="dynamic-form/src/app/question-control.service.ts" header="src/app/question-control.service.ts" linenums="false">
<code-example path="dynamic-form/src/app/question-control.service.ts" title="src/app/question-control.service.ts" linenums="false">
</code-example>
@ -112,11 +112,11 @@ to create components to represent the dynamic form.
<code-tabs>
<code-pane header="dynamic-form.component.html" path="dynamic-form/src/app/dynamic-form.component.html">
<code-pane title="dynamic-form.component.html" path="dynamic-form/src/app/dynamic-form.component.html">
</code-pane>
<code-pane header="dynamic-form.component.ts" path="dynamic-form/src/app/dynamic-form.component.ts">
<code-pane title="dynamic-form.component.ts" path="dynamic-form/src/app/dynamic-form.component.ts">
</code-pane>
@ -132,11 +132,11 @@ question based on values in the data-bound question object.
<code-tabs>
<code-pane header="dynamic-form-question.component.html" path="dynamic-form/src/app/dynamic-form-question.component.html">
<code-pane title="dynamic-form-question.component.html" path="dynamic-form/src/app/dynamic-form-question.component.html">
</code-pane>
<code-pane header="dynamic-form-question.component.ts" path="dynamic-form/src/app/dynamic-form-question.component.ts">
<code-pane title="dynamic-form-question.component.ts" path="dynamic-form/src/app/dynamic-form-question.component.ts">
</code-pane>
@ -169,7 +169,7 @@ directly since you imported `ReactiveFormsModule` from `AppModule`.
and removing objects from the `questions` array.
<code-example path="dynamic-form/src/app/question.service.ts" header="src/app/question.service.ts">
<code-example path="dynamic-form/src/app/question.service.ts" title="src/app/question.service.ts">
</code-example>
@ -178,7 +178,7 @@ directly since you imported `ReactiveFormsModule` from `AppModule`.
Finally, display an instance of the form in the `AppComponent` shell.
<code-example path="dynamic-form/src/app/app.component.ts" header="app.component.ts">
<code-example path="dynamic-form/src/app/app.component.ts" title="app.component.ts">
</code-example>

View File

@ -107,7 +107,7 @@ The recently-developed [custom elements](https://developer.mozilla.org/en-US/doc
</tr>
<tr>
<td>Firefox</td>
<td>Supported natively as of version 63. In older versions: Set the <code>dom.webcomponents.enabled</code> and <code>dom.webcomponents.customelements.enabled</code> preferences to true.</td>
<td> Set the <code>dom.webcomponents.enabled</code> and <code>dom.webcomponents.customelements.enabled</code> preferences to true. Planned to be enabled by default in version 63.</td>
</tr>
<tr>
<td>Edge</td>
@ -119,7 +119,7 @@ The recently-developed [custom elements](https://developer.mozilla.org/en-US/doc
In browsers that support Custom Elements natively, the specification requires developers use ES2015 classes to define Custom Elements - developers can opt-in to this by setting the `target: "es2015"` property in their project's `tsconfig.json`. As Custom Element and ES2015 support may not be available in all browsers, developers can instead choose to use a polyfill to support older browsers and ES5 code.
Use the [Angular CLI](cli) to automatically set up your project with the correct polyfill: `ng add @angular/elements --name=*your_project_name*`.
Use the [Angular CLI](https://cli.angular.io/) to automatically set up your project with the correct polyfill: `ng add @angular/elements --name=*your_project_name*`.
- For more information about polyfills, see [polyfill documentation](https://www.webcomponents.org/polyfills).
- For more information about Angular browser support, see [Browser Support](guide/browser-support).
@ -142,19 +142,19 @@ For comparison, the demo shows both methods. One button adds the popup using the
<code-tabs>
<code-pane header="popup.component.ts" path="elements/src/app/popup.component.ts">
<code-pane title="popup.component.ts" path="elements/src/app/popup.component.ts">
</code-pane>
<code-pane header="popup.service.ts" path="elements/src/app/popup.service.ts">
<code-pane title="popup.service.ts" path="elements/src/app/popup.service.ts">
</code-pane>
<code-pane header="app.module.ts" path="elements/src/app/app.module.ts">
<code-pane title="app.module.ts" path="elements/src/app/app.module.ts">
</code-pane>
<code-pane header="app.component.ts" path="elements/src/app/app.component.ts">
<code-pane title="app.component.ts" path="elements/src/app/app.component.ts">
</code-pane>
</code-tabs>

View File

@ -33,7 +33,7 @@ pipes that it shares.
## How to make a feature module
Assuming you already have an app that you created with the [Angular CLI](cli), create a feature
Assuming you already have a CLI generated app, create a feature
module using the CLI by entering the following command in the
root project directory. Replace `CustomerDashboard` with the
name of your module. You can omit the "Module" suffix from the name because the CLI appends it:
@ -72,7 +72,7 @@ ng generate component customer-dashboard/CustomerDashboard
This generates a folder for the new component within the customer-dashboard folder and updates the feature module with the `CustomerDashboardComponent` info:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" header="src/app/customer-dashboard/customer-dashboard.module.ts" linenums="false">
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" title="src/app/customer-dashboard/customer-dashboard.module.ts" linenums="false">
</code-example>
@ -83,7 +83,7 @@ The `CustomerDashboardComponent` is now in the JavaScript import list at the top
To incorporate the feature module into your app, you have to let the root module, `app.module.ts`, know about it. Notice the `CustomerDashboardModule` export at the bottom of `customer-dashboard.module.ts`. This exposes it so that other modules can get to it. To import it into the `AppModule`, add it to the imports in `app.module.ts` and to the `imports` array:
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts" linenums="false">
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" title="src/app/app.module.ts" linenums="false">
</code-example>
@ -94,20 +94,20 @@ Now the `AppModule` knows about the feature module. If you were to add any servi
When the CLI generated the `CustomerDashboardComponent` for the feature module, it included a template, `customer-dashboard.component.html`, with the following markup:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" region="feature-template" header="src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" linenums="false">
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" region="feature-template" title="src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" linenums="false">
</code-example>
To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardComponent`:
To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardModule`:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts" linenums="false">
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" title="src/app/customer-dashboard/customer-dashboard.module.ts" linenums="false">
</code-example>
Next, in the `AppComponent`, `app.component.html`, add the tag `<app-customer-dashboard>`:
<code-example path="feature-modules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html" linenums="false">
<code-example path="feature-modules/src/app/app.component.html" region="app-component-template" title="src/app/app.component.html" linenums="false">
</code-example>

View File

@ -1,113 +0,0 @@
# Workspace and project file structure
You develop apps in the context of an Angular [workspace](guide/glossary#workspace). A workspace contains the files for one or more [projects](guide/glossary#project). A project is the set of files that comprise a standalone app, a library, or a set of end-to-end (e2e) tests.
The Angular CLI command `ng new <project_name>` gets you started.
When you run this command, the CLI installs the necessary Angular npm packages and other dependencies in a new workspace, with a root folder named *project_name*.
It also creates the following workspace and starter project files:
* An initial skeleton app project, also called *project_name* (in the `src/` subfolder).
* An end-to-end test project (in the `e2e/` subfolder).
* Related configuration files.
The initial app project contains a simple Welcome app, ready to run.
## Workspace files
The top level of the workspace contains a number of workspace-wide configuration files.
| WORKSPACE CONFIG FILES | PURPOSE |
| :--------------------- | :------------------------------------------|
| `.editorconfig` | Configuration for code editors. See [EditorConfig](https://editorconfig.org/). |
| `.gitignore` | Specifies intentionally untracked files that [Git](https://git-scm.com/) should ignore. |
| `angular.json` | CLI configuration defaults for all projects in the workspace, including configuration options for build, serve, and test tools that the CLI uses, such as [TSLint](https://palantir.github.io/tslint/), [Karma](https://karma-runner.github.io/), and [Protractor](http://www.protractortest.org/). For details, see [Angular Workspace Configuration](guide/workspace-config). |
| `node_modules` | Provides [npm packages](guide/npm-packages) to the entire workspace. |
| `package.json` | Configures [npm package dependencies](guide/npm-packages) that are available to all projects in the workspace. See [npm documentation](https://docs.npmjs.com/files/package.json) for the specific format and contents of this file. |
| `package-lock.json` | Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. |
| `tsconfig.json` | Default [TypeScript](https://www.typescriptlang.org/) configuration for apps in the workspace, including TypeScript and Angular template compiler options. See [TypeScript Configuration](guide/typescript-configuration). |
| `tslint.json` | Default [TSLint](https://palantir.github.io/tslint/) configuration for apps in the workspace. |
| `README.md` | Introductory documentation. |
All projects within a workspace share a [CLI configuration context](guide/workspace-config).
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.*.json`, and app-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
### Default app project files
The CLI command `ng new my-app` creates a workspace folder named "my-app" and generates a new app skeleton.
This initial app is the *default app* for CLI commands (unless you change the default after creating additional apps).
A newly generated app contains the source files for a root module, with a root component and template.
When the workspace file structure is in place, you can use the `ng generate` command on the command line to add functionality and data to the initial app.
<div class="alert is-helpful">
Besides using the CLI on the command line, you can also use an interactive development environment like [Angular Console](https://angularconsole.com/), or manipulate files directly in the app's source folder and configuration files.
</div>
The `src/` subfolder contains the source files (app logic, data, and assets), along with configuration files for the initial app.
Workspace-wide `node_modules` dependencies are visible to this project.
| APP SOURCE & CONFIG FILES | PURPOSE |
| :--------------------- | :------------------------------------------|
| `app/` | Contains the component files in which your app logic and data are defined. See details in [App source folder](#app-src) below. |
| `assets/` | Contains image files and other asset files to be copied as-is when you build your application. |
| `environments/` | Contains build configuration options for particular target environments. By default there is an unnamed standard development environment and a production ("prod") environment. You can define additional target environment configurations. |
| `browserlist` | Configures sharing of target browsers and Node.js versions among various front-end tools. See [Browserlist on GitHub](https://github.com/browserslist/browserslist) for more information. |
| `favicon.ico` | An icon to use for this app in the bookmark bar. |
| `index.html` | The main HTML page that is served when someone visits your site. The CLI automatically adds all JavaScript and CSS files when building your app, so you typically don't need to add any `<script>` or` <link>` tags here manually. |
| `main.ts` | The main entry point for your app. Compiles the application with the [JIT compiler](https://angular.io/guide/glossary#jit) and bootstraps the application's root module (AppModule) to run in the browser. You can also use the [AOT compiler](https://angular.io/guide/aot-compiler) without changing any code by appending the `--aot` flag to the CLI `build` and `serve` commands. |
| `polyfills.ts` | Provides polyfill scripts for browser support. |
| `styles.sass` | Lists CSS files that supply styles for a project. The extension reflects the style preprocessor you have configured for the project. |
| `test.ts` | The main entry point for your unit tests, with some Angular-specific configuration. You don't typically need to edit this file. |
| `tsconfig.app.json` | Inherits from the workspace-wide `tsconfig.json` file. |
| `tsconfig.spec.json` | Inherits from the workspace-wide `tsconfig.json` file. |
| `tslint.json` | Inherits from the workspace-wide `tslint.json` file. |
### Default app project e2e files
An `e2e/` subfolder contains configuration and source files for a set of end-to-end tests that correspond to the initial app.
Workspace-wide `node_modules` dependencies are visible to this project.
<code-example language="none" linenums="false">
my-app/
e2e/ (end-to-end test app for my-app)
src/ (app source files)
protractor.conf.js (test-tool config)
tsconfig.e2e.json (TypeScript config inherits from workspace tsconfig.json)
</code-example>
### Project folders for additional apps and libraries
When you generate new projects in a workspace,
the CLI creates a new *workspace*`/projects` folder, and adds the generated files there.
When you generate an app (`ng generate application my-other-app`), the CLI adds folders under `projects/` for both the app and its corresponding end-to-end tests. Newly generated libraries are also added under `projects/`.
<code-example language="none" linenums="false">
my-app/
...
projects/ (additional apps and libs)
my-other-app/ (a second app)
src/
(config files)
my-other-app-e2e/ (corresponding test app)
src/
(config files)
my-lib/ (a generated library)
(config files)
</code-example>
{@a app-src}
## App source folder
Inside the `src/` folder, the `app/` folder contains your app's logic and data. Angular components, templates, and styles go here. An `assets/` subfolder contains images and anything else your app needs. Files at the top level of `src/` support testing and running your app.
| APP SOURCE FILES | PURPOSE |
| :-------------------------- | :------------------------------------------|
| `app/app.component.ts` | Defines the logic for the app's root component, named `AppComponent`. The view associated with this root component becomes the root of the [view hierarchy](guide/glossary#view-hierarchy) as you add components and services to your app. |
| `app/app.component.html` | Defines the HTML template associated with the root `AppComponent`. |
| `app/app.component.css` | Defines the base CSS stylesheet for the root `AppComponent`. |
| `app/app.component.spec.ts` | Defines a unit test for the root `AppComponent`. |
| `app/app.module.ts` | Defines the root module, named `AppModule`, that tells Angular how to assemble the application. Initially declares only the `AppComponent`. As you add more components to the app, they must be declared here. |
| `assets/*` | Contains image files and other asset files to be copied as-is when you build your application. |

View File

@ -29,7 +29,7 @@ either a list of validation errors, which results in an INVALID status, or null,
You can then inspect the control's state by exporting `ngModel` to a local template variable.
The following example exports `NgModel` into a variable called `name`:
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="name-with-error-msg" header="template/hero-form-template.component.html (name)" linenums="false">
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="name-with-error-msg" title="template/hero-form-template.component.html (name)" linenums="false">
</code-example>
@ -92,7 +92,7 @@ built-in validators&mdash;this time, in function form. See below:
{@a reactive-component-class}
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="form-group" header="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="form-group" title="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
</code-example>
Note that:
@ -106,7 +106,7 @@ for the template.
If you look at the template for the name input again, it is fairly similar to the template-driven example.
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="name-with-error-msg" header="reactive/hero-form-reactive.component.html (name with error msg)" linenums="false">
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="name-with-error-msg" title="reactive/hero-form-reactive.component.html (name with error msg)" linenums="false">
</code-example>
Key takeaways:
@ -125,7 +125,7 @@ Consider the `forbiddenNameValidator` function from previous
[examples](guide/form-validation#reactive-component-class) in
this guide. Here's what the definition of that function looks like:
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="custom-validator" header="shared/forbidden-name.directive.ts (forbiddenNameValidator)" linenums="false">
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="custom-validator" title="shared/forbidden-name.directive.ts (forbiddenNameValidator)" linenums="false">
</code-example>
The function is actually a factory that takes a regular expression to detect a _specific_ forbidden name and returns a validator function.
@ -148,7 +148,7 @@ at which point the form uses the last value emitted for validation.
In reactive forms, custom validators are fairly simple to add. All you have to do is pass the function directly
to the `FormControl`.
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="custom-validator" header="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="custom-validator" title="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
</code-example>
### Adding to template-driven forms
@ -161,19 +161,19 @@ The corresponding `ForbiddenValidatorDirective` serves as a wrapper around the `
Angular recognizes the directive's role in the validation process because the directive registers itself
with the `NG_VALIDATORS` provider, a provider with an extensible collection of validators.
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="directive-providers" header="shared/forbidden-name.directive.ts (providers)" linenums="false">
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="directive-providers" title="shared/forbidden-name.directive.ts (providers)" linenums="false">
</code-example>
The directive class then implements the `Validator` interface, so that it can easily integrate
with Angular forms. Here is the rest of the directive to help you get an idea of how it all
comes together:
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="directive" header="shared/forbidden-name.directive.ts (directive)">
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="directive" title="shared/forbidden-name.directive.ts (directive)">
</code-example>
Once the `ForbiddenValidatorDirective` is ready, you can simply add its selector, `appForbiddenName`, to any input element to activate it. For example:
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="name-input" header="template/hero-form-template.component.html (forbidden-name-input)" linenums="false">
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="name-input" title="template/hero-form-template.component.html (forbidden-name-input)" linenums="false">
</code-example>
@ -204,7 +204,7 @@ Like in AngularJS, Angular automatically mirrors many control properties onto th
The hero form uses the `.ng-valid` and `.ng-invalid` classes to
set the color of each form control's border.
<code-example path="form-validation/src/assets/forms.css" header="forms.css (status classes)">
<code-example path="form-validation/src/assets/forms.css" title="forms.css (status classes)">
</code-example>
@ -245,7 +245,7 @@ const heroForm = new FormGroup({
The validator code is as follows:
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-validator" header="shared/identity-revealed.directive.ts" linenums="false">
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-validator" title="shared/identity-revealed.directive.ts" linenums="false">
</code-example>
The identity validator implements the `ValidatorFn` interface. It takes an Angular control object as an argument and returns either null if the form is valid, or `ValidationErrors` otherwise.
@ -255,7 +255,7 @@ First we retrieve the child controls by calling the `FormGroup`'s [get](api/form
If the values do not match, the hero's identity remains secret, and we can safely return null. Otherwise, the hero's identity is revealed and we must mark the form as invalid by returning an error object.
Next, to provide better user experience, we show an appropriate error message when the form is invalid.
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="cross-validation-error-message" header="reactive/hero-form-template.component.html" linenums="false">
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="cross-validation-error-message" title="reactive/hero-form-template.component.html" linenums="false">
</code-example>
Note that we check if:
@ -265,15 +265,15 @@ Note that we check if:
### Adding to template driven forms
First we must create a directive that will wrap the validator function. We provide it as the validator using the `NG_VALIDATORS` token. If you are not sure why, or you do not fully understand the syntax, revisit the previous [section](guide/form-validation#adding-to-template-driven-forms).
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-directive" header="shared/identity-revealed.directive.ts" linenums="false">
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-directive" title="shared/identity-revealed.directive.ts" linenums="false">
</code-example>
Next, we have to add the directive to the html template. Since the validator must be registered at the highest level in the form, we put the directive on the `form` tag.
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-register-validator" header="template/hero-form-template.component.html" linenums="false">
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-register-validator" title="template/hero-form-template.component.html" linenums="false">
</code-example>
To provide better user experience, we show an appropriate error message when the form is invalid.
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-error-message" header="template/hero-form-template.component.html" linenums="false">
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-error-message" title="template/hero-form-template.component.html" linenums="false">
</code-example>
Note that we check if:

View File

@ -1,21 +1,21 @@
# Introduction to forms in Angular
Handling user input with forms is the cornerstone of many common applications. Applications use forms to enable users to log in, to update a profile, to enter sensitive information, and to perform many other data-entry tasks.
Handling user input with forms is the cornerstone of many common applications. Applications use forms to enable users log in, to update a profile, to enter sensitive information, and to perform many other data-entry tasks.
Angular provides two different approaches to handling user input through forms: reactive and template-driven. Both capture user input events from the view, validate the user input, create a form model and data model to update, and provide a way to track changes.
Reactive and template-driven forms process and manage form data differently. Each offers different advantages.
Reactive and template-driven forms differ, however, in how they do the work of processing and managing forms and form data. Each offers different advantages.
**In general:**
* **Reactive forms** are more robust: they're more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms.
* **Template-driven forms** are useful for adding a simple form to an app, such as an email list signup form. They're easy to add to an app, but they don't scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, use template-driven forms.
* **Reactive forms** are more robust: they are more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms.
* **Template-driven forms** are useful for adding a simple form to an app, such as an email list signup form. They are easy to add to an app, but they do not scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, use template-driven forms.
This guide provides information to help you decide which type of form works best for your situation. It introduces the common building blocks used by both approaches. It also summarizes the key differences between the two approaches, and demonstrates those differences in the context of setup, data flow, and testing.
This guide provides information to help you decide which approach works best for your situation. It introduces the common building blocks used by both approaches. It also summarizes the key differences between the two approaches, and demonstrates those differences in the context of setup, data flow, and testing.
<div class="alert is-helpful">
<div class="alert is-important">
**Note:** For complete information about each kind of form, see [Reactive Forms](guide/reactive-forms) and [Template-driven Forms](guide/forms).
*Note:* For complete information about each kind of form, see the [Reactive Forms](guide/reactive-forms) and [Template-driven Forms](guide/forms) guides.
</div>
@ -30,7 +30,7 @@ The table below summarizes the key differences between reactive and template-dri
||Reactive|Template-driven|
|--- |--- |--- |
|Setup (form model)|More explicit, created in component class|Less explicit, created by directives|
|Setup (form model)|More explicit, created in the component class.|Less explicit, created by the directives.|
|Data model|Structured|Unstructured|
|Predictability|Synchronous|Asynchronous|
|Form validation|Functions|Directives|
@ -41,41 +41,35 @@ The table below summarizes the key differences between reactive and template-dri
Both reactive and template-driven forms share underlying building blocks.
- A `FormControl` instance that tracks the value and validation status of an individual form control.
- A `FormGroup` instance that tracks the same values and status for a collection of form controls.
- A `FormArray` instance that tracks the same values and status for an array of form controls.
- A `ControlValueAccessor` that creates a bridge between Angular `FormControl` instances and native DOM elements.
* `FormControl` tracks the value and validation status of an individual form control.
How these control instances are created and managed with reactive and template-driven forms is introduced in the [form model setup](#setup-the-form-model) section below and detailed further in the [data flow section](#data-flow-in-forms) of this guide.
* `FormGroup` tracks the same values and status for a collection of form controls.
## Setup: The form model
* `FormArray` tracks the same values and status for an array of form controls.
* `ControlValueAccessor` creates a bridge between Angular `FormControl` instances and native DOM elements.
See the [Form model setup](#setup-the-form-model) section below for an introduction to how these control instances are created and managed with reactive and template-driven forms. Further details are provided in the [data flow section](#data-flow-in-forms) of this guide.
{@a setup-the-form-model}
## Form model setup
Reactive and template-driven forms both use a form model to track value changes between Angular forms and form input elements. The examples below show how the form model is defined and created.
Reactive and template-driven forms both use a form model to track value changes between Angular forms and form input elements. The examples below show how the form model is defined and created.
### Setup in reactive forms
Here's a component with an input field for a single control implemented using reactive forms.
Here is a component with an input field for a single control implemented using reactive forms.
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.ts">
</code-example>
The source of truth provides the value and status of the form element at a given point in time. In reactive forms, the form model is the source of truth. In the example above, the form model is the `FormControl` instance.
The source of truth provides the value and status of the form element at a given point in time. In reactive forms, the form model is source of truth. The form model in the above example is the `FormControl` instance.
<figure>
<img src="generated/images/guide/forms-overview/key-diff-reactive-forms.png" alt="Reactive forms key differences">
</figure>
With reactive forms, the form model is explicitly defined in the component class. The reactive form directive (in this case, `FormControlDirective`) then links the existing `FormControl` instance to a specific form element in the view using a value accessor (`ControlValueAccessor` instance).
With reactive forms, the form model is explicitly defined in the component class. The reactive form directive (in this case, `FormControlDirective`) then links the existing form control instance to a specific form element in the view using a value accessor (instance of `ControlValueAccessor`).
### Setup in template-driven forms
Here's the same component with an input field for a single control implemented using template-driven forms.
Here is the same component with an input field for a single control implemented using template-driven forms.
<code-example path="forms-overview/src/app/template/favorite-color/favorite-color.component.ts">
</code-example>
@ -86,25 +80,23 @@ In template-driven forms, the source of truth is the template.
<img src="generated/images/guide/forms-overview/key-diff-td-forms.png" alt="Template-driven forms key differences">
</figure>
The abstraction of the form model promotes simplicity over structure. The template-driven form directive `NgModel` is responsible for creating and managing the `FormControl` instance for a given form element. It's less explicit, but you no longer have direct control over the form model.
{@a data-flow-in-forms}
The abstraction of the form model promotes simplicity over structure. The template-driven form directive `NgModel` is responsible for creating and managing the form control instance for a given form element. It is less explicit, but you no longer have direct control over the form model.
## Data flow in forms
When building forms in Angular, it's important to understand how the framework handles data flowing from the user or from programmatic changes. Reactive and template-driven forms follow two different strategies when handling form input. The data flow examples below begin with the favorite color input field example from above, and then show how changes to favorite color are handled in reactive forms compared to template-driven forms.
When building forms in Angular, it's important to understand how the framework handles data flowing from the user or from programmatic changes. Reactive and template-driven forms follow two different strategies when handling form input. The data flow examples below begin with the favorite color input field example from above, and they show how changes to favorite color are handled in reactive forms compared to template-driven forms.
### Data flow in reactive forms
As described above, in reactive forms each form element in the view is directly linked to a form model (`FormControl` instance). Updates from the view to the model and from the model to the view are synchronous and aren't dependent on the UI rendered. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
As described above, in reactive forms each form element in the view is directly linked to a form model (`FormControl` instance). Updates from the view to model and model to view are synchronous and not dependent on the UI rendered. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
<figure>
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-vtm.png" alt="Reactive forms data flow - view to model" width="100%">
</figure>
The steps below outline the data flow from view to model.
The steps below outline the view to model data flow.
1. The user types a value into the input element, in this case the favorite color *Blue*.
1. The end user types a value into the input element, in this case the favorite color "Blue".
1. The form input element emits an "input" event with the latest value.
1. The control value accessor listening for events on the form input element immediately relays the new value to the `FormControl` instance.
1. The `FormControl` instance emits the new value through the `valueChanges` observable.
@ -114,37 +106,37 @@ The steps below outline the data flow from view to model.
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-mtv.png" alt="Reactive forms data flow - model to view" width="100%">
</figure>
The steps below outline the data flow from model to view.
The steps below outline the model to view data flow.
1. The user calls the `favoriteColorControl.setValue()` method, which updates the `FormControl` value.
1. The `favoriteColorControl.setValue()` method is called, which updates the `FormControl` value.
1. The `FormControl` instance emits the new value through the `valueChanges` observable.
1. Any subscribers to the `valueChanges` observable receive the new value.
1. The control value accessor on the form input element updates the element with the new value.
### Data flow in template-driven forms
In template-driven forms, each form element is linked to a directive that manages the form model internally. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
In template-driven forms, each form element is linked to a directive that manages the form model internally. The diagrams below uses the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
<figure>
<img src="generated/images/guide/forms-overview/dataflow-td-forms-vtm.png" alt="Template-driven forms data flow - view to model" width="100%">
<img src="generated/images/guide/forms-overview/dataflow-td-forms-vtm.png" alt="Template-driven forms view to model data flow" width="100%">
</figure>
The steps below outline the data flow from view to model when the input value changes from *Red* to *Blue*.
The steps below outline the view to model data flow.
1. The user types *Blue* into the input element.
1. The input element emits an "input" event with the value *Blue*.
1. The end user types "Blue" into the input element.
1. The input element emits an "input" event with the value "Blue".
1. The control value accessor attached to the input triggers the `setValue()` method on the `FormControl` instance.
1. The `FormControl` instance emits the new value through the `valueChanges` observable.
1. Any subscribers to the `valueChanges` observable receive the new value.
1. The control value accessor also calls the `NgModel.viewToModelUpdate()` method which emits an `ngModelChange` event.
1. Because the component template uses two-way data binding for the `favoriteColor` property, the `favoriteColor` property in the component
is updated to the value emitted by the `ngModelChange` event (*Blue*).
1. The control value accessor also calls the `NgModel.viewToModel()` method which emits an `ngModelChange` event.
1. Because the component template uses two-way data binding for the `favoriteColor`, the `favoriteColor` property in the component
is updated to the value emitted by the `ngModelChange` event ("Blue").
<figure>
<img src="generated/images/guide/forms-overview/dataflow-td-forms-mtv.png" alt="Template-driven forms data flow - model to view" width="100%">
<img src="generated/images/guide/forms-overview/dataflow-td-forms-mtv.png" alt="Template-driven forms model to view data flow" width="100%">
</figure>
The steps below outline the data flow from model to view when the `favoriteColor` changes from *Blue* to *Red*.
The steps below outline the model to view data flow.
1. The `favoriteColor` value is updated in the component.
1. Change detection begins.
@ -158,117 +150,110 @@ The steps below outline the data flow from model to view when the `favoriteColor
## Form validation
Validation is an integral part of managing any set of forms. Whether you're checking for required fields or querying an external API for an existing username, Angular provides a set of built-in validators as well as the ability to create custom validators.
Validation is an integral part of managing any set of forms. Whether youre checking for required fields or querying an external API for an existing username, Angular provides a set of built-in validators as well as the ability to create custom validators.
* **Reactive forms** define custom validators as **functions** that receive a control to validate.
* **Template-driven forms** are tied to template **directives**, and must provide custom validator directives that wrap validation functions.
For more information, see [Form Validation](guide/form-validation).
For more on form validation, see the [Form Validation](guide/form-validation) guide.
## Testing
Testing plays a large part in complex applications and a simpler testing strategy is useful when validating that your forms function correctly. Reactive forms and template-driven forms have different levels of reliance on rendering the UI to perform assertions based on form control and form field changes. The following examples demonstrate the process of testing forms with reactive and template-driven forms.
Testing also plays a large part in complex applications and an easier testing strategy is always welcomed. One difference in testing reactive forms and template-driven forms is their reliance on rendering the UI in order to perform assertions based on form control and form field changes. The following examples demonstrate the process of testing forms with reactive and template-driven forms.
### Testing reactive forms
Reactive forms provide a relatively easy testing strategy because they provide synchronous access to the form and data models, and they can be tested without rendering the UI. In these tests, status and data are queried and manipulated through the control without interacting with the change detection cycle.
Reactive forms provide a relatively easy testing strategy because they provide synchronous access to the form and data models, and they can be tested without rendering the UI. In these set of tests, controls and data are queried and manipulated through the control without interacting with the change detection cycle.
The following tests use the favorite color components mentioned earlier to verify the data flows from view to model and model to view for a reactive form.
The following tests use the favorite color components mentioned earlier to verify the view to model and model to view data flows for a reactive form.
The following test verifies the data flow from view to model.
The following test verifies the view to model data flow:
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="view-to-model" header="Favorite color test - view to model">
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="view-to-model" title="Favorite color test - view to model">
</code-example>
Here are the steps performed in the view to model test.
The steps performed in the view to model test.
1. Query the view for the form input element, and create a custom "input" event for the test.
1. Set the new value for the input to *Red*, and dispatch the "input" event on the form input element.
1. Assert that the component's `favoriteColorControl` value matches the value from the input.
1. Set the new value for the input is set to *Red*, and dispatch the "input" event on the form input element.
1. Assert that the `favoriteColor` `FormControl` instance value matches the value from the input.
The following test verifies the data flow from model to view.
The following test verifies the model to view data flow:
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="model-to-view" header="Favorite color test - model to view">
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="model-to-view" title="Favorite color test - model to view">
</code-example>
Here are the steps performed in the model to view test.
The steps performed in the model to view test.
1. Use the `favoriteColorControl`, a `FormControl` instance, to set the new value.
1. Use the `favoriteColor` `FormControl` instance to set the new value.
1. Query the view for the form input element.
1. Assert that the new value set on the control matches the value in the input.
### Testing template-driven forms
Writing tests with template-driven forms requires a detailed knowledge of the change detection process and an understanding of how directives run on each cycle to ensure that elements are queried, tested, or changed at the correct time.
Writing tests with template-driven forms requires more detailed knowledge of the change detection process and how directives run on each cycle to ensure elements are queried, tested, or changed at the correct time.
The following tests use the favorite color components mentioned earlier to verify the data flows from view to model and model to view for a template-driven form.
The following tests use the favorite color components mentioned earlier to verify the view to model and model to view data flows for a template-driven form.
The following test verifies the data flow from view to model.
The following test verifies the view to model data flow:
<code-example path="forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts" region="view-to-model" header="Favorite color test - view to model">
<code-example path="forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts" region="view-to-model" title="Favorite color test - view to model">
</code-example>
Here are the steps performed in the view to model test.
The steps performed in the view to model test.
1. Query the view for the form input element, and create a custom "input" event for the test.
1. Set the new value for the input to *Red*, and dispatch the "input" event on the form input element.
1. Set the new value for the input is set to *Red*, and dispatch the "input" event on the form input element.
1. Run change detection through the test fixture.
1. Assert that the component `favoriteColor` property value matches the value from the input.
The following test verifies the data flow from model to view.
The following test verifies the model to view data flow:
<code-example path="forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts" region="model-to-view" header="Favorite color test - model to view">
<code-example path="forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts" region="model-to-view" title="Favorite color test - model to view">
</code-example>
Here are the steps performed in the model to view test.
The steps performed in the model to view test.
1. Use the component instance to set the value of the `favoriteColor` property.
1. Use the component instance to set the value of `favoriteColor` property.
1. Run change detection through the test fixture.
1. Use the `tick()` method to simulate the passage of time within the `fakeAsync()` task.
1. Use the `tick()` method to simulate passage of time within the `fakeAsync()` task.
1. Query the view for the form input element.
1. Assert that the input value matches the value of the `favoriteColor` property in the component instance.
1. Assert that the input value matches the `favoriteColor` value property in the component instance.
## Mutability
The change tracking method plays a role in the efficiency of your application.
How changes are tracked plays a role in the efficiency of your application.
* **Reactive forms** keep the data model pure by providing it as an immutable data structure. Each time a change is triggered on the data model, the `FormControl` instance returns a new data model rather than updating the existing data model. This gives you the ability to track unique changes to the data model through the control's observable. This provides one way for change detection to be more efficient because it only needs to update on unique changes. It also follows reactive patterns that integrate with observable operators to transform data.
* **Template-driven** forms rely on mutability with two-way data binding to update the data model in the component as changes are made in the template. Because there are no unique changes to track on the data model when using two-way data binding, change detection is less efficient at determining when updates are required.
- **Reactive forms** keep the data model pure by providing it as an immutable data structure. Each time a change is triggered on the data model, the `FormControl` instance returns a new data model rather than updating the data model directly. This gives you the ability track unique changes to the data model through the control's observable. This allows change detection to be more efficient because it only needs to update on unique changes. It also follows reactive patterns that integrate with observable operators to transform data.
- **Template-driven** forms rely on mutability with two-way data binding to update the data model in the component as changes are made in the template. Because there are no unique changes to track on the data model when using two-way data binding, change detection is less efficient at determining when updates are required.
The difference is demonstrated in the examples above using the **favorite color** input element.
* With reactive forms, the **`FormControl` instance** always returns a new value when the control's value is updated.
* With template-driven forms, the **favorite color property** is always modified to its new value.
- With reactive forms, the **`FormControl` instance** always returns a new value when the control's value is updated.
- With template-driven forms, the **favorite color property** is always modified to its new value.
## Scalability
If forms are a central part of your application, scalability is very important. Being able to reuse form models across components is critical.
- **Reactive forms** make creating large scale forms easier by providing access to low-level APIs and synchronous access to the form model.
- **Template-driven** forms focus on simple scenarios, are not as reusable, abstract away the low-level APIs and access to the form model is provided asynchronously. The abstraction with template-driven forms surfaces in testing also, where testing reactive forms requires less setup and no dependence on the change detection cycle when updating and validating the form and data models during testing.
* **Reactive forms** provide access to low-level APIs and synchronous access to the form model, making creating large-scale forms easier.
## Final Thoughts
* **Template-driven** forms focus on simple scenarios, are not as reusable, abstract away the low-level APIs, and provide asynchronous access to the form model. The abstraction with template-driven forms also surfaces in testing, where testing reactive forms requires less setup and no dependence on the change detection cycle when updating and validating the form and data models during testing.
## Final thoughts
Choosing a strategy begins with understanding the strengths and weaknesses of the options presented. Low-level API and form model access, predictability, mutability, straightforward validation and testing strategies, and scalability are all important considerations in choosing the infrastructure you use to build your forms in Angular. Template-driven forms are similar to patterns in AngularJS, but they have limitations given the criteria of many modern, large-scale Angular apps. Reactive forms minimize these limitations. Reactive forms integrate with reactive patterns already present in other areas of the Angular architecture, and complement those requirements well.
## Next steps
Choosing a strategy begins with understanding the strengths and weaknesses of the options presented. Low-level API and form model access, predictability, mutability, straightforward validation and testing strategies, and scalability are all important consideration in choosing the infrastructure you use when building your forms in Angular. Template-driven forms are similar to patterns in AngularJS, but they have limitations given the criteria of many modern, large-scale Angular apps. Reactive forms integrate with reactive patterns already present in other areas of the Angular architecture, and complement those requirements well. Those limitations are alleviated with reactive forms.
## Next Steps
The following guides are the next steps in the learning process.
To learn more about reactive forms, see the following guides:
* [Reactive Forms](guide/reactive-forms)
* [Form Validation](guide/form-validation#reactive-form-validation)
* [Dynamic Forms](guide/dynamic-form)
* [Dynamic forms](guide/dynamic-form)
To learn more about template-driven forms, see the following guides:
* [Template-driven Forms](guide/forms#template-driven-forms)
* [Template-driven Forms](guide/forms)
* [Form Validation](guide/form-validation#template-driven-validation)

View File

@ -1,4 +1,4 @@
# Template-driven forms
# Forms
Forms are the mainstay of business applications.
You use forms to log in, submit a help request, place an order, book a flight,
@ -7,8 +7,6 @@ schedule a meeting, and perform countless other data-entry tasks.
In developing a form, it's important to create a data-entry experience that guides the
user efficiently and effectively through the workflow.
## Introduction to Template-driven forms
Developing forms requires design skills (which are out of scope for this page), as well as framework support for
*two-way data binding, change tracking, validation, and error handling*,
which you'll learn about on this page.
@ -26,6 +24,8 @@ You can run the <live-example></live-example> in Stackblitz and download the cod
{@a template-driven}
## Template-driven forms
You can build forms by writing templates in the Angular [template syntax](guide/template-syntax) with
the form-specific directives and techniques described in this page.
@ -99,7 +99,7 @@ A model can be as simple as a "property bag" that holds facts about a thing of a
That describes well the `Hero` class with its three required fields (`id`, `name`, `power`)
and one optional field (`alterEgo`).
Using the Angular CLI command [`ng generate class`](cli/generate), generate a new class named `Hero`:
Using the Angular CLI, generate a new class named `Hero`:
<code-example language="sh" class="code-shell">
@ -109,7 +109,7 @@ Using the Angular CLI command [`ng generate class`](cli/generate), generate a ne
With this content:
<code-example path="forms/src/app/hero.ts" header="src/app/hero.ts">
<code-example path="forms/src/app/hero.ts" title="src/app/hero.ts">
</code-example>
@ -132,7 +132,7 @@ An Angular form has two parts: an HTML-based _template_ and a component _class_
to handle data and user interactions programmatically.
Begin with the class because it states, in brief, what the hero editor can do.
Using the Angular CLI command [`ng generate component`](cli/generate), generate a new component named `HeroForm`:
Using the Angular CLI, generate a new component named `HeroForm`:
<code-example language="sh" class="code-shell">
@ -142,7 +142,7 @@ Using the Angular CLI command [`ng generate component`](cli/generate), generate
With this content:
<code-example path="forms/src/app/hero-form/hero-form.component.ts" linenums="false" header="src/app/hero-form/hero-form.component.ts (v1)" region="v1">
<code-example path="forms/src/app/hero-form/hero-form.component.ts" linenums="false" title="src/app/hero-form/hero-form.component.ts (v1)" region="v1">
</code-example>
@ -176,7 +176,7 @@ Because template-driven forms are in their own module, you need to add the `Form
Update it with the following:
<code-example path="forms/src/app/app.module.ts" header="src/app/app.module.ts">
<code-example path="forms/src/app/app.module.ts" title="src/app/app.module.ts">
</code-example>
@ -204,7 +204,7 @@ Update it with the following:
Replace the contents of its template with the following:
<code-example path="forms/src/app/app.component.html" header="src/app/app.component.html">
<code-example path="forms/src/app/app.component.html" title="src/app/app.component.html">
</code-example>
@ -221,7 +221,7 @@ Replace the contents of its template with the following:
Update the template file with the following contents:
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="start" header="src/app/hero-form/hero-form.component.html">
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="start" title="src/app/hero-form/hero-form.component.html">
</code-example>
@ -259,7 +259,7 @@ Bootstrap gives the form a little style.
To add the stylesheet, open `styles.css` and add the following import line at the top:
<code-example path="forms/src/styles.1.css" linenums="false" header="src/styles.css">
<code-example path="forms/src/styles.1.css" linenums="false" title="src/styles.css">
</code-example>
@ -274,7 +274,7 @@ a technique seen previously in the [Displaying Data](guide/displaying-data) page
Add the following HTML *immediately below* the *Alter Ego* group:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (powers)" region="powers">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (powers)" region="powers">
</code-example>
@ -307,7 +307,7 @@ makes binding the form to the model easy.
Find the `<input>` tag for *Name* and update it like this:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-1">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-1">
</code-example>
@ -325,7 +325,7 @@ You need one more addition to display the data. Declare
a template variable for the form. Update the `<form>` tag with
`#heroForm="ngForm"` as follows:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="template-variable">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (excerpt)" region="template-variable">
</code-example>
@ -391,7 +391,7 @@ Then you can confirm that two-way data binding works *for the entire hero model*
After revision, the core of the form should look like this:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModel-2">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModel-2">
</code-example>
@ -493,7 +493,7 @@ You can leverage those class names to change the appearance of the control.
Temporarily add a [template reference variable](guide/template-syntax#ref-vars) named `spy`
to the _Name_ `<input>` tag and use it to display the input's CSS classes.
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-2">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-2">
</code-example>
@ -535,13 +535,13 @@ on the left of the input box:
You achieve this effect by adding these class definitions to a new `forms.css` file
that you add to the project as a sibling to `index.html`:
<code-example path="forms/src/assets/forms.css" header="src/assets/forms.css">
<code-example path="forms/src/assets/forms.css" title="src/assets/forms.css">
</code-example>
Update the `<head>` of `index.html` to include this style sheet:
<code-example path="forms/src/index.html" linenums="false" header="src/index.html (styles)" region="styles">
<code-example path="forms/src/index.html" linenums="false" title="src/index.html (styles)" region="styles">
</code-example>
@ -564,7 +564,7 @@ To achieve this effect, extend the `<input>` tag with the following:
Here's an example of an error message added to the _name_ input box:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="name-with-error-msg">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (excerpt)" region="name-with-error-msg">
</code-example>
@ -583,7 +583,7 @@ Here you created a variable called `name` and gave it the value "ngModel".
You control visibility of the name error message by binding properties of the `name`
control to the message `<div>` element's `hidden` property.
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (hidden-error-msg)" region="hidden-error-msg">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (hidden-error-msg)" region="hidden-error-msg">
</code-example>
@ -609,11 +609,11 @@ power to valid values.
Now you'll add a new hero in this form.
Place a *New Hero* button at the bottom of the form and bind its click event to a `newHero` component method.
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-no-reset" header="src/app/hero-form/hero-form.component.html (New Hero button)">
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-no-reset" title="src/app/hero-form/hero-form.component.html (New Hero button)">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.ts" region="new-hero" header="src/app/hero-form/hero-form.component.ts (New Hero method)" linenums="false">
<code-example path="forms/src/app/hero-form/hero-form.component.ts" region="new-hero" title="src/app/hero-form/hero-form.component.ts (New Hero method)" linenums="false">
</code-example>
@ -634,7 +634,7 @@ Replacing the hero object *did not restore the pristine state* of the form contr
You have to clear all of the flags imperatively, which you can do
by calling the form's `reset()` method after calling the `newHero()` method.
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-form-reset" header="src/app/hero-form/hero-form.component.html (Reset the form)">
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-form-reset" title="src/app/hero-form/hero-form.component.html (Reset the form)">
</code-example>
@ -651,7 +651,7 @@ A "form submit" is useless at the moment.
To make it useful, bind the form's `ngSubmit` event property
to the hero form component's `onSubmit()` method:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (ngSubmit)" region="ngSubmit">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (ngSubmit)" region="ngSubmit">
</code-example>
@ -664,7 +664,7 @@ You'll bind the form's overall validity via
the `heroForm` variable to the button's `disabled` property
using an event binding. Here's the code:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (submit-button)" region="submit-button">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (submit-button)" region="submit-button">
</code-example>
@ -703,7 +703,7 @@ hide the data entry area and display something else.
Wrap the form in a `<div>` and bind
its `hidden` property to the `HeroFormComponent.submitted` property.
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="edit-div">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (excerpt)" region="edit-div">
</code-example>
@ -711,7 +711,7 @@ The main form is visible from the start because the
`submitted` property is false until you submit the form,
as this fragment from the `HeroFormComponent` shows:
<code-example path="forms/src/app/hero-form/hero-form.component.ts" linenums="false" header="src/app/hero-form/hero-form.component.ts (submitted)" region="submitted">
<code-example path="forms/src/app/hero-form/hero-form.component.ts" linenums="false" title="src/app/hero-form/hero-form.component.ts (submitted)" region="submitted">
</code-example>
@ -721,7 +721,7 @@ as planned.
Now the app needs to show something else while the form is in the submitted state.
Add the following HTML below the `<div>` wrapper you just wrote:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="submitted">
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" title="src/app/hero-form/hero-form.component.html (excerpt)" region="submitted">
</code-example>
@ -752,35 +752,35 @@ Heres the code for the final version of the application:
<code-tabs>
<code-pane header="hero-form/hero-form.component.ts" path="forms/src/app/hero-form/hero-form.component.ts" region="final">
<code-pane title="hero-form/hero-form.component.ts" path="forms/src/app/hero-form/hero-form.component.ts" region="final">
</code-pane>
<code-pane header="hero-form/hero-form.component.html" path="forms/src/app/hero-form/hero-form.component.html" region="final">
<code-pane title="hero-form/hero-form.component.html" path="forms/src/app/hero-form/hero-form.component.html" region="final">
</code-pane>
<code-pane header="hero.ts" path="forms/src/app/hero.ts">
<code-pane title="hero.ts" path="forms/src/app/hero.ts">
</code-pane>
<code-pane header="app.module.ts" path="forms/src/app/app.module.ts">
<code-pane title="app.module.ts" path="forms/src/app/app.module.ts">
</code-pane>
<code-pane header="app.component.html" path="forms/src/app/app.component.html">
<code-pane title="app.component.html" path="forms/src/app/app.component.html">
</code-pane>
<code-pane header="app.component.ts" path="forms/src/app/app.component.ts">
<code-pane title="app.component.ts" path="forms/src/app/app.component.ts">
</code-pane>
<code-pane header="main.ts" path="forms/src/main.ts">
<code-pane title="main.ts" path="forms/src/main.ts">
</code-pane>
<code-pane header="forms.css" path="forms/src/assets/forms.css">
<code-pane title="forms.css" path="forms/src/assets/forms.css">
</code-pane>

View File

@ -71,7 +71,7 @@ of some of the things they contain:
When you use these Angular modules, import them in `AppModule`,
or your feature module as appropriate, and list them in the `@NgModule`
`imports` array. For example, in the basic app generated by the [Angular CLI](cli),
`imports` array. For example, in the basic app generated by the CLI,
`BrowserModule` is the first import at the top of the `AppModule`,
`app.module.ts`.

View File

@ -130,10 +130,10 @@ A [decorator](guide/glossary#decorator) statement immediately before a field in
## command-line interface (CLI)
The [Angular CLI](cli) is a command-line tool for managing the Angular development cycle. Use it to create the initial filesystem scaffolding for a [workspace](guide/glossary#workspace) or [project](guide/glossary#project), and to run [schematics](guide/glossary#schematic) that add and modify code for initial generic versions of various elements. The CLI supports all stages of the development cycle, including building, testing, bundling, and deployment.
The [Angular CLI](https://cli.angular.io/) is a command-line tool for managing the Angular development cycle. Use it to create the initial filesystem scaffolding for a [workspace](guide/glossary#workspace) or [project](guide/glossary#project), and to run [schematics](guide/glossary#schematic) that add and modify code for initial generic versions of various elements. The CLI supports all stages of the development cycle, including building, testing, bundling, and deployment.
* To begin using the CLI for a new project, see [Getting Started](guide/quickstart).
* To learn more about the full capabilities of the CLI, see the [CLI command reference](cli).
* To learn more about the full capabilities of the CLI, see the [Angular CLI documentation](https://github.com/angular/angular-cli/wiki).
{@a component}
@ -317,30 +317,6 @@ Within Angular, use [NgModules](guide/glossary#ngmodule) to make public parts av
{@a F}
{@a form-control}
## form control
A instance of `FormControl`, which is a fundamental building block for Angular forms. Together with `FormGroup` and `FormArray`, tracks the value, validation, and status of a form input element.
Read more forms in the [Introduction to forms in Angular](guide/forms-overview).
{@a form-model}
## form model
The "source of truth" for the value and validation status of a form input element at a given point in time. When using [reactive forms](guide/glossary#reactive-forms), the form model is created explicitly in the component class. When using [template-driven forms](guide/glossary#template-driven-forms), the form model is implicitly created by directives.
Learn more about reactive and template-driven forms in the [Introduction to forms in Angular](guide/forms-overview).
{@a form-validation}
## form validation
A check that runs when form values change and reports whether the given values are correct and complete, according to the defined constraints. Reactive forms apply [validator functions](guide/form-validation#adding-to-reactive-forms). Template-driven forms use [validator directives](guide/form-validation#adding-to-template-driven-forms).
To learn more, see [Form Validation](guide/form-validation).
{@a G}
@ -349,14 +325,6 @@ To learn more, see [Form Validation](guide/form-validation).
{@a I}
{@a immutability}
## immutability
The ability to alter the state of a value after its creation. [Reactive forms](guide/glossary#reactive-forms) perform immutable changes in that
each change to the data model produces a new data model rather than modifying the existing one. [Template-driven forms](guide/glossary#template-driven-forms) perform mutable changes with `NgModel` and [two-way data binding](guide/glossary#data-binding) to modify the existing data model in place.
{@a injectable}
## injectable
@ -607,15 +575,14 @@ Learn more in [Dependency Injection](guide/dependency-injection).
A framework for building Angular forms through code in a component.
The alternative is a [template-driven form](guide/glossary#template-driven-forms).
When using reactive forms:
When building reactive forms:
* The "source of truth", the form model, is defined in the component class.
* Validation is set up through validation functions rather than valdation directives.
* Each control is explicitly created in the component class by creating a `FormControl` instance manually or with `FormBuilder`.
* The "source of truth" is the component. The validation is defined using code in the component.
* Each control is explicitly created in the component class with `new FormControl()` or with `FormBuilder`.
* The template input elements do *not* use `ngModel`.
* The associated Angular directives are prefixed with `form`, such as `formControl`, `formGroup`, and `formControlName`.
* The associated Angular directives are prefixed with `Form`, such as `FormGroup()`, `FormControl()`, and `FormControlName()`.
The alternative is a template-driven form. For an introduction and comparison of both forms approaches, see [Introduction to Angular Forms](guide/forms-overview).
Reactive forms are powerful, flexible, and a good choice for more complex data-entry form scenarios, such as dynamic generation of form controls.
{@a router}
{@a router-module}
@ -654,7 +621,8 @@ For more information, see [Routing and Navigation](guide/router).
A scaffolding library that defines how to generate or transform a programming project by creating, modifying, refactoring, or moving files and code.
The Angular [CLI](guide/glossary#cli) uses schematics to generate and modify [Angular projects](guide/glossary#project) and parts of projects.
* Angular provides a set of schematics for use with the CLI. See the [Angular CLI command reference](cli). The [`ng add`](cli/add) command runs schematics as part of adding a library to your project. The [`ng generate`](cli/generate) command runs schematics to create apps, libraries, and Angular code constructs.
* Angular provides a set of schematics for use with the CLI.
For details, see [Angular CLI documentation](https://github.com/angular/angular-cli/wiki).
* Library developers can create schematics that enable the CLI to generate their published libraries.
For more information, see [devkit documentation](https://www.npmjs.com/package/@angular-devkit/schematics).
@ -668,7 +636,7 @@ NgModules are delivered within scoped packages whose names begin with the Angula
Import a scoped package in the same way that you import a normal package.
<code-example path="architecture/src/app/app.component.ts" linenums="false" header="architecture/src/app/app.component.ts (import)" region="import">
<code-example path="architecture/src/app/app.component.ts" linenums="false" title="architecture/src/app/app.component.ts (import)" region="import">
</code-example>
@ -730,14 +698,16 @@ Additional templates, represented by `TemplateRef` objects, can define alternati
A format for building Angular forms using HTML forms and input elements in the view.
The alternative format uses the [reactive forms](guide/glossary#reactive-forms) framework.
When using template-driven forms:
When building template-driven forms:
* The "source of truth" is the template. The validation is defined using attributes on the individual input elements.
* [Two-way binding](guide/glossary#data-binding) with `ngModel` keeps the component model synchronized with the user's entry into the input elements.
* Behind the scenes, Angular creates a new control for each input element, provided you have set up a `name` attribute and two-way binding for each input.
* The associated Angular directives are prefixed with `ng` such as `ngForm`, `ngModel`, and `ngModelGroup`.
The alternative is a reactive form. For an introduction and comparison of both forms approaches, see [Introduction to Angular Forms](guide/forms-overview).
Template-driven forms are convenient, quick, and simple. They are a good choice for many basic data-entry form scenarios.
Read about how to build template-driven forms in [Forms](guide/forms).
{@a template-expression}
@ -815,7 +785,7 @@ See [custom element](guide/glossary#custom-element).
## workspace
In Angular, a folder that contains [projects](guide/glossary#project) (that is, apps and libraries).
The [CLI](guide/glossary#cli) `ng new` command creates a workspace to contain projects.
The [CLI](guide/glossary#cli) `new` command creates a workspace to contain projects.
Commands that create or operate on apps and libraries (such as `add` and `generate`) must be executed from within a workspace folder.
{@a X}

View File

@ -23,9 +23,9 @@ When you specify providers in the `@Injectable()` decorator of the service itsel
* Learn more about [tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
You're likely to inject `UserService` in many places throughout the app and will want to inject the same service instance every time. Providing `UserService` through the `root` injector is a good choice, and is the default that the [Angular CLI](cli) uses when you generate a service for your app.
You're likely to inject `UserService` in many places throughout the app and will want to inject the same service instance every time. Providing `UserService` through the `root` injector is a good choice, and is the default that the CLI uses when you generate a service for your app.
<div class="alert is-helpful">
<div class="alert-is-helpful">
<header>Platform injector</header>
When you use `providedIn:'root'`, you are configuring the root injector for the _app_, which is the injector for `AppModule`.
@ -75,7 +75,7 @@ When an injectable class provides its own service to the `root` injector, the se
The following example configures a provider for `HeroService` using the `@Injectable()` decorator on the class.
<code-example path="dependency-injection/src/app/heroes/hero.service.0.ts" header="src/app/heroes/heroes.service.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/heroes/hero.service.0.ts" title="src/app/heroes/heroes.service.ts" linenums="false"> </code-example>
This configuration tells Angular that the app's root injector is responsible for creating an
instance of `HeroService` by invoking its constructor,
@ -92,7 +92,7 @@ Instead of specifying the `root` injector, you can set `providedIn` to a specifi
For example, in the following excerpt, the `@Injectable()` decorator configures a provider
that is available in any injector that includes the `HeroModule`.
<code-example path="dependency-injection/src/app/heroes/hero.service.4.ts" header="src/app/heroes/hero.service.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/heroes/hero.service.4.ts" title="src/app/heroes/hero.service.ts" linenums="false"> </code-example>
This is generally no different from configuring the injector of the NgModule itself,
except that the service is tree-shakable if the NgModule doesn't use it.
@ -117,7 +117,7 @@ Here is an example of the case where the component router configuration includes
a non-default [location strategy](guide/router#location-strategy) by listing its provider
in the `providers` list of the `AppModule`.
<code-example path="dependency-injection-in-action/src/app/app.module.ts" region="providers" header="src/app/app.module.ts (providers)" linenums="false">
<code-example path="dependency-injection-in-action/src/app/app.module.ts" region="providers" title="src/app/app.module.ts (providers)" linenums="false">
</code-example>
@ -132,7 +132,7 @@ by configuring the provider at the component level using the `@Component` metada
The following example is a revised `HeroesComponent` that specifies `HeroService` in its `providers` array. `HeroService` can provide heroes to instances of this component, or to any child component instances.
<code-example path="dependency-injection/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts" linenums="false">
<code-example path="dependency-injection/src/app/heroes/heroes.component.1.ts" title="src/app/heroes/heroes.component.ts" linenums="false">
</code-example>
### Element injectors
@ -207,7 +207,7 @@ that would make the `VillainsService` available everywhere in the application, i
Instead, you can provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:
<code-example path="hierarchical-dependency-injection/src/app/villains-list.component.ts" linenums="false" header="src/app/villains-list.component.ts (metadata)" region="metadata">
<code-example path="hierarchical-dependency-injection/src/app/villains-list.component.ts" linenums="false" title="src/app/villains-list.component.ts (metadata)" region="metadata">
</code-example>
@ -250,14 +250,14 @@ It caches a single `HeroTaxReturn`, tracks changes to that return, and can save
It also delegates to the application-wide singleton `HeroService`, which it gets by injection.
<code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.service.ts" header="src/app/hero-tax-return.service.ts">
<code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.service.ts" title="src/app/hero-tax-return.service.ts">
</code-example>
Here is the `HeroTaxReturnComponent` that makes use of it.
<code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" header="src/app/hero-tax-return.component.ts">
<code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" title="src/app/hero-tax-return.component.ts">
</code-example>
@ -273,7 +273,7 @@ Every component would share the same service instance, and each component would
To prevent this, we configure the component-level injector of `HeroTaxReturnComponent` to provide the service, using the `providers` property in the component metadata.
<code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" linenums="false" header="src/app/hero-tax-return.component.ts (providers)" region="providers">
<code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" linenums="false" title="src/app/hero-tax-return.component.ts (providers)" region="providers">
</code-example>

View File

@ -28,7 +28,7 @@ Most apps do so in the root `AppModule`.
<code-example
path="http/src/app/app.module.ts"
region="sketch"
header="app/app.module.ts (excerpt)" linenums="false">
title="app/app.module.ts (excerpt)" linenums="false">
</code-example>
Having imported `HttpClientModule` into the `AppModule`, you can inject the `HttpClient`
@ -37,7 +37,7 @@ into an application class as shown in the following `ConfigService` example.
<code-example
path="http/src/app/config/config.service.ts"
region="proto"
header="app/config/config.service.ts (excerpt)" linenums="false">
title="app/config/config.service.ts (excerpt)" linenums="false">
</code-example>
## Getting JSON data
@ -48,7 +48,7 @@ that specifies resource URLs.
<code-example
path="http/src/assets/config.json"
header="assets/config.json" linenums="false">
title="assets/config.json" linenums="false">
</code-example>
The `ConfigService` fetches this file with a `get()` method on `HttpClient`.
@ -56,7 +56,7 @@ The `ConfigService` fetches this file with a `get()` method on `HttpClient`.
<code-example
path="http/src/app/config/config.service.ts"
region="getConfig_1"
header="app/config/config.service.ts (getConfig v.1)" linenums="false">
title="app/config/config.service.ts (getConfig v.1)" linenums="false">
</code-example>
A component, such as `ConfigComponent`, injects the `ConfigService` and calls
@ -65,7 +65,7 @@ the `getConfig` service method.
<code-example
path="http/src/app/config/config.component.ts"
region="v1"
header="app/config/config.component.ts (showConfig v.1)" linenums="false">
title="app/config/config.component.ts (showConfig v.1)" linenums="false">
</code-example>
Because the service method returns an `Observable` of configuration data,
@ -116,7 +116,7 @@ Then, specify that interface as the `HttpClient.get()` call's type parameter in
<code-example
path="http/src/app/config/config.service.ts"
region="getConfig_2"
header="app/config/config.service.ts (getConfig v.2)" linenums="false">
title="app/config/config.service.ts (getConfig v.2)" linenums="false">
</code-example>
The callback in the updated component method receives a typed data object, which is
@ -125,7 +125,7 @@ easier and safer to consume:
<code-example
path="http/src/app/config/config.component.ts"
region="v2"
header="app/config/config.component.ts (showConfig v.2)" linenums="false">
title="app/config/config.component.ts (showConfig v.2)" linenums="false">
</code-example>
### Reading the full response
@ -146,7 +146,7 @@ The component's `showConfigResponse()` method displays the response headers as w
<code-example
path="http/src/app/config/config.component.ts"
region="showConfigResponse"
header="app/config/config.component.ts (showConfigResponse)"
title="app/config/config.component.ts (showConfigResponse)"
linenums="false">
</code-example>
@ -161,7 +161,7 @@ You _could_ handle in the component by adding a second callback to the `.subscri
<code-example
path="http/src/app/config/config.component.ts"
region="v3"
header="app/config/config.component.ts (showConfig v.3 with error handling)"
title="app/config/config.component.ts (showConfig v.3 with error handling)"
linenums="false">
</code-example>
@ -188,7 +188,7 @@ You might first devise an error handler like this one:
<code-example
path="http/src/app/config/config.service.ts"
region="handleError"
header="app/config/config.service.ts (handleError)" linenums="false">
title="app/config/config.service.ts (handleError)" linenums="false">
</code-example>
Notice that this handler returns an RxJS [`ErrorObservable`](#rxjs) with a user-friendly error message.
@ -201,7 +201,7 @@ and _pipe them through_ to the error handler.
<code-example
path="http/src/app/config/config.service.ts"
region="getConfig_3"
header="app/config/config.service.ts (getConfig v.3 with error handler)" linenums="false">
title="app/config/config.service.ts (getConfig v.3 with error handler)" linenums="false">
</code-example>
### `retry()`
@ -218,7 +218,7 @@ _Pipe_ it onto the `HttpClient` method result just before the error handler.
<code-example
path="http/src/app/config/config.service.ts"
region="getConfig"
header="app/config/config.service.ts (getConfig with retry)" linenums="false">
title="app/config/config.service.ts (getConfig with retry)" linenums="false">
</code-example>
{@a rxjs}
@ -239,7 +239,7 @@ If you're following along with these code snippets, note that you must import th
<code-example
path="http/src/app/config/config.service.ts"
region="rxjs-imports"
header="app/config/config.service.ts (RxJS imports)" linenums="false">
title="app/config/config.service.ts (RxJS imports)" linenums="false">
</code-example>
## Requesting non-JSON data
@ -252,7 +252,7 @@ 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">
title="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.
@ -264,7 +264,7 @@ A `download()` method in the `DownloaderComponent` initiates the request by subs
<code-example
path="http/src/app/downloader/downloader.component.ts"
region="download"
header="app/downloader/downloader.component.ts (download)" linenums="false">
title="app/downloader/downloader.component.ts (download)" linenums="false">
</code-example>
## Sending data to the server
@ -289,7 +289,7 @@ 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)" linenums="false">
title="app/heroes/heroes.service.ts (httpOptions)" linenums="false">
</code-example>
### Making a POST request
@ -300,7 +300,7 @@ In the following example, the `HeroesService` posts when adding a hero to the da
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="addHero"
header="app/heroes/heroes.service.ts (addHero)" linenums="false">
title="app/heroes/heroes.service.ts (addHero)" linenums="false">
</code-example>
The `HttpClient.post()` method is similar to `get()` in that it has a type parameter
@ -320,7 +320,7 @@ the `Observable` returned by this service method.
<code-example
path="http/src/app/heroes/heroes.component.ts"
region="add-hero-subscribe"
header="app/heroes/heroes.component.ts (addHero)" linenums="false">
title="app/heroes/heroes.component.ts (addHero)" linenums="false">
</code-example>
When the server responds successfully with the newly added hero, the component adds
@ -334,7 +334,7 @@ in the request URL.
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="deleteHero"
header="app/heroes/heroes.service.ts (deleteHero)" linenums="false">
title="app/heroes/heroes.service.ts (deleteHero)" linenums="false">
</code-example>
The `HeroesComponent` initiates the actual DELETE operation by subscribing to
@ -343,7 +343,7 @@ the `Observable` returned by this service method.
<code-example
path="http/src/app/heroes/heroes.component.ts"
region="delete-hero-subscribe"
header="app/heroes/heroes.component.ts (deleteHero)" linenums="false">
title="app/heroes/heroes.component.ts (deleteHero)" linenums="false">
</code-example>
The component isn't expecting a result from the delete operation, so it subscribes without a callback. Even though you are not using the result, you still have to subscribe. Calling the `subscribe()` method _executes_ the observable, which is what initiates the DELETE request.
@ -403,7 +403,7 @@ The following `HeroesService` example is just like the POST example.
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="updateHero"
header="app/heroes/heroes.service.ts (updateHero)" linenums="false">
title="app/heroes/heroes.service.ts (updateHero)" linenums="false">
</code-example>
For the reasons [explained above](#always-subscribe), the caller (`HeroesComponent.update()` in this case) must `subscribe()` to the observable returned from the `HttpClient.put()`
@ -464,7 +464,7 @@ 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)">
title="app/package-search/package-search.component.html (search)">
</code-example>
The `(keyup)` event binding sends every keystroke to the component's `search()` method.
@ -476,7 +476,7 @@ 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))">
title="app/package-search/package-search.component.ts (excerpt))">
</code-example>
The `searchText$` is the sequence of search-box values coming from the user.
@ -543,7 +543,7 @@ To implement an interceptor, declare a class that implements the `intercept()` m
Here is a do-nothing _noop_ interceptor that simply passes the request through without touching it:
<code-example
path="http/src/app/http-interceptors/noop-interceptor.ts"
header="app/http-interceptors/noop-interceptor.ts"
title="app/http-interceptors/noop-interceptor.ts"
linenums="false">
</code-example>
@ -608,7 +608,7 @@ Consider creating a "barrel" file that gathers all the interceptor providers int
<code-example
path="http/src/app/http-interceptors/index.ts"
region="interceptor-providers"
header="app/http-interceptors/index.ts" linenums="false">
title="app/http-interceptors/index.ts" linenums="false">
</code-example>
Then import and add it to the `AppModule` _providers array_ like this:
@ -616,7 +616,7 @@ Then import and add it to the `AppModule` _providers array_ like this:
<code-example
path="http/src/app/app.module.ts"
region="interceptor-providers"
header="app/app.module.ts (interceptor providers)" linenums="false">
title="app/app.module.ts (interceptor providers)" linenums="false">
</code-example>
As you create new interceptors, add them to the `httpInterceptorProviders` array and
@ -672,7 +672,7 @@ You can clone and modify the request in a single step as in this example.
<code-example
path="http/src/app/http-interceptors/ensure-https-interceptor.ts"
region="excerpt"
header="app/http-interceptors/ensure-https-interceptor.ts (excerpt)" linenums="false">
title="app/http-interceptors/ensure-https-interceptor.ts (excerpt)" linenums="false">
</code-example>
The `clone()` method's hash argument allows you to mutate specific properties of the request while copying the others.
@ -692,7 +692,7 @@ If you must mutate the request body, copy it first, change the copy,
<code-example
path="http/src/app/http-interceptors/trim-name-interceptor.ts"
region="excerpt"
header="app/http-interceptors/trim-name-interceptor.ts (excerpt)" linenums="false">
title="app/http-interceptors/trim-name-interceptor.ts (excerpt)" linenums="false">
</code-example>
##### Clearing the request body
@ -718,7 +718,7 @@ adds an authorization header with that token to every outgoing request:
<code-example
path="http/src/app/http-interceptors/auth-interceptor.ts"
header="app/http-interceptors/auth-interceptor.ts">
title="app/http-interceptors/auth-interceptor.ts">
</code-example>
The practice of cloning a request to set new headers is so common that
@ -747,7 +747,7 @@ with the injected `MessageService`.
<code-example
path="http/src/app/http-interceptors/logging-interceptor.ts"
region="excerpt"
header="app/http-interceptors/logging-interceptor.ts)">
title="app/http-interceptors/logging-interceptor.ts)">
</code-example>
The RxJS `tap` operator captures whether the request succeed or failed.
@ -768,7 +768,7 @@ The `CachingInterceptor` demonstrates this approach.
<code-example
path="http/src/app/http-interceptors/caching-interceptor.ts"
region="v1"
header="app/http-interceptors/caching-interceptor.ts)" linenums="false">
title="app/http-interceptors/caching-interceptor.ts)" linenums="false">
</code-example>
The `isCachable()` function determines if the request is cachable.
@ -858,7 +858,7 @@ with the `reportProgress` option set true to enable tracking of progress events.
<code-example
path="http/src/app/uploader/uploader.service.ts"
region="upload-request"
header="app/uploader/uploader.service.ts (upload request)">
title="app/uploader/uploader.service.ts (upload request)">
</code-example>
<div class="alert is-important">
@ -873,7 +873,7 @@ returns an `Observable` of `HttpEvents`, the same events processed by intercepto
<code-example
path="http/src/app/uploader/uploader.service.ts"
region="upload-body"
header="app/uploader/uploader.service.ts (upload body)" linenums="false">
title="app/uploader/uploader.service.ts (upload body)" linenums="false">
</code-example>
The `getEventMessage` method interprets each type of `HttpEvent` in the event stream.
@ -881,7 +881,7 @@ The `getEventMessage` method interprets each type of `HttpEvent` in the event st
<code-example
path="http/src/app/uploader/uploader.service.ts"
region="getEventMessage"
header="app/uploader/uploader.service.ts (getEventMessage)" linenums="false">
title="app/uploader/uploader.service.ts (getEventMessage)" linenums="false">
</code-example>
<div class="alert is-helpful">
@ -964,7 +964,7 @@ along with the other symbols your tests require.
<code-example
path="http/src/testing/http-client.spec.ts"
region="imports"
header="app/testing/http-client.spec.ts (imports)" linenums="false">
title="app/testing/http-client.spec.ts (imports)" linenums="false">
</code-example>
Then add the `HttpClientTestingModule` to the `TestBed` and continue with
@ -973,7 +973,7 @@ the setup of the _service-under-test_.
<code-example
path="http/src/testing/http-client.spec.ts"
region="setup"
header="app/testing/http-client.spec.ts(setup)" linenums="false">
title="app/testing/http-client.spec.ts(setup)" linenums="false">
</code-example>
Now requests made in the course of your tests will hit the testing backend instead of the normal backend.
@ -988,7 +988,7 @@ Now you can write a test that expects a GET Request to occur and provides a mock
<code-example
path="http/src/testing/http-client.spec.ts"
region="get-test"
header="app/testing/http-client.spec.ts(httpClient.get)" linenums="false">
title="app/testing/http-client.spec.ts(httpClient.get)" linenums="false">
</code-example>
The last step, verifying that no requests remain outstanding, is common enough for you to move it into an `afterEach()` step:

View File

@ -19,7 +19,7 @@ Angular simplifies the following aspects of internationalization:
* Handling plural forms of words.
* Handling alternative text.
For localization, you can use the [Angular CLI](cli) to generate most of the boilerplate necessary to create files for translators, and to publish your app in multiple languages.
For localization, you can use the [**Angular CLI**](https://cli.angular.io/) to generate most of the boilerplate necessary to create files for translators, and to publish your app in multiple languages.
After you have set up your app to use i18n, the CLI can help you with the following steps:
* Extracting localizable text into a file that you can send out to be translated.
* Building and serving the app for a given locale, using the translated text.
@ -57,7 +57,7 @@ To set your app's locale to another value, use the CLI parameter `--configuratio
If you use JIT, you also need to define the `LOCALE_ID` provider in your main module:
<code-example path="i18n/doc-files/app.module.ts" header="src/app/app.module.ts" linenums="false">
<code-example path="i18n/doc-files/app.module.ts" title="src/app/app.module.ts" linenums="false">
</code-example>
@ -97,7 +97,7 @@ The CLI imports the locale data for you when you use the parameter `--configurat
If you want to import locale data for other languages, you can do it manually:
<code-example path="i18n/doc-files/app.locale_data.ts" region="import-locale" header="src/app/app.module.ts" linenums="false">
<code-example path="i18n/doc-files/app.locale_data.ts" region="import-locale" title="src/app/app.module.ts" linenums="false">
</code-example>
The first parameter is an object containing the locale data imported from `@angular/common/locales`.
@ -112,7 +112,7 @@ The files in `@angular/common/locales` contain most of the locale data that you
need, but some advanced formatting options might only be available in the extra dataset that you can
import from `@angular/common/locales/extra`. An error message informs you when this is the case.
<code-example path="i18n/doc-files/app.locale_data_extra.ts" region="import-locale-extra" header="src/app/app.module.ts" linenums="false">
<code-example path="i18n/doc-files/app.locale_data_extra.ts" region="import-locale-extra" title="src/app/app.module.ts" linenums="false">
</code-example>
<div class="alert is-helpful">
@ -158,12 +158,12 @@ text is to be translated.
In the example below, an `<h1>` tag displays a simple English language greeting, "Hello i18n!"
<code-example path="i18n/doc-files/app.component.html" region="greeting" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/doc-files/app.component.html" region="greeting" title="src/app/app.component.html" linenums="false">
</code-example>
To mark the greeting for translation, add the `i18n` attribute to the `<h1>` tag.
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute" title="src/app/app.component.html" linenums="false">
</code-example>
@ -183,7 +183,7 @@ To translate a text message accurately, the translator may need additional infor
You can add a description of the text message as the value of the `i18n` attribute, as shown in the
example below:
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute-desc" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute-desc" title="src/app/app.component.html" linenums="false">
</code-example>
The translator may also need to know the meaning or intent of the text message within this particular
@ -192,7 +192,7 @@ app context.
You add context by beginning the `i18n` attribute value with the _meaning_ and
separating it from the _description_ with the `|` character: `<meaning>|<description>`
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute-meaning" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute-meaning" title="src/app/app.component.html" linenums="false">
</code-example>
All occurrences of a text message that have the same meaning will have the same translation.
@ -220,7 +220,7 @@ You must then update the translation file with the new id.
Alternatively, you can specify a custom id in the `i18n` attribute by using the prefix `@@`.
The example below defines the custom id `introductionHeader`:
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-solo-id' header='app/app.component.html' linenums="false">
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-solo-id' title='app/app.component.html' linenums="false">
</code-example>
When you specify a custom id, the extractor tool and compiler generate a translation unit with that
@ -238,12 +238,12 @@ You can use a custom id in combination with a description by including both in t
`i18n` attribute. In the example below, the `i18n` attribute value includes a description, followed
by the custom `id`:
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-id' header='app/app.component.html' linenums="false">
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-id' title='app/app.component.html' linenums="false">
</code-example>
You also can add a meaning, as shown in this example:
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-meaning-and-id' header='app/app.component.html' linenums="false">
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-meaning-and-id' title='app/app.component.html' linenums="false">
</code-example>
#### Define unique custom ids
@ -287,7 +287,7 @@ However, if you don't want to create a new DOM element merely to facilitate tran
you can wrap the text in an `<ng-container>` element.
The `<ng-container>` is transformed into an html comment:
<code-example path="i18n/src/app/app.component.html" region="i18n-ng-container" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/src/app/app.component.html" region="i18n-ng-container" title="src/app/app.component.html" linenums="false">
</code-example>
{@a translate-attributes}
@ -296,14 +296,14 @@ The `<ng-container>` is transformed into an html comment:
Displayed text is sometimes supplied as the value of an attribute, rather than the content of tag.
For example, if your template has an image with a `title` attribute, the text value of the `title` attribute needs to be translated.
<code-example path="i18n/doc-files/app.component.html" region="i18n-title" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/doc-files/app.component.html" region="i18n-title" title="src/app/app.component.html" linenums="false">
</code-example>
To mark an attribute for translation, add an attribute in the form of `i18n-x`,
where `x` is the name of the attribute to translate. The following example shows how to mark the
`title` attribute for translation by adding the `i18n-title` attribute on the `img` tag:
<code-example path="i18n/src/app/app.component.html" region="i18n-title-translate" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/src/app/app.component.html" region="i18n-title-translate" title="src/app/app.component.html" linenums="false">
</code-example>
This technique works for any attribute of any element.
@ -328,7 +328,7 @@ Other languages might express the cardinality differently.
The example below shows how to use a `plural` ICU expression to display one of those three options
based on when the update occurred:
<code-example path="i18n/src/app/app.component.html" region="i18n-plural" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/src/app/app.component.html" region="i18n-plural" title="src/app/app.component.html" linenums="false">
</code-example>
* The first parameter is the key. It is bound to the component property (`minutes`), which determines
@ -384,7 +384,7 @@ The following format message in the component template binds to the component's
which outputs one of the following string values: "m", "f" or "o".
The message maps those values to the appropriate translations:
<code-example path="i18n/src/app/app.component.html" region="i18n-select" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/src/app/app.component.html" region="i18n-select" title="src/app/app.component.html" linenums="false">
</code-example>
{@a nesting-ICUS}
@ -392,7 +392,7 @@ The message maps those values to the appropriate translations:
You can also nest different ICU expressions together, as shown in this example:
<code-example path="i18n/src/app/app.component.html" region="i18n-nested" header="src/app/app.component.html">
<code-example path="i18n/src/app/app.component.html" region="i18n-nested" title="src/app/app.component.html">
</code-example>
{@a ng-xi18n}
@ -413,7 +413,7 @@ By default, the command creates a file named `messages.xlf` in your `src/` folde
If you don't use the CLI, you have two options:
* You can use the `ng-xi18n` tool directly from the `@angular/compiler-cli` package.
For more information, see the [`ng xi18n` command documentation](cli/xi18n).
For more information, see [i18n in the CLI documentation](https://github.com/angular/angular-cli/wiki/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).
@ -530,7 +530,7 @@ This sample file is easy to translate without a special editor or knowledge of F
1. Open `messages.fr.xlf` and find the first `<trans-unit>` section:
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello-before" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello-before" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
> This XML element represents the translation of the `<h1>` greeting tag that you marked with the
@ -546,12 +546,12 @@ This sample file is easy to translate without a special editor or knowledge of F
and context provided by the source, description, and meaning elements to guide your selection of
the appropriate French translation.
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;, after translation)" linenums="false">
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;, after translation)" linenums="false">
</code-example>
3. Translate the other text nodes the same way:
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-other-nodes" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-other-nodes" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
<div class="alert is-important">
@ -578,7 +578,7 @@ must be just below the translation unit for the logo.
To translate a `plural`, translate its ICU format match values:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-plural" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-plural" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
You can add or remove plural cases, with each language having its own cardinality. (See
@ -589,7 +589,7 @@ You can add or remove plural cases, with each language having its own cardinalit
Below is the content of our example `select` ICU expression in the component template:
<code-example path="i18n/src/app/app.component.html" region="i18n-select" header="src/app/app.component.html" linenums="false">
<code-example path="i18n/src/app/app.component.html" region="i18n-select" title="src/app/app.component.html" linenums="false">
</code-example>
The extraction tool broke that into two translation units because ICU expressions are extracted
@ -600,18 +600,18 @@ In place of the `select` is a placeholder, `<x id="ICU">`, that represents the `
Translate the text and move around the placeholder if necessary, but don't remove it. If you remove
the placeholder, the ICU expression will not be present in your translated app.
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-select-1" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-select-1" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
The second translation unit, immediately below the first one, contains the `select` message.
Translate that as well.
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-select-2" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-select-2" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
Here they are together, after translation:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-select" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-select" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
{@a translate-nested}
@ -620,17 +620,17 @@ Here they are together, after translation:
A nested expression is similar to the previous examples. As in the previous example, there are
two translation units. The first one contains the text outside of the nested expression:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested-1" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested-1" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
The second unit contains the complete nested expression:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested-2" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested-2" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
And both together:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested" title="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
The entire template translation is complete. The next section describes how to load that translation
@ -642,15 +642,15 @@ into the app.
The sample app and its translation file are now as follows:
<code-tabs>
<code-pane header="src/app/app.component.html" path="i18n/src/app/app.component.html">
<code-pane title="src/app/app.component.html" path="i18n/src/app/app.component.html">
</code-pane>
<code-pane header="src/app/app.component.ts" path="i18n/src/app/app.component.ts">
<code-pane title="src/app/app.component.ts" path="i18n/src/app/app.component.ts">
</code-pane>
<code-pane header="src/app/app.module.ts" path="i18n/src/app/app.module.ts">
<code-pane title="src/app/app.module.ts" path="i18n/src/app/app.module.ts">
</code-pane>
<code-pane header="src/main.ts" path="i18n/doc-files/main.1.ts">
<code-pane title="src/main.ts" path="i18n/doc-files/main.1.ts">
</code-pane>
<code-pane header="src/locale/messages.fr.xlf" path="i18n/doc-files/messages.fr.xlf.html">
<code-pane title="src/locale/messages.fr.xlf" path="i18n/doc-files/messages.fr.xlf.html">
</code-pane>
</code-tabs>
@ -672,7 +672,7 @@ format that Angular understands, such as `.xtb`.
How you provide this information depends upon whether you compile with
the JIT compiler or the AOT compiler.
* With [AOT](guide/i18n#merge-aot), you pass the information as configuration settings.
* With [AOT](guide/i18n#merge-aot), you pass the information as a configuration
* With [JIT](guide/i18n#merge-jit), you provide the information at bootstrap time.
@ -790,12 +790,12 @@ while compiling the app:
The Angular `bootstrapModule` method has a second `compilerOptions` parameter that can influence the
behavior of the compiler. You can use it to specify the translation providers:
<code-example path="i18n/doc-files/main.2.ts" header="src/main.ts">
<code-example path="i18n/doc-files/main.2.ts" title="src/main.ts">
</code-example>
Then provide the `LOCALE_ID` in the main module:
<code-example path="i18n/doc-files/app.module.ts" header="src/app/app.module.ts" linenums="false">
<code-example path="i18n/doc-files/app.module.ts" title="src/app/app.module.ts" linenums="false">
</code-example>
@ -826,7 +826,7 @@ If you use the JIT compiler, specify the warning level in the compiler config at
the 'MissingTranslationStrategy' property. The example below shows how to set the warning level to
error:
<code-example path="i18n/doc-files/main.3.ts" header="src/main.ts">
<code-example path="i18n/doc-files/main.3.ts" title="src/main.ts">
</code-example>
### Build for multiple locales

View File

@ -98,7 +98,7 @@ 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" linenums="false">
<code-example path="lazy-loading-ngmodules/src/app/app.component.html" region="app-component-template" title="src/app/app.component.html" linenums="false">
</code-example>
@ -138,19 +138,19 @@ Each feature module acts as a doorway via the router. In the `AppRoutingModule`,
In `AppRoutingModule`, update the `routes` array with the following:
<code-example path="lazy-loading-ngmodules/src/app/app-routing.module.ts" region="const-routes" header="src/app/app-routing.module.ts" linenums="false">
<code-example path="lazy-loading-ngmodules/src/app/app-routing.module.ts" region="const-routes" title="src/app/app-routing.module.ts" linenums="false">
</code-example>
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 string that is the relative path to the module, a hash mark or `#`, and the modules class name.
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 string that is the path to the module, a hash mark or `#`, and the modules class name.
### 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" linenums="false">
<code-example path="lazy-loading-ngmodules/src/app/customers/customers.module.ts" region="customers-module" title="src/app/customers/customers.module.ts" linenums="false">
</code-example>
@ -163,7 +163,7 @@ The `customers.module.ts` file imports the `CustomersRoutingModule` and `Custome
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" linenums="false">
<code-example path="lazy-loading-ngmodules/src/app/customers/customers-routing.module.ts" region="customers-routing-module" title="src/app/customers/customers-routing.module.ts" linenums="false">
</code-example>
@ -172,7 +172,7 @@ Notice that the `path` is set to an empty string. This is because the path in `A
Repeat this last step of importing the `OrdersListComponent` and configuring the Routes array for the `orders-routing.module.ts`:
<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)" linenums="false">
<code-example path="lazy-loading-ngmodules/src/app/orders/orders-routing.module.ts" region="orders-routing-module-detail" title="src/app/orders/orders-routing.module.ts (excerpt)" linenums="false">
</code-example>

View File

@ -23,7 +23,7 @@ Each interface has a single hook method whose name is the interface name prefixe
For example, the `OnInit` interface has a hook method named `ngOnInit()`
that Angular calls shortly after creating the component:
<code-example path="lifecycle-hooks/src/app/peek-a-boo.component.ts" region="ngOnInit" header="peek-a-boo.component.ts (excerpt)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/peek-a-boo.component.ts" region="ngOnInit" title="peek-a-boo.component.ts (excerpt)" linenums="false"></code-example>
No directive or component will implement all of the lifecycle hooks.
Angular only calls a directive/component hook method *if it is defined*.
@ -339,13 +339,13 @@ The heroes will never know they're being watched.
The sneaky spy directive is simple, consisting almost entirely of `ngOnInit()` and `ngOnDestroy()` hooks
that log messages to the parent via an injected `LoggerService`.
<code-example path="lifecycle-hooks/src/app/spy.directive.ts" region="spy-directive" header="src/app/spy.directive.ts" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/spy.directive.ts" region="spy-directive" title="src/app/spy.directive.ts" linenums="false"></code-example>
You can apply the spy to any native or component element and it'll be initialized and destroyed
at the same time as that element.
Here it is attached to the repeated hero `<div>`:
<code-example path="lifecycle-hooks/src/app/spy.component.html" region="template" header="src/app/spy.component.html" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/spy.component.html" region="template" title="src/app/spy.component.html" linenums="false"></code-example>
Each spy's birth and death marks the birth and death of the attached hero `<div>`
with an entry in the *Hook Log* as seen here:
@ -425,7 +425,7 @@ You risk memory leaks if you neglect to do so.
Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive).
This example monitors the `OnChanges` hook.
<code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="ng-on-changes" header="on-changes.component.ts (excerpt)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="ng-on-changes" title="on-changes.component.ts (excerpt)" linenums="false"></code-example>
The `ngOnChanges()` method takes an object that maps each changed property name to a
[SimpleChange](api/core/SimpleChange) object holding the current and previous property values.
@ -433,11 +433,11 @@ This hook iterates over the changed properties and logs them.
The example component, `OnChangesComponent`, has two input properties: `hero` and `power`.
<code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="inputs" header="src/app/on-changes.component.ts" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="inputs" title="src/app/on-changes.component.ts" linenums="false"></code-example>
The host `OnChangesParentComponent` binds to them like this:
<code-example path="lifecycle-hooks/src/app/on-changes-parent.component.html" region="on-changes" header="src/app/on-changes-parent.component.html"></code-example>
<code-example path="lifecycle-hooks/src/app/on-changes-parent.component.html" region="on-changes" title="src/app/on-changes-parent.component.html"></code-example>
Here's the sample in action as the user makes changes.
@ -468,7 +468,7 @@ Use the `DoCheck` hook to detect and act upon changes that Angular doesn't catch
The *DoCheck* sample extends the *OnChanges* sample with the following `ngDoCheck()` hook:
<code-example path="lifecycle-hooks/src/app/do-check.component.ts" region="ng-do-check" header="DoCheckComponent (ngDoCheck)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/do-check.component.ts" region="ng-do-check" title="DoCheckComponent (ngDoCheck)" linenums="false"></code-example>
This code inspects certain _values of interest_, capturing and comparing their current state against previous values.
It writes a special message to the log when there are no substantive changes to the `hero` or the `power`
@ -497,25 +497,25 @@ The *AfterView* sample explores the `AfterViewInit()` and `AfterViewChecked()` h
Here's a child view that displays a hero's name in an `<input>`:
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="child-view" header="ChildComponent" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="child-view" title="ChildComponent" linenums="false"></code-example>
The `AfterViewComponent` displays this child view *within its template*:
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="template" header="AfterViewComponent (template)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="template" title="AfterViewComponent (template)" linenums="false"></code-example>
The following hooks take action based on changing values *within the child view*,
which can only be reached by querying for the child view via the property decorated with
[@ViewChild](api/core/ViewChild).
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="hooks" header="AfterViewComponent (class excerpts)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="hooks" title="AfterViewComponent (class excerpts)" linenums="false"></code-example>
{@a wait-a-tick}
### Abide by the unidirectional data flow rule
The `doSomething()` method updates the screen when the hero name exceeds 10 characters.
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="do-something" header="AfterViewComponent (doSomething)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="do-something" title="AfterViewComponent (doSomething)" linenums="false"></code-example>
Why does the `doSomething()` method wait a tick before updating `comment`?
@ -559,7 +559,7 @@ Consider this variation on the [previous _AfterView_](guide/lifecycle-hooks#afte
This time, instead of including the child view within the template, it imports the content from
the `AfterContentComponent`'s parent. Here's the parent's template:
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="parent-template" header="AfterContentParentComponent (template excerpt)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="parent-template" title="AfterContentParentComponent (template excerpt)" linenums="false"></code-example>
Notice that the `<app-child>` tag is tucked between the `<after-content>` tags.
Never put content between a component's element tags *unless you intend to project that content
@ -567,7 +567,7 @@ into the component*.
Now look at the component's template:
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="template" header="AfterContentComponent (template)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="template" title="AfterContentComponent (template)" linenums="false"></code-example>
The `<ng-content>` tag is a *placeholder* for the external content.
It tells Angular where to insert that content.
@ -603,7 +603,7 @@ The following *AfterContent* hooks take action based on changing values in a *co
which can only be reached by querying for them via the property decorated with
[@ContentChild](api/core/ContentChild).
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="hooks" header="AfterContentComponent (class excerpts)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="hooks" title="AfterContentComponent (class excerpts)" linenums="false"></code-example>
{@a no-unidirectional-flow-worries}

View File

@ -480,7 +480,7 @@ You can throw an error or take other remedial action.
Certain NgModules, such as `BrowserModule`, implement such a guard.
Here is a custom constructor for an NgModule called `CoreModule`.
<code-example path="ngmodule-faq/src/app/core/core.module.ts" region="ctor" header="src/app/core/core.module.ts (Constructor)" linenums="false">
<code-example path="ngmodule-faq/src/app/core/core.module.ts" region="ctor" title="src/app/core/core.module.ts (Constructor)" linenums="false">
</code-example>
<hr/>

View File

@ -29,7 +29,7 @@ JavaScript modules help you namespace, preventing accidental global variables.
<!-- KW-- perMisko: let's discuss. This does not answer the question why it is different. Also, last sentence is confusing.-->
NgModules are classes decorated with `@NgModule`. The `@NgModule` decorators `imports` array tells Angular what other NgModules the current module needs. The modules in the `imports` array are different than JavaScript modules because they are NgModules rather than regular JavaScript modules. Classes with an `@NgModule` decorator are by convention kept in their own files, but what makes them an `NgModule` isnt being in their own file, like JavaScript modules; its the presence of `@NgModule` and its metadata.
The `AppModule` generated from the [Angular CLI](cli) demonstrates both kinds of modules in action:
The `AppModule` generated from the Angular CLI demonstrates both kinds of modules in action:
```typescript
/* These are JavaScript import statements. Angular doesnt know anything about these. */

View File

@ -57,9 +57,9 @@ You then import these modules into the root module.
## The basic NgModule
The [Angular CLI](cli) generates the following basic app module when creating a new app.
The CLI generates the following basic app module when creating a new app.
<code-example path="bootstrapping/src/app/app.module.ts" region="whole-ngmodule" header="src/app/app.module.ts" linenums="false">
<code-example path="bootstrapping/src/app/app.module.ts" region="whole-ngmodule" title="src/app/app.module.ts" linenums="false">
</code-example>
At the top are the import statements. The next section is where you configure the `@NgModule` by stating what components and directives belong to it (`declarations`) as well as which other modules it uses (`imports`). This page builds on [Bootstrapping](guide/bootstrapping), which covers the structure of an NgModule in detail. If you need more information on the structure of an `@NgModule`, be sure to read [Bootstrapping](guide/bootstrapping).

View File

@ -1,141 +1,173 @@
# Workspace npm dependencies
# Npm Packages
The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm packages](https://docs.npmjs.com/getting-started/what-is-npm "What is npm?") and distributed via the [npm registry](https://docs.npmjs.com/).
The [**Angular CLI**](https://cli.angular.io/), Angular applications, and Angular itself depend upon features and functionality provided by libraries that are available as [**npm**](https://docs.npmjs.com/) packages.
You can download and install these npm packages by using the [npm CLI client](https://docs.npmjs.com/cli/install), which is installed with and runs as a [Node.js®](https://nodejs.org "Nodejs.org") application. By default, the Angular CLI uses the npm client.
Alternatively, you can use the [yarn client](https://yarnpkg.com/) for downloading and installing npm packages.
You can download and install these npm packages with the [**npm client**](https://docs.npmjs.com/cli/install), which runs as a Node.js® application.
The [**yarn client**](https://yarnpkg.com/en/) is a popular alternative for downloading and installing npm packages.
The Angular CLI uses `yarn` by default to install npm packages when you create a new project.
<div class="alert is-helpful">
See [Getting Started](guide/quickstart#prerequisites) for information about the required versions and installation of Node.js and npm.
Node.js and npm are essential to Angular development.
If you already have projects running on your machine that use other versions of Node.js and npm, consider using [nvm](https://github.com/creationix/nvm) to manage the multiple versions of Node.js and npm.
[Get them now](https://docs.npmjs.com/getting-started/installing-node "Installing Node.js and updating npm")
if they're not already installed on your machine.
**Verify that you are running Node.js `v8.x` or higher and npm `5.x` or higher**
by running the commands `node -v` and `npm -v` in a terminal/console window.
Older versions produce errors.
Consider using [nvm](https://github.com/creationix/nvm) for managing multiple
versions of Node.js and npm. You may need [nvm](https://github.com/creationix/nvm) if
you already have projects running on your machine that use other versions of Node.js and npm.
</div>
## _package.json_
## `package.json`
Both `npm` and `yarn` install packages that are identified in a [**package.json**](https://docs.npmjs.com/files/package.json) file.
Both `npm` and `yarn` install the packages that are identified in a [`package.json`](https://docs.npmjs.com/files/package.json) file.
The CLI `ng new` command creates a default `package.json` file for your project.
This `package.json` specifies _a starter set of packages_ that work well together and
jointly support many common application scenarios.
The CLI command `ng new` creates a `package.json` file when it creates the new workspace.
This `package.json` is used by all projects in the workspace, including the initial app project that is created by the CLI when it creates the workspace.
You will add packages to `package.json` as your application evolves.
You may even remove some.
Initially, this `package.json` includes _a starter set of packages_, some of which are required by Angular and others that support common application scenarios.
You add packages to `package.json` as your application evolves.
You may even remove some.
This guide focuses on the most important packages in the starter set.
The `package.json` is organized into two groups of packages:
#### *dependencies* and *devDependencies*
* [Dependencies](guide/npm-packages#dependencies) are essential to *running* applications.
* [DevDependencies](guide/npm-packages#dev-dependencies) are only necessary to *develop* applications.
<div class="alert is-helpful">
**Library developers:** By default, the CLI command [`ng generate library`](cli/generate) creates a `package.json` for the new library. That `package.json` is used when publishing the library to npm.
For more information, see the CLI wiki page [Library Support](https://github.com/angular/angular-cli/wiki/stories-create-library).
</div>
The `package.json` includes two sets of packages,
[dependencies](guide/npm-packages#dependencies) and [devDependencies](guide/npm-packages#dev-dependencies).
The *dependencies* are essential to *running* the application.
The *devDependencies* are only necessary to *develop* the application.
{@a dependencies}
## Dependencies
The packages listed in the `dependencies` section of `package.json` are essential to *running* applications.
## *Dependencies*
The `dependencies` section of `package.json` contains:
* [**Angular packages**](#angular-packages): Angular core and optional modules; their package names begin `@angular/`.
* **Angular packages**: Angular core and optional modules; their package names begin `@angular/`.
* [**Support packages**](#support-packages): 3rd party libraries that must be present for Angular apps to run.
* **Support packages**: 3rd party libraries that must be present for Angular apps to run.
* [**Polyfill packages**](#polyfills): Polyfills plug gaps in a browser's JavaScript implementation.
* **Polyfill packages**: Polyfills plug gaps in a browser's JavaScript implementation.
To add a new dependency, use the [`ng add`](cli/add) command.
### Angular Packages
{@a angular-packages}
### Angular packages
**@angular/animations**: Angular's animations library makes it easy to define and apply animation effects such as page and list transitions.
Read about it in the [Animations guide](guide/animations).
The following Angular packages are included as dependencies in the default `package.json` file for a new Angular workspace.
For a complete list of Angular packages, see the [API reference](http://angular.io/api?type=package).
**@angular/common**: The commonly needed services, pipes, and directives provided by the Angular team.
The [`HttpClientModule`](guide/http) is also here, in the '@angular/common/http' subfolder.
Package name | Description
---------------------------------------- | --------------------------------------------------
[**@angular/animations**](api/animations) | Angular's animations library makes it easy to define and apply animation effects such as page and list transitions. For more information, see the [Animations guide](guide/animations).
[**@angular/common**](api/common) | The commonly-needed services, pipes, and directives provided by the Angular team. The [`HttpClientModule`](api/common/http/HttpClientModule) is also here, in the [`@angular/common/http`](api/common/http) subfolder. For more information, see the [HttpClient guide](guide/http).
**@angular/compiler** | Angular's template compiler. It understands templates and can convert them to code that makes the application run and render. Typically you dont interact with the compiler directly; rather, you use it indirectly via `platform-browser-dynamic` when JIT compiling in the browser. For more information, see the [Ahead-of-time Compilation guide](guide/aot-compiler).
[**@angular/core**](api/core) | Critical runtime parts of the framework that are needed by every application. Includes all metadata decorators, `Component`, `Directive`, dependency injection, and the component lifecycle hooks.
[**@angular/forms**](api/forms) | Support for both [template-driven](guide/forms) and [reactive forms](guide/reactive-forms). For information about choosing the best forms approach for your app, see [Introduction to forms](guide/forms-overview).
[**@angular/http**](api/http) | Angular's legacy HTTP client, which was deprecated in version 5.0 in favor of [@angular/common/http](api/common/http).
[**@angular/<br />platform&#8209;browser**](api/platform-browser) | Everything DOM and browser related, especially the pieces that help render into the DOM. This package also includes the `bootstrapModuleFactory()` method for bootstrapping applications for production builds that pre-compile with [AOT](guide/aot-compiler).
[**@angular/<br />platform&#8209;browser&#8209;dynamic**](api/platform-browser-dynamic) | Includes [providers](api/core/Provider) and methods to compile and run the app on the client using the [JIT compiler](guide/aot-compiler).
[**@angular/router**](api/router) | The router module navigates among your app pages when the browser URL changes. For more information, see [Routing and Navigation](guide/router).
**@angular/core**: Critical runtime parts of the framework needed by every application.
Includes all metadata decorators, `Component`, `Directive`, dependency injection, and the component lifecycle hooks.
**@angular/compiler**: Angular's *Template Compiler*.
It understands templates and can convert them to code that makes the application run and render.
Typically you dont interact with the compiler directly; rather, you use it indirectly via `platform-browser-dynamic` when [JIT compiling](guide/aot-compiler) in the browser.
{@a support-packages}
### Support packages
**@angular/forms**: support for both [template-driven](guide/forms) and [reactive forms](guide/reactive-forms).
The following support packages are included as dependencies in the default `package.json` file for a new Angular workspace.
**@angular/http**: Angular's old, deprecated, HTTP client.
**@angular/platform-browser**: Everything DOM and browser related, especially
the pieces that help render into the DOM.
This package also includes the `bootstrapModuleFactory()` method
for bootstrapping applications for production builds that pre-compile with [AOT](guide/aot-compiler).
Package name | Description
---------------------------------------- | --------------------------------------------------
[**rxjs**](https://github.com/ReactiveX/rxjs) | Many Angular APIs return [_observables_](guide/glossary#observable). RxJS is an implementation of the proposed [Observables specification](https://github.com/tc39/proposal-observable) currently before the [TC39](https://www.ecma-international.org/memento/tc39-m.htm) committee, which determines standards for the JavaScript language.
[**zone.js**](https://github.com/angular/zone.js) | Angular relies on zone.js to run Angular's change detection processes when native JavaScript operations raise events. Zone.js is an implementation of a [specification](https://gist.github.com/mhevery/63fdcdf7c65886051d55) currently before the [TC39](http://www.ecma-international.org/memento/TC39.htm) committee that determines standards for the JavaScript language.
**@angular/platform-browser-dynamic**: Includes [Providers](api/core/Provider)
and methods to compile and run the app on the client
using the [JIT compiler](guide/aot-compiler).
**@angular/router**: The [router module](/guide/router) navigates among your app pages when the browser URL changes.
**@angular/upgrade**: Set of utilities for upgrading AngularJS applications to Angular.
{@a polyfills}
### Polyfill packages
Many browsers lack native support for some features in the latest HTML standards,
features that Angular requires.
[_Polyfills_](https://en.wikipedia.org/wiki/Polyfill) can emulate the missing features.
"[Polyfills](https://en.wikipedia.org/wiki/Polyfill)" can emulate the missing features.
The [Browser Support](guide/browser-support) guide explains which browsers need polyfills and
how you can add them.
The `package.json` for a new Angular workspace installs the [core-js](https://github.com/zloirock/core-js) package,
The default `package.json` installs the **[core-js](https://github.com/zloirock/core-js)** package
which polyfills missing features for several popular browser.
### Support packages
**[rxjs](https://github.com/benlesh/RxJS)**: Many Angular APIs return _observables_. RxJS is an implementation of the proposed [Observables specification](https://github.com/zenparsing/es-observable) currently before the
[TC39](http://www.ecma-international.org/memento/TC39.htm) committee that determines standards for the JavaScript language.
**[zone.js](https://github.com/angular/zone.js)**: Angular relies on zone.js to run Angular's change detection processes when native JavaScript operations raise events. Zone.js is an implementation of a [specification](https://gist.github.com/mhevery/63fdcdf7c65886051d55) currently before the
[TC39](http://www.ecma-international.org/memento/TC39.htm) committee that determines standards for the JavaScript language.
{@a dev-dependencies}
## DevDependencies
## *DevDependencies*
The packages listed in the `devDependencies` section of `package.json` help you develop the application on your local machine. You don't deploy them with the production application.
The packages listed in the *devDependencies* section of the `package.json` help you develop the application on your local machine.
To add a new `devDependency`, use either one of the following commands:
You don't deploy them with the production application although there is no harm in doing so.
<code-example language="sh" class="code-shell">
npm install --dev &lt;package-name&gt;
</code-example>
<code-example language="sh" class="code-shell">
yarn add --dev &lt;package-name&gt;
</code-example>
The following `devDependencies` are provided in the default `package.json` file for a new Angular workspace.
**[@angular/cli](https://github.com/angular/angular-cli/)**: The Angular CLI tools.
Package name | Description
---------------------------------------- | -----------------------------------
[**@angular&#8209;devkit/<br />build&#8209;angular**](https://github.com/angular/angular-cli/) | The Angular build tools.
[**@angular/cli**](https://github.com/angular/angular-cli/) | The Angular CLI tools.
**@angular/<br />compiler&#8209;cli** | The Angular compiler, which is invoked by the Angular CLI's `ng build` and `ng serve` commands.
**@angular/<br />language&#8209;service** | The [Angular language service](guide/language-service) analyzes component templates and provides type and error information that TypeScript-aware editors can use to improve the developer's experience. For example, see the [Angular language service extension for VS Code](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template).
**@types/... ** | TypeScript definition files for 3rd party libraries such as Jasmine and Node.js.
[**codelyzer**](https://www.npmjs.com/package/codelyzer) | A linter for Angular apps whose rules conform to the Angular [style guide](guide/styleguide).
**jasmine/... ** | Packages to support the [Jasmine](https://jasmine.github.io/) test library.
**karma/... ** | Packages to support the [karma](https://www.npmjs.com/package/karma) test runner.
[**protractor**](https://www.npmjs.com/package/protractor) | An end-to-end (e2e) framework for Angular apps. Built on top of [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs).
[**ts-node**](https://www.npmjs.com/package/ts-node) | TypeScript execution environment and REPL for Node.js.
[**tslint**](https://www.npmjs.com/package/tslint) | A static analysis tool that checks TypeScript code for readability, maintainability, and functionality errors.
[**typescript**](https://www.npmjs.com/package/typescript) | The TypeScript language server, including the *tsc* TypeScript compiler.
**[@angular/compiler-cli](https://github.com/angular/angular/blob/master/packages/compiler-cli/README.md)**: The Angular compiler, which is invoked by the Angular CLI's `build` and `serve` commands.
## Related information
**[@angular/language-service](https://github.com/angular/angular-cli/)**: The Angular language service analyzes component templates and provides type and error information that TypeScript-aware editors can use to improve the developer's experience.
For example, see the [Angular language service extension for VS Code](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template)
For information about how the Angular CLI handles packages see the following guides:
* [Building and serving](guide/build) describes how packages come together to create a development build.
* [Deployment](guide/deployment) describes how packages come together to create a production build.
**@types/... **: TypeScript definition files for 3rd party libraries such as Jasmine and Node.js.
**[codelyzer](https://www.npmjs.com/package/codelyzer)**: A linter for Angular apps whose rules conform to the Angular [style guide](guide/styleguide).
**jasmine/... **: packages to support the [Jasmine](https://jasmine.github.io/) test library.
**karma/... **: packages to support the [karma](https://www.npmjs.com/package/karma) test runner.
**[protractor](https://www.npmjs.com/package/protractor)**: an end-to-end (e2e) framework for Angular apps.
Built on top of [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs).
**[ts-node](https://www.npmjs.com/package/ts-node)**: TypeScript execution environment and REPL for Node.js.
**[tslint](https://www.npmjs.com/package/tslint)**: a static analysis tool that checks TypeScript code for readability, maintainability, and functionality errors.
**[typescript](https://www.npmjs.com/package/typescript)**:
the TypeScript language server, including the *tsc* TypeScript compiler.
## So many packages! So many files!
The default `package.json` installs more packages than you'll need for your project.
A given package may contain tens, hundreds, even thousands of files,
all of them in your local machine's `node_modules` directory.
The sheer volume of files is intimidating,
You can remove packages that you don't need but how can you be sure that you won't need it?
As a practical matter, it's better to install a package you don't need than worry about it.
Extra packages and package files on your local development machine are harmless.
By default the Angular CLI build process bundles into a single file just the few "vendor" library files that your application actually needs.
The browser downloads this bundle, not the original package files.
See the [Deployment](guide/deployment) to learn more.

View File

@ -16,7 +16,7 @@ A good example of usage can be found on the [EventEmitter](https://angular.io/ap
Here is the component definition:
<code-example path="observables-in-angular/src/main.ts" header="EventEmitter" region="eventemitter"></code-example>
<code-example path="observables-in-angular/src/main.ts" title="EventEmitter" region="eventemitter"></code-example>
## HTTP
Angulars `HttpClient` returns observables from HTTP method calls. For instance, `http.get(/api)` returns an observable. This provides several advantages over promise-based HTTP APIs:
@ -32,20 +32,20 @@ The [AsyncPipe](https://angular.io/api/common/AsyncPipe) subscribes to an observ
The following example binds the `time` observable to the component's view. The observable continuously updates the view with the current time.
<code-example path="observables-in-angular/src/main.ts" header="Using async pipe" region="pipe"></code-example>
<code-example path="observables-in-angular/src/main.ts" title="Using async pipe" region="pipe"></code-example>
## Router
[`Router.events`](https://angular.io/api/router/Router#events) provides events as observables. You can use the `filter()` operator from RxJS to look for events of interest, and subscribe to them in order to make decisions based on the sequence of events in the navigation process. Here's an example:
<code-example path="observables-in-angular/src/main.ts" header="Router events" region="router"></code-example>
<code-example path="observables-in-angular/src/main.ts" title="Router events" region="router"></code-example>
The [ActivatedRoute](https://angular.io/api/router/ActivatedRoute) is an injected router service that makes use of observables to get information about a route path and parameters. For example, `ActivateRoute.url` contains an observable that reports the route path or paths. Here's an example:
<code-example path="observables-in-angular/src/main.ts" header="ActivatedRoute" region="activated_route"></code-example>
<code-example path="observables-in-angular/src/main.ts" title="ActivatedRoute" region="activated_route"></code-example>
## Reactive forms
Reactive forms have properties that use observables to monitor form control values. The [`FormControl`](https://angular.io/api/forms/FormControl) properties `valueChanges` and `statusChanges` contain observables that raise change events. Subscribing to an observable form-control property is a way of triggering application logic within the component class. For example:
<code-example path="observables-in-angular/src/main.ts" header="Reactive forms" region="forms"></code-example>
<code-example path="observables-in-angular/src/main.ts" title="Reactive forms" region="forms"></code-example>

View File

@ -17,7 +17,7 @@ To execute the observable you have created and begin receiving notifications, yo
Here's an example that demonstrates the basic usage model by showing how an observable could be used to provide geolocation updates.
<code-example path="observables/src/geolocation.ts" header="Observe geolocation updates"></code-example>
<code-example path="observables/src/geolocation.ts" title="Observe geolocation updates"></code-example>
## Defining observers
@ -49,11 +49,11 @@ Here's an example of creating and subscribing to a simple observable, with an ob
<code-example
path="observables/src/subscribing.ts"
region="observer"
header="Subscribe using observer"></code-example>
title="Subscribe using observer"></code-example>
Alternatively, the `subscribe()` method can accept callback function definitions in line, for `next`, `error`, and `complete` handlers. For example, the following `subscribe()` call is the same as the one that specifies the predefined observer:
<code-example path="observables/src/subscribing.ts" region="sub_fn" header="Subscribe with positional arguments"></code-example>
<code-example path="observables/src/subscribing.ts" region="sub_fn" title="Subscribe with positional arguments"></code-example>
In either case, a `next` handler is required. The `error` and `complete` handlers are optional.
@ -65,15 +65,15 @@ Use the `Observable` constructor to create an observable stream of any type. The
For example, to create an observable equivalent to the `of(1, 2, 3)` above, you could do something like this:
<code-example path="observables/src/creating.ts" region="subscriber" header="Create observable with constructor"></code-example>
<code-example path="observables/src/creating.ts" region="subscriber" title="Create observable with constructor"></code-example>
To take this example a little further, we can create an observable that publishes events. In this example, the subscriber function is defined inline.
<code-example path="observables/src/creating.ts" region="fromevent" header="Create with custom fromEvent function"></code-example>
<code-example path="observables/src/creating.ts" region="fromevent" title="Create with custom fromEvent function"></code-example>
Now you can use this function to create an observable that publishes keydown events:
<code-example path="observables/src/creating.ts" region="fromevent_use" header="Use custom fromEvent function"></code-example>
<code-example path="observables/src/creating.ts" region="fromevent_use" title="Use custom fromEvent function"></code-example>
## Multicasting
@ -87,15 +87,15 @@ When creating an observable you should determine how you want that observable to
Lets look at an example that counts from 1 to 3, with a one-second delay after each number emitted.
<code-example path="observables/src/multicasting.ts" region="delay_sequence" header="Create a delayed sequence"></code-example>
<code-example path="observables/src/multicasting.ts" region="delay_sequence" title="Create a delayed sequence"></code-example>
Notice that if you subscribe twice, there will be two separate streams, each emitting values every second. It looks something like this:
<code-example path="observables/src/multicasting.ts" region="subscribe_twice" header="Two subscriptions"></code-example>
<code-example path="observables/src/multicasting.ts" region="subscribe_twice" title="Two subscriptions"></code-example>
Changing the observable to be multicasting could look something like this:
<code-example path="observables/src/multicasting.ts" region="multicast_sequence" header="Create a multicast subscriber"></code-example>
<code-example path="observables/src/multicasting.ts" region="multicast_sequence" title="Create a multicast subscriber"></code-example>
<div class="alert is-helpful">
Multicasting observables take a bit more setup, but they can be useful for certain applications. Later we will look at tools that simplify the process of multicasting, allowing you to take any observable and make it multicasting.

View File

@ -26,7 +26,7 @@ In this page, you'll use pipes to transform a component's birthday property into
a human-friendly date.
<code-example path="pipes/src/app/hero-birthday1.component.ts" header="src/app/hero-birthday1.component.ts" linenums="false">
<code-example path="pipes/src/app/hero-birthday1.component.ts" title="src/app/hero-birthday1.component.ts" linenums="false">
</code-example>
@ -35,7 +35,7 @@ a human-friendly date.
Focus on the component's template.
<code-example path="pipes/src/app/app.component.html" region="hero-birthday-template" header="src/app/app.component.html" linenums="false">
<code-example path="pipes/src/app/app.component.html" region="hero-birthday-template" title="src/app/app.component.html" linenums="false">
</code-example>
@ -79,7 +79,7 @@ Modify the birthday template to give the date pipe a format parameter.
After formatting the hero's April 15th birthday, it renders as **<samp>04/15/88</samp>**:
<code-example path="pipes/src/app/app.component.html" region="format-birthday" header="src/app/app.component.html" linenums="false">
<code-example path="pipes/src/app/app.component.html" region="format-birthday" title="src/app/app.component.html" linenums="false">
</code-example>
@ -95,7 +95,7 @@ Write a second component that *binds* the pipe's format parameter
to the component's `format` property. Here's the template for that component:
<code-example path="pipes/src/app/hero-birthday2.component.ts" region="template" header="src/app/hero-birthday2.component.ts (template)" linenums="false">
<code-example path="pipes/src/app/hero-birthday2.component.ts" region="template" title="src/app/hero-birthday2.component.ts (template)" linenums="false">
</code-example>
@ -106,7 +106,7 @@ That method toggles the component's `format` property between a short form
(`'shortDate'`) and a longer form (`'fullDate'`).
<code-example path="pipes/src/app/hero-birthday2.component.ts" region="class" header="src/app/hero-birthday2.component.ts (class)" linenums="false">
<code-example path="pipes/src/app/hero-birthday2.component.ts" region="class" title="src/app/hero-birthday2.component.ts (class)" linenums="false">
</code-example>
@ -143,7 +143,7 @@ the birthday is chained to the `DatePipe` and on to the `UpperCasePipe`.
The birthday displays as **<samp>APR 15, 1988</samp>**.
<code-example path="pipes/src/app/app.component.html" region="chained-birthday" header="src/app/app.component.html" linenums="false">
<code-example path="pipes/src/app/app.component.html" region="chained-birthday" title="src/app/app.component.html" linenums="false">
</code-example>
@ -153,7 +153,7 @@ This example&mdash;which displays **<samp>FRIDAY, APRIL 15, 1988</samp>**&mdash;
the same pipes as above, but passes in a parameter to `date` as well.
<code-example path="pipes/src/app/app.component.html" region="chained-parameter-birthday" header="src/app/app.component.html" linenums="false">
<code-example path="pipes/src/app/app.component.html" region="chained-parameter-birthday" title="src/app/app.component.html" linenums="false">
</code-example>
@ -166,7 +166,7 @@ You can write your own custom pipes.
Here's a custom pipe named `ExponentialStrengthPipe` that can boost a hero's powers:
<code-example path="pipes/src/app/exponential-strength.pipe.ts" header="src/app/exponential-strength.pipe.ts" linenums="false">
<code-example path="pipes/src/app/exponential-strength.pipe.ts" title="src/app/exponential-strength.pipe.ts" linenums="false">
</code-example>
@ -200,7 +200,7 @@ Technically, it's optional; Angular looks for and executes the `transform` metho
Now you need a component to demonstrate the pipe.
<code-example path="pipes/src/app/power-booster.component.ts" header="src/app/power-booster.component.ts" linenums="false">
<code-example path="pipes/src/app/power-booster.component.ts" title="src/app/power-booster.component.ts" linenums="false">
</code-example>
<figure>
@ -223,7 +223,7 @@ Note the following:
You must register custom pipes.
If you don't, Angular reports an error.
The [Angular CLI's](cli) generator registers the pipe automatically.
Angular CLI's generator registers the pipe automatically.
</div>
@ -240,7 +240,7 @@ Upgrade the example to a "Power Boost Calculator" that combines
your pipe and two-way data binding with `ngModel`.
<code-example path="pipes/src/app/power-boost-calculator.component.ts" header="src/app/power-boost-calculator.component.ts">
<code-example path="pipes/src/app/power-boost-calculator.component.ts" title="src/app/power-boost-calculator.component.ts">
</code-example>
@ -270,7 +270,7 @@ In the next example, the component uses the default, aggressive change detection
its display of every hero in the `heroes` array. Here's the template:
<code-example path="pipes/src/app/flying-heroes.component.html" region="template-1" header="src/app/flying-heroes.component.html (v1)" linenums="false">
<code-example path="pipes/src/app/flying-heroes.component.html" region="template-1" title="src/app/flying-heroes.component.html (v1)" linenums="false">
</code-example>
@ -278,7 +278,7 @@ its display of every hero in the `heroes` array. Here's the template:
The companion component class provides heroes, adds heroes into the array, and can reset the array.
<code-example path="pipes/src/app/flying-heroes.component.ts" region="v1" header="src/app/flying-heroes.component.ts (v1)" linenums="false">
<code-example path="pipes/src/app/flying-heroes.component.ts" region="v1" title="src/app/flying-heroes.component.ts (v1)" linenums="false">
</code-example>
@ -292,7 +292,7 @@ If you added the ability to remove or change a hero, Angular would detect those
Add a `FlyingHeroesPipe` to the `*ngFor` repeater that filters the list of heroes to just those heroes who can fly.
<code-example path="pipes/src/app/flying-heroes.component.html" region="template-flying-heroes" header="src/app/flying-heroes.component.html (flyers)" linenums="false">
<code-example path="pipes/src/app/flying-heroes.component.html" region="template-flying-heroes" title="src/app/flying-heroes.component.html (flyers)" linenums="false">
</code-example>
@ -300,7 +300,7 @@ Add a `FlyingHeroesPipe` to the `*ngFor` repeater that filters the list of heroe
Here's the `FlyingHeroesPipe` implementation, which follows the pattern for custom pipes described earlier.
<code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pure" header="src/app/flying-heroes.pipe.ts" linenums="false">
<code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pure" title="src/app/flying-heroes.pipe.ts" linenums="false">
</code-example>
@ -314,7 +314,7 @@ It's just using a different change-detection algorithm that ignores changes to t
Notice how a hero is added:
<code-example path="pipes/src/app/flying-heroes.component.ts" region="push" header="src/app/flying-heroes.component.ts" linenums="false">
<code-example path="pipes/src/app/flying-heroes.component.ts" region="push" title="src/app/flying-heroes.component.ts" linenums="false">
</code-example>
@ -364,7 +364,7 @@ You make a pipe impure by setting its pure flag to false. You could make the `Fl
impure like this:
<code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pipe-decorator" header="src/app/flying-heroes.pipe.ts" linenums="false">
<code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pipe-decorator" title="src/app/flying-heroes.pipe.ts" linenums="false">
</code-example>
@ -422,11 +422,11 @@ The complete implementation is as follows:
<code-tabs>
<code-pane header="FlyingHeroesImpurePipe" path="pipes/src/app/flying-heroes.pipe.ts" region="impure">
<code-pane title="FlyingHeroesImpurePipe" path="pipes/src/app/flying-heroes.pipe.ts" region="impure">
</code-pane>
<code-pane header="FlyingHeroesPipe" path="pipes/src/app/flying-heroes.pipe.ts" region="pure">
<code-pane title="FlyingHeroesPipe" path="pipes/src/app/flying-heroes.pipe.ts" region="pure">
</code-pane>
@ -440,7 +440,7 @@ The only difference is the `pure` flag in the pipe metadata.
This is a good candidate for an impure pipe because the `transform` function is trivial and fast.
<code-example path="pipes/src/app/flying-heroes.pipe.ts" linenums="false" header="src/app/flying-heroes.pipe.ts (filter)" region="filter">
<code-example path="pipes/src/app/flying-heroes.pipe.ts" linenums="false" title="src/app/flying-heroes.pipe.ts (filter)" region="filter">
</code-example>
@ -449,7 +449,7 @@ This is a good candidate for an impure pipe because the `transform` function is
You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`.
<code-example path="pipes/src/app/flying-heroes-impure.component.html" linenums="false" header="src/app/flying-heroes-impure.component.html (excerpt)" region="template-flying-heroes">
<code-example path="pipes/src/app/flying-heroes-impure.component.html" linenums="false" title="src/app/flying-heroes-impure.component.html (excerpt)" region="template-flying-heroes">
</code-example>
@ -476,7 +476,7 @@ This next example binds an `Observable` of message strings
(`message$`) to a view with the `async` pipe.
<code-example path="pipes/src/app/hero-async-message.component.ts" header="src/app/hero-async-message.component.ts">
<code-example path="pipes/src/app/hero-async-message.component.ts" title="src/app/hero-async-message.component.ts">
</code-example>
@ -499,7 +499,7 @@ In the following code, the pipe only calls the server when the request URL chang
The code uses the [Angular http](guide/http) client to retrieve data:
<code-example path="pipes/src/app/fetch-json.pipe.ts" header="src/app/fetch-json.pipe.ts">
<code-example path="pipes/src/app/fetch-json.pipe.ts" title="src/app/fetch-json.pipe.ts">
</code-example>
@ -509,7 +509,7 @@ Now demonstrate it in a harness component whose template defines two bindings to
both requesting the heroes from the `heroes.json` file.
<code-example path="pipes/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts">
<code-example path="pipes/src/app/hero-list.component.ts" title="src/app/hero-list.component.ts">
</code-example>

View File

@ -14,10 +14,10 @@ Observables can simplify the implementation of type-ahead suggestions. Typically
Writing this in full JavaScript can be quite involved. With observables, you can use a simple series of RxJS operators:
<code-example path="practical-observable-usage/src/typeahead.ts" header="Typeahead"></code-example>
<code-example path="practical-observable-usage/src/typeahead.ts" title="Typeahead"></code-example>
## Exponential backoff
Exponential backoff is a technique in which you retry an API after failure, making the time in between retries longer after each consecutive failure, with a maximum number of retries after which the request is considered to have failed. This can be quite complex to implement with promises and other methods of tracking AJAX calls. With observables, it is very easy:
<code-example path="practical-observable-usage/src/backoff.ts" header="Exponential backoff"></code-example>
<code-example path="practical-observable-usage/src/backoff.ts" title="Exponential backoff"></code-example>

View File

@ -13,7 +13,7 @@ A provider is an instruction to the DI system on how to obtain a value for a dep
## Providing a service
If you already have an app that was created with the [Angular CLI](cli), you can create a service using the [`ng generate`](cli/generate) CLI command in the root project directory. Replace _User_ with the name of your service.
If you already have a CLI generated app, create a service using the following CLI command in the root project directory. Replace _User_ with the name of your service.
```sh
ng generate service User
@ -21,7 +21,7 @@ ng generate service User
This command creates the following `UserService` skeleton:
<code-example path="providers/src/app/user.service.0.ts" header="src/app/user.service.0.ts" linenums="false"> </code-example>
<code-example path="providers/src/app/user.service.0.ts" title="src/app/user.service.0.ts" linenums="false"> </code-example>
You can now inject `UserService` anywhere in your application.
@ -38,15 +38,15 @@ You should always provide your service in the root injector unless there is a ca
It's also possible to specify that a service should be provided in a particular `@NgModule`. For example, if you don't want `UserService` to be available to applications unless they import a `UserModule` you've created, you can specify that the service should be provided in the module:
<code-example path="providers/src/app/user.service.1.ts" header="src/app/user.service.1.ts" linenums="false"> </code-example>
<code-example path="providers/src/app/user.service.1.ts" title="src/app/user.service.1.ts" linenums="false"> </code-example>
The example above shows the preferred way to provide a service in a module. This method is preferred because it enables tree-shaking of the service if nothing injects it. If it's not possible to specify in the service which module should provide it, you can also declare a provider for the service within the module:
<code-example path="providers/src/app/user.module.ts" header="src/app/user.module.ts" linenums="false"> </code-example>
<code-example path="providers/src/app/user.module.ts" title="src/app/user.module.ts" linenums="false"> </code-example>
## Limiting provider scope by lazy loading modules
In the basic CLI-generated app, modules are eagerly loaded which means that they are all loaded when the app launches. Angular uses an injector system to make things available between modules. In an eagerly loaded app, the root application injector makes all of the providers in all of the modules available throughout the app.
In the basic CLI generated app, modules are eagerly loaded which means that they are all loaded when the app launches. Angular uses an injector system to make things available between modules. In an eagerly loaded app, the root application injector makes all of the providers in all of the modules available throughout the app.
This behavior necessarily changes when you use lazy loading. Lazy loading is when you load modules only when you need them; for example, when routing. They arent loaded right away like with eagerly loaded modules. This means that any services listed in their provider arrays arent available because the root injector doesnt know about these modules.
@ -67,7 +67,7 @@ method is helpful for when you want to eagerly load a module that needs a servic
Providing a service in the component limits the service only to that component (other components in
the same module cant access it.)
<code-example path="providers/src/app/app.component.ts" region="component-providers" header="src/app/app.component.ts" linenums="false">
<code-example path="providers/src/app/app.component.ts" region="component-providers" title="src/app/app.component.ts" linenums="false">
</code-example>

View File

@ -1,51 +1,46 @@
# Getting started
# Getting Started
Welcome to Angular! Angular helps you build modern applications for the web, mobile, or desktop.
Good tools make application development quicker and easier to maintain than
if you did everything by hand.
This guide shows you how to build and run a simple Angular
app. You'll use the [Angular CLI tool](cli "CLI command reference") to accelerate development,
while adhering to the [Style Guide](guide/styleguide "Angular style guide") recommendations that
The [**Angular CLI**](https://cli.angular.io/) is a **_command line interface_** tool
that can create a project, add files, and perform a variety of ongoing development tasks such
as testing, bundling, and deployment.
The goal in this guide is to build and run a simple Angular
application in TypeScript, using the Angular CLI
while adhering to the [Style Guide](guide/styleguide) recommendations that
benefit _every_ Angular project.
This guide takes less than 30 minutes to complete.
At the end of this guide&mdash;as part of final code review&mdash;there is a link to download a copy of the final application code. (If you don't execute the commands in this guide, you can still download the final application code.)
By the end of the chapter, you'll have a basic understanding of development with the CLI
and a foundation for both these documentation samples and for real world applications.
And you can also <a href="generated/zips/cli-quickstart/cli-quickstart.zip" target="_blank">download the example.</a>
<h2 id='devenv'>
Step 1. Set up the Development Environment
</h2>
{@a devenv}
{@a prerequisites}
## Prerequisites
Before you begin, make sure your development environment includes `Node.js®` and an npm package manager.
You need to set up your development environment before you can do anything.
{@a nodejs}
### Node.js
Install **[Node.js® and npm](https://nodejs.org/en/download/)**
if they are not already on your machine.
Angular requires `Node.js` version 8.x or 10.x.
* To check your version, run `node -v` in a terminal/console window.
* To get `Node.js`, go to [nodejs.org](https://nodejs.org "Nodejs.org").
{@a npm}
### npm package manager
Angular, the Angular CLI, and Angular apps depend on features and functionality provided by libraries that are available as [npm packages](https://docs.npmjs.com/getting-started/what-is-npm). To download and install npm packages, you must have an npm package manager.
This Quick Start uses the [npm client](https://docs.npmjs.com/cli/install) command line interface, which is installed with `Node.js` by default.
To check that you have the npm client installed, run `npm -v` in a terminal/console window.
<div class="alert is-helpful">
{@a install-cli}
## Step 1: Install the Angular CLI
**Verify that you are running at least Node.js version `8.x` or greater and npm version `5.x` or greater**
by running `node -v` and `npm -v` in a terminal/console window.
Older versions produce errors, but newer versions are fine.
You use the Angular CLI
to create projects, generate application and library code, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
</div>
Install the Angular CLI globally.
To install the CLI using `npm`, open a terminal/console window and enter the following command:
Then install the [Angular CLI](https://github.com/angular/angular-cli) globally.
<code-example language="sh" class="code-shell">
@ -55,86 +50,101 @@ To install the CLI using `npm`, open a terminal/console window and enter the fol
{@a create-proj}
## Step 2: Create a workspace and initial application
<h2 id='create-proj'>
Step 2. Create a new project
</h2>
You develop apps in the context of an Angular [**workspace**](guide/glossary#workspace). A workspace contains the files for one or more [**projects**](guide/glossary/#project). A project is the set of files that comprise an app, a library, or end-to-end (e2e) tests.
To create a new workspace and initial app project:
1. Run the CLI command `ng new` and provide the name `my-app`, as shown here:
Open a terminal window.
<code-example language="sh" class="code-shell">
ng new my-app
</code-example>
Generate a new project and default app by running the following command:
2. The `ng new` command prompts you for information about features to include in the initial app project. Accept the defaults by pressing the Enter or Return key.
The Angular CLI installs the necessary Angular npm packages and other dependencies. This can take a few minutes.
<code-example language="sh" class="code-shell">
ng new my-app
It also creates the following workspace and starter project files:
</code-example>
* A new workspace, with a root folder named `my-app`
* An initial skeleton app project, also called `my-app` (in the `src` subfolder)
* An end-to-end test project (in the `e2e` subfolder)
* Related configuration files
The initial app project contains a simple Welcome app, ready to run.
The Angular CLI installs the necessary npm packages, creates the project files, and populates the project with a simple default app. This can take some time.
{@a serve}
## Step 3: Serve the application
Angular includes a server, so that you can easily build and serve your app locally.
<div class="alert is-helpful">
1. Go to the workspace folder (`my-app`).
1. Launch the server by using the CLI command `ng serve`, with the `--open` option.
You can add pre-packaged functionality to a new project by using the `ng add` command. The `ng add` command transforms a project by applying the schematics in the specified package.
For more information, see the [Angular CLI documentation.](https://github.com/angular/angular-cli/wiki/add "Angular CLI documentation")
Angular Material provides schematics for typical app layouts.
See the [Angular Material documentation](https://material.angular.io/guides "Angular Material documentation") for details.
</div>
<h2 id='serve'>
Step 3: Serve the application
</h2>
Go to the project directory and launch the server.
<code-example language="sh" class="code-shell">
cd my-app
ng serve --open
</code-example>
The `ng serve` command launches the server, watches your files,
and rebuilds the app as you make changes to those files.
The `--open` (or just `-o`) option automatically opens your browser
to `http://localhost:4200/`.
Using the `--open` (or just `-o`) option will automatically open your browser
on `http://localhost:4200/`.
Your app greets you with a message:
<figure>
<img src='generated/images/guide/cli-quickstart/app-works.png' alt="Welcome to my-app!">
<img src='generated/images/guide/cli-quickstart/app-works.png' alt="The app works!">
</figure>
{@a first-component}
## Step 4: Edit your first Angular component
<h2 id='first-component'>
Step 4: Edit your first Angular component
</h2>
[**_Components_**](guide/glossary#component) are the fundamental building blocks of Angular applications.
They display data on the screen, listen for user input, and take action based on that input.
As part of the initial app, the CLI created the first Angular component for you. It is the _root component_, and it is named `app-root`.
1. Open `./src/app/app.component.ts`.
The CLI created the first Angular component for you.
This is the _root component_ and it is named `app-root`.
You can find it in `./src/app/app.component.ts`.
2. Change the `title` property from `'my-app'` to `'My First Angular App'`.
<code-example path="cli-quickstart/src/app/app.component.ts" region="component" header="src/app/app.component.ts" linenums="false"></code-example>
Open the component file and change the `title` property from `'app'` to `'My First Angular App!'`.
The browser reloads automatically with the revised title. That's nice, but it could look better.
3. Open `./src/app/app.component.css` and give the component some style.
<code-example path="cli-quickstart/src/app/app.component.ts" region="title" title="src/app/app.component.ts" linenums="false"></code-example>
The browser reloads automatically with the revised title. That's nice, but it could look better.
Open `src/app/app.component.css` and give the component some style.
<code-example path="cli-quickstart/src/app/app.component.css" title="src/app/app.component.css" linenums="false"></code-example>
<code-example path="cli-quickstart/src/app/app.component.css" header="src/app/app.component.css" linenums="false"></code-example>
Looking good!
<figure>
<img src='generated/images/guide/cli-quickstart/my-first-app.png' alt="Output of Getting Started app">
@ -142,43 +152,490 @@ Looking good!
{@a project-file-review}
## Final code review
You can <a href="generated/zips/cli-quickstart/cli-quickstart.zip" target="_blank">download an example</a> of the app that you created in this Getting Started guide.
Looking good!
<div class="alert is-helpful">
**Tip:** Most Angular guides include links to download example files and run live examples in [Stackblitz](http://www.stackblitz.com), so that you can see Angular concepts and code in action.
## What's next?
That's about all you'd expect to do in a "Hello, World" app.
You're ready to take the [Tour of Heroes Tutorial](tutorial) and build
a small application that demonstrates the great things you can build with Angular.
Or you can stick around a bit longer to learn about the files in your brand new project.
## Project file review
An Angular CLI project is the foundation for both quick experiments and enterprise solutions.
The first file you should check out is `README.md`.
It has some basic information on how to use CLI commands.
Whenever you want to know more about how Angular CLI works make sure to visit
[the Angular CLI repository](https://github.com/angular/angular-cli) and
[Wiki](https://github.com/angular/angular-cli/wiki).
Some of the generated files might be unfamiliar to you.
### The `src` folder
Your app lives in the `src` folder.
All Angular components, templates, styles, images, and anything else your app needs go here.
Any files outside of this folder are meant to support building your app.
<div class='filetree'>
<div class='file'>src</div>
<div class='children'>
<div class='file'>app</div>
<div class='children'>
<div class='file'>app.component.css</div>
<div class='file'>app.component.html</div>
<div class="file">app.component.spec.ts</div>
<div class="file">app.component.ts</div>
<div class="file">app.module.ts</div>
</div>
<div class="file">assets</div>
<div class='children'>
<div class="file">.gitkeep</div>
</div>
<div class="file">environments</div>
<div class='children'>
<div class="file">environment.prod.ts</div>
<div class="file">environment.ts</div>
</div>
<div class="file">browserslist</div>
<div class="file">favicon.ico</div>
<div class="file">index.html</div>
<div class="file">karma.conf.js</div>
<div class="file">main.ts</div>
<div class="file">polyfills.ts</div>
<div class="file">styles.css</div>
<div class="file">test.ts</div>
<div class="file">tsconfig.app.json</div>
<div class="file">tsconfig.spec.json</div>
<div class="file">tslint.json</div>
</div>
</div>
For more information about Angular project files and the file structure, see [Workspace and project file struture](guide/file-structure).
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="20%">
</col>
<col width="80%">
</col>
<tr>
<th>
File
</th>
<th>
Purpose
</th>
</tr>
<tr>
<td>
## Next steps
`app/app.component.{ts,html,css,spec.ts}`
Now that you've seen the essentials of an Angular app and the Angular CLI, continue with these other introductory materials:
</td>
<td>
* The [Tour of Heroes tutorial](tutorial "Tour of Heroes tutorial") provides additional hands-on learning. It walks you through the steps to build an app that helps a staffing agency manage a group of superhero employees.
It has many of the features you'd expect to find in a data-driven application:
Defines the `AppComponent` along with an HTML template, CSS stylesheet, and a unit test.
It is the **root** component of what will become a tree of nested components
as the application evolves.
- Acquiring and displaying a list of items
</td>
</tr>
<tr>
<td>
- Editing a selected item's detail
`app/app.module.ts`
- Navigating among different views of the data
</td>
<td>
Defines `AppModule`, the [root module](guide/bootstrapping "AppModule: the root module") that tells Angular how to assemble the application.
Right now it declares only the `AppComponent`.
Soon there will be more components to declare.
</td>
</tr>
<tr>
<td>
`assets/*`
</td>
<td>
A folder where you can put images and anything else to be copied wholesale
when you build your application.
</td>
</tr>
<tr>
<td>
`environments/*`
</td>
<td>
This folder contains one file for each of your destination environments,
each exporting simple configuration variables to use in your application.
The files are replaced on-the-fly when you build your app.
You might use a different API endpoint for development than you do for production
or maybe different analytics tokens.
You might even use some mock services.
Either way, the CLI has you covered.
</td>
</tr>
<tr>
<td>
`browserslist`
</td>
<td>
A configuration file to share [target browsers](https://github.com/browserslist/browserslist) between different front-end tools.
</td>
</tr>
<tr>
<td>
`favicon.ico`
</td>
<td>
Every site wants to look good on the bookmark bar.
Get started with your very own Angular icon.
</td>
</tr>
<tr>
<td>
`index.html`
</td>
<td>
The main HTML page that is served when someone visits your site.
Most of the time you'll never need to edit it.
The CLI automatically adds all `js` and `css` files when building your app so you
never need to add any `<script>` or `<link>` tags here manually.
</td>
</tr>
<tr>
<td>
`karma.conf.js`
</td>
<td>
Unit test configuration for the [Karma test runner](https://karma-runner.github.io),
used when running `ng test`.
</td>
</tr>
<tr>
<td>
`main.ts`
</td>
<td>
The main entry point for your app.
Compiles the application with the [JIT compiler](guide/glossary#jit)
and bootstraps the application's root module (`AppModule`) to run in the browser.
You can also use the [AOT compiler](guide/aot-compiler)
without changing any code by appending the`--aot` flag to the `ng build` and `ng serve` commands.
</td>
</tr>
<tr>
<td>
`polyfills.ts`
</td>
<td>
Different browsers have different levels of support of the web standards.
Polyfills help normalize those differences.
You should be pretty safe with `core-js` and `zone.js`, but be sure to check out
the [Browser Support guide](guide/browser-support) for more information.
</td>
</tr>
<tr>
<td>
`styles.css`
</td>
<td>
Your global styles go here.
Most of the time you'll want to have local styles in your components for easier maintenance,
but styles that affect all of your app need to be in a central place.
</td>
</tr>
<tr>
<td>
`test.ts`
</td>
<td>
This is the main entry point for your unit tests.
It has some custom configuration that might be unfamiliar, but it's not something you'll
need to edit.
</td>
</tr>
<tr>
<td>
`tsconfig.{app|spec}.json`
</td>
<td>
TypeScript compiler configuration for the Angular app (`tsconfig.app.json`)
and for the unit tests (`tsconfig.spec.json`).
</td>
</tr>
<tr>
<td>
`tslint.json`
</td>
<td>
Additional Linting configuration for [TSLint](https://palantir.github.io/tslint/) together with
[Codelyzer](http://codelyzer.com/), used when running `ng lint`.
Linting helps keep your code style consistent.
</td>
</tr>
</table>
### The root folder
The `src/` folder is just one of the items inside the project's root folder.
Other files help you build, test, maintain, document, and deploy the app.
These files go in the root folder next to `src/`.
* The [Architecture guide](guide/architecture "Architecture guide") describes key concepts such as modules, components, services, and dependency injection (DI). It provides a foundation for more in-depth guides about specific Angular concepts and features.
<div class='filetree'>
<div class="file">my-app</div>
<div class='children'>
<div class="file">e2e</div>
<div class='children'>
<div class="file">src</div>
<div class='children'>
<div class="file">app.e2e-spec.ts</div>
<div class="file">app.po.ts</div>
</div>
<div class="file">tsconfig.e2e.json</div>
<div class="file">protractor.conf.js</div>
</div>
<div class="file">node_modules/...</div>
<div class="file">src/...</div>
<div class='children'>
<div class="file">karma.conf.js</div>
</div>
<div class="file">.editorconfig</div>
<div class="file">.gitignore</div>
<div class="file">angular.json</div>
<div class="file">package.json</div>
<div class="file">README.md</div>
<div class="file">tsconfig.json</div>
<div class="file">tslint.json</div>
</div>
</div>
After the Tutorial and Architecture guide, you'll be ready to continue exploring Angular on your own through the other guides and references in this documentation set, focusing on the features most important for your apps.
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="20%">
</col>
<col width="80%">
</col>
<tr>
<th>
File
</th>
<th>
Purpose
</th>
</tr>
<tr>
<td>
`e2e/`
</td>
<td>
Inside `e2e/` live the end-to-end tests.
They shouldn't be inside `src/` because e2e tests are really a separate app that
just so happens to test your main app.
That's also why they have their own `tsconfig.e2e.json`.
</td>
</tr>
<tr>
<td>
`node_modules/`
</td>
<td>
`Node.js` creates this folder and puts all third party modules listed in
`package.json` inside of it.
</td>
</tr>
<tr>
<td>
`.editorconfig`
</td>
<td>
Simple configuration for your editor to make sure everyone that uses your project
has the same basic configuration.
Most editors support an `.editorconfig` file.
See http://editorconfig.org for more information.
</td>
</tr>
<tr>
<td>
`.gitignore`
</td>
<td>
Git configuration to make sure autogenerated files are not committed to source control.
</td>
</tr>
<tr>
<td>
`angular.json`
</td>
<td>
Configuration for Angular CLI.
In this file you can set several defaults and also configure what files are included
when your project is built.
Check out the official documentation if you want to know more.
</td>
</tr>
<tr>
<td>
`package.json`
</td>
<td>
`npm` configuration listing the third party packages your project uses.
You can also add your own [custom scripts](https://docs.npmjs.com/misc/scripts) here.
</td>
</tr>
<tr>
<td>
`protractor.conf.js`
</td>
<td>
End-to-end test configuration for [Protractor](http://www.protractortest.org/),
used when running `ng e2e`.
</td>
</tr>
<tr>
<td>
`README.md`
</td>
<td>
Basic documentation for your project, pre-filled with CLI command information.
Make sure to enhance it with project documentation so that anyone
checking out the repo can build your app!
</td>
</tr>
<tr>
<td>
`tsconfig.json`
</td>
<td>
TypeScript compiler configuration for your IDE to pick up and give you helpful tooling.
</td>
</tr>
<tr>
<td>
`tslint.json`
</td>
<td>
Linting configuration for [TSLint](https://palantir.github.io/tslint/) together with
[Codelyzer](http://codelyzer.com/), used when running `ng lint`.
Linting helps keep your code style consistent.
</td>
</tr>
</table>
<div class="alert is-helpful">
### Next Step
If you're new to Angular, continue with the
[tutorial](tutorial "Tour of Heroes tutorial").
You can skip the "Setup" step since you're already using the Angular CLI setup.
</div>

View File

@ -26,7 +26,7 @@ This section describes how to add a single form control. In the example, the use
To use reactive forms, import `ReactiveFormsModule` from the `@angular/forms` package and add it to your NgModule's `imports` array.
<code-example path="reactive-forms/src/app/app.module.ts" region="imports" header="src/app/app.module.ts (excerpt)">
<code-example path="reactive-forms/src/app/app.module.ts" region="imports" title="src/app/app.module.ts (excerpt)">
</code-example>
@ -42,7 +42,7 @@ Generate a component for the control.
The `FormControl` class is the basic building block when using reactive forms. To register a single form control, import the `FormControl` class into your component and create a new instance of the form control to save as a class property.
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.ts" region="create-control" header="src/app/name-editor/name-editor.component.ts">
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.ts" region="create-control" title="src/app/name-editor/name-editor.component.ts">
</code-example>
@ -52,7 +52,7 @@ Use the constructor of `FormControl` to set its initial value, which in this cas
After you create the control in the component class, you must associate it with a form control element in the template. Update the template with the form control using the `formControl` binding provided by `FormControlDirective` included in `ReactiveFormsModule`.
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="control-binding" linenums="false" header="src/app/name-editor/name-editor.component.html">
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="control-binding" linenums="false" title="src/app/name-editor/name-editor.component.html">
</code-example>
@ -68,7 +68,7 @@ Using the template binding syntax, the form control is now registered to the `na
The form control assigned to `name` is displayed when the component is added to a template.
<code-example path="reactive-forms/src/app/app.component.1.html" region="app-name-editor" linenums="false" header="src/app/app.component.html (name editor)">
<code-example path="reactive-forms/src/app/app.component.1.html" region="app-name-editor" linenums="false" title="src/app/app.component.html (name editor)">
</code-example>
@ -92,7 +92,7 @@ You can display the value in these ways:
The following example shows you how to display the current value using interpolation in the template.
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="display-value" linenums="false" header="src/app/name-editor/name-editor.component.html (control value)">
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="display-value" linenums="false" title="src/app/name-editor/name-editor.component.html (control value)">
</code-example>
@ -108,13 +108,13 @@ Reactive forms have methods to change a control's value programmatically, which
The following example adds a method to the component class to update the value of the control to *Nancy* using the `setValue()` method.
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.ts" region="update-value" header="src/app/name-editor/name-editor.component.ts (update value)">
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.ts" region="update-value" title="src/app/name-editor/name-editor.component.ts (update value)">
</code-example>
Update the template with a button to simulate a name update. When you click the **Update Name** button, the value entered in the form control element is reflected as its current value.
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="update-value" linenums="false" header="src/app/name-editor/name-editor.component.html (update value)">
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="update-value" linenums="false" title="src/app/name-editor/name-editor.component.html (update value)">
</code-example>
@ -142,7 +142,7 @@ Generate a `ProfileEditor` component and import the `FormGroup` and `FormControl
</code-example>
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="imports" header="src/app/profile-editor/profile-editor.component.ts (imports)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="imports" title="src/app/profile-editor/profile-editor.component.ts (imports)">
</code-example>
@ -152,7 +152,7 @@ Create a property in the component class named `profileForm` and set the propert
For the profile form, add two form control instances with the names `firstName` and `lastName`.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="formgroup" header="src/app/profile-editor/profile-editor.component.ts (form group)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="formgroup" title="src/app/profile-editor/profile-editor.component.ts (form group)">
</code-example>
@ -162,7 +162,7 @@ The individual form controls are now collected within a group. A `FormGroup` ins
A form group tracks the status and changes for each of its controls, so if one of the controls changes, the parent control also emits a new status or value change. The model for the group is maintained from its members. After you define the model, you must update the template to reflect the model in the view.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="formgroup" linenums="false" header="src/app/profile-editor/profile-editor.component.html (template form group)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="formgroup" linenums="false" title="src/app/profile-editor/profile-editor.component.html (template form group)">
</code-example>
@ -174,13 +174,13 @@ The `ProfileEditor` component accepts input from the user, but in a real scenari
Add an `ngSubmit` event listener to the `form` tag with the `onSubmit()` callback method.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="ng-submit" linenums="false" header="src/app/profile-editor/profile-editor.component.html (submit event)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="ng-submit" linenums="false" title="src/app/profile-editor/profile-editor.component.html (submit event)">
</code-example>
The `onSubmit()` method in the `ProfileEditor` component captures the current value of `profileForm`. Use `EventEmitter` to keep the form encapsulated and to provide the form value outside the component. The following example uses `console.warn` to log a message to the browser console.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="on-submit" header="src/app/profile-editor/profile-editor.component.ts (submit method)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="on-submit" title="src/app/profile-editor/profile-editor.component.ts (submit method)">
</code-example>
@ -188,7 +188,7 @@ The `submit` event is emitted by the `form` tag using the native DOM event. You
Use a `button` element to add a button to the bottom of the form to trigger the form submission.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="submit-button" linenums="false" header="src/app/profile-editor/profile-editor.component.html (submit button)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="submit-button" linenums="false" title="src/app/profile-editor/profile-editor.component.html (submit button)">
</code-example>
@ -202,7 +202,7 @@ Use a `button` element to add a button to the bottom of the form to trigger the
To display the `ProfileEditor` component that contains the form, add it to a component template.
<code-example path="reactive-forms/src/app/app.component.1.html" region="app-profile-editor" linenums="false" header="src/app/app.component.html (profile editor)">
<code-example path="reactive-forms/src/app/app.component.1.html" region="app-profile-editor" linenums="false" title="src/app/app.component.html (profile editor)">
</code-example>
@ -220,7 +220,7 @@ When building complex forms, managing the different areas of information is easi
An address is a good example of information that can be grouped together. Form groups can accept both form control and form group instances as children. This makes composing complex form models easier to maintain and logically group together. To create a nested group in `profileForm`, add a nested `address` element to the form group instance.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="nested-formgroup" linenums="false" header="src/app/profile-editor/profile-editor.component.ts (nested form group)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="nested-formgroup" linenums="false" title="src/app/profile-editor/profile-editor.component.ts (nested form group)">
</code-example>
@ -232,7 +232,7 @@ After you update the model in the component class, update the template to connec
Add the `address` form group containing the `firstName` and `lastName` fields to the `ProfileEditor` template.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="formgroupname" linenums="false" header="src/app/profile-editor/profile-editor.component.html (template nested form group)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="formgroupname" linenums="false" title="src/app/profile-editor/profile-editor.component.html (template nested form group)">
</code-example>
@ -264,13 +264,13 @@ The strict checks of the `setValue()` method help catch nesting errors in comple
In `ProfileEditorComponent`, use the `updateProfile` method with the example below to update the first name and street address for the user.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="patch-value" header="src/app/profile-editor/profile-editor.component.ts (patch value)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="patch-value" title="src/app/profile-editor/profile-editor.component.ts (patch value)">
</code-example>
Simulate an update by adding a button to the template to update the user profile on demand.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="patch-value" linenums="false" header="src/app/profile-editor/profile-editor.component.html (update value)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="patch-value" linenums="false" title="src/app/profile-editor/profile-editor.component.html (update value)">
</code-example>
@ -286,7 +286,7 @@ The following section refactors the `ProfileEditor` component to use the form bu
Import the `FormBuilder` class from the `@angular/forms` package.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="form-builder-imports" header="src/app/profile-editor/profile-editor.component.ts (import)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="form-builder-imports" title="src/app/profile-editor/profile-editor.component.ts (import)">
</code-example>
@ -294,7 +294,7 @@ Import the `FormBuilder` class from the `@angular/forms` package.
The `FormBuilder` service is an injectable provider that is provided with the reactive forms module. Inject this dependency by adding it to the component constructor.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="inject-form-builder" header="src/app/profile-editor/profile-editor.component.ts (constructor)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="inject-form-builder" title="src/app/profile-editor/profile-editor.component.ts (constructor)">
</code-example>
@ -304,7 +304,7 @@ The `FormBuilder` service has three methods: `control()`, `group()`, and `array(
Use the `group` method to create the `profileForm` controls.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="form-builder" header="src/app/profile-editor/profile-editor.component.ts (form builder)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="form-builder" title="src/app/profile-editor/profile-editor.component.ts (form builder)">
</code-example>
@ -320,11 +320,11 @@ Compare using the form builder to creating the instances manually.
<code-tabs>
<code-pane path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="formgroup-compare" header="src/app/profile-editor/profile-editor.component.ts (instances)">
<code-pane path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="formgroup-compare" title="src/app/profile-editor/profile-editor.component.ts (instances)">
</code-pane>
<code-pane path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="formgroup-compare" header="src/app/profile-editor/profile-editor.component.ts (form builder)">
<code-pane path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="formgroup-compare" title="src/app/profile-editor/profile-editor.component.ts (form builder)">
</code-pane>
@ -340,7 +340,7 @@ Reactive forms include a set of validator functions for common use cases. These
Import the `Validators` class from the `@angular/forms` package.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="validator-imports" header="src/app/profile-editor/profile-editor.component.ts (import)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="validator-imports" title="src/app/profile-editor/profile-editor.component.ts (import)">
</code-example>
@ -350,13 +350,13 @@ The most common validation is making a field required. This section describes ho
In the `ProfileEditor` component, add the `Validators.required` static method as the second item in the array for the `firstName` control.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="required-validator" header="src/app/profile-editor/profile-editor.component.ts (required validator)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="required-validator" title="src/app/profile-editor/profile-editor.component.ts (required validator)">
</code-example>
HTML5 has a set of built-in attributes that you can use for native validation, including `required`, `minlength`, and `maxlength`. You can take advantage of these optional attributes on your form input elements. Add the `required` attribute to the `firstName` input element.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="required-attribute" linenums="false" header="src/app/profile-editor/profile-editor.component.html (required attribute)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="required-attribute" linenums="false" title="src/app/profile-editor/profile-editor.component.html (required attribute)">
</code-example>
@ -372,7 +372,7 @@ When you add a required field to the form control, its initial status is invalid
Display the current status of `profileForm` using interpolation.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="display-status" linenums="false" header="src/app/profile-editor/profile-editor.component.html (display status)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="display-status" linenums="false" title="src/app/profile-editor/profile-editor.component.html (display status)">
</code-example>
@ -392,7 +392,7 @@ For more on form validation, visit the [Form Validation](guide/form-validation)
Import the `FormArray` class from `@angular/forms` to use for type information. The `FormBuilder` service is ready to create a `FormArray` instance.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="form-array-imports" header="src/app/profile-editor/profile-editor.component.ts (import)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="form-array-imports" title="src/app/profile-editor/profile-editor.component.ts (import)">
</code-example>
@ -402,7 +402,7 @@ You can initialize a form array with any number of controls, from zero to many,
Use the `FormBuilder.array()` method to define the array, and the `FormBuilder.control()` method to populate the array with an initial control.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="aliases" header="src/app/profile-editor/profile-editor.component.ts (aliases form array)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="aliases" title="src/app/profile-editor/profile-editor.component.ts (aliases form array)">
</code-example>
@ -414,7 +414,7 @@ A getter provides easy access to the aliases in the form array instance compared
Use the getter syntax to create an `aliases` class property to retrieve the alias's form array control from the parent form group.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="aliases-getter" header="src/app/profile-editor/profile-editor.component.ts (aliases getter)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="aliases-getter" title="src/app/profile-editor/profile-editor.component.ts (aliases getter)">
</code-example>
@ -426,7 +426,7 @@ Use the getter syntax to create an `aliases` class property to retrieve the alia
Define a method to dynamically insert an alias control into the alias's form array. The `FormArray.push()` method inserts the control as a new item in the array.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="add-alias" header="src/app/profile-editor/profile-editor.component.ts (add alias)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.ts" region="add-alias" title="src/app/profile-editor/profile-editor.component.ts (add alias)">
</code-example>
@ -438,7 +438,7 @@ To attach the aliases from your form model, you must add it to the template. Sim
Add the template HTML below after the `<div>` closing the `formGroupName` element.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="formarrayname" linenums="false" header="src/app/profile-editor/profile-editor.component.html (aliases form array template)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="formarrayname" linenums="false" title="src/app/profile-editor/profile-editor.component.html (aliases form array template)">
</code-example>

View File

@ -65,34 +65,68 @@ Disclaimer: The dates are offered as general guidance and may be adjusted by us
The following table contains our current target release dates for the next two major versions of Angular:
Date | Stable Release | Compatibility
---------------------- | -------------- | -------------
Date | Stable Release | Compatibility
---------------------- | -------------- | ----------------
September/October 2018 | 7.0.0 | ^6.0.0
March/April 2019 | 8.0.0 | ^7.0.0
September/October 2019 | 9.0.0 | ^8.0.0
Compatibility note: The primary goal of the backward compatibility promise is to ensure that changes in the core framework and tooling don't break the existing ecosystem of components and applications and don't put undue upgrade/migration burden on Angular application and component authors.
{@a lts}
{@a support}
## Support policy and schedule
## Support policy
All of our major releases are supported for 18 months.
* 6 months of *active support*, during which regularly-scheduled updates and patches are released.
* 6 months of active support, during which regularly-scheduled updates and patches are released, as described above in [Release frequency](#frequency "Release frequency").
* 12 months of *long-term support (LTS)*, during which only critical fixes and security patches are released.
* 12 months of long-term support (LTS). During the LTS period, only critical fixes and security patches will be released.
The following table provides the support status and key dates for Angular version 5.0.0 and higher.
The following table provides the support status and key dates for Angular version 4.0.0 and higher.
<style>
Version | Status | Released | Active Ends | LTS Ends
------- | ------ | ------------ | ------------ | ------------
^7.0.0 | Active | Oct 18, 2018 | Apr 18, 2019 | Apr 18, 2020
^6.0.0 | LTS | May 3, 2018 | Nov 3, 2018 | Nov 3, 2019
^5.0.0 | LTS | Nov 1, 2017 | May 1, 2018 | May 1, 2019
td, th {vertical-align: top}
</style>
<table>
<tr>
<th>Version</th>
<th>Status</th>
<th>Release Date</th>
<th>LTS Start Date</th>
<th>LTS End Date</th>
</tr>
<tr>
<td>^4.0.0</td>
<td>LTS</td>
<td>March 23, 2017</td>
<td>September 23, 2017</td>
<td>September 23, 2018</td>
</tr>
<tr>
<td>^5.0.0</td>
<td>LTS</td>
<td>November 1, 2017</td>
<td>May 1, 2018</td>
<td>May 1, 2019</td>
</tr>
<tr>
<td>^6.0.0</td>
<td>Active</td>
<td>May 3, 2018</td>
<td>November 3, 2018</td>
<td>November 3, 2019</td>
</tr>
</table>
LTS for Angular version ^4.0.0 ended on September 23, 2018.
{@a deprecation}

View File

@ -15,7 +15,7 @@ The [AnimationOptions](https://angular.io/api/animations/AnimationOptions) inter
To create a reusable animation, use the [`animation()`](https://angular.io/api/animations/animation) method to define an animation in a separate `.ts` file and declare this animation definition as a `const` export variable. You can then import and reuse this animation in any of your app components using the [`useAnimation()`](https://angular.io/api/animations/useAnimation) API.
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="reusable" language="typescript" linenums="false">
<code-example path="animations/src/app/animations.ts" title="src/app/animations.ts" region="reusable" language="typescript" linenums="false">
</code-example>
In the above code snippet, `transAnimation` is made reusable by declaring it as an export variable.
@ -27,7 +27,7 @@ In the above code snippet, `transAnimation` is made reusable by declaring it as
You can import the reusable `transAnimation` variable in your component class and reuse it using the `useAnimation()` method as shown below.
<code-example path="animations/src/app/open-close.component.3.ts" header="src/app/open-close.component.ts" region="reusable" language="typescript" linenums="false">
<code-example path="animations/src/app/open-close.component.3.ts" title="src/app/open-close.component.ts" region="reusable" language="typescript" linenums="false">
</code-example>
## More on Angular animations

View File

@ -43,7 +43,7 @@ Use the `RouterModule.forRoot` method to define a set of routes. Also, import th
The following configuration defines the possible routes for the application.
<code-example path="animations/src/app/app.module.ts" linenums="false" header="src/app/app.module.ts" region="route-animation-data" language="typescript">
<code-example path="animations/src/app/app.module.ts" linenums="false" title="src/app/app.module.ts" region="route-animation-data" language="typescript">
</code-example>
The `home` and `about` paths are associated with the `HomeComponent` and `AboutComponent` views. The route configuration tells the Angular router to instantiate the `HomeComponent` and `AboutComponent` views when the navigation matches the corresponding path.
@ -62,12 +62,12 @@ After configuring the routes, tell the Angular router where to render the views
The `<router-outlet>` container has an attribute directive that contains data about active routes and their states, based on the `data` property that we set in the route configuration.
<code-example path="animations/src/app/app.component.html" header="src/app/app.component.html" region="route-animations-outlet">
<code-example path="animations/src/app/app.component.html" title="src/app/app.component.html" region="route-animations-outlet">
</code-example>
`AppComponent` defines a method that can detect when a view changes. The method assigns an animation state value to the animation trigger (`@routeAnimation`) based on the route configuration `data` property value. Here's an example of an `AppComponent` method that detects when a route change happens.
<code-example path="animations/src/app/app.component.ts" linenums="false" header="src/app/app.component.ts" region="prepare-router-outlet" language="typescript">
<code-example path="animations/src/app/app.component.ts" linenums="false" title="src/app/app.component.ts" region="prepare-router-outlet" language="typescript">
</code-example>
Here, the `prepareRoute()` method takes the value of the output directive (established through `#outlet="outlet"`) and returns a string value representing the state of the animation based on the custom data of the current active route. You can use this data to control which transition to execute for each route.
@ -79,7 +79,7 @@ Animations can be defined directly inside your components. For this example we a
The following code snippet defines a reusable animation named `slideInAnimation`.
<code-example path="animations/src/app/animations.ts" linenums="false" header="src/app/animations.ts" region="route-animations" language="typescript">
<code-example path="animations/src/app/animations.ts" linenums="false" title="src/app/animations.ts" region="route-animations" language="typescript">
</code-example>
The animation definition does several things:
@ -97,14 +97,14 @@ A route change activates the animation trigger, and a transition matching the st
Make the animation definition available in your application by adding the reusable animation (`slideInAnimation`) to the `animations` metadata of the `AppComponent`.
<code-example path="animations/src/app/app.component.ts" linenums="false" header="src/app/app.component.ts" region="define" language="typescript">
<code-example path="animations/src/app/app.component.ts" linenums="false" title="src/app/app.component.ts" region="define" language="typescript">
</code-example>
### Styling the host and child components
During a transition, a new view is inserted directly after the old one and both elements appear on screen at the same time. To prevent this, apply additional styling to the host view, and to the removed and inserted child views. The host view must use relative positioning, and the child views must use absolute positioning. Adding styling to the views animates the containers in place, without the DOM moving things around.
<code-example path="animations/src/app/animations.ts" linenums="false" header="src/app/animations.ts" region="style-view" language="typescript">
<code-example path="animations/src/app/animations.ts" linenums="false" title="src/app/animations.ts" region="style-view" language="typescript">
</code-example>
### Querying the view containers
@ -113,7 +113,7 @@ Use the `query()` method to find and animate elements within the current host co
Let's assume that we are routing from the *Home => About*.
<code-example path="animations/src/app/animations.ts" linenums="false" header="src/app/animations.ts" region="query" language="typescript" linenums="false">
<code-example path="animations/src/app/animations.ts" linenums="false" title="src/app/animations.ts" region="query" language="typescript" linenums="false">
</code-example>
The animation code does the following after styling the views:

File diff suppressed because it is too large Load Diff

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