Compare commits
215 Commits
4.2.0-rc.1
...
4.2.4
Author | SHA1 | Date | |
---|---|---|---|
8a09015211 | |||
f4b7bf7e38 | |||
d20313698d | |||
74954f1a8d | |||
368aed087c | |||
975341a77e | |||
c112232fa3 | |||
36348325de | |||
fdbe62f112 | |||
af9ba91e5c | |||
b840ec3684 | |||
b38552f36e | |||
572885dcc8 | |||
33906489ad | |||
59299de374 | |||
f99793700f | |||
77860a0023 | |||
93d834a0b2 | |||
63a5f33e99 | |||
20eb5cfd59 | |||
4ab7353a9f | |||
eb23460e09 | |||
2e8efdaffa | |||
3cfb13f746 | |||
7de1ae2be8 | |||
341b812a10 | |||
09512c7770 | |||
1ec0a53fec | |||
3607a48a08 | |||
62957fa515 | |||
ab81c1c068 | |||
25234227ec | |||
71a8ef5a15 | |||
4dd6deca16 | |||
f8db05ef7d | |||
623b9c6e58 | |||
8a547eeee0 | |||
4211432fc8 | |||
b8c39cdf71 | |||
9c7a84de51 | |||
dbc6a4cb12 | |||
784410e3c8 | |||
90a5a1ef43 | |||
301f99cd6c | |||
64e63b9422 | |||
b192dd5761 | |||
96aa3bb135 | |||
8abc1df2c1 | |||
f5eb528a5c | |||
5cf06a9f3f | |||
ab90f63575 | |||
150d271f79 | |||
a686eb2c9e | |||
bfa788935a | |||
64fa100a71 | |||
5fae987bfa | |||
9c4cda1c7d | |||
d9cbe56b63 | |||
86df7108b0 | |||
e7a4f92be7 | |||
76af452d29 | |||
11dfb685f4 | |||
d363aa0aa4 | |||
209d74c342 | |||
fec8f6febe | |||
ee9daaf4c8 | |||
4164369db4 | |||
747b6a61b8 | |||
9ed836c939 | |||
e4c82443f9 | |||
a2f232166b | |||
668f9ede65 | |||
b784829512 | |||
ad4fee7053 | |||
2d31e17251 | |||
39cff565ee | |||
203c5ba1b3 | |||
eda7bb5c3e | |||
1480a30050 | |||
d6087f75e2 | |||
dc084a5bdf | |||
7a2d2efff8 | |||
e95062d1df | |||
0268818fbb | |||
234268eec2 | |||
ed73d4f3ac | |||
6ca46929fa | |||
185075d870 | |||
451257a2fd | |||
3d5f520ff0 | |||
a1065bfaf0 | |||
d6f345cc3c | |||
d961911a98 | |||
e543272eb3 | |||
c8c0ceeee9 | |||
afbc2b0082 | |||
69ec1e2e31 | |||
ff15509bc7 | |||
7e22a2fc0b | |||
0a48c92d2c | |||
991ca92a9d | |||
c550f885a4 | |||
851038c3a8 | |||
df7774c018 | |||
15090a8ad4 | |||
8575e3f71c | |||
90b0713e32 | |||
d56b7ed96d | |||
db5e5067a0 | |||
0020dad595 | |||
c2d31fb01e | |||
65d49d5c94 | |||
3a99af2696 | |||
503fd1fbaf | |||
4c74dba2f3 | |||
33df13ad65 | |||
ce18c68eca | |||
2d5623911a | |||
a0b30e5dfb | |||
76a920651c | |||
ef6609a723 | |||
c0dcb342f3 | |||
8a9a5ecdd7 | |||
12c5ead39c | |||
3db6b6ca7a | |||
e894f5c399 | |||
8524187869 | |||
f7422a9607 | |||
cf0a9e0730 | |||
8e5beb024f | |||
576d6d8f86 | |||
41a765d715 | |||
f370fd36e0 | |||
a222c3e609 | |||
5a71df0cb3 | |||
6a46cabb10 | |||
74673545c0 | |||
75a311f250 | |||
391ed6334d | |||
0940e6d6ed | |||
4d2ee51bb0 | |||
680128bc09 | |||
5364b51979 | |||
67ef0f0c8f | |||
e9886d701d | |||
022835bab2 | |||
8be2e4c325 | |||
33ba3e31ed | |||
cba2b3c72d | |||
a4a2901294 | |||
bb46f54ad7 | |||
c9b930dd82 | |||
a39f7d63bb | |||
e317f7d51c | |||
3ddd28d37d | |||
fe6b39d585 | |||
d837bfc2d7 | |||
4759975be6 | |||
078a4b00a7 | |||
b00b80a45b | |||
269bbe0e7d | |||
bb2fc6b8da | |||
d4e196035c | |||
b8979c8701 | |||
bfdd3398f6 | |||
3a121a621f | |||
c06f4fc702 | |||
95f1ea2f12 | |||
784347f61f | |||
42176a7ac4 | |||
76b4b80a23 | |||
7c78282ce8 | |||
47c2a2e411 | |||
5faf520067 | |||
02d74cafba | |||
734f30d14c | |||
f2d810febc | |||
819514aeba | |||
b55adee982 | |||
4c32cb952f | |||
35f714e438 | |||
d5ce086089 | |||
82ec02daf8 | |||
8e7a3f031b | |||
7822187b17 | |||
068133ec85 | |||
598fdad089 | |||
ad6a57e0a3 | |||
230255f887 | |||
1338995ee9 | |||
47e4fca7fd | |||
665e7071fa | |||
c20f60b144 | |||
1408357198 | |||
1f9a3dd1e6 | |||
11505fa0d8 | |||
9326e062d8 | |||
cb2cb7c3bd | |||
92d99ba279 | |||
dfbbbb5e3e | |||
89f317915d | |||
4d5fa5c855 | |||
2f35392cd8 | |||
b056adc032 | |||
0d894a18fc | |||
e5138081ec | |||
8ffa483bb6 | |||
ea8a43def0 | |||
535d9da6b6 | |||
18bf77204e | |||
160221c815 | |||
6220b49463 | |||
aa683a765d | |||
b8b91d3418 | |||
0018acfede |
6
.bazelrc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Disable sandboxing because it's too slow.
|
||||||
|
# https://github.com/bazelbuild/bazel/issues/2424
|
||||||
|
build --spawn_strategy=standalone
|
||||||
|
|
||||||
|
# Performance: avoid stat'ing input files
|
||||||
|
build --watchfs
|
20
.circleci/config.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
version: 2
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
working_directory: ~/ng
|
||||||
|
docker:
|
||||||
|
- image: angular/ngcontainer
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- restore_cache:
|
||||||
|
key: angular-{{ .Branch }}-{{ checksum "npm-shrinkwrap.json" }}
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run postinstall
|
||||||
|
- run: ./node_modules/.bin/gulp lint
|
||||||
|
# Build twice, workaround for
|
||||||
|
# https://github.com/bazelbuild/bazel/issues/3114
|
||||||
|
- run: bazel build ... || bazel build ...
|
||||||
|
- save_cache:
|
||||||
|
key: angular-{{ .Branch }}-{{ checksum "npm-shrinkwrap.json" }}
|
||||||
|
paths:
|
||||||
|
- "node_modules"
|
64
.github/ISSUE_TEMPLATE.md
vendored
@ -1,39 +1,57 @@
|
|||||||
<!--
|
<!--
|
||||||
IF YOU DON'T FILL OUT THE FOLLOWING INFORMATION WE MIGHT CLOSE YOUR ISSUE WITHOUT INVESTIGATING
|
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
|
||||||
|
|
||||||
|
ISSUES MISSING IMPORTANT INFORMATION MIGHT BE CLOSED WITHOUT INVESTIGATION.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
**I'm submitting a ...** (check one with "x")
|
## I'm submitting a ...
|
||||||
```
|
<!-- Check one of the following options with "x" -->
|
||||||
[ ] bug report => search github for a similar issue or PR before submitting
|
<pre><code>
|
||||||
[ ] feature request
|
[ ] Regression (behavior that used to work and stopped working in a new release)
|
||||||
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
|
[ ] Bug report <!-- Please search github for a similar issue or PR before submitting -->
|
||||||
```
|
[ ] 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
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
**Current behavior**
|
## Current behavior
|
||||||
<!-- Describe how the bug manifests. -->
|
<!-- Describe how the issue manifests. -->
|
||||||
|
|
||||||
**Expected behavior**
|
|
||||||
<!-- Describe what the behavior would be without the bug. -->
|
|
||||||
|
|
||||||
**Minimal reproduction of the problem with instructions**
|
## Expected behavior
|
||||||
|
<!-- Describe what the desired behavior would be. -->
|
||||||
|
|
||||||
|
|
||||||
|
## Minimal reproduction of the problem with instructions
|
||||||
<!--
|
<!--
|
||||||
If the current behavior is a bug or you can illustrate your feature request better with an example,
|
For bug reports please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
|
||||||
please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
|
|
||||||
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5).
|
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5).
|
||||||
-->
|
-->
|
||||||
|
|
||||||
**What is the motivation / use case for changing the behavior?**
|
## What is the motivation / use case for changing the behavior?
|
||||||
<!-- Describe the motivation or the concrete use case -->
|
<!-- Describe the motivation or the concrete use case. -->
|
||||||
|
|
||||||
**Please tell us about your environment:**
|
|
||||||
<!-- Operating system, IDE, package manager, HTTP server, ... -->
|
|
||||||
|
|
||||||
* **Angular version:** 2.0.X
|
## Please tell us about your environment
|
||||||
|
|
||||||
|
<pre><code>
|
||||||
|
Angular version: X.Y.Z
|
||||||
<!-- Check whether this is still an issue in the most recent Angular version -->
|
<!-- Check whether this is still an issue in the most recent Angular version -->
|
||||||
|
|
||||||
* **Browser:** [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
|
Browser:
|
||||||
<!-- All browsers where this could be reproduced -->
|
- [ ] 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
|
||||||
|
|
||||||
* **Language:** [all | TypeScript X.X | ES6/7 | ES5]
|
For Tooling issues:
|
||||||
|
- Node version: XX <!-- use `node --version` -->
|
||||||
|
- Platform: <!-- Mac, Linux, Windows -->
|
||||||
|
|
||||||
* **Node (for AoT issues):** `node --version` =
|
Others:
|
||||||
|
<!-- Anything else relevant? Operating system version, IDE, package manager, HTTP server, ... -->
|
||||||
|
</code></pre>
|
||||||
|
27
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,10 +1,15 @@
|
|||||||
**Please check if the PR fulfills these requirements**
|
## PR Checklist
|
||||||
|
Does please check if your PR fulfills the following requirements:
|
||||||
|
|
||||||
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
|
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
|
||||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||||
- [ ] Docs have been added / updated (for bug fixes / features)
|
- [ ] Docs have been added / updated (for bug fixes / features)
|
||||||
|
|
||||||
|
|
||||||
**What kind of change does this PR introduce?** (check one with "x")
|
## PR Type
|
||||||
|
What kind of change does this PR introduce?
|
||||||
|
|
||||||
|
<!-- Please check the one that applies to this PR using "x". -->
|
||||||
```
|
```
|
||||||
[ ] Bugfix
|
[ ] Bugfix
|
||||||
[ ] Feature
|
[ ] Feature
|
||||||
@ -12,25 +17,27 @@
|
|||||||
[ ] Refactoring (no functional changes, no api changes)
|
[ ] Refactoring (no functional changes, no api changes)
|
||||||
[ ] Build related changes
|
[ ] Build related changes
|
||||||
[ ] CI related changes
|
[ ] CI related changes
|
||||||
|
[ ] Documentation content changes
|
||||||
|
[ ] angular.io application / infrastructure changes
|
||||||
[ ] Other... Please describe:
|
[ ] Other... Please describe:
|
||||||
```
|
```
|
||||||
|
|
||||||
**What is the current behavior?** (You can also link to an open issue here)
|
## What is the current behavior?
|
||||||
|
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
|
||||||
|
|
||||||
|
Issue Number: N/A
|
||||||
|
|
||||||
|
|
||||||
|
## What is the new behavior?
|
||||||
**What is the new behavior?**
|
|
||||||
|
|
||||||
|
|
||||||
|
## Does this PR introduce a breaking change?
|
||||||
**Does this PR introduce a breaking change?** (check one with "x")
|
|
||||||
```
|
```
|
||||||
[ ] Yes
|
[ ] Yes
|
||||||
[ ] No
|
[ ] No
|
||||||
```
|
```
|
||||||
|
|
||||||
If this PR contains a breaking change, please describe the impact and migration path for existing applications: ...
|
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
|
||||||
|
|
||||||
|
|
||||||
**Other information**:
|
## Other information
|
||||||
|
|
||||||
|
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
.DS_STORE
|
.DS_STORE
|
||||||
|
|
||||||
/dist/
|
/dist/
|
||||||
|
bazel-*
|
||||||
node_modules
|
node_modules
|
||||||
bower_components
|
bower_components
|
||||||
|
|
||||||
|
@ -97,15 +97,15 @@ groups:
|
|||||||
- vicb
|
- vicb
|
||||||
- IgorMinar #fallback
|
- IgorMinar #fallback
|
||||||
|
|
||||||
compiler/animations:
|
animations:
|
||||||
conditions:
|
conditions:
|
||||||
files:
|
files:
|
||||||
- "packages/compiler/src/animation/*"
|
- "packages/animation/*"
|
||||||
|
- "packages/platform-browser/animations/*"
|
||||||
users:
|
users:
|
||||||
- matsko #primary
|
- matsko #primary
|
||||||
- tbosch
|
|
||||||
- IgorMinar #fallback
|
|
||||||
- mhevery #fallback
|
- mhevery #fallback
|
||||||
|
- IgorMinar #fallback
|
||||||
|
|
||||||
compiler/i18n:
|
compiler/i18n:
|
||||||
conditions:
|
conditions:
|
||||||
|
18
BUILD
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
exports_files(["tsconfig.json"])
|
||||||
|
|
||||||
|
# This rule belongs in node_modules/BUILD
|
||||||
|
# It's here as a workaround for
|
||||||
|
# https://github.com/bazelbuild/bazel/issues/374#issuecomment-296217940
|
||||||
|
filegroup(
|
||||||
|
name = "node_modules",
|
||||||
|
srcs = glob([
|
||||||
|
# Performance workaround: list individual files
|
||||||
|
# This won't scale in the general case.
|
||||||
|
# TODO(alexeagle): figure out what to do
|
||||||
|
"node_modules/typescript/**",
|
||||||
|
"node_modules/zone.js/**/*.d.ts",
|
||||||
|
"node_modules/rxjs/**/*.d.ts",
|
||||||
|
"node_modules/@types/**/*.d.ts",
|
||||||
|
]),
|
||||||
|
)
|
104
CHANGELOG.md
@ -1,3 +1,105 @@
|
|||||||
|
<a name="4.2.4"></a>
|
||||||
|
## [4.2.4](https://github.com/angular/angular/compare/4.2.3...4.2.4) (2017-06-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **compiler:** avoid emitting self importing factories ([c112232](https://github.com/angular/angular/commit/c112232))
|
||||||
|
* **compiler-cli:** find lazy routes in nested module import arrays ([59299de](https://github.com/angular/angular/commit/59299de))
|
||||||
|
* **core**: argument destructuring sometimes breaks strictNullChecks ([77860a0](https://github.com/angular/angular/commit/77860a0))
|
||||||
|
* **forms:** roll back breaking change with min/max directives ([4ab7353](https://github.com/angular/angular/commit/4ab7353)), closes [#17491](https://github.com/angular/angular/issues/17491)
|
||||||
|
* **language-service:** infer `any` `ngForOf` of type `any` ([63a5f33](https://github.com/angular/angular/commit/63a5f33))
|
||||||
|
* **language-service:** rollup `tslib` into the language service package ([20eb5cf](https://github.com/angular/angular/commit/20eb5cf))
|
||||||
|
* **router:** update the version placeholder so that it gets replaced during the build ([7de1ae2](https://github.com/angular/angular/commit/7de1ae2)), closes [#17403](https://github.com/angular/angular/issues/17403)
|
||||||
|
* **tsc-wrapped:** skip collecting metadata for default functions ([3390648](https://github.com/angular/angular/commit/3390648))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="4.2.3"></a>
|
||||||
|
## [4.2.3](https://github.com/angular/angular/compare/4.2.1...4.2.3) (2017-06-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
||||||
|
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
||||||
|
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
|
||||||
|
* **animations:** remove duplicate license header ([b192dd5](https://github.com/angular/angular/commit/b192dd5))
|
||||||
|
* **forms:** temp roll back breaking change with min/max directives ([b8c39cd](https://github.com/angular/angular/commit/b8c39cd)), closes [#17491](https://github.com/angular/angular/issues/17491)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="4.2.2"></a>
|
||||||
|
## [4.2.2](https://github.com/angular/angular/compare/4.2.1...4.2.2) (2017-06-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
||||||
|
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
||||||
|
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
|
||||||
|
* **compiler:** don’t always compile `.ngfactory.ts` files by default ([ed73d4f](https://github.com/angular/angular/commit/ed73d4f3ac6b542bf5ea3eb73fbe91e2ceabcdb4))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="4.2.1"></a>
|
||||||
|
## [4.2.1](https://github.com/angular/angular/compare/4.2.0-rc.2...4.2.1) (2017-06-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
|
||||||
|
* **compiler:** don’t write summaries for jit by default ([d3a5f1a](https://github.com/angular/angular/commit/d3a5f1a))
|
||||||
|
* **http:** move destructuring inside {Request,Response}Options ctor ([c2d31fb](https://github.com/angular/angular/commit/c2d31fb)), closes [#16663](https://github.com/angular/angular/issues/16663)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="4.2.0"></a>
|
||||||
|
# [4.2.0](https://github.com/angular/angular/compare/4.2.0-rc.2...4.2.0) salubrious-stratagem (2017-06-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** ensure web-animations understands a numeric CSS perspective value ([819514a](https://github.com/angular/angular/commit/819514a)), closes [#14007](https://github.com/angular/angular/issues/14007)
|
||||||
|
* **animations:** evaluate substitutions on option param values ([e9886d7](https://github.com/angular/angular/commit/e9886d7))
|
||||||
|
* **forms:** fix min and max validator behavior on non-numbers ([a222c3e](https://github.com/angular/angular/commit/a222c3e))
|
||||||
|
* **router:** opening links in new window ([4c32cb9](https://github.com/angular/angular/commit/4c32cb9))
|
||||||
|
* **upgrade:** call setInterval outside the Angular zone ([269bbe0](https://github.com/angular/angular/commit/269bbe0))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **compiler-cli:** introduce synchronous codegen API ([b00b80a](https://github.com/angular/angular/commit/b00b80a))
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **animations:** do not create a closure each time a node is removed ([fe6b39d](https://github.com/angular/angular/commit/fe6b39d))
|
||||||
|
* **animations:** only apply `:leave` flags if animations are set to run ([b55adee](https://github.com/angular/angular/commit/b55adee))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="4.2.0-rc.2"></a>
|
||||||
|
# [4.2.0-rc.2](https://github.com/angular/angular/compare/4.2.0-rc.1...4.2.0-rc.2) (2017-06-01)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** always change to desired animation state even if no transition fires ([#17025](https://github.com/angular/angular/issues/17025)) ([665e707](https://github.com/angular/angular/commit/665e707)), closes [#16947](https://github.com/angular/angular/issues/16947)
|
||||||
|
* **animations:** do not retain deleted nodes during an non-removal animation ([#17153](https://github.com/angular/angular/issues/17153)) ([068133e](https://github.com/angular/angular/commit/068133e)), closes [#17086](https://github.com/angular/angular/issues/17086)
|
||||||
|
* **common:** always use 'other' case for locales with no plural rules ([#16990](https://github.com/angular/angular/issues/16990)) ([535d9da](https://github.com/angular/angular/commit/535d9da))
|
||||||
|
* **compiler:** enableLegacyTemplate should not be ignored ([#17051](https://github.com/angular/angular/issues/17051)) ([8ffa483](https://github.com/angular/angular/commit/8ffa483)), closes [#15555](https://github.com/angular/angular/issues/15555)
|
||||||
|
* **router:** make remove trailing slash consistent with URL params ([c20f60b](https://github.com/angular/angular/commit/c20f60b)), closes [#16069](https://github.com/angular/angular/issues/16069)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **compiler:** emit typescript nodes from an output ast ([#16823](https://github.com/angular/angular/issues/16823)) ([18bf772](https://github.com/angular/angular/commit/18bf772))
|
||||||
|
* **compiler-cli:** produce template diagnostics error messages ([#17125](https://github.com/angular/angular/issues/17125)) ([230255f](https://github.com/angular/angular/commit/230255f))
|
||||||
|
* **tsc-wrapped:** always convert shorthand imports ([#16898](https://github.com/angular/angular/issues/16898)) ([ea8a43d](https://github.com/angular/angular/commit/ea8a43d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **animations:** do not place enterId values on elements for querying purposes ([#17150](https://github.com/angular/angular/issues/17150)) ([ad6a57e](https://github.com/angular/angular/commit/ad6a57e))
|
||||||
|
|
||||||
<a name="4.2.0-rc.1"></a>
|
<a name="4.2.0-rc.1"></a>
|
||||||
# [4.2.0-rc.1](https://github.com/angular/angular/compare/4.2.0-rc.0...4.2.0-rc.1) (2017-05-26)
|
# [4.2.0-rc.1](https://github.com/angular/angular/compare/4.2.0-rc.0...4.2.0-rc.1) (2017-05-26)
|
||||||
|
|
||||||
@ -342,7 +444,9 @@ Note: 4.1.0-beta.0 release also contains all the changes present in the 4.0.1 re
|
|||||||
* **router:** should pass new data to Observable when query params change ([#15387](https://github.com/angular/angular/issues/15387)) ([08f2f08](https://github.com/angular/angular/commit/08f2f08)), closes [#15290](https://github.com/angular/angular/issues/15290)
|
* **router:** should pass new data to Observable when query params change ([#15387](https://github.com/angular/angular/issues/15387)) ([08f2f08](https://github.com/angular/angular/commit/08f2f08)), closes [#15290](https://github.com/angular/angular/issues/15290)
|
||||||
* prevent strictNullChecks support until [#15432](https://github.com/angular/angular/issues/15432) is fixed ([#15434](https://github.com/angular/angular/issues/15434)) ([b800a0c](https://github.com/angular/angular/commit/b800a0c))
|
* prevent strictNullChecks support until [#15432](https://github.com/angular/angular/issues/15432) is fixed ([#15434](https://github.com/angular/angular/issues/15434)) ([b800a0c](https://github.com/angular/angular/commit/b800a0c))
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
From 4.0.0 @angular/core uses a [`WeakMap`](https://github.com/angular/angular/commit/52b21275f4c2c26c46627f5648b41a33bb5c8283), a polyfill needs to be included for [browsers that do not support it natively](http://kangax.github.io/compat-table/es6/#test-WeakMap).
|
||||||
|
|
||||||
<a name="4.0.0-rc.6"></a>
|
<a name="4.0.0-rc.6"></a>
|
||||||
# [4.0.0-rc.6](https://github.com/angular/angular/compare/4.0.0-rc.5...4.0.0-rc.6) (2017-03-23)
|
# [4.0.0-rc.6](https://github.com/angular/angular/compare/4.0.0-rc.5...4.0.0-rc.6) (2017-03-23)
|
||||||
|
12
WORKSPACE
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
|
||||||
|
|
||||||
|
git_repository(
|
||||||
|
name = "io_bazel_rules_typescript",
|
||||||
|
remote = "https://github.com/bazelbuild/rules_typescript.git",
|
||||||
|
commit = "804c5da",
|
||||||
|
)
|
||||||
|
|
||||||
|
load("@io_bazel_rules_typescript//:defs.bzl", "node_repositories", "npm_install")
|
||||||
|
|
||||||
|
node_repositories()
|
||||||
|
npm_install(package_json = "//:package.json")
|
@ -31,6 +31,7 @@
|
|||||||
"environmentSource": "environments/environment.ts",
|
"environmentSource": "environments/environment.ts",
|
||||||
"environments": {
|
"environments": {
|
||||||
"dev": "environments/environment.ts",
|
"dev": "environments/environment.ts",
|
||||||
|
"stage": "environments/environment.stage.ts",
|
||||||
"prod": "environments/environment.prod.ts"
|
"prod": "environments/environment.prod.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"projects": {
|
|
||||||
"staging": "aio-staging"
|
|
||||||
}
|
|
||||||
}
|
|
3
aio/.gitignore
vendored
@ -43,3 +43,6 @@ protractor-results*.txt
|
|||||||
# System Files
|
# System Files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
|
# copied dependencies
|
||||||
|
src/assets/js/lunr*
|
4
aio/content/examples/.gitignore
vendored
@ -45,12 +45,16 @@ dist/
|
|||||||
# aot
|
# aot
|
||||||
**/*.ngfactory.ts
|
**/*.ngfactory.ts
|
||||||
**/*.ngsummary.json
|
**/*.ngsummary.json
|
||||||
|
**/*.ngsummary.ts
|
||||||
**/*.shim.ngstyle.ts
|
**/*.shim.ngstyle.ts
|
||||||
**/*.metadata.json
|
**/*.metadata.json
|
||||||
!aot/bs-config.json
|
!aot/bs-config.json
|
||||||
!aot/index.html
|
!aot/index.html
|
||||||
!rollup-config.js
|
!rollup-config.js
|
||||||
|
|
||||||
|
# i18n
|
||||||
|
!i18n/src/systemjs-text-plugin.js
|
||||||
|
|
||||||
# testing
|
# testing
|
||||||
!testing/src/browser-test-shim.js
|
!testing/src/browser-test-shim.js
|
||||||
!testing/karma*.js
|
!testing/karma*.js
|
||||||
|
1
aio/content/examples/animations/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
**/*.js
|
|
@ -44,7 +44,7 @@ import { Heroes } from './hero.service';
|
|||||||
animate('0.2s ease-in')
|
animate('0.2s ease-in')
|
||||||
]),
|
]),
|
||||||
transition('* => void', [
|
transition('* => void', [
|
||||||
animate('0.2s 10 ease-out', style({
|
animate('0.2s 0.1s ease-out', style({
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
transform: 'translateX(100%)'
|
transform: 'translateX(100%)'
|
||||||
}))
|
}))
|
||||||
|
7
aio/content/examples/aot-compiler/.gitignore
vendored
@ -1,7 +0,0 @@
|
|||||||
**/*.ngfactory.ts
|
|
||||||
**/*.ngsummary.json
|
|
||||||
**/*.shim.ngstyle.ts
|
|
||||||
**/*.metadata.json
|
|
||||||
dist
|
|
||||||
!app/tsconfig.json
|
|
||||||
!rollup-config.js
|
|
45
aio/content/examples/cli-quickstart/.gitignore
vendored
@ -1,45 +0,0 @@
|
|||||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# compiled output
|
|
||||||
/dist
|
|
||||||
/tmp
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules
|
|
||||||
|
|
||||||
# IDEs and editors
|
|
||||||
/.idea
|
|
||||||
.project
|
|
||||||
.classpath
|
|
||||||
.c9/
|
|
||||||
*.launch
|
|
||||||
.settings/
|
|
||||||
*.sublime-workspace
|
|
||||||
|
|
||||||
# IDE - VSCode
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
|
|
||||||
# misc
|
|
||||||
/.sass-cache
|
|
||||||
/connect.lock
|
|
||||||
/coverage/*
|
|
||||||
/libpeerconnection.log
|
|
||||||
npm-debug.log
|
|
||||||
testem.log
|
|
||||||
/typings
|
|
||||||
|
|
||||||
# e2e
|
|
||||||
/e2e/*.js
|
|
||||||
/e2e/*.map
|
|
||||||
|
|
||||||
#System Files
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
|
|
||||||
!src/styles.css
|
|
||||||
!karma.conf.js
|
|
||||||
!protractor.conf.js
|
|
@ -1,116 +0,0 @@
|
|||||||
/* #docregion , quickstart, toh */
|
|
||||||
/* Master Styles */
|
|
||||||
h1 {
|
|
||||||
color: #369;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
font-size: 250%;
|
|
||||||
}
|
|
||||||
h2, h3 {
|
|
||||||
color: #444;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
font-weight: lighter;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
margin: 2em;
|
|
||||||
}
|
|
||||||
/* #enddocregion quickstart */
|
|
||||||
body, input[text], button {
|
|
||||||
color: #888;
|
|
||||||
font-family: Cambria, Georgia;
|
|
||||||
}
|
|
||||||
/* #enddocregion toh */
|
|
||||||
a {
|
|
||||||
cursor: pointer;
|
|
||||||
cursor: hand;
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
font-family: Arial;
|
|
||||||
background-color: #eee;
|
|
||||||
border: none;
|
|
||||||
padding: 5px 10px;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
cursor: hand;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
background-color: #cfd8dc;
|
|
||||||
}
|
|
||||||
button:disabled {
|
|
||||||
background-color: #eee;
|
|
||||||
color: #aaa;
|
|
||||||
cursor: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Navigation link styles */
|
|
||||||
nav a {
|
|
||||||
padding: 5px 10px;
|
|
||||||
text-decoration: none;
|
|
||||||
margin-right: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
display: inline-block;
|
|
||||||
background-color: #eee;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
nav a:visited, a:link {
|
|
||||||
color: #607D8B;
|
|
||||||
}
|
|
||||||
nav a:hover {
|
|
||||||
color: #039be5;
|
|
||||||
background-color: #CFD8DC;
|
|
||||||
}
|
|
||||||
nav a.active {
|
|
||||||
color: #039be5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* items class */
|
|
||||||
.items {
|
|
||||||
margin: 0 0 2em 0;
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
width: 24em;
|
|
||||||
}
|
|
||||||
.items li {
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
left: 0;
|
|
||||||
background-color: #EEE;
|
|
||||||
margin: .5em;
|
|
||||||
padding: .3em 0;
|
|
||||||
height: 1.6em;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.items li:hover {
|
|
||||||
color: #607D8B;
|
|
||||||
background-color: #DDD;
|
|
||||||
left: .1em;
|
|
||||||
}
|
|
||||||
.items li.selected {
|
|
||||||
background-color: #CFD8DC;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.items li.selected:hover {
|
|
||||||
background-color: #BBD8DC;
|
|
||||||
}
|
|
||||||
.items .text {
|
|
||||||
position: relative;
|
|
||||||
top: -3px;
|
|
||||||
}
|
|
||||||
.items .badge {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: small;
|
|
||||||
color: white;
|
|
||||||
padding: 0.8em 0.7em 0 0.7em;
|
|
||||||
background-color: #607D8B;
|
|
||||||
line-height: 1em;
|
|
||||||
position: relative;
|
|
||||||
left: -1px;
|
|
||||||
top: -4px;
|
|
||||||
height: 1.8em;
|
|
||||||
margin-right: .8em;
|
|
||||||
border-radius: 4px 0 0 4px;
|
|
||||||
}
|
|
||||||
/* #docregion toh */
|
|
||||||
/* everywhere else */
|
|
||||||
* {
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
**/*.js
|
|
1
aio/content/examples/deployment/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
!systemjs.config.server.js
|
|
15
aio/content/examples/docs-style-guide/e2e-spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
|
describe('Docs Style Guide', function () {
|
||||||
|
let _title = 'Authors Style Guide Sample';
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
browser.get('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display correct title: ' + _title, function () {
|
||||||
|
expect(element(by.css('h1')).getText()).toEqual(_title);
|
||||||
|
});
|
||||||
|
});
|
7
aio/content/examples/docs-style-guide/package.1.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"start": "concurrently \"npm run build:watch\" \"npm run serve\"",
|
||||||
|
"test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"",
|
||||||
|
"lint": "tslint ./src/**/*.ts -t verbose"
|
||||||
|
}
|
||||||
|
}
|
10
aio/content/examples/docs-style-guide/plnkr.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"description": "Authors style guide",
|
||||||
|
"basePath": "src/",
|
||||||
|
"files": [
|
||||||
|
"!**/*.d.ts",
|
||||||
|
"!**/*.js",
|
||||||
|
"!**/*.[1,2,3].*"
|
||||||
|
],
|
||||||
|
"tags": ["author", "style guide"]
|
||||||
|
}
|
9
aio/content/examples/docs-style-guide/second.plnkr.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"description": "Second authors style guide plunker (non-executing)",
|
||||||
|
"basePath": "src/",
|
||||||
|
"files": [
|
||||||
|
"index.2.html"
|
||||||
|
],
|
||||||
|
"main": "index.2.html",
|
||||||
|
"tags": ["author", "style guide"]
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/* #docregion heroes */
|
||||||
|
.heroes {
|
||||||
|
margin: 0 0 2em 0;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
width: 15em;
|
||||||
|
}
|
||||||
|
/* #enddocregion heroes */
|
||||||
|
|
||||||
|
.heroes li {
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
background-color: #EEE;
|
||||||
|
margin: .5em;
|
||||||
|
padding: .3em 0;
|
||||||
|
height: 1.6em;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.heroes li.selected:hover {
|
||||||
|
background-color: #BBD8DC !important;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.heroes li:hover {
|
||||||
|
color: #607D8B;
|
||||||
|
background-color: #DDD;
|
||||||
|
left: .1em;
|
||||||
|
}
|
||||||
|
.heroes .text {
|
||||||
|
position: relative;
|
||||||
|
top: -3px;
|
||||||
|
}
|
||||||
|
.heroes .badge {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: small;
|
||||||
|
color: white;
|
||||||
|
padding: 0.8em 0.7em 0 0.7em;
|
||||||
|
background-color: #607D8B;
|
||||||
|
line-height: 1em;
|
||||||
|
position: relative;
|
||||||
|
left: -1px;
|
||||||
|
top: -4px;
|
||||||
|
height: 1.8em;
|
||||||
|
margin-right: .8em;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
background-color: #CFD8DC !important;
|
||||||
|
color: white;
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<!-- #docplaster -->
|
||||||
|
<!-- #docregion -->
|
||||||
|
<h1>{{title}}</h1>
|
||||||
|
<h2>My Heroes</h2>
|
||||||
|
<ul class="heroes">
|
||||||
|
<li *ngFor="let hero of heroes"
|
||||||
|
[class.selected]="hero === selectedHero"
|
||||||
|
(click)="onSelect(hero)">
|
||||||
|
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div *ngIf="selectedHero">
|
||||||
|
<h2>{{selectedHero.name}} details!</h2>
|
||||||
|
<div><label>id: </label>{{selectedHero.id}}</div>
|
||||||
|
<div>
|
||||||
|
<label>name: </label>
|
||||||
|
<!-- #docregion selected-hero -->
|
||||||
|
<input [(ngModel)]="selectedHero.name" placeholder="name"/>
|
||||||
|
<!-- #enddocregion selected-hero -->
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,23 @@
|
|||||||
|
// #docplaster
|
||||||
|
// #docregion
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { Hero, HEROES } from './hero';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.css']
|
||||||
|
})
|
||||||
|
// #docregion class, class-skeleton
|
||||||
|
export class AppComponent {
|
||||||
|
// #enddocregion class-skeleton
|
||||||
|
title = 'Authors Style Guide Sample';
|
||||||
|
heroes = HEROES;
|
||||||
|
selectedHero: Hero;
|
||||||
|
|
||||||
|
onSelect(hero: Hero): void {
|
||||||
|
this.selectedHero = hero;
|
||||||
|
}
|
||||||
|
// #docregion class-skeleton
|
||||||
|
}
|
||||||
|
// #enddocregion class, class-skeleton
|
15
aio/content/examples/docs-style-guide/src/app/app.module.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// #docregion
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
// #docregion class
|
||||||
|
@NgModule({
|
||||||
|
imports: [ BrowserModule, FormsModule ],
|
||||||
|
declarations: [ AppComponent ],
|
||||||
|
bootstrap: [ AppComponent ]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
||||||
|
// #enddocregion class
|
11
aio/content/examples/docs-style-guide/src/app/hero.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export class Hero {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const HEROES: Hero[] = [
|
||||||
|
{ id: 11, name: 'Mr. Nice' },
|
||||||
|
{ id: 12, name: 'Narco' },
|
||||||
|
{ id: 13, name: 'Bombasto' },
|
||||||
|
{ id: 14, name: 'Celeritas' }
|
||||||
|
];
|
10
aio/content/examples/docs-style-guide/src/index.2.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Second Authors Style Guide</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Second Authors Style Guide</h1>
|
||||||
|
<p>Placeholder. Does nothing at all.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
30
aio/content/examples/docs-style-guide/src/index.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- #docregion -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Docs Style Guide</title>
|
||||||
|
<base href="/">
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<!-- #docregion styles -->
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
<!-- #enddocregion styles -->
|
||||||
|
|
||||||
|
<!-- Polyfills -->
|
||||||
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
|
<script src="systemjs.config.js"></script>
|
||||||
|
<script>
|
||||||
|
System.import('main.js').catch(function(err){ console.error(err); });
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<my-app>Loading...</my-app>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
4
aio/content/examples/docs-style-guide/src/main.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// #docregion
|
||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
import { AppModule } from './app/app.module';
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule);
|
6
aio/content/examples/i18n/.gitignore
vendored
@ -1,6 +0,0 @@
|
|||||||
**/*.ngfactory.ts
|
|
||||||
**/*.metadata.json
|
|
||||||
dist
|
|
||||||
!app/tsconfig.json
|
|
||||||
!rollup.js
|
|
||||||
!src/systemjs-text-plugin.js
|
|
@ -30,4 +30,8 @@ describe('i18n E2E Tests', () => {
|
|||||||
expect(element.all(by.css('span')).get(1).getText()).toBe('El heroe es mujer');
|
expect(element.all(by.css('span')).get(1).getText()).toBe('El heroe es mujer');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should display the nested expression', function() {
|
||||||
|
expect(element.all(by.css('span')).get(2).getText()).toBe('Aquí tenemos: 3 mujeres');
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||||
<body>
|
<body>
|
||||||
<trans-unit id="af2ccf4b5dba59616e92cf1531505af02da8f6d2" datatype="html">
|
<trans-unit id="introductionHeader" datatype="html">
|
||||||
<source>Hello i18n!</source>
|
<source>
|
||||||
|
Hello i18n!
|
||||||
|
</source>
|
||||||
<target/>
|
<target/>
|
||||||
<note priority="1" from="description">An introduction header for this sample</note>
|
<note priority="1" from="description">An introduction header for this sample</note>
|
||||||
<note priority="1" from="meaning">User welcome</note>
|
<note priority="1" from="meaning">User welcome</note>
|
||||||
@ -24,12 +26,6 @@ I don't output any element either
|
|||||||
<source>Angular logo</source>
|
<source>Angular logo</source>
|
||||||
<target/>
|
<target/>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2579611bfcccd75bcd41fac90150d27d6ebb30b8" datatype="html">
|
|
||||||
<source>
|
|
||||||
<x id="START_TAG_SPAN" ctype="x-span"/><x id="ICU"/><x id="CLOSE_TAG_SPAN" ctype="x-span"/>
|
|
||||||
</source>
|
|
||||||
<target/>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="6e22e74e8cbd3095560cfe08993c4fdfa3c50eb0" datatype="html">
|
<trans-unit id="6e22e74e8cbd3095560cfe08993c4fdfa3c50eb0" datatype="html">
|
||||||
<source/>
|
<source/>
|
||||||
<target/>
|
<target/>
|
||||||
@ -42,6 +38,14 @@ I don't output any element either
|
|||||||
<source/>
|
<source/>
|
||||||
<target/>
|
<target/>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
|
||||||
|
<source>Here we have: <x id="ICU"/></source>
|
||||||
|
<target/>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
|
||||||
|
<source/>
|
||||||
|
<target/>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
@ -10,6 +10,23 @@
|
|||||||
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
|
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
|
||||||
<!--#enddocregion i18n-attribute-desc-->
|
<!--#enddocregion i18n-attribute-desc-->
|
||||||
|
|
||||||
|
<!--#docregion i18n-attribute-meaning-->
|
||||||
|
<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>
|
||||||
|
<!--#enddocregion i18n-attribute-meaning-->
|
||||||
|
|
||||||
|
<!--#docregion i18n-attribute-id-->
|
||||||
|
<h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
|
||||||
|
<!--#enddocregion i18n-attribute-id-->
|
||||||
|
|
||||||
|
<!--#docregion i18n-attribute-meaning-and-id-->
|
||||||
|
<h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
|
||||||
|
<!--#enddocregion i18n-attribute-meaning-and-id-->
|
||||||
|
|
||||||
|
<!--#docregion i18n-attribute-solo-id-->
|
||||||
|
<h1 i18n="@@introductionHeader">Hello i18n!</h1>
|
||||||
|
<!--#enddocregion i18n-attribute-solo-id-->
|
||||||
|
|
||||||
<!--#docregion i18n-title-->
|
<!--#docregion i18n-title-->
|
||||||
<img [src]="logo" title="Angular logo">
|
<img [src]="logo" title="Angular logo">
|
||||||
<!--#enddocregion i18n-title-->
|
<!--#enddocregion i18n-title-->
|
||||||
|
Contact GitHub API Training Shop Blog About
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<!--#docregion-->
|
<!--#docregion-->
|
||||||
<!--#docregion i18n-attribute-meaning-->
|
<!--#docregion i18n-attribute-meaning-->
|
||||||
<h1 i18n="User welcome|An introduction header for this sample">Hello i18n!</h1>
|
<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">
|
||||||
|
Hello i18n!
|
||||||
|
</h1>
|
||||||
<!--#enddocregion i18n-attribute-meaning-->
|
<!--#enddocregion i18n-attribute-meaning-->
|
||||||
|
|
||||||
<!--#docregion i18n-ng-container-->
|
<!--#docregion i18n-ng-container-->
|
||||||
@ -31,4 +33,11 @@ I don't output any element either
|
|||||||
<!--#docregion i18n-select-->
|
<!--#docregion i18n-select-->
|
||||||
<span i18n>The hero is {gender, select, m {male} f {female}}</span>
|
<span i18n>The hero is {gender, select, m {male} f {female}}</span>
|
||||||
<!--#enddocregion i18n-select-->
|
<!--#enddocregion i18n-select-->
|
||||||
<br>
|
<br><br>
|
||||||
|
<!--#docregion i18n-nested-->
|
||||||
|
<span i18n>Here we have: {count, plural,
|
||||||
|
=0 {no one}
|
||||||
|
=1 {one {gender, select, male {man} female {woman}}}
|
||||||
|
other {{{heroes.length}} {gender, select, male {men} female {women}}}
|
||||||
|
}</span>
|
||||||
|
<!--#enddocregion i18n-nested-->
|
||||||
|
@ -10,6 +10,8 @@ export class AppComponent {
|
|||||||
gender = 'f';
|
gender = 'f';
|
||||||
fly = true;
|
fly = true;
|
||||||
logo = 'https://angular.io/resources/images/logos/angular/angular.png';
|
logo = 'https://angular.io/resources/images/logos/angular/angular.png';
|
||||||
|
count = 3;
|
||||||
|
heroes: string[] = ['Magneta', 'Celeritas', 'Dynama'];
|
||||||
inc(i: number) {
|
inc(i: number) {
|
||||||
this.wolves = Math.min(5, Math.max(0, this.wolves + i));
|
this.wolves = Math.min(5, Math.max(0, this.wolves + i));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// #docregion
|
// #docplaster
|
||||||
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from '@angular/core';
|
// #docregion without-missing-translation
|
||||||
|
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, MissingTranslationStrategy } from '@angular/core';
|
||||||
|
import { CompilerConfig } from '@angular/compiler';
|
||||||
|
|
||||||
export function getTranslationProviders(): Promise<Object[]> {
|
export function getTranslationProviders(): Promise<Object[]> {
|
||||||
|
|
||||||
@ -17,13 +19,18 @@ export function getTranslationProviders(): Promise<Object[]> {
|
|||||||
// Ex: 'locale/messages.es.xlf`
|
// Ex: 'locale/messages.es.xlf`
|
||||||
const translationFile = `./locale/messages.${locale}.xlf`;
|
const translationFile = `./locale/messages.${locale}.xlf`;
|
||||||
|
|
||||||
|
// #docregion missing-translation
|
||||||
return getTranslationsWithSystemJs(translationFile)
|
return getTranslationsWithSystemJs(translationFile)
|
||||||
.then( (translations: string ) => [
|
.then( (translations: string ) => [
|
||||||
{ provide: TRANSLATIONS, useValue: translations },
|
{ provide: TRANSLATIONS, useValue: translations },
|
||||||
{ provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
|
{ provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
|
||||||
{ provide: LOCALE_ID, useValue: locale }
|
{ provide: LOCALE_ID, useValue: locale },
|
||||||
|
// #enddocregion without-missing-translation
|
||||||
|
{ provide: CompilerConfig, useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error }) }
|
||||||
|
// #docregion without-missing-translation
|
||||||
])
|
])
|
||||||
.catch(() => noProviders); // ignore if file not found
|
.catch(() => noProviders); // ignore if file not found
|
||||||
|
// #enddocregion missing-translation
|
||||||
}
|
}
|
||||||
|
|
||||||
declare var System: any;
|
declare var System: any;
|
||||||
@ -31,3 +38,4 @@ declare var System: any;
|
|||||||
function getTranslationsWithSystemJs(file: string) {
|
function getTranslationsWithSystemJs(file: string) {
|
||||||
return System.import(file + '!text'); // relies on text plugin
|
return System.import(file + '!text'); // relies on text plugin
|
||||||
}
|
}
|
||||||
|
// #enddocregion without-missing-translation
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||||
<body>
|
<body>
|
||||||
<trans-unit id="af2ccf4b5dba59616e92cf1531505af02da8f6d2" datatype="html">
|
<trans-unit id="introductionHeader" datatype="html">
|
||||||
<source>Hello i18n!</source>
|
<source>Hello i18n!</source>
|
||||||
<target>¡Hola i18n!</target>
|
<target>¡Hola i18n!</target>
|
||||||
<note priority="1" from="description">An introduction header for this sample</note>
|
<note priority="1" from="description">An introduction header for this sample</note>
|
||||||
@ -36,6 +36,20 @@ I don't output any element either
|
|||||||
<source/>
|
<source/>
|
||||||
<target>{gender, select, m {hombre} f {mujer}}</target>
|
<target>{gender, select, m {hombre} f {mujer}}</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
|
||||||
|
<source>Here we have: <x id="ICU"/></source>
|
||||||
|
<target>Aquí tenemos: <x id="ICU"/></target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
|
||||||
|
<source/>
|
||||||
|
<target>
|
||||||
|
{count, plural,
|
||||||
|
=0 { nadie }
|
||||||
|
=1 {{gender, select, m {un hombre} f {una mujer}}}
|
||||||
|
other {{{heroes.length}} {gender, select, m {hombres} f {mujeres}}}
|
||||||
|
}
|
||||||
|
</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||||
<body>
|
<body>
|
||||||
<!-- #docregion translated-hello -->
|
<!-- #docregion translated-hello -->
|
||||||
<trans-unit id="af2ccf4b5dba59616e92cf1531505af02da8f6d2" datatype="html">
|
<!-- #docregion custom-id -->
|
||||||
|
<trans-unit id="introductionHeader" datatype="html">
|
||||||
|
<!-- #enddocregion custom-id -->
|
||||||
<source>Hello i18n!</source>
|
<source>Hello i18n!</source>
|
||||||
<target>¡Hola i18n!</target>
|
<target>¡Hola i18n!</target>
|
||||||
<note priority="1" from="description">An introduction header for this sample</note>
|
<note priority="1" from="description">An introduction header for this sample</note>
|
||||||
@ -13,7 +15,9 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<!-- #enddocregion translated-hello -->
|
<!-- #enddocregion translated-hello -->
|
||||||
<!-- #docregion translated-other-nodes -->
|
<!-- #docregion translated-other-nodes -->
|
||||||
|
<!-- #docregion generated-id -->
|
||||||
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
|
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
|
||||||
|
<!-- #enddocregion generated-id -->
|
||||||
<source>I don't output any element</source>
|
<source>I don't output any element</source>
|
||||||
<target>No genero ningún elemento</target>
|
<target>No genero ningún elemento</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -48,6 +52,34 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<!-- #enddocregion translate-select-2 -->
|
<!-- #enddocregion translate-select-2 -->
|
||||||
<!-- #enddocregion translated-select -->
|
<!-- #enddocregion translated-select -->
|
||||||
|
<trans-unit id="db04527df562d12c8607eab2b5723ef6e2066ba0" datatype="html">
|
||||||
|
<source>Here we have: <x id="ICU"/></source>
|
||||||
|
<target/>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="000058be4e6f08b685d1d0a70f9da68067df7379" datatype="html">
|
||||||
|
<source/>
|
||||||
|
<target/>
|
||||||
|
</trans-unit>
|
||||||
|
<!-- #docregion translate-nested -->
|
||||||
|
<!-- #docregion translate-nested-1 -->
|
||||||
|
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
|
||||||
|
<source>Here we have: <x id="ICU"/></source>
|
||||||
|
<target>Aquí tenemos: <x id="ICU"/></target>
|
||||||
|
</trans-unit>
|
||||||
|
<!-- #enddocregion translate-nested-1 -->
|
||||||
|
<!-- #docregion translate-nested-2 -->
|
||||||
|
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
|
||||||
|
<source/>
|
||||||
|
<target>
|
||||||
|
{count, plural,
|
||||||
|
=0 { nadie }
|
||||||
|
=1 {{gender, select, m {un hombre} f {una mujer}}}
|
||||||
|
other {{{heroes.length}} {gender, select, m {hombres} f {mujeres}}}
|
||||||
|
}
|
||||||
|
</target>
|
||||||
|
</trans-unit>
|
||||||
|
<!-- #enddocregion translate-nested-2 -->
|
||||||
|
<!-- #enddocregion translate-nested -->
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
47
aio/content/examples/router/src/app.css
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* items class */
|
||||||
|
.items {
|
||||||
|
margin: 0 0 2em 0;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
width: 24em;
|
||||||
|
}
|
||||||
|
.items li {
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
background-color: #EEE;
|
||||||
|
margin: .5em;
|
||||||
|
padding: .3em 0;
|
||||||
|
height: 1.6em;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.items li:hover {
|
||||||
|
color: #607D8B;
|
||||||
|
background-color: #DDD;
|
||||||
|
left: .1em;
|
||||||
|
}
|
||||||
|
.items li.selected {
|
||||||
|
background-color: #CFD8DC;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.items li.selected:hover {
|
||||||
|
background-color: #BBD8DC;
|
||||||
|
}
|
||||||
|
.items .text {
|
||||||
|
position: relative;
|
||||||
|
top: -3px;
|
||||||
|
}
|
||||||
|
.items .badge {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: small;
|
||||||
|
color: white;
|
||||||
|
padding: 0.8em 0.7em 0 0.7em;
|
||||||
|
background-color: #607D8B;
|
||||||
|
line-height: 1em;
|
||||||
|
position: relative;
|
||||||
|
left: -1px;
|
||||||
|
top: -4px;
|
||||||
|
height: 1.8em;
|
||||||
|
margin-right: .8em;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
}
|
@ -10,6 +10,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="styles.css">
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
<link rel="stylesheet" href="app.css">
|
||||||
|
|
||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
@ -27,7 +27,7 @@ describe('AppComponent', function () {
|
|||||||
it('should have expected <h1> text', () => {
|
it('should have expected <h1> text', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const h1 = de.nativeElement;
|
const h1 = de.nativeElement;
|
||||||
expect(h1.innerText).toMatch(/angular/i,
|
expect(h1.textContent).toMatch(/angular/i,
|
||||||
'<h1> should say something about "Angular"');
|
'<h1> should say something about "Angular"');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
2
aio/content/examples/styleguide/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
*.js
|
|
||||||
!systemjs.custom.js
|
|
@ -36,6 +36,7 @@
|
|||||||
<a href="#inputs-and-outputs">Inputs and outputs</a><br>
|
<a href="#inputs-and-outputs">Inputs and outputs</a><br>
|
||||||
<a href="#pipes">Pipes</a><br>
|
<a href="#pipes">Pipes</a><br>
|
||||||
<a href="#safe-navigation-operator">Safe navigation operator <i>?.</i></a><br>
|
<a href="#safe-navigation-operator">Safe navigation operator <i>?.</i></a><br>
|
||||||
|
<a href="#non-null-assertion-operator">Non-null assertion operator <i>!.</i></a><br>
|
||||||
<a href="#enums">Enums</a><br>
|
<a href="#enums">Enums</a><br>
|
||||||
|
|
||||||
<!-- Interpolation and expressions -->
|
<!-- Interpolation and expressions -->
|
||||||
@ -803,6 +804,21 @@ The null hero's name is {{nullHero && nullHero.name}}
|
|||||||
<!-- #enddocregion safe-6 -->
|
<!-- #enddocregion safe-6 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<a class="to-toc" href="#toc">top</a>
|
||||||
|
|
||||||
|
<!-- non-null assertion operator -->
|
||||||
|
<hr><h2 id="non-null-assertion-operator">Non-null assertion operator <i>!.</i></h2>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<!-- #docregion non-null-assertion-1 -->
|
||||||
|
<!--No hero, no text -->
|
||||||
|
<div *ngIf="hero">
|
||||||
|
The hero's name is {{hero!.name}}
|
||||||
|
</div>
|
||||||
|
<!-- #enddocregion non-null-assertion-1 -->
|
||||||
|
</div>
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
|
|
||||||
<!-- TODO: discuss this in the Style binding section -->
|
<!-- TODO: discuss this in the Style binding section -->
|
||||||
|
@ -111,7 +111,7 @@ export class AppComponent implements AfterViewInit, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onSave(event: KeyboardEvent) {
|
onSave(event: KeyboardEvent) {
|
||||||
let evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).innerText : '';
|
let evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).textContent : '';
|
||||||
this.alert('Saved.' + evtMsg);
|
this.alert('Saved.' + evtMsg);
|
||||||
if (event) { event.stopPropagation(); }
|
if (event) { event.stopPropagation(); }
|
||||||
}
|
}
|
||||||
@ -127,6 +127,7 @@ export class AppComponent implements AfterViewInit, OnInit {
|
|||||||
resetHeroes() {
|
resetHeroes() {
|
||||||
this.heroes = Hero.heroes.map(hero => hero.clone());
|
this.heroes = Hero.heroes.map(hero => hero.clone());
|
||||||
this.currentHero = this.heroes[0];
|
this.currentHero = this.heroes[0];
|
||||||
|
this.hero = this.currentHero;
|
||||||
this.heroesWithTrackByCountReset = 0;
|
this.heroesWithTrackByCountReset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,8 +173,8 @@ function trackChanges(views: QueryList<ElementRef>, changed: () => void) {
|
|||||||
let oldRefs = views.toArray();
|
let oldRefs = views.toArray();
|
||||||
views.changes.subscribe((changes: QueryList<ElementRef>) => {
|
views.changes.subscribe((changes: QueryList<ElementRef>) => {
|
||||||
const changedRefs = changes.toArray();
|
const changedRefs = changes.toArray();
|
||||||
// Is every changed ElemRef the same as old and in the same position
|
// Check if every changed Element is the same as old and in the same position
|
||||||
const isSame = oldRefs.every((v, i) => v === changedRefs[i]);
|
const isSame = oldRefs.every((v, i) => v.nativeElement === changedRefs[i].nativeElement);
|
||||||
if (!isSame) {
|
if (!isSame) {
|
||||||
oldRefs = changedRefs;
|
oldRefs = changedRefs;
|
||||||
// wait a tick because called after views are constructed
|
// wait a tick because called after views are constructed
|
||||||
|
1
aio/content/examples/testing/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
!src/browser-test-shim.js
|
|
22
aio/content/examples/toh-pt5/src/styles.1.css
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* Master Styles */
|
||||||
|
h1 {
|
||||||
|
color: #369;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 250%;
|
||||||
|
}
|
||||||
|
h2, h3 {
|
||||||
|
color: #444;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-weight: lighter;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 2em;
|
||||||
|
}
|
||||||
|
body, input[text], button {
|
||||||
|
color: #888;
|
||||||
|
font-family: Cambria, Georgia;
|
||||||
|
}
|
||||||
|
/* everywhere else */
|
||||||
|
* {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
8
aio/content/examples/universal/.gitignore
vendored
@ -1,8 +0,0 @@
|
|||||||
aot/**/*.ts
|
|
||||||
**/*.ngfactory.ts
|
|
||||||
**/*.ngsummary.json
|
|
||||||
**/*.metadata.json
|
|
||||||
**/*.js
|
|
||||||
dist
|
|
||||||
!app/tsconfig.json
|
|
||||||
!/*.js
|
|
@ -1 +0,0 @@
|
|||||||
!karma.conf.ajs.js
|
|
@ -1,8 +0,0 @@
|
|||||||
aot/**/*
|
|
||||||
!aot/index.html
|
|
||||||
dist
|
|
||||||
!app/tsconfig.json
|
|
||||||
!rollup-config.js
|
|
||||||
!karma.conf.ajs.js
|
|
||||||
!copy-dist-files.js
|
|
||||||
!systemjs.config.1.js
|
|
@ -1,11 +1,6 @@
|
|||||||
// #docregion bootstrap
|
// #docregion bootstrap
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
import { UpgradeModule } from '@angular/upgrade/static';
|
|
||||||
|
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
|
||||||
upgrade.bootstrap(document.documentElement, ['phonecatApp']);
|
|
||||||
});
|
|
||||||
// #enddocregion bootstrap
|
// #enddocregion bootstrap
|
||||||
|
@ -7,12 +7,6 @@ import { browser, element, by } from 'protractor';
|
|||||||
|
|
||||||
describe('PhoneCat Application', function() {
|
describe('PhoneCat Application', function() {
|
||||||
|
|
||||||
beforeAll(function () {
|
|
||||||
// Set protractor to hybrid mode.
|
|
||||||
browser.rootEl = 'body';
|
|
||||||
browser.ng12Hybrid = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should redirect `index.html` to `index.html#!/phones', function() {
|
it('should redirect `index.html` to `index.html#!/phones', function() {
|
||||||
browser.get('index.html');
|
browser.get('index.html');
|
||||||
expect(browser.getLocationAbsUrl()).toBe('/phones');
|
expect(browser.getLocationAbsUrl()).toBe('/phones');
|
||||||
@ -70,7 +64,7 @@ describe('PhoneCat Application', function() {
|
|||||||
query.sendKeys('nexus');
|
query.sendKeys('nexus');
|
||||||
|
|
||||||
element.all(by.css('.phones li a')).first().click();
|
element.all(by.css('.phones li a')).first().click();
|
||||||
browser.sleep(200); // Not sure why this is needed but it is. The route change works fine.
|
browser.sleep(1000); // Not sure why this is needed but it is. The route change works fine.
|
||||||
expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s');
|
expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
!tsconfig.json
|
|
5
aio/content/examples/webpack/.gitignore
vendored
@ -1,5 +0,0 @@
|
|||||||
dist
|
|
||||||
!karma.webpack.conf.js
|
|
||||||
!webpack.config.js
|
|
||||||
!config/*
|
|
||||||
!public/css/styles.css
|
|
@ -9,14 +9,14 @@
|
|||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/common": "~4.0.0",
|
"@angular/common": "~4.2.0",
|
||||||
"@angular/compiler": "~4.0.0",
|
"@angular/compiler": "~4.2.0",
|
||||||
"@angular/core": "~4.0.0",
|
"@angular/core": "~4.2.0",
|
||||||
"@angular/forms": "~4.0.0",
|
"@angular/forms": "~4.2.0",
|
||||||
"@angular/http": "~4.0.0",
|
"@angular/http": "~4.2.0",
|
||||||
"@angular/platform-browser": "~4.0.0",
|
"@angular/platform-browser": "~4.2.0",
|
||||||
"@angular/platform-browser-dynamic": "~4.0.0",
|
"@angular/platform-browser-dynamic": "~4.2.0",
|
||||||
"@angular/router": "~4.0.0",
|
"@angular/router": "~4.2.0",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
"rxjs": "5.0.1",
|
"rxjs": "5.0.1",
|
||||||
"zone.js": "^0.8.4"
|
"zone.js": "^0.8.4"
|
||||||
@ -41,7 +41,7 @@
|
|||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"rimraf": "^2.5.2",
|
"rimraf": "^2.5.2",
|
||||||
"style-loader": "^0.13.1",
|
"style-loader": "^0.13.1",
|
||||||
"typescript": "~2.0.10",
|
"typescript": "~2.3.1",
|
||||||
"webpack": "2.2.1",
|
"webpack": "2.2.1",
|
||||||
"webpack-dev-server": "2.4.1",
|
"webpack-dev-server": "2.4.1",
|
||||||
"webpack-merge": "^3.0.0"
|
"webpack-merge": "^3.0.0"
|
||||||
|
@ -38,7 +38,7 @@ This page introduces modules; the [Angular modules](guide/ngmodule) page covers
|
|||||||
|
|
||||||
<br class="clear">
|
<br class="clear">
|
||||||
|
|
||||||
Every Angular app has at least one Angular module class, [the _root module_](guide/appmodule "AppModule: the root module"),
|
Every Angular app has at least one Angular module class, [the _root module_](guide/bootstrapping "AppModule: the root module"),
|
||||||
conventionally named `AppModule`.
|
conventionally named `AppModule`.
|
||||||
|
|
||||||
While the _root module_ may be the only module in a small application, most apps have many more
|
While the _root module_ may be the only module in a small application, most apps have many more
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# AppModule: the root module
|
# Bootstrapping
|
||||||
|
|
||||||
An Angular module class describes how the application parts fit together.
|
An Angular module class describes how the application parts fit together.
|
||||||
Every application has at least one Angular module, the _root_ module
|
Every application has at least one Angular module, the _root_ module
|
||||||
that you [bootstrap](guide/appmodule#main) to launch the application.
|
that you [bootstrap](guide/bootstrapping#main) to launch the application.
|
||||||
You can call it anything you want. The conventional name is `AppModule`.
|
You can call it anything you want. The conventional name is `AppModule`.
|
||||||
|
|
||||||
The [setup](guide/setup) instructions produce a new project with the following minimal `AppModule`.
|
The [setup](guide/setup) instructions produce a new project with the following minimal `AppModule`.
|
||||||
@ -10,7 +10,6 @@ You'll evolve this module as your application grows.
|
|||||||
|
|
||||||
|
|
||||||
<code-example path="setup/src/app/app.module.ts" title="src/app/app.module.ts" linenums="false">
|
<code-example path="setup/src/app/app.module.ts" title="src/app/app.module.ts" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
@ -26,7 +25,7 @@ The `@NgModule` decorator identifies `AppModule` as an Angular module class (als
|
|||||||
* **_bootstrap_** — the _root_ component that Angular creates and inserts into the `index.html` host web page.
|
* **_bootstrap_** — the _root_ component that Angular creates and inserts into the `index.html` host web page.
|
||||||
|
|
||||||
The [Angular Modules (NgModule)](guide/ngmodule) guide dives deeply into the details of Angular modules.
|
The [Angular Modules (NgModule)](guide/ngmodule) guide dives deeply into the details of Angular modules.
|
||||||
All you need to know at the moment is a few basics about these three properties.
|
All you need to know at the moment is a few basics about these three properties.
|
||||||
|
|
||||||
|
|
||||||
{@a imports}
|
{@a imports}
|
||||||
@ -35,7 +34,7 @@ All you need to know at the moment is a few basics about these three properties.
|
|||||||
### The _imports_ array
|
### The _imports_ array
|
||||||
|
|
||||||
Angular modules are a way to consolidate features that belong together into discrete units.
|
Angular modules are a way to consolidate features that belong together into discrete units.
|
||||||
Many features of Angular itself are organized as Angular modules.
|
Many features of Angular itself are organized as Angular modules.
|
||||||
HTTP services are in the `HttpModule`. The router is in the `RouterModule`.
|
HTTP services are in the `HttpModule`. The router is in the `RouterModule`.
|
||||||
Eventually you may create a feature module.
|
Eventually you may create a feature module.
|
||||||
|
|
||||||
@ -67,7 +66,7 @@ are unrelated and have completely different jobs.
|
|||||||
|
|
||||||
The _JavaScript_ `import` statements give you access to symbols _exported_ by other files
|
The _JavaScript_ `import` statements give you access to symbols _exported_ by other files
|
||||||
so you can reference them within _this_ file.
|
so you can reference them within _this_ file.
|
||||||
You add `import` statements to almost every application file.
|
You add `import` statements to almost every application file.
|
||||||
They have nothing to do with Angular and Angular knows nothing about them.
|
They have nothing to do with Angular and Angular knows nothing about them.
|
||||||
|
|
||||||
The _module's_ `imports` array appears _exclusively_ in the `@NgModule` metadata object.
|
The _module's_ `imports` array appears _exclusively_ in the `@NgModule` metadata object.
|
||||||
@ -86,10 +85,10 @@ that the application needs to function properly.
|
|||||||
You tell Angular which components belong to the `AppModule` by listing it in the module's `declarations` array.
|
You tell Angular which components belong to the `AppModule` by listing it in the module's `declarations` array.
|
||||||
As you create more components, you'll add them to `declarations`.
|
As you create more components, you'll add them to `declarations`.
|
||||||
|
|
||||||
You must declare _every_ component in an `NgModule` class.
|
You must declare _every_ component in an `NgModule` class.
|
||||||
If you use a component without declaring it, you'll see a clear error message in the browser console.
|
If you use a component without declaring it, you'll see a clear error message in the browser console.
|
||||||
|
|
||||||
You'll learn to create two other kinds of classes —
|
You'll learn to create two other kinds of classes —
|
||||||
[directives](guide/attribute-directives) and [pipes](guide/pipes) —
|
[directives](guide/attribute-directives) and [pipes](guide/pipes) —
|
||||||
that you must also add to the `declarations` array.
|
that you must also add to the `declarations` array.
|
||||||
|
|
||||||
@ -98,7 +97,7 @@ that you must also add to the `declarations` array.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Only _declarables_** — _components_, _directives_ and _pipes_ — belong in the `declarations` array.
|
**Only _declarables_** — _components_, _directives_ and _pipes_ — belong in the `declarations` array.
|
||||||
Do not put any other kind of class in `declarations`; _not_ `NgModule` classes, _not_ service classes, _not_ model classes.
|
Do not put any other kind of class in `declarations`; _not_ `NgModule` classes, _not_ service classes, _not_ model classes.
|
||||||
|
|
||||||
|
|
||||||
@ -111,14 +110,14 @@ Do not put any other kind of class in `declarations`; _not_ `NgModule` classes,
|
|||||||
|
|
||||||
### The _bootstrap_ array
|
### The _bootstrap_ array
|
||||||
|
|
||||||
You launch the application by [_bootstrapping_](guide/appmodule#main) the root `AppModule`.
|
You launch the application by [_bootstrapping_](guide/bootstrapping#main) the root `AppModule`.
|
||||||
Among other things, the _bootstrapping_ process creates the component(s) listed in the `bootstrap` array
|
Among other things, the _bootstrapping_ process creates the component(s) listed in the `bootstrap` array
|
||||||
and inserts each one into the browser DOM.
|
and inserts each one into the browser DOM.
|
||||||
|
|
||||||
Each bootstrapped component is the base of its own tree of components.
|
Each bootstrapped component is the base of its own tree of components.
|
||||||
Inserting a bootstrapped component usually triggers a cascade of component creations that fill out that tree.
|
Inserting a bootstrapped component usually triggers a cascade of component creations that fill out that tree.
|
||||||
|
|
||||||
While you can put more than one component tree on a host web page, that's not typical.
|
While you can put more than one component tree on a host web page, that's not typical.
|
||||||
Most applications have only one component tree and they bootstrap a single _root_ component.
|
Most applications have only one component tree and they bootstrap a single _root_ component.
|
||||||
|
|
||||||
You can call the one _root_ component anything you want but most developers call it `AppComponent`.
|
You can call the one _root_ component anything you want but most developers call it `AppComponent`.
|
||||||
@ -143,7 +142,7 @@ The variations depend upon how you want to compile the application and where you
|
|||||||
In the beginning, you will compile the application dynamically with the _Just-in-Time (JIT)_ compiler
|
In the beginning, you will compile the application dynamically with the _Just-in-Time (JIT)_ compiler
|
||||||
and you'll run it in a browser. You can learn about other options later.
|
and you'll run it in a browser. You can learn about other options later.
|
||||||
|
|
||||||
The recommended place to bootstrap a JIT-compiled browser application is in a separate file
|
The recommended place to bootstrap a JIT-compiled browser application is in a separate file
|
||||||
in the `src` folder named `src/main.ts`
|
in the `src` folder named `src/main.ts`
|
||||||
|
|
||||||
<code-example path="setup/src/main.ts" title="src/main.ts" linenums="false">
|
<code-example path="setup/src/main.ts" title="src/main.ts" linenums="false">
|
||||||
@ -156,10 +155,10 @@ This code creates a browser platform for dynamic (JIT) compilation and
|
|||||||
bootstraps the `AppModule` described above.
|
bootstraps the `AppModule` described above.
|
||||||
|
|
||||||
The _bootstrapping_ process sets up the execution environment,
|
The _bootstrapping_ process sets up the execution environment,
|
||||||
digs the _root_ `AppComponent` out of the module's `bootstrap` array,
|
digs the _root_ `AppComponent` out of the module's `bootstrap` array,
|
||||||
creates an instance of the component and inserts it within the element tag identified by the component's `selector`.
|
creates an instance of the component and inserts it within the element tag identified by the component's `selector`.
|
||||||
|
|
||||||
The `AppComponent` selector — here and in most documentation samples — is `my-app`
|
The `AppComponent` selector — here and in most documentation samples — is `my-app`
|
||||||
so Angular looks for a `<my-app>` tag in the `index.html` like this one ...
|
so Angular looks for a `<my-app>` tag in the `index.html` like this one ...
|
||||||
|
|
||||||
<code-example path="setup/src/index.html" region="my-app" title="setup/src/index.html" linenums="false">
|
<code-example path="setup/src/index.html" region="my-app" title="setup/src/index.html" linenums="false">
|
@ -68,7 +68,7 @@ Angular supports most recent browsers. This includes the following specific vers
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Marshmallow (6.0)
|
Nougat (7.0)<br>Marshmallow (6.0)
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
@ -1,617 +0,0 @@
|
|||||||
# CLI QuickStart
|
|
||||||
|
|
||||||
Good tools make application development quicker and easier to maintain than
|
|
||||||
if you did everything by hand.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
You'll pursue these ends in the following high-level steps:
|
|
||||||
|
|
||||||
1. [Set up](guide/cli-quickstart#devenv) the development environment.
|
|
||||||
2. [Create](guide/cli-quickstart#create-proj) a new project and skeleton application.
|
|
||||||
3. [Serve](guide/cli-quickstart#serve) the application.
|
|
||||||
4. [Edit](guide/cli-quickstart#first-component) the application.
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
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>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
You need to set up your development environment before you can do anything.
|
|
||||||
|
|
||||||
Install **[Node.js® and npm](https://nodejs.org/en/download/)**
|
|
||||||
if they are not already on your machine.
|
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Verify that you are running at least node `6.9.x` and npm `3.x.x`**
|
|
||||||
by running `node -v` and `npm -v` in a terminal/console window.
|
|
||||||
Older versions produce errors, but newer versions are fine.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Then **install the [Angular CLI](https://github.com/angular/angular-cli)** globally.
|
|
||||||
|
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
|
||||||
npm install -g @angular/cli
|
|
||||||
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id='create-proj'>
|
|
||||||
Step 2. Create a new project
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Open a terminal window.
|
|
||||||
|
|
||||||
|
|
||||||
Generate a new project and skeleton application by running the following commands:
|
|
||||||
|
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
|
||||||
ng new my-app
|
|
||||||
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Patience please.
|
|
||||||
It takes time to set up a new project, most of it spent installing npm packages.
|
|
||||||
|
|
||||||
|
|
||||||
</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.
|
|
||||||
|
|
||||||
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="The app works!">
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id='first-component'>
|
|
||||||
Step 4: Edit your first Angular component
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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`.
|
|
||||||
|
|
||||||
|
|
||||||
Open the component file and change the `title` property from _app works!_ to _My First Angular App_:
|
|
||||||
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<figure>
|
|
||||||
<img src='generated/images/guide/cli-quickstart/my-first-app.png' alt="Output of QuickStart app">
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Looking good!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 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">favicon.ico</div>
|
|
||||||
<div class="file">index.html</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>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
`app/app.component.{ts,html,css,spec.ts}`
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
`app/app.module.ts`
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Defines `AppModule`, the [root module](guide/appmodule "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>
|
|
||||||
|
|
||||||
`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>
|
|
||||||
|
|
||||||
`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/glossary#ahead-of-time-aot-compilation)
|
|
||||||
without changing any code by passing in `--aot` to `ng build` or `ng serve`.
|
|
||||||
|
|
||||||
</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>
|
|
||||||
</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/`.
|
|
||||||
|
|
||||||
|
|
||||||
<div class='filetree'>
|
|
||||||
<div class="file">my-app</div>
|
|
||||||
<div class='children'>
|
|
||||||
<div class="file">e2e</div>
|
|
||||||
<div class='children'>
|
|
||||||
<div class="file">app.e2e-spec.ts</div>
|
|
||||||
<div class="file">app.po.ts</div>
|
|
||||||
<div class="file">tsconfig.e2e.json</div>
|
|
||||||
</div>
|
|
||||||
<div class="file">node_modules/...</div>
|
|
||||||
<div class="file">src/...</div>
|
|
||||||
<div class="file">.angular-cli.json</div>
|
|
||||||
<div class="file">.editorconfig</div>
|
|
||||||
<div class="file">.gitignore</div>
|
|
||||||
<div class="file">karma.conf.js</div>
|
|
||||||
<div class="file">package.json</div>
|
|
||||||
<div class="file">protractor.conf.js</div>
|
|
||||||
<div class="file">README.md</div>
|
|
||||||
<div class="file">tsconfig.json</div>
|
|
||||||
<div class="file">tslint.json</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
`.angular-cli.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 build.
|
|
||||||
Check out the official documentation if you want to know more.
|
|
||||||
|
|
||||||
</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 commited to source control.
|
|
||||||
|
|
||||||
</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>
|
|
||||||
|
|
||||||
`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="l-sub-section">
|
|
||||||
|
|
||||||
### 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>
|
|
1213
aio/content/guide/docs-style-guide.md
Normal file
@ -1,27 +1,21 @@
|
|||||||
# Form Validation
|
# Form Validation
|
||||||
|
|
||||||
{@a top}
|
|
||||||
|
|
||||||
|
|
||||||
Improve overall data quality by validating user input for accuracy and completeness.
|
Improve overall data quality by validating user input for accuracy and completeness.
|
||||||
|
|
||||||
This cookbook shows how to validate user input in the UI and display useful validation messages
|
This page shows how to validate user input in the UI and display useful validation messages
|
||||||
using first the template-driven forms and then the reactive forms approach.
|
using first the Template Driven Forms and then the Reactive Forms approach.
|
||||||
|
|
||||||
<div class="l-sub-section">
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Read more about these choices in the [Forms](guide/forms)
|
Read more about these choices in the [Forms](guide/forms)
|
||||||
and the [Reactive Forms](guide/reactive-forms) guides.
|
and the [Reactive Forms](guide/reactive-forms) guides.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a toc}
|
|
||||||
|
|
||||||
{@a live-example}
|
{@a live-example}
|
||||||
|
|
||||||
|
|
||||||
@ -34,17 +28,29 @@ and the [Reactive Forms](guide/reactive-forms) guides.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a template1}
|
## Built-in validators
|
||||||
|
|
||||||
|
Angular forms include a number of built-in validator functions, which are functions
|
||||||
|
that help you check common user input in forms. In addition to the built-in
|
||||||
|
validators covered here of `minlength`, `maxlength`,
|
||||||
|
and `required`, there are others such as `min`, `max`, `email` and `pattern`
|
||||||
|
for Template Driven as well as Reactive Forms.
|
||||||
|
For a full list of built-in validators,
|
||||||
|
see the [Validators](api/forms/Validators) API reference.
|
||||||
|
|
||||||
|
|
||||||
## Simple template-driven forms
|
|
||||||
|
|
||||||
In the template-driven approach, you arrange
|
|
||||||
|
|
||||||
|
|
||||||
|
## Simple Template Driven Forms
|
||||||
|
|
||||||
|
In the Template Driven approach, you arrange
|
||||||
[form elements](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms_in_HTML) in the component's template.
|
[form elements](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms_in_HTML) in the component's template.
|
||||||
|
|
||||||
You add Angular form directives (mostly directives beginning `ng...`) to help
|
You add Angular form directives (mostly directives beginning `ng...`) to help
|
||||||
Angular construct a corresponding internal control model that implements form functionality.
|
Angular construct a corresponding internal control model that implements form functionality.
|
||||||
In template-drive forms, the control model is _implicit_ in the template.
|
In Template Driven forms, the control model is _implicit_ in the template.
|
||||||
|
|
||||||
To validate user input, you add [HTML validation attributes](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation)
|
To validate user input, you add [HTML validation attributes](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation)
|
||||||
to the elements. Angular interprets those as well, adding validator functions to the control model.
|
to the elements. Angular interprets those as well, adding validator functions to the control model.
|
||||||
@ -76,7 +82,8 @@ This gives you a reference to the Angular `NgModel` directive
|
|||||||
associated with this control that you can use _in the template_
|
associated with this control that you can use _in the template_
|
||||||
to check for control states such as `valid` and `dirty`.
|
to check for control states such as `valid` and `dirty`.
|
||||||
|
|
||||||
* The `*ngIf` on the `<div>` element reveals a set of nested message `divs` but only if there are "name" errors and
|
* The `*ngIf` on the `<div>` element reveals a set of nested message `divs`
|
||||||
|
but only if there are `name` errors and
|
||||||
the control is either `dirty` or `touched`.
|
the control is either `dirty` or `touched`.
|
||||||
|
|
||||||
* Each nested `<div>` can present a custom message for one of the possible validation errors.
|
* Each nested `<div>` can present a custom message for one of the possible validation errors.
|
||||||
@ -112,9 +119,9 @@ as well as other code to support the view.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Use this template-driven validation technique when working with static forms with simple, standard validation rules.
|
Use this Template Driven validation technique when working with static forms with simple, standard validation rules.
|
||||||
|
|
||||||
Here are the complete files for the first version of `HeroFormTemplateCompononent` in the template-driven approach:
|
Here are the complete files for the first version of `HeroFormTemplateCompononent` in the Template Driven approach:
|
||||||
|
|
||||||
|
|
||||||
<code-tabs>
|
<code-tabs>
|
||||||
@ -132,10 +139,8 @@ Here are the complete files for the first version of `HeroFormTemplateCompononen
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a template2}
|
|
||||||
|
|
||||||
|
## Template Driven Forms with validation messages in code
|
||||||
## Template-driven forms with validation messages in code
|
|
||||||
|
|
||||||
While the layout is straightforward,
|
While the layout is straightforward,
|
||||||
there are obvious shortcomings with the way it's handling validation messages:
|
there are obvious shortcomings with the way it's handling validation messages:
|
||||||
@ -152,7 +157,7 @@ In this example, you can move the logic and the messages into the component with
|
|||||||
the template and component.
|
the template and component.
|
||||||
|
|
||||||
Here's the hero name again, excerpted from the revised template
|
Here's the hero name again, excerpted from the revised template
|
||||||
(Template 2), next to the original version:
|
(template 2), next to the original version:
|
||||||
|
|
||||||
<code-tabs>
|
<code-tabs>
|
||||||
|
|
||||||
@ -174,14 +179,14 @@ The `<input>` element HTML is almost the same. There are noteworthy differences:
|
|||||||
|
|
||||||
* There's a new attribute, `forbiddenName`, that is actually a custom validation directive.
|
* There's a new attribute, `forbiddenName`, that is actually a custom validation directive.
|
||||||
It invalidates the control if the user enters "bob" in the name `<input>`([try it](guide/form-validation#live-example)).
|
It invalidates the control if the user enters "bob" in the name `<input>`([try it](guide/form-validation#live-example)).
|
||||||
See the [custom validation](guide/form-validation#custom-validation) section later in this cookbook for more information
|
See the [custom validation](guide/form-validation#custom-validation) section later in this page for more information
|
||||||
on custom validation directives.
|
on custom validation directives.
|
||||||
|
|
||||||
* The `#name` template variable is gone because the app no longer refers to the Angular control for this element.
|
* The `#name` template variable is gone because the app no longer refers to the Angular control for this element.
|
||||||
|
|
||||||
* Binding to the new `formErrors.name` property is sufficent to display all name validation error messages.
|
* Binding to the new `formErrors.name` property is sufficient to display all name validation error messages.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a component-class}
|
{@a component-class}
|
||||||
|
|
||||||
|
|
||||||
@ -219,7 +224,7 @@ the name of that variable as a string (`'heroForm'` in this case).
|
|||||||
* The `heroForm` object changes several times during the life of the component, most notably when you add a new hero.
|
* The `heroForm` object changes several times during the life of the component, most notably when you add a new hero.
|
||||||
Periodically inspecting it reveals these changes.
|
Periodically inspecting it reveals these changes.
|
||||||
|
|
||||||
* Angular calls the `ngAfterViewChecked` [lifecycle hook method](guide/lifecycle-hooks#afterview)
|
* Angular calls the `ngAfterViewChecked()` [lifecycle hook method](guide/lifecycle-hooks#afterview)
|
||||||
when anything changes in the view.
|
when anything changes in the view.
|
||||||
That's the right time to see if there's a new `heroForm` object.
|
That's the right time to see if there's a new `heroForm` object.
|
||||||
|
|
||||||
@ -246,7 +251,7 @@ For each field, the `onValueChanged` handler does the following:
|
|||||||
* If such a control exists _and_ it's been changed ("dirty")
|
* If such a control exists _and_ it's been changed ("dirty")
|
||||||
_and_ it's invalid, the handler composes a consolidated error message for all of the control's errors.
|
_and_ it's invalid, the handler composes a consolidated error message for all of the control's errors.
|
||||||
|
|
||||||
Next, the component needs some error messages of course—a set for each validated property with
|
Next, the component needs some error messages—a set for each validated property with
|
||||||
one message per validation rule:
|
one message per validation rule:
|
||||||
|
|
||||||
<code-example path="form-validation/src/app/template/hero-form-template2.component.ts" region="messages" title="template/hero-form-template2.component.ts (messages)" linenums="false">
|
<code-example path="form-validation/src/app/template/hero-form-template2.component.ts" region="messages" title="template/hero-form-template2.component.ts (messages)" linenums="false">
|
||||||
@ -278,8 +283,6 @@ Each field has approximately the same number of lines no matter its number of va
|
|||||||
The component also grows proportionally, at the rate of one line per validated field
|
The component also grows proportionally, at the rate of one line per validated field
|
||||||
and one line per validation message.
|
and one line per validation message.
|
||||||
|
|
||||||
Both trends are manageable.
|
|
||||||
|
|
||||||
Now that the messages are in code, you have more flexibility and can compose messages more efficiently.
|
Now that the messages are in code, you have more flexibility and can compose messages more efficiently.
|
||||||
You can refactor the messages out of the component, perhaps to a service class that retrieves them from the server.
|
You can refactor the messages out of the component, perhaps to a service class that retrieves them from the server.
|
||||||
In short, there are more opportunities to improve message handling now that text and logic have moved from template to code.
|
In short, there are more opportunities to improve message handling now that text and logic have moved from template to code.
|
||||||
@ -288,14 +291,14 @@ In short, there are more opportunities to improve message handling now that text
|
|||||||
{@a formmodule}
|
{@a formmodule}
|
||||||
|
|
||||||
|
|
||||||
### _FormModule_ and template-driven forms
|
### _FormModule_ and Template Driven forms
|
||||||
|
|
||||||
Angular has two different forms modules—`FormsModule` and
|
Angular has two different forms modules—`FormsModule` and
|
||||||
`ReactiveFormsModule`—that correspond with the
|
`ReactiveFormsModule`—that correspond with the
|
||||||
two approaches to form development. Both modules come
|
two approaches to form development. Both modules come
|
||||||
from the same `@angular/forms` library package.
|
from the same `@angular/forms` library package.
|
||||||
|
|
||||||
You've been reviewing the "Template-driven" approach which requires the `FormsModule`.
|
You've been reviewing the Template Driven approach which requires the `FormsModule`.
|
||||||
Here's how you imported it in the `HeroFormTemplateModule`.
|
Here's how you imported it in the `HeroFormTemplateModule`.
|
||||||
|
|
||||||
|
|
||||||
@ -323,9 +326,9 @@ They're not germane to the validation story. Look at the [live example](guide/fo
|
|||||||
{@a reactive}
|
{@a reactive}
|
||||||
|
|
||||||
|
|
||||||
## Reactive forms with validation in code
|
## Reactive Forms with validation in code
|
||||||
|
|
||||||
In the template-driven approach, you markup the template with form elements, validation attributes,
|
In the Template Driven approach, you mark up the template with form elements, validation attributes,
|
||||||
and `ng...` directives from the Angular `FormsModule`.
|
and `ng...` directives from the Angular `FormsModule`.
|
||||||
At runtime, Angular interprets the template and derives its _form control model_.
|
At runtime, Angular interprets the template and derives its _form control model_.
|
||||||
|
|
||||||
@ -334,23 +337,21 @@ You create the form control model in code. You write the template with form elem
|
|||||||
and `form...` directives from the Angular `ReactiveFormsModule`.
|
and `form...` directives from the Angular `ReactiveFormsModule`.
|
||||||
At runtime, Angular binds the template elements to your control model based on your instructions.
|
At runtime, Angular binds the template elements to your control model based on your instructions.
|
||||||
|
|
||||||
This approach requires a bit more effort. *You have to write the control model and manage it*.
|
|
||||||
|
|
||||||
This allows you to do the following:
|
This allows you to do the following:
|
||||||
|
|
||||||
* Add, change, and remove validation functions on the fly.
|
* Add, change, and remove validation functions on the fly.
|
||||||
* Manipulate the control model dynamically from within the component.
|
* Manipulate the control model dynamically from within the component.
|
||||||
* [Test](guide/form-validation#testing) validation and control logic with isolated unit tests.
|
* [Test](guide/form-validation#testing) validation and control logic with isolated unit tests.
|
||||||
|
|
||||||
The following cookbook sample re-writes the hero form in _reactive forms_ style.
|
The following sample re-writes the hero form in Reactive Forms style.
|
||||||
|
|
||||||
|
|
||||||
{@a reactive-forms-module}
|
{@a reactive-forms-module}
|
||||||
|
|
||||||
|
|
||||||
### Switch to the _ReactiveFormsModule_
|
### Switch to the _ReactiveFormsModule_
|
||||||
The reactive forms classes and directives come from the Angular `ReactiveFormsModule`, not the `FormsModule`.
|
The Reactive Forms classes and directives come from the Angular `ReactiveFormsModule`, not the `FormsModule`.
|
||||||
The application module for the reactive forms feature in this sample looks like this:
|
The application module for the Reactive Forms feature in this sample looks like this:
|
||||||
|
|
||||||
<code-example path="form-validation/src/app/reactive/hero-form-reactive.module.ts" title="src/app/reactive/hero-form-reactive.module.ts" linenums="false">
|
<code-example path="form-validation/src/app/reactive/hero-form-reactive.module.ts" title="src/app/reactive/hero-form-reactive.module.ts" linenums="false">
|
||||||
|
|
||||||
@ -358,7 +359,7 @@ The application module for the reactive forms feature in this sample looks like
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
The reactive forms feature module and component are in the `src/app/reactive` folder.
|
The Reactive Forms feature module and component are in the `src/app/reactive` folder.
|
||||||
Focus on the `HeroFormReactiveComponent` there, starting with its template.
|
Focus on the `HeroFormReactiveComponent` there, starting with its template.
|
||||||
|
|
||||||
|
|
||||||
@ -378,8 +379,8 @@ The `heroForm` is the control model that the component class builds and maintain
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Next, modify the template HTML elements to match the _reactive forms_ style.
|
Next, modify the template HTML elements to match the Reactive Forms style.
|
||||||
Here is the "name" portion of the template again, revised for reactive forms and compared with the template-driven version:
|
Here is the "name" portion of the template again, revised for Reactive Forms and compared with the Template Driven version:
|
||||||
|
|
||||||
<code-tabs>
|
<code-tabs>
|
||||||
|
|
||||||
@ -405,15 +406,13 @@ but rather for css styling and accessibility.
|
|||||||
|
|
||||||
<div class="l-sub-section">
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
Currently, Reactive Forms doesn't add the `required` or `aria-required`
|
||||||
|
HTML validation attribute to the DOM element
|
||||||
A future version of reactive forms will add the `required` HTML validation attribute to the DOM element
|
when the control has the `required` validator function.
|
||||||
(and perhaps the `aria-required` attribute) when the control has the `required` validator function.
|
|
||||||
|
|
||||||
Until then, apply the `required` attribute _and_ add the `Validator.required` function
|
Until then, apply the `required` attribute _and_ add the `Validator.required` function
|
||||||
to the control model, as you'll see below.
|
to the control model, as you'll see below.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -426,15 +425,6 @@ The reactive approach does not use data binding to move data into and out of the
|
|||||||
That's all in code.
|
That's all in code.
|
||||||
|
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The retreat from data binding is a principle of the reactive paradigm rather than a technical limitation.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a reactive-component-class}
|
{@a reactive-component-class}
|
||||||
|
|
||||||
@ -447,7 +437,7 @@ Angular no longer derives the control model from the template so you can no long
|
|||||||
You can create the Angular form control model explicitly with
|
You can create the Angular form control model explicitly with
|
||||||
the help of the `FormBuilder` class.
|
the help of the `FormBuilder` class.
|
||||||
|
|
||||||
Here's the section of code devoted to that process, paired with the template-driven code it replaces:
|
Here's the section of code devoted to that process, paired with the Template Driven code it replaces:
|
||||||
|
|
||||||
<code-tabs>
|
<code-tabs>
|
||||||
|
|
||||||
@ -507,18 +497,17 @@ discussed in a separate [section below](guide/form-validation#custom-validation)
|
|||||||
|
|
||||||
Learn more about `FormBuilder` in the [Introduction to FormBuilder](guide/reactive-forms#formbuilder) section of Reactive Forms guide.
|
Learn more about `FormBuilder` in the [Introduction to FormBuilder](guide/reactive-forms#formbuilder) section of Reactive Forms guide.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a committing-changes}
|
{@a committing-changes}
|
||||||
|
|
||||||
|
|
||||||
#### Committing hero value changes
|
#### Committing hero value changes
|
||||||
|
|
||||||
In two-way data binding, the user's changes flow automatically from the controls back to the data model properties.
|
In two-way data binding, the user's changes flow automatically from the controls back to the data model properties.
|
||||||
Reactive forms do not use data binding to update data model properties.
|
A Reactive Forms component should not use data binding to
|
||||||
|
automatically update data model properties.
|
||||||
The developer decides _when and how_ to update the data model from control values.
|
The developer decides _when and how_ to update the data model from control values.
|
||||||
|
|
||||||
This sample updates the model twice:
|
This sample updates the model twice:
|
||||||
@ -533,18 +522,6 @@ The `onSubmit()` method simply replaces the `hero` object with the combined valu
|
|||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This example is lucky in that the `heroForm.value` properties _just happen_ to
|
|
||||||
correspond _exactly_ to the hero data object properties.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The `addHero()` method discards pending changes and creates a brand new `hero` model object.
|
The `addHero()` method discards pending changes and creates a brand new `hero` model object.
|
||||||
|
|
||||||
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="add-hero" title="form-validation/src/app/reactive/hero-form-reactive.component.ts" linenums="false">
|
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="add-hero" title="form-validation/src/app/reactive/hero-form-reactive.component.ts" linenums="false">
|
||||||
@ -556,7 +533,7 @@ The `addHero()` method discards pending changes and creates a brand new `hero` m
|
|||||||
Then it calls `buildForm()` again which replaces the previous `heroForm` control model with a new one.
|
Then it calls `buildForm()` again which replaces the previous `heroForm` control model with a new one.
|
||||||
The `<form>` tag's `[formGroup]` binding refreshes the page with the new control model.
|
The `<form>` tag's `[formGroup]` binding refreshes the page with the new control model.
|
||||||
|
|
||||||
Here's the complete reactive component file, compared to the two template-driven component files.
|
Here's the complete reactive component file, compared to the two Template Driven component files.
|
||||||
|
|
||||||
<code-tabs>
|
<code-tabs>
|
||||||
|
|
||||||
@ -581,7 +558,7 @@ Here's the complete reactive component file, compared to the two template-driven
|
|||||||
|
|
||||||
|
|
||||||
Run the [live example](guide/form-validation#live-example) to see how the reactive form behaves,
|
Run the [live example](guide/form-validation#live-example) to see how the reactive form behaves,
|
||||||
and to compare all of the files in this cookbook sample.
|
and to compare all of the files in this sample.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -594,7 +571,7 @@ and to compare all of the files in this cookbook sample.
|
|||||||
|
|
||||||
## Custom validation
|
## Custom validation
|
||||||
This cookbook sample has a custom `forbiddenNameValidator()` function that's applied to both the
|
This cookbook sample has a custom `forbiddenNameValidator()` function that's applied to both the
|
||||||
template-driven and the reactive form controls. It's in the `src/app/shared` folder
|
Template Driven and the reactive form controls. It's in the `src/app/shared` folder
|
||||||
and declared in the `SharedModule`.
|
and declared in the `SharedModule`.
|
||||||
|
|
||||||
Here's the `forbiddenNameValidator()` function:
|
Here's the `forbiddenNameValidator()` function:
|
||||||
@ -623,7 +600,7 @@ and whose value is an arbitrary dictionary of values that you could insert into
|
|||||||
|
|
||||||
|
|
||||||
### Custom validation directive
|
### Custom validation directive
|
||||||
In the reactive forms component, the `'name'` control's validator function list
|
In the Reactive Forms component, the `'name'` control's validator function list
|
||||||
has a `forbiddenNameValidator` at the bottom.
|
has a `forbiddenNameValidator` at the bottom.
|
||||||
|
|
||||||
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="name-validators" title="reactive/hero-form-reactive.component.ts (name validators)" linenums="false">
|
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="name-validators" title="reactive/hero-form-reactive.component.ts (name validators)" linenums="false">
|
||||||
@ -632,7 +609,7 @@ has a `forbiddenNameValidator` at the bottom.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
In the _template-driven_ example, the `<input>` has the selector (`forbiddenName`)
|
In the Template Driven example, the `<input>` has the selector (`forbiddenName`)
|
||||||
of a custom _attribute directive_, which rejects "bob".
|
of a custom _attribute directive_, which rejects "bob".
|
||||||
|
|
||||||
<code-example path="form-validation/src/app/template/hero-form-template2.component.html" region="name-input" title="template/hero-form-template2.component.html (name input)" linenums="false">
|
<code-example path="form-validation/src/app/template/hero-form-template2.component.html" region="name-input" title="template/hero-form-template2.component.html (name input)" linenums="false">
|
||||||
@ -703,7 +680,7 @@ see [Attribute Directives](guide/attribute-directives).
|
|||||||
|
|
||||||
## Testing Considerations
|
## Testing Considerations
|
||||||
|
|
||||||
You can write _isolated unit tests_ of validation and control logic in _Reactive Forms_.
|
You can write _isolated unit tests_ of validation and control logic in Reactive Forms.
|
||||||
|
|
||||||
_Isolated unit tests_ probe the component class directly, independent of its
|
_Isolated unit tests_ probe the component class directly, independent of its
|
||||||
interactions with its template, the DOM, other dependencies, or Angular itself.
|
interactions with its template, the DOM, other dependencies, or Angular itself.
|
||||||
@ -711,8 +688,8 @@ interactions with its template, the DOM, other dependencies, or Angular itself.
|
|||||||
Such tests have minimal setup, are quick to write, and easy to maintain.
|
Such tests have minimal setup, are quick to write, and easy to maintain.
|
||||||
They do not require the `Angular TestBed` or asynchronous testing practices.
|
They do not require the `Angular TestBed` or asynchronous testing practices.
|
||||||
|
|
||||||
That's not possible with _template-driven_ forms.
|
That's not possible with Template Driven forms.
|
||||||
The template-driven approach relies on Angular to produce the control model and
|
The Template Driven approach relies on Angular to produce the control model and
|
||||||
to derive validation rules from the HTML validation attributes.
|
to derive validation rules from the HTML validation attributes.
|
||||||
You must use the `Angular TestBed` to create component test instances,
|
You must use the `Angular TestBed` to create component test instances,
|
||||||
write asynchronous tests, and interact with the DOM.
|
write asynchronous tests, and interact with the DOM.
|
||||||
|
@ -19,26 +19,14 @@ unexpected definitions.
|
|||||||
|
|
||||||
## Ahead-of-time (AOT) compilation
|
## Ahead-of-time (AOT) compilation
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
You can compile Angular applications at build time.
|
You can compile Angular applications at build time.
|
||||||
By compiling your application using the compiler-cli, `ngc`, you can bootstrap directly
|
By compiling your application using the compiler-cli, `ngc`, you can bootstrap directly
|
||||||
to a module factory, meaning you don't need to include the Angular compiler in your JavaScript bundle.
|
to a module factory, meaning you don't need to include the Angular compiler in your JavaScript bundle.
|
||||||
Ahead-of-time compiled applications also benefit from decreased load time and increased performance.
|
Ahead-of-time compiled applications also benefit from decreased load time and increased performance.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Angular module
|
## Angular module
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Helps you organize an application into cohesive blocks of functionality.
|
Helps you organize an application into cohesive blocks of functionality.
|
||||||
An Angular module identifies the components, directives, and pipes that the application uses along with the list of external Angular modules that the application needs, such as `FormsModule`.
|
An Angular module identifies the components, directives, and pipes that the application uses along with the list of external Angular modules that the application needs, such as `FormsModule`.
|
||||||
|
|
||||||
@ -48,23 +36,11 @@ called `AppModule` and resides in a file named `app.module.ts`.
|
|||||||
For details and examples, see the [Angular Modules (NgModule)](guide/ngmodule) page.
|
For details and examples, see the [Angular Modules (NgModule)](guide/ngmodule) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Annotation
|
## Annotation
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
In practice, a synonym for [Decoration](guide/glossary#decorator).
|
In practice, a synonym for [Decoration](guide/glossary#decorator).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a attribute-directive}
|
{@a attribute-directive}
|
||||||
|
|
||||||
|
|
||||||
@ -73,10 +49,6 @@ In practice, a synonym for [Decoration](guide/glossary#decorator).
|
|||||||
|
|
||||||
## Attribute directives
|
## Attribute directives
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A category of [directive](guide/glossary#directive) that can listen to and modify the behavior of
|
A category of [directive](guide/glossary#directive) that can listen to and modify the behavior of
|
||||||
other HTML elements, attributes, properties, and components. They are usually represented
|
other HTML elements, attributes, properties, and components. They are usually represented
|
||||||
as HTML attributes, hence the name.
|
as HTML attributes, hence the name.
|
||||||
@ -86,18 +58,10 @@ For example, you can use the `ngClass` directive to add and remove CSS class nam
|
|||||||
Learn about them in the [_Attribute Directives_](guide/attribute-directives) guide.
|
Learn about them in the [_Attribute Directives_](guide/attribute-directives) guide.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a B}
|
{@a B}
|
||||||
|
|
||||||
## Barrel
|
## Barrel
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A way to *roll up exports* from several ES2015 modules into a single convenient ES2015 module.
|
A way to *roll up exports* from several ES2015 modules into a single convenient ES2015 module.
|
||||||
The barrel itself is an ES2015 module file that re-exports *selected* exports of other ES2015 modules.
|
The barrel itself is an ES2015 module file that re-exports *selected* exports of other ES2015 modules.
|
||||||
|
|
||||||
@ -157,17 +121,8 @@ You can often achieve the same result using [Angular modules](guide/glossary#ang
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Binding
|
## Binding
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Usually refers to [data binding](guide/glossary#data-binding) and the act of
|
Usually refers to [data binding](guide/glossary#data-binding) and the act of
|
||||||
binding an HTML object property to a data object property.
|
binding an HTML object property to a data object property.
|
||||||
|
|
||||||
@ -175,16 +130,8 @@ Sometimes refers to a [dependency-injection](guide/glossary#dependency-injection
|
|||||||
between a "token"—also referred to as a "key"—and a dependency [provider](guide/glossary#provider).
|
between a "token"—also referred to as a "key"—and a dependency [provider](guide/glossary#provider).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Bootstrap
|
## Bootstrap
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
You launch an Angular application by "bootstrapping" it using the application root Angular module (`AppModule`).
|
You launch an Angular application by "bootstrapping" it using the application root Angular module (`AppModule`).
|
||||||
Bootstrapping identifies an application's top level "root" [component](guide/glossary#component),
|
Bootstrapping identifies an application's top level "root" [component](guide/glossary#component),
|
||||||
which is the first component that is loaded for the application.
|
which is the first component that is loaded for the application.
|
||||||
@ -193,17 +140,10 @@ For more information, see the [Setup](guide/setup) page.
|
|||||||
You can bootstrap multiple apps in the same `index.html`, each app with its own top-level root.
|
You can bootstrap multiple apps in the same `index.html`, each app with its own top-level root.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a C}
|
{@a C}
|
||||||
|
|
||||||
## camelCase
|
## camelCase
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The practice of writing compound words or phrases such that each word or abbreviation begins with a capital letter
|
The practice of writing compound words or phrases such that each word or abbreviation begins with a capital letter
|
||||||
_except the first letter, which is lowercase_.
|
_except the first letter, which is lowercase_.
|
||||||
|
|
||||||
@ -213,19 +153,11 @@ camelCase is also known as *lower camel case* to distinguish it from *upper came
|
|||||||
In Angular documentation, "camelCase" always means *lower camel case*.
|
In Angular documentation, "camelCase" always means *lower camel case*.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a component}
|
{@a component}
|
||||||
|
|
||||||
|
|
||||||
## Component
|
## Component
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
An Angular class responsible for exposing data to a [view](guide/glossary#view) and handling most of the view’s display and user-interaction logic.
|
An Angular class responsible for exposing data to a [view](guide/glossary#view) and handling most of the view’s display and user-interaction logic.
|
||||||
|
|
||||||
The *component* is one of the most important building blocks in the Angular system.
|
The *component* is one of the most important building blocks in the Angular system.
|
||||||
@ -240,17 +172,10 @@ Those familiar with "MVC" and "MVVM" patterns will recognize
|
|||||||
the component in the role of "controller" or "view model".
|
the component in the role of "controller" or "view model".
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a D}
|
{@a D}
|
||||||
|
|
||||||
## dash-case
|
## dash-case
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The practice of writing compound words or phrases such that each word is separated by a dash or hyphen (`-`).
|
The practice of writing compound words or phrases such that each word is separated by a dash or hyphen (`-`).
|
||||||
This form is also known as kebab-case.
|
This form is also known as kebab-case.
|
||||||
|
|
||||||
@ -259,16 +184,8 @@ the root of filenames (such as `hero-list.component.ts`) are often
|
|||||||
spelled in dash-case.
|
spelled in dash-case.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Data binding
|
## Data binding
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Applications display data values to a user and respond to user
|
Applications display data values to a user and respond to user
|
||||||
actions (such as clicks, touches, and keystrokes).
|
actions (such as clicks, touches, and keystrokes).
|
||||||
|
|
||||||
@ -292,10 +209,6 @@ operations and supporting declaration syntax.
|
|||||||
* [Two-way data binding with ngModel](guide/template-syntax#ngModel).
|
* [Two-way data binding with ngModel](guide/template-syntax#ngModel).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a decorator}
|
{@a decorator}
|
||||||
|
|
||||||
|
|
||||||
@ -304,10 +217,6 @@ operations and supporting declaration syntax.
|
|||||||
|
|
||||||
## Decorator | decoration
|
## Decorator | decoration
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A *function* that adds metadata to a class, its members (properties, methods) and function arguments.
|
A *function* that adds metadata to a class, its members (properties, methods) and function arguments.
|
||||||
|
|
||||||
Decorators are an experimental (stage 2), JavaScript language [feature](https://github.com/wycats/javascript-decorators). TypeScript adds support for decorators.
|
Decorators are an experimental (stage 2), JavaScript language [feature](https://github.com/wycats/javascript-decorators). TypeScript adds support for decorators.
|
||||||
@ -340,17 +249,8 @@ Always include parentheses `()` when applying a decorator.
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Dependency injection
|
## Dependency injection
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A design pattern and mechanism
|
A design pattern and mechanism
|
||||||
for creating and delivering parts of an application to other
|
for creating and delivering parts of an application to other
|
||||||
parts of an application that request them.
|
parts of an application that request them.
|
||||||
@ -401,10 +301,6 @@ You can register your own providers.
|
|||||||
Read more in the [Dependency Injection](guide/dependency-injection) page.
|
Read more in the [Dependency Injection](guide/dependency-injection) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a directive}
|
{@a directive}
|
||||||
|
|
||||||
|
|
||||||
@ -413,10 +309,6 @@ Read more in the [Dependency Injection](guide/dependency-injection) page.
|
|||||||
|
|
||||||
## Directive
|
## Directive
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
An Angular class responsible for creating, reshaping, and interacting with HTML elements
|
An Angular class responsible for creating, reshaping, and interacting with HTML elements
|
||||||
in the browser DOM. The directive is Angular's most fundamental feature.
|
in the browser DOM. The directive is Angular's most fundamental feature.
|
||||||
|
|
||||||
@ -447,17 +339,10 @@ shaping or reshaping HTML layout, typically by adding, removing, or manipulating
|
|||||||
elements and their children.
|
elements and their children.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a E}
|
{@a E}
|
||||||
|
|
||||||
## ECMAScript
|
## ECMAScript
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The [official JavaScript language specification](https://en.wikipedia.org/wiki/ECMAScript).
|
The [official JavaScript language specification](https://en.wikipedia.org/wiki/ECMAScript).
|
||||||
|
|
||||||
The latest approved version of JavaScript is
|
The latest approved version of JavaScript is
|
||||||
@ -473,47 +358,21 @@ to ES5 JavaScript.
|
|||||||
Angular developers can write in ES5 directly.
|
Angular developers can write in ES5 directly.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ES2015
|
## ES2015
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.
|
Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ES5
|
## ES5
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Short hand for [ECMAScript](guide/glossary#ecmascript) 5, the version of JavaScript run by most modern browsers.
|
Short hand for [ECMAScript](guide/glossary#ecmascript) 5, the version of JavaScript run by most modern browsers.
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ES6
|
## ES6
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.
|
Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a F}
|
{@a F}
|
||||||
|
|
||||||
|
|
||||||
@ -526,25 +385,13 @@ Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.
|
|||||||
|
|
||||||
## Injector
|
## Injector
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
An object in the Angular [dependency-injection system](guide/glossary#dependency-injection)
|
An object in the Angular [dependency-injection system](guide/glossary#dependency-injection)
|
||||||
that can find a named dependency in its cache or create a dependency
|
that can find a named dependency in its cache or create a dependency
|
||||||
with a registered [provider](guide/glossary#provider).
|
with a registered [provider](guide/glossary#provider).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Input
|
## Input
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A directive property that can be the *target* of a
|
A directive property that can be the *target* of a
|
||||||
[property binding](guide/template-syntax#property-binding) (explained in detail in the [Template Syntax](guide/template-syntax) page).
|
[property binding](guide/template-syntax#property-binding) (explained in detail in the [Template Syntax](guide/template-syntax) page).
|
||||||
Data values flow *into* this property from the data source identified
|
Data values flow *into* this property from the data source identified
|
||||||
@ -553,16 +400,8 @@ in the template expression to the right of the equal sign.
|
|||||||
See the [Input and output properties](guide/template-syntax#inputs-outputs) section of the [Template Syntax](guide/template-syntax) page.
|
See the [Input and output properties](guide/template-syntax#inputs-outputs) section of the [Template Syntax](guide/template-syntax) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Interpolation
|
## Interpolation
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A form of [property data binding](guide/glossary#data-binding) in which a
|
A form of [property data binding](guide/glossary#data-binding) in which a
|
||||||
[template expression](guide/glossary#template-expression) between double-curly braces
|
[template expression](guide/glossary#template-expression) between double-curly braces
|
||||||
renders as text. That text may be concatenated with neighboring text
|
renders as text. That text may be concatenated with neighboring text
|
||||||
@ -581,9 +420,6 @@ Read more about [interpolation](guide/template-syntax#interpolation) in the
|
|||||||
[Template Syntax](guide/template-syntax) page.
|
[Template Syntax](guide/template-syntax) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a J}
|
{@a J}
|
||||||
|
|
||||||
{@a jit}
|
{@a jit}
|
||||||
@ -591,40 +427,22 @@ Read more about [interpolation](guide/template-syntax#interpolation) in the
|
|||||||
|
|
||||||
## Just-in-time (JIT) compilation
|
## Just-in-time (JIT) compilation
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A bootstrapping method of compiling components and modules in the browser
|
A bootstrapping method of compiling components and modules in the browser
|
||||||
and launching the application dynamically. Just-in-time mode is a good choice during development.
|
and launching the application dynamically. Just-in-time mode is a good choice during development.
|
||||||
Consider using the [ahead-of-time](guide/glossary#aot) mode for production apps.
|
Consider using the [ahead-of-time](guide/glossary#aot) mode for production apps.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a K}
|
{@a K}
|
||||||
|
|
||||||
## kebab-case
|
## kebab-case
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
See [dash-case](guide/glossary#dash-case).
|
See [dash-case](guide/glossary#dash-case).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a L}
|
{@a L}
|
||||||
|
|
||||||
## Lifecycle hooks
|
## Lifecycle hooks
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Directives](guide/glossary#directive) and [components](guide/glossary#component) have a lifecycle
|
[Directives](guide/glossary#directive) and [components](guide/glossary#component) have a lifecycle
|
||||||
managed by Angular as it creates, updates, and destroys them.
|
managed by Angular as it creates, updates, and destroys them.
|
||||||
|
|
||||||
@ -648,21 +466,13 @@ Angular calls these hook methods in the following order:
|
|||||||
Read more in the [Lifecycle Hooks](guide/lifecycle-hooks) page.
|
Read more in the [Lifecycle Hooks](guide/lifecycle-hooks) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a M}
|
{@a M}
|
||||||
|
|
||||||
## Module
|
## Module
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Angular has the following types of modules:
|
Angular has the following types of modules:
|
||||||
|
|
||||||
* [Angular modules](guide/glossary#angular-module).
|
* [Angular modules](guide/glossary#angular-module).
|
||||||
@ -699,20 +509,12 @@ class belongs to a feature module named `date_pipe` in the file `date_pipe.ts`.
|
|||||||
You rarely access Angular feature modules directly. You usually import them from an Angular [scoped package](guide/glossary#scoped-package) such as `@angular/core`.
|
You rarely access Angular feature modules directly. You usually import them from an Angular [scoped package](guide/glossary#scoped-package) such as `@angular/core`.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a N}
|
{@a N}
|
||||||
|
|
||||||
{@a O}
|
{@a O}
|
||||||
|
|
||||||
## Observable
|
## Observable
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
An array whose items arrive asynchronously over time.
|
An array whose items arrive asynchronously over time.
|
||||||
Observables help you manage asynchronous data, such as data coming from a backend service.
|
Observables help you manage asynchronous data, such as data coming from a backend service.
|
||||||
Observables are used within Angular itself, including Angular's event system and its HTTP client service.
|
Observables are used within Angular itself, including Angular's event system and its HTTP client service.
|
||||||
@ -721,14 +523,8 @@ To use observables, Angular uses a third-party library called Reactive Extension
|
|||||||
Observables are a proposed feature for ES2016, the next version of JavaScript.
|
Observables are a proposed feature for ES2016, the next version of JavaScript.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A directive property that can be the *target* of event binding
|
A directive property that can be the *target* of event binding
|
||||||
(read more in the [event binding](guide/template-syntax#event-binding)
|
(read more in the [event binding](guide/template-syntax#event-binding)
|
||||||
section of the [Template Syntax](guide/template-syntax) page).
|
section of the [Template Syntax](guide/template-syntax) page).
|
||||||
@ -738,17 +534,10 @@ in the template expression to the right of the equal sign.
|
|||||||
See the [Input and output properties](guide/template-syntax#inputs-outputs) section of the [Template Syntax](guide/template-syntax) page.
|
See the [Input and output properties](guide/template-syntax#inputs-outputs) section of the [Template Syntax](guide/template-syntax) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a P}
|
{@a P}
|
||||||
|
|
||||||
## PascalCase
|
## PascalCase
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The practice of writing individual words, compound words, or phrases such that each word or abbreviation begins with a capital letter.
|
The practice of writing individual words, compound words, or phrases such that each word or abbreviation begins with a capital letter.
|
||||||
Class names are typically spelled in PascalCase. For example, `Person` and `HeroDetailComponent`.
|
Class names are typically spelled in PascalCase. For example, `Person` and `HeroDetailComponent`.
|
||||||
|
|
||||||
@ -756,16 +545,8 @@ This form is also known as *upper camel case* to distinguish it from *lower came
|
|||||||
In this documentation, "PascalCase" means *upper camel case* and "camelCase" means *lower camel case*.
|
In this documentation, "PascalCase" means *upper camel case* and "camelCase" means *lower camel case*.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Pipe
|
## Pipe
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
An Angular pipe is a function that transforms input values to output values for
|
An Angular pipe is a function that transforms input values to output values for
|
||||||
display in a [view](guide/glossary#view).
|
display in a [view](guide/glossary#view).
|
||||||
Here's an example that uses the built-in `currency` pipe to display
|
Here's an example that uses the built-in `currency` pipe to display
|
||||||
@ -783,35 +564,19 @@ You can also write your own custom pipes.
|
|||||||
Read more in the page on [pipes](guide/pipes).
|
Read more in the page on [pipes](guide/pipes).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Provider
|
## Provider
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A _provider_ creates a new instance of a dependency for the
|
A _provider_ creates a new instance of a dependency for the
|
||||||
[dependency injection](guide/glossary#dependency-injection) system.
|
[dependency injection](guide/glossary#dependency-injection) system.
|
||||||
It relates a lookup token to code—sometimes called a "recipe"—that can create a dependency value.
|
It relates a lookup token to code—sometimes called a "recipe"—that can create a dependency value.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a Q}
|
{@a Q}
|
||||||
|
|
||||||
{@a R}
|
{@a R}
|
||||||
|
|
||||||
## Reactive forms
|
## Reactive forms
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A technique for building Angular forms through code in a component.
|
A technique for building Angular forms through code in a component.
|
||||||
The alternative technique is [template-driven forms](guide/glossary#template-driven-forms).
|
The alternative technique is [template-driven forms](guide/glossary#template-driven-forms).
|
||||||
|
|
||||||
@ -825,16 +590,8 @@ When building reactive forms:
|
|||||||
Reactive forms are powerful, flexible, and a good choice for more complex data-entry form scenarios, such as dynamic generation of form controls.
|
Reactive forms are powerful, flexible, and a good choice for more complex data-entry form scenarios, such as dynamic generation of form controls.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Router
|
## Router
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Most applications consist of many screens or [views](guide/glossary#view).
|
Most applications consist of many screens or [views](guide/glossary#view).
|
||||||
The user navigates among them by clicking links and buttons,
|
The user navigates among them by clicking links and buttons,
|
||||||
and performing other similar actions that cause the application to
|
and performing other similar actions that cause the application to
|
||||||
@ -855,47 +612,24 @@ directives that users can click to navigate.
|
|||||||
For more information, see the [Routing & Navigation](guide/router) page.
|
For more information, see the [Routing & Navigation](guide/router) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Router module
|
## Router module
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A separate [Angular module](guide/glossary#angular-module) that provides the necessary service providers and directives for navigating through application views.
|
A separate [Angular module](guide/glossary#angular-module) that provides the necessary service providers and directives for navigating through application views.
|
||||||
|
|
||||||
For more information, see the [Routing & Navigation](guide/router) page.
|
For more information, see the [Routing & Navigation](guide/router) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Routing component
|
## Routing component
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
An Angular [component](guide/glossary#component) with a `RouterOutlet` that displays views based on router navigations.
|
An Angular [component](guide/glossary#component) with a `RouterOutlet` that displays views based on router navigations.
|
||||||
|
|
||||||
For more information, see the [Routing & Navigation](guide/router) page.
|
For more information, see the [Routing & Navigation](guide/router) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a S}
|
{@a S}
|
||||||
|
|
||||||
## Scoped package
|
## Scoped package
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A way to group related *npm* packages.
|
A way to group related *npm* packages.
|
||||||
Read more at the [npm-scope](https://docs.npmjs.com/misc/scope) page.
|
Read more at the [npm-scope](https://docs.npmjs.com/misc/scope) page.
|
||||||
|
|
||||||
@ -912,17 +646,8 @@ is that the scoped package name begins with the Angular *scope name*, `@angular`
|
|||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Service
|
## Service
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
For data or logic that is not associated
|
For data or logic that is not associated
|
||||||
with a specific view or that you want to share across components, build services.
|
with a specific view or that you want to share across components, build services.
|
||||||
|
|
||||||
@ -938,27 +663,15 @@ Applications often require services such as a data service or a logging service.
|
|||||||
For more information, see the [Services](tutorial/toh-pt4) page of the [Tour of Heroes](tutorial) tutorial.
|
For more information, see the [Services](tutorial/toh-pt4) page of the [Tour of Heroes](tutorial) tutorial.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a snake-case}
|
{@a snake-case}
|
||||||
|
|
||||||
|
|
||||||
## snake_case
|
## snake_case
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The practice of writing compound words or phrases such that an
|
The practice of writing compound words or phrases such that an
|
||||||
underscore (`_`) separates one word from the next. This form is also known as *underscore case*.
|
underscore (`_`) separates one word from the next. This form is also known as *underscore case*.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a structural-directive}
|
{@a structural-directive}
|
||||||
|
|
||||||
|
|
||||||
@ -967,10 +680,6 @@ underscore (`_`) separates one word from the next. This form is also known as *u
|
|||||||
|
|
||||||
## Structural directives
|
## Structural directives
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A category of [directive](guide/glossary#directive) that can
|
A category of [directive](guide/glossary#directive) that can
|
||||||
shape or reshape HTML layout, typically by adding and removing elements in the DOM.
|
shape or reshape HTML layout, typically by adding and removing elements in the DOM.
|
||||||
The `ngIf` "conditional element" directive and the `ngFor` "repeater" directive are well-known examples.
|
The `ngIf` "conditional element" directive and the `ngFor` "repeater" directive are well-known examples.
|
||||||
@ -978,32 +687,17 @@ The `ngIf` "conditional element" directive and the `ngFor` "repeater" directive
|
|||||||
Read more in the [Structural Directives](guide/structural-directives) page.
|
Read more in the [Structural Directives](guide/structural-directives) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a T}
|
{@a T}
|
||||||
|
|
||||||
## Template
|
## Template
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A chunk of HTML that Angular uses to render a [view](guide/glossary#view) with
|
A chunk of HTML that Angular uses to render a [view](guide/glossary#view) with
|
||||||
the support and guidance of an Angular [directive](guide/glossary#directive),
|
the support and guidance of an Angular [directive](guide/glossary#directive),
|
||||||
most notably a [component](guide/glossary#component).
|
most notably a [component](guide/glossary#component).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Template-driven forms
|
## Template-driven forms
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A technique for building Angular forms using HTML forms and input elements in the view.
|
A technique for building Angular forms using HTML forms and input elements in the view.
|
||||||
The alternate technique is [Reactive Forms](guide/glossary#reactive-forms).
|
The alternate technique is [Reactive Forms](guide/glossary#reactive-forms).
|
||||||
|
|
||||||
@ -1020,16 +714,8 @@ Read about how to build template-driven forms
|
|||||||
in the [Forms](guide/forms) page.
|
in the [Forms](guide/forms) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Template expression
|
## Template expression
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A TypeScript-like syntax that Angular evaluates within
|
A TypeScript-like syntax that Angular evaluates within
|
||||||
a [data binding](guide/glossary#data-binding).
|
a [data binding](guide/glossary#data-binding).
|
||||||
|
|
||||||
@ -1038,30 +724,14 @@ in the [Template expressions](guide/template-syntax#template-expressions) sectio
|
|||||||
of the [Template Syntax](guide/template-syntax) page.
|
of the [Template Syntax](guide/template-syntax) page.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Transpile
|
## Transpile
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The process of transforming code written in one form of JavaScript
|
The process of transforming code written in one form of JavaScript
|
||||||
(such as TypeScript) into another form of JavaScript (such as [ES5](guide/glossary#es5)).
|
(such as TypeScript) into another form of JavaScript (such as [ES5](guide/glossary#es5)).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## TypeScript
|
## TypeScript
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A version of JavaScript that supports most [ECMAScript 2015](guide/glossary#es2015)
|
A version of JavaScript that supports most [ECMAScript 2015](guide/glossary#es2015)
|
||||||
language features such as [decorators](guide/glossary#decorator).
|
language features such as [decorators](guide/glossary#decorator).
|
||||||
|
|
||||||
@ -1076,20 +746,12 @@ you can use other JavaScript dialects such as [ES5](guide/glossary#es5).
|
|||||||
Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).
|
Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a U}
|
{@a U}
|
||||||
|
|
||||||
{@a V}
|
{@a V}
|
||||||
|
|
||||||
## View
|
## View
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A portion of the screen that displays information and responds
|
A portion of the screen that displays information and responds
|
||||||
to user actions such as clicks, mouse moves, and keystrokes.
|
to user actions such as clicks, mouse moves, and keystrokes.
|
||||||
|
|
||||||
@ -1103,10 +765,6 @@ dynamically as the user navigates through the application, typically
|
|||||||
under the control of a [router](guide/glossary#router).
|
under the control of a [router](guide/glossary#router).
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a W}
|
{@a W}
|
||||||
|
|
||||||
|
|
||||||
@ -1120,10 +778,6 @@ under the control of a [router](guide/glossary#router).
|
|||||||
|
|
||||||
## Zone
|
## Zone
|
||||||
|
|
||||||
<div class="l-sub-section">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A mechanism for encapsulating and intercepting
|
A mechanism for encapsulating and intercepting
|
||||||
a JavaScript application's asynchronous activity.
|
a JavaScript application's asynchronous activity.
|
||||||
|
|
||||||
@ -1141,7 +795,4 @@ asynchronous events by checking for data changes and updating
|
|||||||
the information it displays via [data bindings](guide/glossary#data-binding).
|
the information it displays via [data bindings](guide/glossary#data-binding).
|
||||||
|
|
||||||
Learn more about zones in this
|
Learn more about zones in this
|
||||||
[Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U).
|
[Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U).
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
@ -407,6 +407,9 @@ like the Observable-based version.
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
First, make sure to import the `toPromise` operator of the RxJS library.
|
||||||
|
|
||||||
|
<code-example path="http/src/app/toh/hero.service.promise.ts" region="rxjs-imports" title="src/app/toh/hero.service.promise.ts (import rxjs)" linenums="false"></code-example>
|
||||||
|
|
||||||
Here is a comparison of the `HeroService` using Promises versus Observables,
|
Here is a comparison of the `HeroService` using Promises versus Observables,
|
||||||
highlighting just the parts that are different.
|
highlighting just the parts that are different.
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
# Internationalization (i18n)
|
# Internationalization (i18n)
|
||||||
|
|
||||||
{@a top}
|
|
||||||
|
|
||||||
|
|
||||||
Angular's _internationalization_ (_i18n_) tools help make your app available in multiple languages.
|
Angular's _internationalization_ (_i18n_) tools help make your app available in multiple languages.
|
||||||
|
|
||||||
Try this <live-example name="i18n" title="i18n Example in Spanish">live example</live-example>
|
Try this <live-example name="i18n" title="i18n Example in Spanish">live example</live-example>
|
||||||
of a JIT-compiled app, translated into Spanish.
|
of a JIT-compiled app, translated into Spanish.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a angular-i18n}
|
{@a angular-i18n}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Angular and _i18n_ template translation
|
## Angular and _i18n_ template translation
|
||||||
|
|
||||||
Application internationalization is a challenging, many-faceted effort that
|
Application internationalization is a challenging, many-faceted effort that
|
||||||
@ -23,20 +16,13 @@ Angular's _i18n_ internationalization facilities can help.
|
|||||||
This page describes the _i18n_ tools available to assist translation of component template text
|
This page describes the _i18n_ tools available to assist translation of component template text
|
||||||
into multiple languages.
|
into multiple languages.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="l-sub-section">
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Practitioners of _internationalization_ refer to a translatable text as a "_message_".
|
Practitioners of _internationalization_ refer to a translatable text as a "_message_".
|
||||||
This page uses the words "_text_" and "_message_" interchangably and in the combination, "_text message_".
|
This page uses the words "_text_" and "_message_" interchangeably and in the combination, "_text message_".
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The _i18n_ template translation process has four phases:
|
The _i18n_ template translation process has four phases:
|
||||||
|
|
||||||
1. Mark static text messages in your component templates for translation.
|
1. Mark static text messages in your component templates for translation.
|
||||||
@ -52,11 +38,8 @@ in the target language.
|
|||||||
|
|
||||||
You need to build and deploy a separate version of the application for each supported language.
|
You need to build and deploy a separate version of the application for each supported language.
|
||||||
|
|
||||||
|
|
||||||
{@a i18n-attribute}
|
{@a i18n-attribute}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Mark text with the _i18n_ attribute
|
## Mark text with the _i18n_ attribute
|
||||||
|
|
||||||
The Angular `i18n` attribute is a marker for translatable content.
|
The Angular `i18n` attribute is a marker for translatable content.
|
||||||
@ -65,73 +48,112 @@ Place it on every element tag whose fixed text should be translated.
|
|||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
`i18n` is not an Angular _directive_.
|
`i18n` is not an Angular _directive_.
|
||||||
It's a custom _attribute_, recognized by Angular tools and compilers.
|
It's a custom _attribute_, recognized by Angular tools and compilers.
|
||||||
After translation, the compiler removes it.
|
After translation, the compiler removes it.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
In the accompanying sample, an `<h1>` tag displays a simple English language greeting
|
In the accompanying sample, an `<h1>` tag displays a simple English language greeting
|
||||||
that you translate into Spanish:
|
that you translate into Spanish:
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.1.html" region="greeting" title="src/app/app.component.html" linenums="false">
|
<code-example path="i18n/src/app/app.component.1.html" region="greeting" title="src/app/app.component.html" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Add the `i18n` attribute to the tag to mark it for translation.
|
Add the `i18n` attribute to the tag to mark it for translation.
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.1.html" region="i18n-attribute" title="src/app/app.component.html" linenums="false">
|
<code-example path="i18n/src/app/app.component.1.html" region="i18n-attribute" title="src/app/app.component.html" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a help-translator}
|
{@a help-translator}
|
||||||
|
|
||||||
|
### Help the translator with a _description_ and _meaning_
|
||||||
### Help the translator with a _description_ and _intent_
|
|
||||||
|
|
||||||
In order to translate it accurately, the translator may
|
In order to translate it accurately, the translator may
|
||||||
need a description of the message.
|
need a description of the message.
|
||||||
Assign a description to the i18n attribute:
|
Assign a description to the i18n attribute:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.1.html" region="i18n-attribute-desc" title="src/app/app.component.html" linenums="false">
|
<code-example path="i18n/src/app/app.component.1.html" region="i18n-attribute-desc" title="src/app/app.component.html" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
In order to deliver a correct translation, the translator may need to
|
In order to deliver a correct translation, the translator may need to
|
||||||
know your _intent_—the true _meaning_ of the text
|
know the _meaning_ or _intent_ of the text within _this particular_ application context.
|
||||||
within _this particular_ application context.
|
|
||||||
In front of the description, add some contextual meaning to the assigned string,
|
|
||||||
separating it from the description with the `|` character (`<meaning>|<description>`):
|
|
||||||
|
|
||||||
|
You add context by beginning the string with the _meaning_ and
|
||||||
|
separating it from the _description_ with the `|` character (`<meaning>|<description>`):
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.html" region="i18n-attribute-meaning" title="src/app/app.component.html" linenums="false">
|
<code-example path="i18n/src/app/app.component.1.html" region="i18n-attribute-meaning" title="src/app/app.component.html" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
While all appearances of a message with the _same_ meaning have the _same_ translation,
|
While all appearances of a message with the _same_ meaning have the _same_ translation,
|
||||||
a message with *a variety of possible meanings* could have different translations.
|
a message with *a variety of possible meanings* could have different translations.
|
||||||
The Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file
|
The Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file
|
||||||
to facilitiate contextually-specific translations.
|
to facilitate contextually-specific translations.
|
||||||
|
|
||||||
|
|
||||||
|
{@a custom-id}
|
||||||
|
|
||||||
|
### Set a custom _id_ to improve search and maintenance
|
||||||
|
|
||||||
|
The angular _i18n_ extractor tool generates a file with a _translation unit_ entry for each `i18n` attribute in a template. By default, it assigns each translation unit a unique _id_ such as this one:
|
||||||
|
|
||||||
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="generated-id" linenums="false">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
This _id_ is obscure and difficult for humans to read or remember.
|
||||||
|
|
||||||
|
Worse, when you change the translatable text, perhaps to fix a typo,
|
||||||
|
the extractor tool generates a new _id_ for that translation.
|
||||||
|
You will lose the translation unless you update it with the new _id_.
|
||||||
|
That [complicates maintenance](#maintenance).
|
||||||
|
|
||||||
|
Consider specifying your own, meaningful _id_ in the `i18n` attribute, **prefixed with `@@`**.
|
||||||
|
|
||||||
|
<code-example path='i18n/src/app/app.component.1.html' region='i18n-attribute-solo-id' title='app/app.component.html' linenums="false">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
Now the extractor tool and compiler will generate a translation unit with _your custom id_ and never change it.
|
||||||
|
|
||||||
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="custom-id" linenums="false">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
Here is the `i18n` attribute with a _definition_, followed by the custom `id`:
|
||||||
|
|
||||||
|
<code-example path='i18n/src/app/app.component.1.html' region='i18n-attribute-id' title='app/app.component.html' linenums="false">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
Here is a _meaning_ and a _description_ and the _id_ at the end:
|
||||||
|
|
||||||
|
<code-example path='i18n/src/app/app.component.1.html' region='i18n-attribute-meaning-and-id' title='app/app.component.html' linenums="false">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
Be sure to define _unique_ custom ids. If you use the same id for 2 _different_ blocks of text, only the first one will be extracted,
|
||||||
|
and its translation used in both blocks of text.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<p i18n="@@myId">Hello</p>
|
||||||
|
<p i18n="@@myId">Good bye</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
with the translation:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<trans-unit id="myId" datatype="html">
|
||||||
|
<source>Hello</source>
|
||||||
|
<target state="new">Hola</target>
|
||||||
|
</trans-unit>
|
||||||
|
```
|
||||||
|
|
||||||
|
Both `<p>` elements will contain the text `Hola`.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
{@a no-element}
|
{@a no-element}
|
||||||
|
|
||||||
|
|
||||||
### Translate text without creating an element
|
### Translate text without creating an element
|
||||||
|
|
||||||
Suppose there is a stretch of text that you'd like to translate.
|
Suppose there is a stretch of text that you'd like to translate.
|
||||||
@ -140,58 +162,37 @@ you don't want to create a new DOM element merely to facilitate translation.
|
|||||||
|
|
||||||
Here are two techniques to try.
|
Here are two techniques to try.
|
||||||
|
|
||||||
(1) Wrap the text in an `<ng-container>` element. The `<ng-container>` is never renderered:
|
(1) Wrap the text in an `<ng-container>` element. The `<ng-container>` is never rendered:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.html" region="i18n-ng-container" title="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>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(2) Wrap the text in a pair of HTML comments:
|
(2) Wrap the text in a pair of HTML comments:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.html" region="i18n-with-comment" title="src/app/app.component.html" linenums="false">
|
<code-example path="i18n/src/app/app.component.html" region="i18n-with-comment" title="src/app/app.component.html" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a translate-attributes}
|
{@a translate-attributes}
|
||||||
|
|
||||||
|
## Add _i18n_ translation attributes
|
||||||
## Add _i18n-..._ translation attributes
|
|
||||||
You've added an image to your template. You care about accessibility too so you add a `title` attribute:
|
You've added an image to your template. You care about accessibility too so you add a `title` attribute:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.1.html" region="i18n-title" title="src/app/app.component.html" linenums="false">
|
<code-example path="i18n/src/app/app.component.1.html" region="i18n-title" title="src/app/app.component.html" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The `title` attribute needs to be translated.
|
The `title` attribute needs to be translated.
|
||||||
Angular i18n support has more translation attributes in the form,`i18n-x`, where `x` is the
|
Angular i18n support has more translation attributes in the form,`i18n-x`, where `x` is the
|
||||||
name of the attribute to translate.
|
name of the attribute to translate.
|
||||||
|
|
||||||
To translate the `title` on the `img` tag from the previous example, write:
|
To translate the `title` on the `img` tag from the previous example, write:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.html" region="i18n-title-translate" title="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>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
You can also assign a meaning and a description with the `i18n-x="<meaning>|<description>"` syntax.
|
You can also assign a meaning and a description with the `i18n-x="<meaning>|<description>"` syntax.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a cardinality}
|
{@a cardinality}
|
||||||
|
|
||||||
|
|
||||||
## Handle singular and plural
|
## Handle singular and plural
|
||||||
|
|
||||||
Different languages have different pluralization rules.
|
Different languages have different pluralization rules.
|
||||||
@ -202,13 +203,9 @@ Other languages might express the _cardinality_ differently.
|
|||||||
|
|
||||||
Here's how you could mark up the component template to display the phrase appropriate to the number of wolves:
|
Here's how you could mark up the component template to display the phrase appropriate to the number of wolves:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.html" region="i18n-plural" title="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>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* The first parameter is the key. It is bound to the component property (`wolves`)
|
* The first parameter is the key. It is bound to the component property (`wolves`)
|
||||||
that determines the number of wolves.
|
that determines the number of wolves.
|
||||||
* The second parameter identifies this as a `plural` translation type.
|
* The second parameter identifies this as a `plural` translation type.
|
||||||
@ -217,43 +214,41 @@ categories and their matching values.
|
|||||||
|
|
||||||
Pluralization categories include:
|
Pluralization categories include:
|
||||||
|
|
||||||
* =0
|
* =0 (or any other number)
|
||||||
* =1
|
* zero
|
||||||
* =5
|
* one
|
||||||
|
* two
|
||||||
* few
|
* few
|
||||||
|
* many
|
||||||
* other
|
* other
|
||||||
|
|
||||||
Put the default _English_ translation in braces (`{}`) next to the pluralization category.
|
Put the default _English_ translation in braces (`{}`) next to the pluralization category.
|
||||||
|
|
||||||
* When you're talking about one wolf, you could write `=1 {one wolf}`.
|
* When you're talking about one wolf, you could write `=1 {one wolf}`.
|
||||||
|
|
||||||
* For zero wolves, you could write `=0 {no wolves}`.
|
* For zero wolves, you could write `=0 {no wolves}`.
|
||||||
|
|
||||||
* For two wolves, you could write `=2 {two wolves}`.
|
* For two wolves, you could write `=2 {two wolves}`.
|
||||||
|
|
||||||
You could keep this up for three, four, and every other number of wolves.
|
You could keep this up for three, four, and every other number of wolves.
|
||||||
Or you could specify the **`other`** category as a catch-all for any unmatched cardinality
|
Or you could specify the **`other`** category as a catch-all for any unmatched cardinality
|
||||||
and write something like: `other {a wolf pack}`.
|
and write something like: `other {a wolf pack}`.
|
||||||
|
|
||||||
|
|
||||||
<div class="l-sub-section">
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This syntax conforms to the
|
This syntax conforms to the
|
||||||
<a href="http://userguide.icu-project.org/formatparse/messages" title="ICU Message Format">ICU Message Format</a>
|
<a href="http://userguide.icu-project.org/formatparse/messages" title="ICU Message Format">ICU Message Format</a>
|
||||||
that derives from the
|
that derives from the
|
||||||
<a href="http://cldr.unicode.org/" title="CLDR">Common Locale Data Repository (CLDR)</a>,
|
<a href="http://cldr.unicode.org/" title="CLDR">Common Locale Data Repository (CLDR)</a>,
|
||||||
which specifies the
|
which specifies the
|
||||||
<a href="http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules" title="Pluralization Rules">pluralization rules</a>.
|
<a href="http://cldr.unicode.org/index/cldr-spec/plural-rules" title="Pluralization Rules">pluralization rules</a>.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a select}
|
{@a select}
|
||||||
|
|
||||||
|
|
||||||
## Select among alternative texts
|
## Select among alternative texts
|
||||||
|
|
||||||
The application displays different text depending upon whether the hero is male or female.
|
The application displays different text depending upon whether the hero is male or female.
|
||||||
These text alternatives require translation too.
|
These text alternatives require translation too.
|
||||||
|
|
||||||
@ -266,17 +261,18 @@ The following format message in the component template binds to the component's
|
|||||||
property, which outputs either an "m" or an "f".
|
property, which outputs either an "m" or an "f".
|
||||||
The message maps those values to the appropriate translation:
|
The message maps those values to the appropriate translation:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.html" region="i18n-select" title="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>
|
</code-example>
|
||||||
|
|
||||||
|
## Nesting pluralization and selection expressions
|
||||||
|
|
||||||
|
You can also nest different ICU expressions together. For example:
|
||||||
|
|
||||||
|
<code-example path="i18n/src/app/app.component.html" region="i18n-nested" title="src/app/app.component.html">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
{@a ng-xi18n}
|
{@a ng-xi18n}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Create a translation source file with the _ng-xi18n_ tool
|
## Create a translation source file with the _ng-xi18n_ tool
|
||||||
|
|
||||||
Use the **_ng-xi18n_ extraction tool** to extract the `i18n`-marked texts
|
Use the **_ng-xi18n_ extraction tool** to extract the `i18n`-marked texts
|
||||||
@ -285,63 +281,46 @@ into a translation source file in an industry standard format.
|
|||||||
This is an Angular CLI tool in the `@angular/compiler-cli` npm package.
|
This is an Angular CLI tool in the `@angular/compiler-cli` npm package.
|
||||||
If you haven't already installed the CLI and its `platform-server` peer dependency, do so now:
|
If you haven't already installed the CLI and its `platform-server` peer dependency, do so now:
|
||||||
|
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
npm install @angular/compiler-cli @angular/platform-server --save
|
npm install @angular/compiler-cli @angular/platform-server --save
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Open a terminal window at the root of the application project and enter the `ng-xi18n` command:
|
Open a terminal window at the root of the application project and enter the `ng-xi18n` command:
|
||||||
|
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
./node_modules/.bin/ng-xi18n
|
./node_modules/.bin/ng-xi18n
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="l-sub-section">
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Windows users may have to quote the command like this: `"./node_modules/.bin/ng-xi18n"`
|
Windows users may have to quote the command like this: `"./node_modules/.bin/ng-xi18n"`
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
By default, the tool generates a translation file named **`messages.xlf`** in the
|
By default, the tool generates a translation file named **`messages.xlf`** in the
|
||||||
<a href="https://en.wikipedia.org/wiki/XLIFF">XML Localisation Interchange File Format (XLIFF, version 1.2)</a>.
|
<a href="https://en.wikipedia.org/wiki/XLIFF">XML Localization Interchange File Format (XLIFF, version 1.2)</a>.
|
||||||
|
|
||||||
|
|
||||||
{@a other-formats}
|
{@a other-formats}
|
||||||
|
|
||||||
|
|
||||||
### Other translation formats
|
### Other translation formats
|
||||||
|
|
||||||
You can generate a file named **`messages.xmb`** in the
|
Angular i18n tooling supports XLIFF 1.2 and XLIFF 2 as well as the
|
||||||
<a href="http://cldr.unicode.org/development/development-process/design-proposals/xmb" >XML Message Bundle (XMB)</a> format
|
<a href="http://cldr.unicode.org/development/development-process/design-proposals/xmb" >XML Message Bundle (XMB)</a>.
|
||||||
by adding the `--i18nFormat=xmb` flag.
|
|
||||||
|
|
||||||
|
You can specify your choice of format _explicitly_ with the `--i18nFormat` flag as illustrated in these example commands
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
./node_modules/.bin/ng-xi18n --i18nFormat=xmb
|
./node_modules/.bin/ng-xi18n --i18nFormat=xlf --outFile=messages.xlf
|
||||||
|
./node_modules/.bin/ng-xi18n --i18nFormat=xlf2 --outFile=messages.xliff2.xlf
|
||||||
|
./node_modules/.bin/ng-xi18n --i18nFormat=xmb --outFile=messages.xmb
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
The sample in _this_ guide sticks with the default _XLIFF 1.2_ format.
|
||||||
|
|
||||||
This sample sticks with the _XLIFF_ format.
|
|
||||||
|
|
||||||
|
|
||||||
{@a ng-xi18n-options}
|
{@a ng-xi18n-options}
|
||||||
|
|
||||||
|
|
||||||
### Other options
|
### Other options
|
||||||
|
|
||||||
You may have to specify additional options.
|
You may have to specify additional options.
|
||||||
For example, if the `tsconfig.json` TypeScript configuration
|
For example, if the `tsconfig.json` TypeScript configuration
|
||||||
file is located somewhere other than in the root folder,
|
file is located somewhere other than in the root folder,
|
||||||
@ -350,15 +329,10 @@ you must identify the path to it with the `-p` option:
|
|||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
./node_modules/.bin/ng-xi18n -p path/to/tsconfig.json
|
./node_modules/.bin/ng-xi18n -p path/to/tsconfig.json
|
||||||
./node_modules/.bin/ng-xi18n --i18nFormat=xmb -p path/to/tsconfig.json
|
./node_modules/.bin/ng-xi18n --i18nFormat=xmb -p path/to/tsconfig.json
|
||||||
|
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a npm-i18n-script}
|
{@a npm-i18n-script}
|
||||||
|
|
||||||
|
|
||||||
### Add an _npm_ script for convenience
|
### Add an _npm_ script for convenience
|
||||||
|
|
||||||
Consider adding a convenience shortcut to the `scripts` section of the `package.json`
|
Consider adding a convenience shortcut to the `scripts` section of the `package.json`
|
||||||
@ -371,8 +345,6 @@ to make the command easier to remember and run:
|
|||||||
}
|
}
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Now you can issue command variations such as these:
|
Now you can issue command variations such as these:
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
@ -381,28 +353,21 @@ Now you can issue command variations such as these:
|
|||||||
npm run i18n -- --i18nFormat=xmb -p path/to/tsconfig.json
|
npm run i18n -- --i18nFormat=xmb -p path/to/tsconfig.json
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note the `--` flag before the options.
|
Note the `--` flag before the options.
|
||||||
It tells _npm_ to pass every flag thereafter to `ng-xi18n`.
|
It tells _npm_ to pass every flag thereafter to `ng-xi18n`.
|
||||||
|
|
||||||
|
|
||||||
{@a translate}
|
{@a translate}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Translate text messages
|
## Translate text messages
|
||||||
|
|
||||||
The `ng-xi18n` command generates a translation source file
|
The `ng-xi18n` command generates a translation source file
|
||||||
in the project root folder named `messages.xlf`.
|
in the project root folder named `messages.xlf`.
|
||||||
The next step is to translate the English language template
|
The next step is to translate the English language template
|
||||||
text into the specific language translation
|
text into the specific language translation
|
||||||
files. The cookbook sample creates a Spanish translation file.
|
files. The guide sample creates a Spanish translation file.
|
||||||
|
|
||||||
|
|
||||||
{@a localization-folder}
|
{@a localization-folder}
|
||||||
|
|
||||||
|
|
||||||
### Create a localization folder
|
### Create a localization folder
|
||||||
|
|
||||||
You will probably translate into more than one other language so it's a good idea
|
You will probably translate into more than one other language so it's a good idea
|
||||||
@ -413,16 +378,12 @@ such as internationalization files, there.
|
|||||||
|
|
||||||
<div class="l-sub-section">
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Localization and internationalization are
|
Localization and internationalization are
|
||||||
<a href="https://en.wikipedia.org/wiki/Internationalization_and_localization">different but closely related terms</a>.
|
<a href="https://en.wikipedia.org/wiki/Internationalization_and_localization">different but closely related terms</a>.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
This guide follows that suggestion. It has a `locale` folder under `src/`.
|
||||||
|
|
||||||
This cookbook follows that suggestion. It has a `locale` folder under the `src/`.
|
|
||||||
Assets within the folder carry a filename extension that matches a language-culture code from a
|
Assets within the folder carry a filename extension that matches a language-culture code from a
|
||||||
<a href="https://msdn.microsoft.com/en-us/library/ee825488(v=cs.20).aspx">well-known codeset</a>.
|
<a href="https://msdn.microsoft.com/en-us/library/ee825488(v=cs.20).aspx">well-known codeset</a>.
|
||||||
|
|
||||||
@ -432,7 +393,6 @@ Do the same for each target language.
|
|||||||
|
|
||||||
{@a translate-text-nodes}
|
{@a translate-text-nodes}
|
||||||
|
|
||||||
|
|
||||||
### Translate text nodes
|
### Translate text nodes
|
||||||
In the real world, you send the `messages.es.xlf` file to a Spanish translator who fills in the translations
|
In the real world, you send the `messages.es.xlf` file to a Spanish translator who fills in the translations
|
||||||
using one of the
|
using one of the
|
||||||
@ -441,50 +401,41 @@ using one of the
|
|||||||
This sample file is easy to translate without a special editor or knowledge of Spanish.
|
This sample file is easy to translate without a special editor or knowledge of Spanish.
|
||||||
Open `messages.es.xlf` and find the first `<trans-unit>` section:
|
Open `messages.es.xlf` and find the first `<trans-unit>` section:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-hello" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-hello" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This XML element represents the translation of the `<h1>` greeting tag you marked with the `i18n` attribute.
|
This XML element represents the translation of the `<h1>` greeting tag you marked with the `i18n` attribute.
|
||||||
|
|
||||||
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
Note that the translation unit `id=introductionHeader` is derived from the _custom_ `id`](#custom-id "Set a custom id") that you set earlier, but **without the `@@` prefix** required in the source HTML.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
Using the _source_, _description_, and _meaning_ elements to guide your translation,
|
Using the _source_, _description_, and _meaning_ elements to guide your translation,
|
||||||
replace the `<target/>` tag with the Spanish greeting:
|
replace the `<target/>` tag with the Spanish greeting:
|
||||||
|
|
||||||
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-hello" title="src/locale/messages.es.xlf (<trans-unit>, after translation)" linenums="false">
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-hello" title="src/locale/messages.es.xlf (<trans-unit>, after translation)" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note that the tool generates the `id`. **Don't touch it.**
|
|
||||||
Its value depends on the content of the message and its assigned meaning.
|
|
||||||
Change either factor and the `id` changes as well.
|
|
||||||
See the **[translation file maintenance discussion](guide/i18n#maintenance)**.
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Translate the other text nodes the same way:
|
Translate the other text nodes the same way:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-other-nodes" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-other-nodes" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
<div class="alert is-important">
|
||||||
|
|
||||||
|
**The tool generated the `id`s for _these_ translation units. Don't touch them.**
|
||||||
|
Each `id` depends upon the content of the message and its assigned meaning.
|
||||||
|
Change either factor and the `id` changes as well.
|
||||||
|
See the **[translation file maintenance discussion](#maintenance)**.
|
||||||
|
|
||||||
|
This is why you should **[specify custom ids](#custom-id "Set a custom id")** and avoid tool generated ids.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
{@a translate-plural-select}
|
{@a translate-plural-select}
|
||||||
|
|
||||||
|
|
||||||
## Translate _plural_ and _select_
|
## Translate _plural_ and _select_
|
||||||
Translating _plural_ and _select_ messages is a little tricky.
|
Translating _plural_ and _select_ messages is a little tricky.
|
||||||
|
|
||||||
@ -496,121 +447,92 @@ However, the `XMB` format does support the ICU rules.
|
|||||||
You'll just have to look for them in relation to other translation units that you recognize from elsewhere in the source template.
|
You'll just have to look for them in relation to other translation units that you recognize from elsewhere in the source template.
|
||||||
In this example, you know the translation unit for the `select` must be just below the translation unit for the logo.
|
In this example, you know the translation unit for the `select` must be just below the translation unit for the logo.
|
||||||
|
|
||||||
|
|
||||||
{@a translate-plural}
|
{@a translate-plural}
|
||||||
|
|
||||||
|
|
||||||
### Translate _plural_
|
### Translate _plural_
|
||||||
To translate a `plural`, translate its ICU format match values:
|
To translate a `plural`, translate its ICU format match values:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-plural" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-plural" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a translate-select}
|
{@a translate-select}
|
||||||
|
|
||||||
|
|
||||||
### Translate _select_
|
### Translate _select_
|
||||||
The `select` behaves a little differently. Here again is the ICU format message in the component template:
|
The `select` behaves a little differently. Here again is the ICU format message in the component template:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/app/app.component.html" region="i18n-select" title="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>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The extraction tool broke that into _two_ translation units.
|
The extraction tool broke that into _two_ translation units.
|
||||||
|
|
||||||
The first unit contains the text that was _outside_ the `select`.
|
The first unit contains the text that was _outside_ the `select`.
|
||||||
In place of the `select` is a placeholder, `<x id="ICU">`, that represents the `select` message.
|
In place of the `select` is a placeholder, `<x id="ICU">`, that represents the `select` message.
|
||||||
Translate the text and leave the placeholder where it is.
|
Translate the text and leave the placeholder where it is.
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translate-select-1" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translate-select-1" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The second translation unit, immediately below the first one, contains the `select` message. Translate that.
|
The second translation unit, immediately below the first one, contains the `select` message. Translate that.
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translate-select-2" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translate-select-2" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Here they are together, after translation:
|
Here they are together, after translation:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-select" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translated-select" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
### Translate a nested expression
|
||||||
|
|
||||||
|
A nested expression is not different from the previous ones. As in the previous example, we have _two_ translation units.
|
||||||
|
|
||||||
<div class='l-main-content'>
|
The first one contains the text outside the nested expression:
|
||||||
|
|
||||||
</div>
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translate-nested-1" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
The second unit contains the complete nested expression:
|
||||||
|
|
||||||
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translate-nested-2" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
And both together:
|
||||||
|
|
||||||
|
<code-example path="i18n/src/locale/messages.es.xlf.html" region="translate-nested" title="src/locale/messages.es.xlf (<trans-unit>)" linenums="false">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The entire template translation is complete. It's
|
The entire template translation is complete. It's
|
||||||
time to incorporate that translation into the application.
|
time to incorporate that translation into the application.
|
||||||
|
|
||||||
|
<a id='app-pre-translation'></a>
|
||||||
<div id='app-pre-translation'>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### The app before translation
|
### The app before translation
|
||||||
|
|
||||||
When the previous steps finish, the sample app _and_ its translation file are as follows:
|
When the previous steps finish, the sample app _and_ its translation file are as follows:
|
||||||
|
|
||||||
|
|
||||||
<code-tabs>
|
<code-tabs>
|
||||||
|
|
||||||
<code-pane title="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>
|
||||||
|
|
||||||
<code-pane title="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>
|
||||||
|
|
||||||
<code-pane title="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>
|
||||||
|
|
||||||
<code-pane title="src/main.ts" path="i18n/src/main.1.ts">
|
<code-pane title="src/main.ts" path="i18n/src/main.1.ts">
|
||||||
|
|
||||||
</code-pane>
|
</code-pane>
|
||||||
|
|
||||||
<code-pane title="src/locale/messages.es.xlf" path="i18n/src/locale/messages.es.xlf.html">
|
<code-pane title="src/locale/messages.es.xlf" path="i18n/src/locale/messages.es.xlf.html">
|
||||||
|
|
||||||
</code-pane>
|
</code-pane>
|
||||||
|
|
||||||
</code-tabs>
|
</code-tabs>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a merge}
|
{@a merge}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Merge the completed translation file into the app
|
## Merge the completed translation file into the app
|
||||||
|
|
||||||
To merge the translated text into component templates,
|
To merge the translated text into component templates,
|
||||||
compile the application with the completed translation file.
|
compile the application with the completed translation file.
|
||||||
The process is the same whether the file is in `.xlf` format or
|
The process is the same whether the file is in `.xlf` format or
|
||||||
in another format that Angular understands, such as `.xlif` or `.xtb`.
|
in another format that Angular understands, such as `.xtb`.
|
||||||
|
|
||||||
You provide the Angular compiler with three new pieces of information:
|
You provide the Angular compiler with three new pieces of information:
|
||||||
|
|
||||||
@ -625,11 +547,8 @@ the JIT (_Just-in-Time_) compiler or the AOT (_Ahead-of-Time_) compiler.
|
|||||||
* With [JIT](guide/i18n#jit), you provide the information at bootstrap time.
|
* With [JIT](guide/i18n#jit), you provide the information at bootstrap time.
|
||||||
* With [AOT](guide/i18n#aot), you pass the information as `ngc` options.
|
* With [AOT](guide/i18n#aot), you pass the information as `ngc` options.
|
||||||
|
|
||||||
|
|
||||||
{@a jit}
|
{@a jit}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Merge with the JIT compiler
|
### Merge with the JIT compiler
|
||||||
|
|
||||||
The JIT compiler compiles the application in the browser as the application loads.
|
The JIT compiler compiles the application in the browser as the application loads.
|
||||||
@ -643,20 +562,22 @@ Translation with the JIT compiler is a dynamic process of:
|
|||||||
Open `index.html` and revise the launch script as follows:
|
Open `index.html` and revise the launch script as follows:
|
||||||
|
|
||||||
<code-example path="i18n/src/index.html" region="i18n" title="index.html (launch script)" linenums="false">
|
<code-example path="i18n/src/index.html" region="i18n" title="index.html (launch script)" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
In this sample, the user's language is hard-coded as a global `document.locale` variable
|
||||||
|
|
||||||
In this sample, the user's language is hardcoded as a global `document.locale` variable
|
|
||||||
in the `index.html`.
|
in the `index.html`.
|
||||||
|
|
||||||
|
|
||||||
{@a text-plugin}
|
{@a text-plugin}
|
||||||
|
|
||||||
|
|
||||||
### SystemJS text plugin
|
### SystemJS text plugin
|
||||||
|
|
||||||
|
<div class="alert is-important">
|
||||||
|
|
||||||
|
This plugin only applies to an application using SystemJS. If you are using the Angular CLI, please refer to their
|
||||||
|
[docs](https://github.com/angular/angular-cli/wiki/xi18n).
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
Notice the SystemJS mapping of `text` to a `systemjs-text-plugin.js`.
|
Notice the SystemJS mapping of `text` to a `systemjs-text-plugin.js`.
|
||||||
With the help of a text plugin, SystemJS can read any file as raw text and
|
With the help of a text plugin, SystemJS can read any file as raw text and
|
||||||
return the contents as a string.
|
return the contents as a string.
|
||||||
@ -666,33 +587,26 @@ SystemJS doesn't ship with a raw text plugin but it's easy to add.
|
|||||||
Create the following `systemjs-text-plugin.js` in the `src/` folder:
|
Create the following `systemjs-text-plugin.js` in the `src/` folder:
|
||||||
|
|
||||||
<code-example path="i18n/src/systemjs-text-plugin.js" title="src/systemjs-text-plugin.js" linenums="false">
|
<code-example path="i18n/src/systemjs-text-plugin.js" title="src/systemjs-text-plugin.js" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a create-translation-providers}
|
{@a create-translation-providers}
|
||||||
|
|
||||||
|
|
||||||
### Create translation providers
|
### Create translation providers
|
||||||
|
|
||||||
Three providers tell the JIT compiler how to translate the template texts for a particular language
|
Three providers tell the JIT compiler how to translate the template texts for a particular language
|
||||||
while compiling the application:
|
while compiling the application:
|
||||||
|
|
||||||
* `TRANSLATIONS` is a string containing the content of the translation file.
|
* `TRANSLATIONS` is a string containing the content of the translation file.
|
||||||
* `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlif`, or `xtb`.
|
* `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlf2`, or `xtb`.
|
||||||
* `LOCALE_ID` is the locale of the target language.
|
* `LOCALE_ID` is the locale of the target language.
|
||||||
|
|
||||||
The `getTranslationProviders()` function in the following `src/app/i18n-providers.ts`
|
The `getTranslationProviders()` function in the following `src/app/i18n-providers.ts`
|
||||||
creates those providers based on the user's _locale_
|
creates those providers based on the user's _locale_
|
||||||
and the corresponding translation file:
|
and the corresponding translation file:
|
||||||
|
|
||||||
<code-example path="i18n/src/app/i18n-providers.ts" title="src/app/i18n-providers.ts">
|
<code-example path="i18n/src/app/i18n-providers.ts" region="without-missing-translation" title="src/app/i18n-providers.ts">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1. It gets the locale from the global `document.locale` variable that was set in `index.html`.
|
1. It gets the locale from the global `document.locale` variable that was set in `index.html`.
|
||||||
|
|
||||||
1. If there is no locale or the language is U.S. English (`en-US`), there is no need to translate.
|
1. If there is no locale or the language is U.S. English (`en-US`), there is no need to translate.
|
||||||
@ -709,10 +623,15 @@ Notice that it appends `!text` to the filename, telling SystemJS to use the [tex
|
|||||||
|
|
||||||
1. Finally, `getTranslationProviders()` returns the entire effort as a promise.
|
1. Finally, `getTranslationProviders()` returns the entire effort as a promise.
|
||||||
|
|
||||||
|
<div class="alert is-important">
|
||||||
|
|
||||||
|
The `LOCALE_ID` has to be a valid locale id as explained in [here](http://userguide.icu-project.org/locale).
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
{@a bootstrap-the-app}
|
{@a bootstrap-the-app}
|
||||||
|
|
||||||
|
### Bootstrap with translation providers
|
||||||
### Bootstrap the app with translation providers
|
|
||||||
|
|
||||||
The Angular `bootstrapModule()` method has a second _options_ parameter
|
The Angular `bootstrapModule()` method has a second _options_ parameter
|
||||||
that can influence the behavior of the compiler.
|
that can influence the behavior of the compiler.
|
||||||
@ -722,22 +641,16 @@ and pass it to `bootstrapModule`.
|
|||||||
Open the `src/main.ts` and modify the bootstrap code as follows:
|
Open the `src/main.ts` and modify the bootstrap code as follows:
|
||||||
|
|
||||||
<code-example path="i18n/src/main.ts" title="src/main.ts" linenums="false">
|
<code-example path="i18n/src/main.ts" title="src/main.ts" linenums="false">
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Notice that it waits for the `getTranslationProviders()` promise to resolve before
|
Notice that it waits for the `getTranslationProviders()` promise to resolve before
|
||||||
bootstrapping the app.
|
bootstrapping the app.
|
||||||
|
|
||||||
The app is now _internationalized_ for English and Spanish and there is a clear path for adding
|
The app is now _internationalized_ for English and Spanish and there is a clear path for adding
|
||||||
more languages.
|
more languages.
|
||||||
|
|
||||||
|
|
||||||
{@a aot}
|
{@a aot}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### _Internationalization_ with the AOT compiler
|
### _Internationalization_ with the AOT compiler
|
||||||
|
|
||||||
The JIT compiler translates the application into the target language
|
The JIT compiler translates the application into the target language
|
||||||
@ -752,7 +665,7 @@ language. Then in the host web page, in this case `index.html`,
|
|||||||
you determine which language the user needs
|
you determine which language the user needs
|
||||||
and serve the appropriate application package.
|
and serve the appropriate application package.
|
||||||
|
|
||||||
This cookbook doesn't cover how to build multiple application packages and
|
This guide doesn't cover how to build multiple application packages and
|
||||||
serve them according to the user's language preference.
|
serve them according to the user's language preference.
|
||||||
It does explain the few steps necessary to tell the AOT compiler to apply a translations file.
|
It does explain the few steps necessary to tell the AOT compiler to apply a translations file.
|
||||||
|
|
||||||
@ -760,7 +673,7 @@ Internationalization with the AOT compiler requires
|
|||||||
some setup specifically for AOT compilation.
|
some setup specifically for AOT compilation.
|
||||||
Start with the application project as shown
|
Start with the application project as shown
|
||||||
[just before merging the translation file](guide/i18n#app-pre-translation)
|
[just before merging the translation file](guide/i18n#app-pre-translation)
|
||||||
and refer to the [AOT cookbook](guide/aot-compiler) to make it _AOT-ready_.
|
and refer to the [AOT guide](guide/aot-compiler) to make it _AOT-ready_.
|
||||||
|
|
||||||
Next, issue an `ngc` compile command for each supported language, including English.
|
Next, issue an `ngc` compile command for each supported language, including English.
|
||||||
The result is a separate version of the application for each language.
|
The result is a separate version of the application for each language.
|
||||||
@ -775,45 +688,65 @@ For this sample, the Spanish language command would be:
|
|||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
./node_modules/.bin/ngc --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf
|
./node_modules/.bin/ngc --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="l-sub-section">
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Windows users may have to quote the command:
|
Windows users may have to quote the command:
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
"./node_modules/.bin/ngc" --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf
|
"./node_modules/.bin/ngc" --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
### Report missing translations
|
||||||
|
|
||||||
|
If you forgot to provide a translation, the build will succeed with a warning that you might easily overlook.
|
||||||
|
You can configure the Angular compiler for different "missing translation" behaviors:
|
||||||
|
|
||||||
|
* Error
|
||||||
|
* Warning (default)
|
||||||
|
* Ignore
|
||||||
|
|
||||||
|
To change the behavior in JIT, you can use the following configuration:
|
||||||
|
|
||||||
|
<code-example language="typescript">
|
||||||
|
{ provide: CompilerConfig, useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error }) }
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
A good place to use it is the translation providers:
|
||||||
|
|
||||||
|
<code-example path="i18n/src/app/i18n-providers.ts" region="missing-translation" title="src/app/i18n-providers.ts"></code-example>
|
||||||
|
|
||||||
|
To change the behavior in AOT, add the `--missingTranslation` flag to the compilation command:
|
||||||
|
|
||||||
|
<code-example language="sh" class="code-shell">
|
||||||
|
./node_modules/.bin/ngc --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf --missingTranslation=error
|
||||||
|
</code-example>
|
||||||
|
|
||||||
{@a maintenance}
|
{@a maintenance}
|
||||||
|
|
||||||
|
## File maintenance and _id_ changes
|
||||||
## Translation file maintenance and _id_ changes
|
|
||||||
|
|
||||||
As the application evolves, you will change the _i18n_ markup
|
As the application evolves, you will change the _i18n_ markup
|
||||||
and re-run the `ng-xi18n` extraction tool many times.
|
and re-run the `ng-xi18n` extraction tool many times.
|
||||||
The _new_ markup that you add is not a problem;
|
The _new_ markup that you add is not a problem.
|
||||||
but _most_ changes to existing markup trigger
|
But the `id` _can be a serious problem!_
|
||||||
generation of new `id`s for the affected translation units.
|
|
||||||
|
If the `id` is generated by the tool, _most_ changes to _existing_ markup
|
||||||
|
cause the tool to generate a _new_ `id` for the affected translation unit.
|
||||||
|
|
||||||
After an `id` changes, the translation files are no longer in sync.
|
After an `id` changes, the translation files are no longer in sync.
|
||||||
**All translated versions of the application will fail** during re-compilation.
|
Because of that, you get some warning messages during re-compilation.
|
||||||
The error messages identify the old `id`s that are no longer valid but
|
The warning messages identify that some translations are missing, but they don't tell you which
|
||||||
they don't tell you what the new `id`s should be.
|
old `ids` are no longer valid.
|
||||||
|
|
||||||
**Commit all translation message files to source control**,
|
If you use a [custom id](#custom-id "Set a custom id"),
|
||||||
|
the tooling preserves the custom `id` as you make changes to the corresponding translation unit. **Use custom _ids_ unless you have a very good reason to do otherwise.**
|
||||||
|
|
||||||
|
Whether you use generated or custom `ids`, **always commit all translation message files to source control**,
|
||||||
especially the English source `messages.xlf`.
|
especially the English source `messages.xlf`.
|
||||||
The difference between the old and the new `messages.xlf` file
|
The difference between the old and the new `messages.xlf` file
|
||||||
help you find and update `id` changes across your translation files.
|
will help you find and update `ids` and other changes across your translation files.
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ making some of them public so external components can use them.
|
|||||||
And there are many more options covered here.
|
And there are many more options covered here.
|
||||||
|
|
||||||
Before reading this page, read the
|
Before reading this page, read the
|
||||||
[The Root Module](guide/appmodule) page, which introduces NgModules and the essentials
|
[The Root Module](guide/bootstrapping) page, which introduces NgModules and the essentials
|
||||||
of creating and maintaining a single root `AppModule` for the entire application.
|
of creating and maintaining a single root `AppModule` for the entire application.
|
||||||
|
|
||||||
This page covers NgModules in greater depth.
|
This page covers NgModules in greater depth.
|
||||||
|
@ -1,79 +1,617 @@
|
|||||||
<h1 class="no-toc">QuickStart</h1>
|
# QuickStart
|
||||||
|
|
||||||
Angular applications are made up of _components_.
|
Good tools make application development quicker and easier to maintain than
|
||||||
A _component_ is the combination of an HTML template and a component class that controls a portion of the screen. Here is an example of a component that displays a simple string:
|
if you did everything by hand.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
You'll pursue these ends in the following high-level steps:
|
||||||
|
|
||||||
|
1. [Set up](guide/cli-quickstart#devenv) the development environment.
|
||||||
|
2. [Create](guide/cli-quickstart#create-proj) a new project and skeleton application.
|
||||||
|
3. [Serve](guide/cli-quickstart#serve) the application.
|
||||||
|
4. [Edit](guide/cli-quickstart#first-component) the application.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
And you can also <a href="generated/zips/cli-quickstart/cli-quickstart.zip" target="_blank">download the example.</a>
|
||||||
|
|
||||||
|
|
||||||
<code-example path="quickstart/src/app/app.component.ts" title="src/app/app.component.ts" linenums="false">
|
|
||||||
|
<h2 id='devenv'>
|
||||||
|
Step 1. Set up the Development Environment
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
You need to set up your development environment before you can do anything.
|
||||||
|
|
||||||
|
Install **[Node.js® and npm](https://nodejs.org/en/download/)**
|
||||||
|
if they are not already on your machine.
|
||||||
|
|
||||||
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Verify that you are running at least node `6.9.x` and npm `3.x.x`**
|
||||||
|
by running `node -v` and `npm -v` in a terminal/console window.
|
||||||
|
Older versions produce errors, but newer versions are fine.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Then **install the [Angular CLI](https://github.com/angular/angular-cli)** globally.
|
||||||
|
|
||||||
|
|
||||||
|
<code-example language="sh" class="code-shell">
|
||||||
|
npm install -g @angular/cli
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id='create-proj'>
|
||||||
|
Step 2. Create a new project
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Open a terminal window.
|
||||||
|
|
||||||
|
|
||||||
|
Generate a new project and skeleton application by running the following commands:
|
||||||
|
|
||||||
|
|
||||||
|
<code-example language="sh" class="code-shell">
|
||||||
|
ng new my-app
|
||||||
|
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="l-sub-section">
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Try this **<live-example noDownload>QuickStart example on Plunker</live-example>** without installing anything.
|
Patience please.
|
||||||
Try it locally with the [***QuickStart seed***](guide/setup "Setup for local development with the QuickStart seed")
|
It takes time to set up a new project, most of it spent installing npm packages.
|
||||||
and prepare for development of a real Angular application.
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Every component begins with an `@Component` [decorator](guide/glossary#decorator '"decorator" explained')
|
|
||||||
function that takes a _metadata_ object. The metadata object describes how the HTML template and component class work together.
|
|
||||||
|
|
||||||
The `selector` property tells Angular to display the component inside a custom `<my-app>` tag in the `index.html`.
|
<h2 id='serve'>
|
||||||
|
Step 3: Serve the application
|
||||||
|
</h2>
|
||||||
|
|
||||||
<code-example path="quickstart/src/index.html" region="my-app" title="index.html (inside <body>)" linenums="false">
|
|
||||||
|
|
||||||
|
Go to the project directory and launch the server.
|
||||||
|
|
||||||
|
|
||||||
|
<code-example language="sh" class="code-shell">
|
||||||
|
cd my-app
|
||||||
|
ng serve --open
|
||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The `template` property defines a message inside an `<h1>` header.
|
The `ng serve` command launches the server, watches your files,
|
||||||
The message starts with "Hello" and ends with `{{name}}`,
|
and rebuilds the app as you make changes to those files.
|
||||||
which is an Angular [interpolation binding](guide/displaying-data) expression.
|
|
||||||
At runtime, Angular replaces `{{name}}` with the value of the component's `name` property.
|
Using the `--open` (or just `-o`) option will automatically open your browser
|
||||||
Interpolation binding is one of many Angular features you'll discover in this documentation.
|
on `http://localhost:4200/`.
|
||||||
|
|
||||||
|
Your app greets you with a message:
|
||||||
|
|
||||||
|
|
||||||
In the example, change the component class's `name` property from `'Angular'` to `'World'` and see what happens.
|
<figure>
|
||||||
|
<img src='generated/images/guide/cli-quickstart/app-works.png' alt="The app works!">
|
||||||
|
</figure>
|
||||||
<div class="callout is-helpful">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<header>
|
|
||||||
A word about TypeScript
|
<h2 id='first-component'>
|
||||||
</header>
|
Step 4: Edit your first Angular component
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
The CLI created the first Angular component for you.
|
||||||
This example is written in <a href="http://www.typescriptlang.org/" title="TypeScript">TypeScript</a>, a superset of JavaScript. Angular
|
This is the _root component_ and it is named `app-root`.
|
||||||
uses TypeScript because its types make it easy to support developer productivity with tooling. You can also write Angular code in JavaScript; [this guide](guide/ts-to-js] explains how.
|
You can find it in `./src/app/app.component.ts`.
|
||||||
|
|
||||||
</p>
|
|
||||||
|
Open the component file and change the `title` property from _app works!_ to _My First Angular App_:
|
||||||
|
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
<img src='generated/images/guide/cli-quickstart/my-first-app.png' alt="Output of QuickStart app">
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Looking good!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 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">favicon.ico</div>
|
||||||
|
<div class="file">index.html</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
`app/app.component.{ts,html,css,spec.ts}`
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
`app/app.module.ts`
|
||||||
|
|
||||||
|
</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>
|
||||||
|
|
||||||
|
`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>
|
||||||
|
|
||||||
|
`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/glossary#ahead-of-time-aot-compilation)
|
||||||
|
without changing any code by passing in `--aot` to `ng build` or `ng serve`.
|
||||||
|
|
||||||
|
</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>
|
||||||
|
</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/`.
|
||||||
|
|
||||||
|
|
||||||
|
<div class='filetree'>
|
||||||
|
<div class="file">my-app</div>
|
||||||
|
<div class='children'>
|
||||||
|
<div class="file">e2e</div>
|
||||||
|
<div class='children'>
|
||||||
|
<div class="file">app.e2e-spec.ts</div>
|
||||||
|
<div class="file">app.po.ts</div>
|
||||||
|
<div class="file">tsconfig.e2e.json</div>
|
||||||
|
</div>
|
||||||
|
<div class="file">node_modules/...</div>
|
||||||
|
<div class="file">src/...</div>
|
||||||
|
<div class="file">.angular-cli.json</div>
|
||||||
|
<div class="file">.editorconfig</div>
|
||||||
|
<div class="file">.gitignore</div>
|
||||||
|
<div class="file">karma.conf.js</div>
|
||||||
|
<div class="file">package.json</div>
|
||||||
|
<div class="file">protractor.conf.js</div>
|
||||||
|
<div class="file">README.md</div>
|
||||||
|
<div class="file">tsconfig.json</div>
|
||||||
|
<div class="file">tslint.json</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
`.angular-cli.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 build.
|
||||||
|
Check out the official documentation if you want to know more.
|
||||||
|
|
||||||
|
</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 commited to source control.
|
||||||
|
|
||||||
|
</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>
|
||||||
|
|
||||||
|
`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="l-sub-section">
|
<div class="l-sub-section">
|
||||||
|
|
||||||
|
### Next Step
|
||||||
|
|
||||||
|
If you're new to Angular, continue with the
|
||||||
### Next step
|
[tutorial](tutorial "Tour of Heroes tutorial").
|
||||||
|
You can skip the "Setup" step since you're already using the Angular CLI setup.
|
||||||
Start the [**tutorial**](tutorial "Tour of Heroes tutorial").
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
{@a develop-locally}
|
{@a develop-locally}
|
||||||
|
|
||||||
The <live-example name=quickstart>QuickStart live-coding</live-example> example is an Angular _playground_.
|
The <live-example name=quickstart>QuickStart live-coding</live-example> example is an Angular _playground_.
|
||||||
It's not where you'd develop a real application.
|
It's not where you'd develop a real application.
|
||||||
You [should develop locally](guide/setup#why-locally "Why develop locally") on your own machine ... and that's also how we think you should learn Angular.
|
You [should develop locally](guide/setup#why-locally "Why develop locally") on your own machine ... and that's also how we think you should learn Angular.
|
||||||
|
|
||||||
Setting up a new project on your machine is quick and easy with the **QuickStart seed**,
|
Setting up a new project on your machine is quick and easy with the **QuickStart seed**,
|
||||||
maintained [on github](https://github.com/angular/quickstart "Install the github QuickStart repo").
|
maintained [on github](https://github.com/angular/quickstart "Install the github QuickStart repo").
|
||||||
|
|
||||||
|
|
||||||
Make sure you have [node and npm installed](guide/setup#install-prerequisites "What if you don't have node and npm?").
|
Make sure you have [node and npm installed](guide/setup#install-prerequisites "What if you don't have node and npm?").
|
||||||
@ -124,7 +124,7 @@ Open a terminal window in the project folder and enter the following commands fo
|
|||||||
|
|
||||||
The **QuickStart seed** contains the same application as the QuickStart playground.
|
The **QuickStart seed** contains the same application as the QuickStart playground.
|
||||||
But its true purpose is to provide a solid foundation for _local_ development.
|
But its true purpose is to provide a solid foundation for _local_ development.
|
||||||
Consequently, there are _many more files_ in the project folder on your machine,
|
Consequently, there are _many more files_ in the project folder on your machine,
|
||||||
most of which you can [learn about later](guide/setup-systemjs-anatomy "Setup Anatomy").
|
most of which you can [learn about later](guide/setup-systemjs-anatomy "Setup Anatomy").
|
||||||
|
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ Focus on the following three TypeScript (`.ts`) files in the **`/src`** folder.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
All guides and cookbooks have _at least these core files_.
|
All guides and cookbooks have _at least these core files_.
|
||||||
Each file has a distinct purpose and evolves independently as the application grows.
|
Each file has a distinct purpose and evolves independently as the application grows.
|
||||||
|
|
||||||
Files outside `src/` concern building, deploying, and testing your app.
|
Files outside `src/` concern building, deploying, and testing your app.
|
||||||
@ -239,7 +239,7 @@ The following are all in `src/`
|
|||||||
|
|
||||||
Defines the same `AppComponent` as the one in the QuickStart playground.
|
Defines the same `AppComponent` as the one in the QuickStart playground.
|
||||||
It is the **root** component of what will become a tree of nested components
|
It is the **root** component of what will become a tree of nested components
|
||||||
as the application evolves.
|
as the application evolves.
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@ -253,7 +253,7 @@ The following are all in `src/`
|
|||||||
<td>
|
<td>
|
||||||
|
|
||||||
|
|
||||||
Defines `AppModule`, the [root module](guide/appmodule "AppModule: the root module") that tells Angular how to assemble the application.
|
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`.
|
Right now it declares only the `AppComponent`.
|
||||||
Soon there will be more components to declare.
|
Soon there will be more components to declare.
|
||||||
</td>
|
</td>
|
||||||
@ -270,7 +270,7 @@ The following are all in `src/`
|
|||||||
|
|
||||||
|
|
||||||
Compiles the application with the [JIT compiler](guide/glossary#jit) and
|
Compiles the application with the [JIT compiler](guide/glossary#jit) and
|
||||||
[bootstraps](guide/appmodule#main "bootstrap the application")
|
[bootstraps](guide/bootstrapping#main "bootstrap the application")
|
||||||
the application's main module (`AppModule`) to run in the browser.
|
the application's main module (`AppModule`) to run in the browser.
|
||||||
The JIT compiler is a reasonable choice during the development of most projects and
|
The JIT compiler is a reasonable choice during the development of most projects and
|
||||||
it's the only viable choice for a sample running in a _live-coding_ environment like Plunker.
|
it's the only viable choice for a sample running in a _live-coding_ environment like Plunker.
|
||||||
@ -315,8 +315,8 @@ Get them now</a> if they're not already installed on your machine.
|
|||||||
by running the commands `node -v` and `npm -v` in a terminal/console window.
|
by running the commands `node -v` and `npm -v` in a terminal/console window.
|
||||||
Older versions produce errors.
|
Older versions produce errors.
|
||||||
|
|
||||||
We recommend [nvm](https://github.com/creationix/nvm) for managing multiple versions of node and npm.
|
We recommend [nvm](https://github.com/creationix/nvm) for managing multiple versions of node and npm.
|
||||||
You may need [nvm](https://github.com/creationix/nvm) if you already have projects running on your machine that
|
You may need [nvm](https://github.com/creationix/nvm) if you already have projects running on your machine that
|
||||||
use other versions of node and npm.
|
use other versions of node and npm.
|
||||||
|
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ You can play with the sample code, share your changes with friends, and download
|
|||||||
The [QuickStart](guide/quickstart "Angular QuickStart Playground") shows just the `AppComponent` file.
|
The [QuickStart](guide/quickstart "Angular QuickStart Playground") shows just the `AppComponent` file.
|
||||||
It creates the equivalent of `app.module.ts` and `main.ts` internally _for the playground only_.
|
It creates the equivalent of `app.module.ts` and `main.ts` internally _for the playground only_.
|
||||||
so the reader can discover Angular without distraction.
|
so the reader can discover Angular without distraction.
|
||||||
The other samples are based on the QuickStart seed.
|
The other samples are based on the QuickStart seed.
|
||||||
|
|
||||||
As much fun as this is ...
|
As much fun as this is ...
|
||||||
|
|
||||||
@ -343,7 +343,7 @@ As much fun as this is ...
|
|||||||
* transpiling TypeScript in the browser is slow
|
* transpiling TypeScript in the browser is slow
|
||||||
* the type support, refactoring, and code completion only work in your local IDE
|
* the type support, refactoring, and code completion only work in your local IDE
|
||||||
|
|
||||||
Use the <live-example title="QuickStart Seed in Plunker">live coding</live-example> environment as a _playground_,
|
Use the <live-example title="QuickStart Seed in Plunker">live coding</live-example> environment as a _playground_,
|
||||||
a place to try the documentation samples and experiment on your own.
|
a place to try the documentation samples and experiment on your own.
|
||||||
It's the perfect place to reproduce a bug when you want to
|
It's the perfect place to reproduce a bug when you want to
|
||||||
<a href="https://github.com/angular/angular/issues/new" title="File a documentation issue">file a documentation issue</a> or
|
<a href="https://github.com/angular/angular/issues/new" title="File a documentation issue">file a documentation issue</a> or
|
||||||
|
@ -12,6 +12,13 @@ component class instance (the *component*) and its user-facing template.
|
|||||||
You may be familiar with the component/template duality from your experience with model-view-controller (MVC) or model-view-viewmodel (MVVM).
|
You may be familiar with the component/template duality from your experience with model-view-controller (MVC) or model-view-viewmodel (MVVM).
|
||||||
In Angular, the component plays the part of the controller/viewmodel, and the template represents the view.
|
In Angular, the component plays the part of the controller/viewmodel, and the template represents the view.
|
||||||
|
|
||||||
|
This page is a comprehensive technical reference to the Angular template language.
|
||||||
|
It explains basic principles of the template language and describes most of the syntax that you'll encounter elsewhere in the documentation.
|
||||||
|
|
||||||
|
Many code snippets illustrate the points and concepts, all of them available
|
||||||
|
in the <live-example title="Template Syntax Live Code"></live-example>.
|
||||||
|
|
||||||
|
|
||||||
{@a html}
|
{@a html}
|
||||||
## HTML in templates
|
## HTML in templates
|
||||||
|
|
||||||
@ -104,7 +111,7 @@ including:
|
|||||||
Other notable differences from JavaScript syntax include:
|
Other notable differences from JavaScript syntax include:
|
||||||
|
|
||||||
* no support for the bitwise operators `|` and `&`
|
* no support for the bitwise operators `|` and `&`
|
||||||
* new [template expression operators](guide/template-syntax#expression-operators), such as `|` and `?.`
|
* new [template expression operators](guide/template-syntax#expression-operators), such as `|`, `?.` and `!`.
|
||||||
|
|
||||||
{@a expression-context}
|
{@a expression-context}
|
||||||
|
|
||||||
@ -1927,6 +1934,42 @@ The display is blank, but the app keeps rolling without errors.
|
|||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
It works perfectly with long property paths such as `a?.b?.c?.d`.
|
It works perfectly with long property paths such as `a?.b?.c?.d`.
|
||||||
|
|
||||||
|
<a href="#top-of-page">back to top</a>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
{@a non-null-assertion-operator}
|
||||||
|
|
||||||
|
### The non-null assertion operator ( <span class="syntax">!</span> )
|
||||||
|
|
||||||
|
As of Typescript 2.0, you can enforce [strict null checking](http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html "Strict null checking in TypeScript") with the `--strictNullChecks` flag. TypeScript then ensures that no variable is _unintentionally_ null or undefined.
|
||||||
|
|
||||||
|
In this mode, typed variables disallow null and undefined by default. The type checker throws an error if you leave a variable unassigned or try to assign null or undefined to a variable whose type disallows null and undefined.
|
||||||
|
|
||||||
|
The type checker also throws an error if it can't determine whether a variable will be null or undefined at runtime.
|
||||||
|
You may know that can't happen but the type checker doesn't know.
|
||||||
|
You tell the type checker that it can't happen by applying the post-fix
|
||||||
|
[_non-null assertion operator (!)_]((http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator "Non-null assertion operator").
|
||||||
|
|
||||||
|
The _Angular_ **non-null assertion operator (`!`)** serves the same purpose in an Angular template.
|
||||||
|
|
||||||
|
For example, after you use [*ngIf](guide/template-syntax#ngIf) to check that `hero` is defined, you can assert that
|
||||||
|
`hero` properties are also defined.
|
||||||
|
|
||||||
|
<code-example path="template-syntax/src/app/app.component.html" region="non-null-assertion-1" title="src/app/app.component.html" linenums="false">
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
When the Angular compiler turns your template into TypeScript code,
|
||||||
|
it prevents TypeScript from reporting that `hero.name` might be null or undefined.
|
||||||
|
|
||||||
|
Unlike the [_safe navigation operator_](guide/template-syntax#safe-navigation-operator "Safe naviation operator (?.)"),
|
||||||
|
the **non-null assertion operator** does not guard against null or undefined.
|
||||||
|
Rather it tells the TypeScript type checker to suspend strict null checks for a specific property expression.
|
||||||
|
|
||||||
|
You'll need this template operator when you turn on strict null checks. It's optional otherwise.
|
||||||
|
|
||||||
|
|
||||||
<a href="#top-of-page">back to top</a>
|
<a href="#top-of-page">back to top</a>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
@ -160,6 +160,7 @@ This guide describes specific choices that are known to work well.
|
|||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
There are two fast paths to getting started with unit testing.
|
There are two fast paths to getting started with unit testing.
|
||||||
|
|
||||||
1. Start a new project following the instructions in [Setup](guide/setup "Setup").
|
1. Start a new project following the instructions in [Setup](guide/setup "Setup").
|
||||||
|
|
||||||
1. Start a new project with the
|
1. Start a new project with the
|
||||||
|
@ -66,7 +66,7 @@ Anything you can import from `@angular` is a nested member of this `ng` object:
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="ng2import">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="ng2import">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/app.module.es6" region="ng2import">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/app.module.es6" region="ng2import">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="ng2import">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="ng2import">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -104,7 +104,7 @@ Here is a `HeroComponent` as it might be defined and "exported" in each of the f
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="appexport">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="appexport">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="appexport">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="appexport">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="appexport">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="appexport">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -121,7 +121,7 @@ In _ES5_ you use the shared namespace object to access "exported" entities from
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="appimport">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="appimport">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/app.module.es6" region="appimport">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/app.module.es6" region="appimport">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="appimport">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="appimport">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -167,7 +167,7 @@ Use the constructor function pattern instead, adding methods to the prototype.
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="class">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="class">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="class">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="class">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="class">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="class">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -193,7 +193,7 @@ See these variations side-by-side:
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="metadata">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="metadata">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="metadata">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="metadata">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="metadata">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="metadata">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -213,7 +213,7 @@ The component, `HeroTitleComponent` in this case, then references the template f
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts" region="templateUrl">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts" region="templateUrl">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-title.component.es6" region="templateUrl">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero-title.component.es6" region="templateUrl">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6" region="templateUrl">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6" region="templateUrl">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -322,7 +322,7 @@ Just implement the methods and ignore interfaces when translating code samples f
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-lifecycle.component.ts">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-lifecycle.component.ts">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-lifecycle.component.es6">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero-lifecycle.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-lifecycle.component.es6">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-lifecycle.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -354,7 +354,7 @@ combined in the metadata `inputs` and `outputs` _arrays_.
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/confirm.component.ts">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/confirm.component.ts">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/confirm.component.es6">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/confirm.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/confirm.component.es6">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/confirm.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -412,7 +412,7 @@ This format should be familiar to AngularJS developers.
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di.component.ts">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di.component.ts">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-di.component.es6">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero-di.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di.component.es6">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -430,8 +430,8 @@ In _TypeScript_ and _ES6-with-decorators_, you precede the class constructor par
|
|||||||
by calling the `@Inject()` decorator with the injection token.
|
by calling the `@Inject()` decorator with the injection token.
|
||||||
In the following example, the token is the string `'heroName'`.
|
In the following example, the token is the string `'heroName'`.
|
||||||
|
|
||||||
The other JavaScript dialects add a `parameters` array to the class contructor function.
|
The other JavaScript dialects add a `parameters` array to the class constructor function.
|
||||||
Each item constains a new instance of `Inject`:
|
Each item constrains a new instance of `Inject`:
|
||||||
|
|
||||||
* _Plain ES6_—each item is a new instance of `Inject(token)` in a sub-array.
|
* _Plain ES6_—each item is a new instance of `Inject(token)` in a sub-array.
|
||||||
* _ES5_—simply list the string tokens.
|
* _ES5_—simply list the string tokens.
|
||||||
@ -442,7 +442,7 @@ array as before. Create a new instance of `ng.core.Inject(token)` for each param
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di-inject.component.ts">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di-inject.component.ts">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-di-inject.component.es6">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero-di-inject.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di-inject.component.es6">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di-inject.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -475,7 +475,7 @@ array as before. Use a nested array to define a parameter's complete injection s
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-title.component.es6">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero-title.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -522,7 +522,7 @@ The `host` value is an object whose properties are host property and listener b
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host.component.ts">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host.component.ts">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-host.component.es6">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero-host.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-host.component.es6">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-host.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -545,7 +545,7 @@ These particular _TypeScript_ and _ES6_ code snippets happen to be identical.
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host-meta.component.ts">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host-meta.component.ts">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-host-meta.component.es6">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero-host-meta.component.es6">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
</code-tabs>
|
</code-tabs>
|
||||||
|
|
||||||
@ -578,7 +578,7 @@ The `queries` property value is a hash map.
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="view">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="view">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6" region="view">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6" region="view">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="view">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="view">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
@ -597,7 +597,7 @@ They can be added in the same way as [`@ViewChild`](api/core/ViewChild) and
|
|||||||
<code-tabs>
|
<code-tabs>
|
||||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="content">
|
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="content">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6" region="content">
|
<code-pane title="ES6 + Decorators" path="ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6" region="content">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="content">
|
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="content">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
|
BIN
aio/content/images/bios/_no-one.jpg
Normal file
After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 13 KiB |
BIN
aio/content/images/bios/andrewseguin.jpg
Executable file
After Width: | Height: | Size: 7.3 KiB |
BIN
aio/content/images/bios/angular-gde-bio-placeholder.jpg
Normal file
After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 7.0 KiB |
BIN
aio/content/images/bios/chrisnoring.jpg
Executable file
After Width: | Height: | Size: 8.1 KiB |
BIN
aio/content/images/bios/christianweyer.jpg
Executable file
After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 12 KiB |
BIN
aio/content/images/bios/cironunes.jpg
Executable file
After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
BIN
aio/content/images/bios/danwahlin.jpg
Executable file
After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.8 KiB |
BIN
aio/content/images/bios/deborah.jpg
Normal file → Executable file
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 10 KiB |
BIN
aio/content/images/bios/filipbech.jpg
Executable file
After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.9 KiB |