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")
|
||||
```
|
||||
[ ] bug report => search github for a similar issue or PR before submitting
|
||||
[ ] feature request
|
||||
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
|
||||
```
|
||||
## I'm submitting a ...
|
||||
<!-- Check one of the following options with "x" -->
|
||||
<pre><code>
|
||||
[ ] Regression (behavior that used to work and stopped working in a new release)
|
||||
[ ] Bug report <!-- Please search github for a similar issue or PR before submitting -->
|
||||
[ ] 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**
|
||||
<!-- Describe how the bug manifests. -->
|
||||
## Current behavior
|
||||
<!-- 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,
|
||||
please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
|
||||
For bug reports 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).
|
||||
-->
|
||||
|
||||
**What is the motivation / use case for changing the behavior?**
|
||||
<!-- Describe the motivation or the concrete use case -->
|
||||
## What is the motivation / use case for changing the behavior?
|
||||
<!-- 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 -->
|
||||
|
||||
* **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 ]
|
||||
<!-- All browsers where this could be reproduced -->
|
||||
Browser:
|
||||
- [ ] Chrome (desktop) version XX
|
||||
- [ ] Chrome (Android) version XX
|
||||
- [ ] Chrome (iOS) version XX
|
||||
- [ ] Firefox version XX
|
||||
- [ ] Safari (desktop) version XX
|
||||
- [ ] Safari (iOS) version XX
|
||||
- [ ] IE version XX
|
||||
- [ ] Edge version XX
|
||||
|
||||
* **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
|
||||
- [ ] Tests for the changes have been added (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
|
||||
[ ] Feature
|
||||
@ -12,25 +17,27 @@
|
||||
[ ] Refactoring (no functional changes, no api changes)
|
||||
[ ] Build related changes
|
||||
[ ] CI related changes
|
||||
[ ] Documentation content changes
|
||||
[ ] angular.io application / infrastructure changes
|
||||
[ ] Other... Please describe:
|
||||
```
|
||||
|
||||
**What is the current behavior?** (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?** (check one with "x")
|
||||
## Does this PR introduce a breaking change?
|
||||
```
|
||||
[ ] Yes
|
||||
[ ] 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
|
||||
|
||||
/dist/
|
||||
bazel-*
|
||||
node_modules
|
||||
bower_components
|
||||
|
||||
|
@ -97,15 +97,15 @@ groups:
|
||||
- vicb
|
||||
- IgorMinar #fallback
|
||||
|
||||
compiler/animations:
|
||||
animations:
|
||||
conditions:
|
||||
files:
|
||||
- "packages/compiler/src/animation/*"
|
||||
- "packages/animation/*"
|
||||
- "packages/platform-browser/animations/*"
|
||||
users:
|
||||
- matsko #primary
|
||||
- tbosch
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
- IgorMinar #fallback
|
||||
|
||||
compiler/i18n:
|
||||
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>
|
||||
# [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)
|
||||
* 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>
|
||||
# [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",
|
||||
"environments": {
|
||||
"dev": "environments/environment.ts",
|
||||
"stage": "environments/environment.stage.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
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# copied dependencies
|
||||
src/assets/js/lunr*
|
4
aio/content/examples/.gitignore
vendored
@ -45,12 +45,16 @@ dist/
|
||||
# aot
|
||||
**/*.ngfactory.ts
|
||||
**/*.ngsummary.json
|
||||
**/*.ngsummary.ts
|
||||
**/*.shim.ngstyle.ts
|
||||
**/*.metadata.json
|
||||
!aot/bs-config.json
|
||||
!aot/index.html
|
||||
!rollup-config.js
|
||||
|
||||
# i18n
|
||||
!i18n/src/systemjs-text-plugin.js
|
||||
|
||||
# testing
|
||||
!testing/src/browser-test-shim.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')
|
||||
]),
|
||||
transition('* => void', [
|
||||
animate('0.2s 10 ease-out', style({
|
||||
animate('0.2s 0.1s ease-out', style({
|
||||
opacity: 0,
|
||||
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');
|
||||
});
|
||||
|
||||
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">
|
||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<trans-unit id="af2ccf4b5dba59616e92cf1531505af02da8f6d2" datatype="html">
|
||||
<source>Hello i18n!</source>
|
||||
<trans-unit id="introductionHeader" datatype="html">
|
||||
<source>
|
||||
Hello i18n!
|
||||
</source>
|
||||
<target/>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
<note priority="1" from="meaning">User welcome</note>
|
||||
@ -24,12 +26,6 @@ I don't output any element either
|
||||
<source>Angular logo</source>
|
||||
<target/>
|
||||
</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">
|
||||
<source/>
|
||||
<target/>
|
||||
@ -42,6 +38,14 @@ I don't output any element either
|
||||
<source/>
|
||||
<target/>
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -10,6 +10,23 @@
|
||||
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
|
||||
<!--#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-->
|
||||
<img [src]="logo" title="Angular logo">
|
||||
<!--#enddocregion i18n-title-->
|
||||
Contact GitHub API Training Shop Blog About
|
||||
|
@ -1,6 +1,8 @@
|
||||
<!--#docregion-->
|
||||
<!--#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-->
|
||||
|
||||
<!--#docregion i18n-ng-container-->
|
||||
@ -31,4 +33,11 @@ I don't output any element either
|
||||
<!--#docregion i18n-select-->
|
||||
<span i18n>The hero is {gender, select, m {male} f {female}}</span>
|
||||
<!--#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';
|
||||
fly = true;
|
||||
logo = 'https://angular.io/resources/images/logos/angular/angular.png';
|
||||
count = 3;
|
||||
heroes: string[] = ['Magneta', 'Celeritas', 'Dynama'];
|
||||
inc(i: number) {
|
||||
this.wolves = Math.min(5, Math.max(0, this.wolves + i));
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
// #docregion
|
||||
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from '@angular/core';
|
||||
// #docplaster
|
||||
// #docregion without-missing-translation
|
||||
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, MissingTranslationStrategy } from '@angular/core';
|
||||
import { CompilerConfig } from '@angular/compiler';
|
||||
|
||||
export function getTranslationProviders(): Promise<Object[]> {
|
||||
|
||||
@ -17,13 +19,18 @@ export function getTranslationProviders(): Promise<Object[]> {
|
||||
// Ex: 'locale/messages.es.xlf`
|
||||
const translationFile = `./locale/messages.${locale}.xlf`;
|
||||
|
||||
// #docregion missing-translation
|
||||
return getTranslationsWithSystemJs(translationFile)
|
||||
.then( (translations: string ) => [
|
||||
{ provide: TRANSLATIONS, useValue: translations },
|
||||
{ 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
|
||||
// #enddocregion missing-translation
|
||||
}
|
||||
|
||||
declare var System: any;
|
||||
@ -31,3 +38,4 @@ declare var System: any;
|
||||
function getTranslationsWithSystemJs(file: string) {
|
||||
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">
|
||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<trans-unit id="af2ccf4b5dba59616e92cf1531505af02da8f6d2" datatype="html">
|
||||
<trans-unit id="introductionHeader" datatype="html">
|
||||
<source>Hello i18n!</source>
|
||||
<target>¡Hola i18n!</target>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
@ -36,6 +36,20 @@ I don't output any element either
|
||||
<source/>
|
||||
<target>{gender, select, m {hombre} f {mujer}}</target>
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -5,7 +5,9 @@
|
||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<!-- #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>
|
||||
<target>¡Hola i18n!</target>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
@ -13,7 +15,9 @@
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translated-hello -->
|
||||
<!-- #docregion translated-other-nodes -->
|
||||
<!-- #docregion generated-id -->
|
||||
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
|
||||
<!-- #enddocregion generated-id -->
|
||||
<source>I don't output any element</source>
|
||||
<target>No genero ningún elemento</target>
|
||||
</trans-unit>
|
||||
@ -48,6 +52,34 @@
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translate-select-2 -->
|
||||
<!-- #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>
|
||||
</file>
|
||||
</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 name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<link rel="stylesheet" href="app.css">
|
||||
|
||||
<!-- Polyfills -->
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
|
@ -27,7 +27,7 @@ describe('AppComponent', function () {
|
||||
it('should have expected <h1> text', () => {
|
||||
fixture.detectChanges();
|
||||
const h1 = de.nativeElement;
|
||||
expect(h1.innerText).toMatch(/angular/i,
|
||||
expect(h1.textContent).toMatch(/angular/i,
|
||||
'<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="#pipes">Pipes</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>
|
||||
|
||||
<!-- Interpolation and expressions -->
|
||||
@ -803,6 +804,21 @@ The null hero's name is {{nullHero && nullHero.name}}
|
||||
<!-- #enddocregion safe-6 -->
|
||||
</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>
|
||||
|
||||
<!-- TODO: discuss this in the Style binding section -->
|
||||
|
@ -111,7 +111,7 @@ export class AppComponent implements AfterViewInit, OnInit {
|
||||
}
|
||||
|
||||
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);
|
||||
if (event) { event.stopPropagation(); }
|
||||
}
|
||||
@ -127,6 +127,7 @@ export class AppComponent implements AfterViewInit, OnInit {
|
||||
resetHeroes() {
|
||||
this.heroes = Hero.heroes.map(hero => hero.clone());
|
||||
this.currentHero = this.heroes[0];
|
||||
this.hero = this.currentHero;
|
||||
this.heroesWithTrackByCountReset = 0;
|
||||
}
|
||||
|
||||
@ -172,8 +173,8 @@ function trackChanges(views: QueryList<ElementRef>, changed: () => void) {
|
||||
let oldRefs = views.toArray();
|
||||
views.changes.subscribe((changes: QueryList<ElementRef>) => {
|
||||
const changedRefs = changes.toArray();
|
||||
// Is every changed ElemRef the same as old and in the same position
|
||||
const isSame = oldRefs.every((v, i) => v === changedRefs[i]);
|
||||
// Check if every changed Element is the same as old and in the same position
|
||||
const isSame = oldRefs.every((v, i) => v.nativeElement === changedRefs[i].nativeElement);
|
||||
if (!isSame) {
|
||||
oldRefs = changedRefs;
|
||||
// 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
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { UpgradeModule } from '@angular/upgrade/static';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.documentElement, ['phonecatApp']);
|
||||
});
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
// #enddocregion bootstrap
|
||||
|
@ -7,12 +7,6 @@ import { browser, element, by } from 'protractor';
|
||||
|
||||
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() {
|
||||
browser.get('index.html');
|
||||
expect(browser.getLocationAbsUrl()).toBe('/phones');
|
||||
@ -70,7 +64,7 @@ describe('PhoneCat Application', function() {
|
||||
query.sendKeys('nexus');
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
|
@ -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",
|
||||
"dependencies": {
|
||||
"@angular/common": "~4.0.0",
|
||||
"@angular/compiler": "~4.0.0",
|
||||
"@angular/core": "~4.0.0",
|
||||
"@angular/forms": "~4.0.0",
|
||||
"@angular/http": "~4.0.0",
|
||||
"@angular/platform-browser": "~4.0.0",
|
||||
"@angular/platform-browser-dynamic": "~4.0.0",
|
||||
"@angular/router": "~4.0.0",
|
||||
"@angular/common": "~4.2.0",
|
||||
"@angular/compiler": "~4.2.0",
|
||||
"@angular/core": "~4.2.0",
|
||||
"@angular/forms": "~4.2.0",
|
||||
"@angular/http": "~4.2.0",
|
||||
"@angular/platform-browser": "~4.2.0",
|
||||
"@angular/platform-browser-dynamic": "~4.2.0",
|
||||
"@angular/router": "~4.2.0",
|
||||
"core-js": "^2.4.1",
|
||||
"rxjs": "5.0.1",
|
||||
"zone.js": "^0.8.4"
|
||||
@ -41,7 +41,7 @@
|
||||
"raw-loader": "^0.5.1",
|
||||
"rimraf": "^2.5.2",
|
||||
"style-loader": "^0.13.1",
|
||||
"typescript": "~2.0.10",
|
||||
"typescript": "~2.3.1",
|
||||
"webpack": "2.2.1",
|
||||
"webpack-dev-server": "2.4.1",
|
||||
"webpack-merge": "^3.0.0"
|
||||
|
@ -38,7 +38,7 @@ This page introduces modules; the [Angular modules](guide/ngmodule) page covers
|
||||
|
||||
<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`.
|
||||
|
||||
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.
|
||||
Every application has at least one Angular module, the _root_ module
|
||||
that you [bootstrap](guide/appmodule#main) to launch the application.
|
||||
Every application has at least one Angular module, the _root_ module
|
||||
that you [bootstrap](guide/bootstrapping#main) to launch the application.
|
||||
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`.
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
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}
|
||||
@ -35,7 +34,7 @@ All you need to know at the moment is a few basics about these three properties.
|
||||
### The _imports_ array
|
||||
|
||||
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`.
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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) —
|
||||
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.
|
||||
|
||||
|
||||
@ -111,14 +110,14 @@ Do not put any other kind of class in `declarations`; _not_ `NgModule` classes,
|
||||
|
||||
### 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
|
||||
and inserts each one into the browser DOM.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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`
|
||||
|
||||
<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.
|
||||
|
||||
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`.
|
||||
|
||||
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 ...
|
||||
|
||||
<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>
|
||||
Marshmallow (6.0)
|
||||
Nougat (7.0)<br>Marshmallow (6.0)
|
||||
</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
|
||||
|
||||
{@a top}
|
||||
|
||||
|
||||
|
||||
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
|
||||
using first the template-driven forms and then the reactive forms approach.
|
||||
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.
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Read more about these choices in the [Forms](guide/forms)
|
||||
and the [Reactive Forms](guide/reactive-forms) guides.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a toc}
|
||||
|
||||
{@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.
|
||||
|
||||
You add Angular form directives (mostly directives beginning `ng...`) to help
|
||||
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 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_
|
||||
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`.
|
||||
|
||||
* 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>
|
||||
@ -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,
|
||||
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.
|
||||
|
||||
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>
|
||||
|
||||
@ -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.
|
||||
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.
|
||||
|
||||
* 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}
|
||||
|
||||
|
||||
@ -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.
|
||||
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.
|
||||
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")
|
||||
_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:
|
||||
|
||||
<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
|
||||
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.
|
||||
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.
|
||||
@ -288,14 +291,14 @@ In short, there are more opportunities to improve message handling now that text
|
||||
{@a formmodule}
|
||||
|
||||
|
||||
### _FormModule_ and template-driven forms
|
||||
### _FormModule_ and Template Driven forms
|
||||
|
||||
Angular has two different forms modules—`FormsModule` and
|
||||
`ReactiveFormsModule`—that correspond with the
|
||||
two approaches to form development. Both modules come
|
||||
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`.
|
||||
|
||||
|
||||
@ -323,9 +326,9 @@ They're not germane to the validation story. Look at the [live example](guide/fo
|
||||
{@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`.
|
||||
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`.
|
||||
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:
|
||||
|
||||
* Add, change, and remove validation functions on the fly.
|
||||
* Manipulate the control model dynamically from within the component.
|
||||
* [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}
|
||||
|
||||
|
||||
### Switch to the _ReactiveFormsModule_
|
||||
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 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:
|
||||
|
||||
<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.
|
||||
|
||||
|
||||
@ -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.
|
||||
Here is the "name" portion of the template again, revised for reactive forms and compared with the template-driven version:
|
||||
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:
|
||||
|
||||
<code-tabs>
|
||||
|
||||
@ -405,15 +406,13 @@ but rather for css styling and accessibility.
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A future version of reactive forms will add the `required` HTML validation attribute to the DOM element
|
||||
(and perhaps the `aria-required` attribute) when the control has the `required` validator function.
|
||||
Currently, Reactive Forms doesn't add the `required` or `aria-required`
|
||||
HTML validation attribute to the DOM element
|
||||
when the control has the `required` validator function.
|
||||
|
||||
Until then, apply the `required` attribute _and_ add the `Validator.required` function
|
||||
to the control model, as you'll see below.
|
||||
|
||||
|
||||
</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.
|
||||
|
||||
|
||||
<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}
|
||||
|
||||
@ -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
|
||||
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>
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a committing-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.
|
||||
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.
|
||||
|
||||
This sample updates the model twice:
|
||||
@ -533,18 +522,6 @@ The `onSubmit()` method simply replaces the `hero` object with the combined valu
|
||||
</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.
|
||||
|
||||
<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.
|
||||
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>
|
||||
|
||||
@ -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,
|
||||
and to compare all of the files in this cookbook sample.
|
||||
and to compare all of the files in this sample.
|
||||
|
||||
|
||||
</div>
|
||||
@ -594,7 +571,7 @@ and to compare all of the files in this cookbook sample.
|
||||
|
||||
## Custom validation
|
||||
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`.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
<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".
|
||||
|
||||
<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
|
||||
|
||||
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
|
||||
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.
|
||||
They do not require the `Angular TestBed` or asynchronous testing practices.
|
||||
|
||||
That's not possible with _template-driven_ forms.
|
||||
The template-driven approach relies on Angular to produce the control model and
|
||||
That's not possible with Template Driven forms.
|
||||
The Template Driven approach relies on Angular to produce the control model and
|
||||
to derive validation rules from the HTML validation attributes.
|
||||
You must use the `Angular TestBed` to create component test instances,
|
||||
write asynchronous tests, and interact with the DOM.
|
||||
|
@ -19,26 +19,14 @@ unexpected definitions.
|
||||
|
||||
## Ahead-of-time (AOT) compilation
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
You can compile Angular applications at build time.
|
||||
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.
|
||||
Ahead-of-time compiled applications also benefit from decreased load time and increased performance.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Angular module
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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`.
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Annotation
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
In practice, a synonym for [Decoration](guide/glossary#decorator).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a attribute-directive}
|
||||
|
||||
|
||||
@ -73,10 +49,6 @@ In practice, a synonym for [Decoration](guide/glossary#decorator).
|
||||
|
||||
## Attribute directives
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a B}
|
||||
|
||||
## Barrel
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
@ -157,17 +121,8 @@ You can often achieve the same result using [Angular modules](guide/glossary#ang
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Binding
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Usually refers to [data binding](guide/glossary#data-binding) and the act of
|
||||
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).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Bootstrap
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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),
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a C}
|
||||
|
||||
## 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
|
||||
_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*.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a 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.
|
||||
|
||||
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".
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a D}
|
||||
|
||||
## 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 (`-`).
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Data binding
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Applications display data values to a user and respond to user
|
||||
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).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a decorator}
|
||||
|
||||
|
||||
@ -304,10 +217,6 @@ operations and supporting declaration syntax.
|
||||
|
||||
## Decorator | decoration
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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.
|
||||
@ -340,17 +249,8 @@ Always include parentheses `()` when applying a decorator.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Dependency injection
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A design pattern and mechanism
|
||||
for creating and delivering parts of an application to other
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a directive}
|
||||
|
||||
|
||||
@ -413,10 +309,6 @@ Read more in the [Dependency Injection](guide/dependency-injection) page.
|
||||
|
||||
## Directive
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
An Angular class responsible for creating, reshaping, and interacting with HTML elements
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a E}
|
||||
|
||||
## ECMAScript
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
The [official JavaScript language specification](https://en.wikipedia.org/wiki/ECMAScript).
|
||||
|
||||
The latest approved version of JavaScript is
|
||||
@ -473,47 +358,21 @@ to ES5 JavaScript.
|
||||
Angular developers can write in ES5 directly.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## ES2015
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## ES5
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Short hand for [ECMAScript](guide/glossary#ecmascript) 5, the version of JavaScript run by most modern browsers.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## ES6
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a F}
|
||||
|
||||
|
||||
@ -526,25 +385,13 @@ Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.
|
||||
|
||||
## Injector
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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
|
||||
with a registered [provider](guide/glossary#provider).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Input
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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).
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Interpolation
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A form of [property data binding](guide/glossary#data-binding) in which a
|
||||
[template expression](guide/glossary#template-expression) between double-curly braces
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a J}
|
||||
|
||||
{@a jit}
|
||||
@ -591,40 +427,22 @@ Read more about [interpolation](guide/template-syntax#interpolation) in the
|
||||
|
||||
## Just-in-time (JIT) compilation
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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.
|
||||
Consider using the [ahead-of-time](guide/glossary#aot) mode for production apps.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a K}
|
||||
|
||||
## kebab-case
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
See [dash-case](guide/glossary#dash-case).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a L}
|
||||
|
||||
## Lifecycle hooks
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
[Directives](guide/glossary#directive) and [components](guide/glossary#component) have a lifecycle
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a M}
|
||||
|
||||
## Module
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
|
||||
|
||||
Angular has the following types of modules:
|
||||
|
||||
* [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`.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a N}
|
||||
|
||||
{@a O}
|
||||
|
||||
## Observable
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
An array whose items arrive asynchronously over time.
|
||||
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.
|
||||
@ -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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
## Output
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A directive property that can be the *target* of event binding
|
||||
(read more in the [event binding](guide/template-syntax#event-binding)
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a P}
|
||||
|
||||
## 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.
|
||||
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*.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Pipe
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
An Angular pipe is a function that transforms input values to output values for
|
||||
display in a [view](guide/glossary#view).
|
||||
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).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Provider
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A _provider_ creates a new instance of a dependency for the
|
||||
[dependency injection](guide/glossary#dependency-injection) system.
|
||||
It relates a lookup token to code—sometimes called a "recipe"—that can create a dependency value.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a Q}
|
||||
|
||||
{@a R}
|
||||
|
||||
## Reactive forms
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A technique for building Angular forms through code in a component.
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Router
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Most applications consist of many screens or [views](guide/glossary#view).
|
||||
The user navigates among them by clicking links and buttons,
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
For more information, see the [Routing & Navigation](guide/router) page.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Routing component
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a S}
|
||||
|
||||
## Scoped package
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A way to group related *npm* packages.
|
||||
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>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Service
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
For data or logic that is not associated
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a snake-case}
|
||||
|
||||
|
||||
## snake_case
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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*.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a structural-directive}
|
||||
|
||||
|
||||
@ -967,10 +680,6 @@ underscore (`_`) separates one word from the next. This form is also known as *u
|
||||
|
||||
## Structural directives
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A category of [directive](guide/glossary#directive) that can
|
||||
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.
|
||||
@ -978,32 +687,17 @@ The `ngIf` "conditional element" directive and the `ngFor` "repeater" directive
|
||||
Read more in the [Structural Directives](guide/structural-directives) page.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a T}
|
||||
|
||||
## Template
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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),
|
||||
most notably a [component](guide/glossary#component).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Template-driven forms
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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).
|
||||
|
||||
@ -1020,16 +714,8 @@ Read about how to build template-driven forms
|
||||
in the [Forms](guide/forms) page.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Template expression
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A TypeScript-like syntax that Angular evaluates within
|
||||
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.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## Transpile
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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)).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
## TypeScript
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A version of JavaScript that supports most [ECMAScript 2015](guide/glossary#es2015)
|
||||
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/).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a U}
|
||||
|
||||
{@a V}
|
||||
|
||||
## View
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A portion of the screen that displays information and responds
|
||||
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).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a W}
|
||||
|
||||
|
||||
@ -1120,10 +778,6 @@ under the control of a [router](guide/glossary#router).
|
||||
|
||||
## Zone
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
A mechanism for encapsulating and intercepting
|
||||
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).
|
||||
|
||||
Learn more about zones in this
|
||||
[Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U).
|
||||
|
||||
</div>
|
||||
|
||||
[Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U).
|
@ -407,6 +407,9 @@ like the Observable-based version.
|
||||
|
||||
</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,
|
||||
highlighting just the parts that are different.
|
||||
|
@ -1,19 +1,12 @@
|
||||
# Internationalization (i18n)
|
||||
|
||||
{@a top}
|
||||
|
||||
|
||||
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>
|
||||
of a JIT-compiled app, translated into Spanish.
|
||||
|
||||
|
||||
|
||||
{@a angular-i18n}
|
||||
|
||||
|
||||
|
||||
## Angular and _i18n_ template translation
|
||||
|
||||
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
|
||||
into multiple languages.
|
||||
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
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>
|
||||
|
||||
|
||||
|
||||
The _i18n_ template translation process has four phases:
|
||||
|
||||
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.
|
||||
|
||||
|
||||
{@a i18n-attribute}
|
||||
|
||||
|
||||
|
||||
## Mark text with the _i18n_ attribute
|
||||
|
||||
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">
|
||||
|
||||
|
||||
|
||||
`i18n` is not an Angular _directive_.
|
||||
It's a custom _attribute_, recognized by Angular tools and compilers.
|
||||
After translation, the compiler removes it.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
In the accompanying sample, an `<h1>` tag displays a simple English language greeting
|
||||
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>
|
||||
|
||||
|
||||
|
||||
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>
|
||||
|
||||
|
||||
|
||||
{@a help-translator}
|
||||
|
||||
|
||||
### Help the translator with a _description_ and _intent_
|
||||
### Help the translator with a _description_ and _meaning_
|
||||
|
||||
In order to translate it accurately, the translator may
|
||||
need a description of the message.
|
||||
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>
|
||||
|
||||
|
||||
|
||||
In order to deliver a correct translation, the translator may need to
|
||||
know your _intent_—the true _meaning_ of the text
|
||||
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>`):
|
||||
know the _meaning_ or _intent_ of the text within _this particular_ application context.
|
||||
|
||||
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>
|
||||
|
||||
|
||||
|
||||
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.
|
||||
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}
|
||||
|
||||
|
||||
### Translate text without creating an element
|
||||
|
||||
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.
|
||||
|
||||
(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>
|
||||
|
||||
|
||||
|
||||
(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>
|
||||
|
||||
|
||||
|
||||
|
||||
{@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:
|
||||
|
||||
|
||||
<code-example path="i18n/src/app/app.component.1.html" region="i18n-title" title="src/app/app.component.html" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
The `title` attribute needs to be translated.
|
||||
Angular i18n support has more translation attributes in the form,`i18n-x`, where `x` is the
|
||||
name of the attribute to translate.
|
||||
|
||||
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>
|
||||
|
||||
|
||||
|
||||
You can also assign a meaning and a description with the `i18n-x="<meaning>|<description>"` syntax.
|
||||
|
||||
|
||||
|
||||
{@a cardinality}
|
||||
|
||||
|
||||
## Handle singular and plural
|
||||
|
||||
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:
|
||||
|
||||
|
||||
<code-example path="i18n/src/app/app.component.html" region="i18n-plural" title="src/app/app.component.html" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
* The first parameter is the key. It is bound to the component property (`wolves`)
|
||||
that determines the number of wolves.
|
||||
* The second parameter identifies this as a `plural` translation type.
|
||||
@ -217,43 +214,41 @@ categories and their matching values.
|
||||
|
||||
Pluralization categories include:
|
||||
|
||||
* =0
|
||||
* =1
|
||||
* =5
|
||||
* =0 (or any other number)
|
||||
* zero
|
||||
* one
|
||||
* two
|
||||
* few
|
||||
* many
|
||||
* other
|
||||
|
||||
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}`.
|
||||
|
||||
* For zero wolves, you could write `=0 {no wolves}`.
|
||||
|
||||
* For two wolves, you could write `=2 {two 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
|
||||
and write something like: `other {a wolf pack}`.
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
This syntax conforms to the
|
||||
<a href="http://userguide.icu-project.org/formatparse/messages" title="ICU Message Format">ICU Message Format</a>
|
||||
that derives from the
|
||||
<a href="http://cldr.unicode.org/" title="CLDR">Common Locale Data Repository (CLDR)</a>,
|
||||
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>
|
||||
|
||||
|
||||
|
||||
{@a select}
|
||||
|
||||
|
||||
## Select among alternative texts
|
||||
|
||||
The application displays different text depending upon whether the hero is male or female.
|
||||
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".
|
||||
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>
|
||||
|
||||
## 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}
|
||||
|
||||
|
||||
|
||||
## Create a translation source file with the _ng-xi18n_ tool
|
||||
|
||||
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.
|
||||
If you haven't already installed the CLI and its `platform-server` peer dependency, do so now:
|
||||
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm install @angular/compiler-cli @angular/platform-server --save
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Open a terminal window at the root of the application project and enter the `ng-xi18n` command:
|
||||
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
./node_modules/.bin/ng-xi18n
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Windows users may have to quote the command like this: `"./node_modules/.bin/ng-xi18n"`
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
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}
|
||||
|
||||
|
||||
### Other translation formats
|
||||
|
||||
You can generate a file named **`messages.xmb`** in the
|
||||
<a href="http://cldr.unicode.org/development/development-process/design-proposals/xmb" >XML Message Bundle (XMB)</a> format
|
||||
by adding the `--i18nFormat=xmb` flag.
|
||||
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>.
|
||||
|
||||
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">
|
||||
./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>
|
||||
|
||||
|
||||
|
||||
This sample sticks with the _XLIFF_ format.
|
||||
|
||||
The sample in _this_ guide sticks with the default _XLIFF 1.2_ format.
|
||||
|
||||
{@a ng-xi18n-options}
|
||||
|
||||
|
||||
### Other options
|
||||
|
||||
You may have to specify additional options.
|
||||
For example, if the `tsconfig.json` TypeScript configuration
|
||||
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">
|
||||
./node_modules/.bin/ng-xi18n -p path/to/tsconfig.json
|
||||
./node_modules/.bin/ng-xi18n --i18nFormat=xmb -p path/to/tsconfig.json
|
||||
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a npm-i18n-script}
|
||||
|
||||
|
||||
### Add an _npm_ script for convenience
|
||||
|
||||
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>
|
||||
|
||||
|
||||
|
||||
Now you can issue command variations such as these:
|
||||
|
||||
<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
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Note the `--` flag before the options.
|
||||
It tells _npm_ to pass every flag thereafter to `ng-xi18n`.
|
||||
|
||||
|
||||
{@a translate}
|
||||
|
||||
|
||||
|
||||
## Translate text messages
|
||||
|
||||
The `ng-xi18n` command generates a translation source file
|
||||
in the project root folder named `messages.xlf`.
|
||||
The next step is to translate the English language template
|
||||
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}
|
||||
|
||||
|
||||
### Create a localization folder
|
||||
|
||||
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">
|
||||
|
||||
|
||||
|
||||
Localization and internationalization are
|
||||
<a href="https://en.wikipedia.org/wiki/Internationalization_and_localization">different but closely related terms</a>.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
This cookbook follows that suggestion. It has a `locale` folder under the `src/`.
|
||||
This guide follows that suggestion. It has a `locale` folder under `src/`.
|
||||
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>.
|
||||
|
||||
@ -432,7 +393,6 @@ Do the same for each target language.
|
||||
|
||||
{@a 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
|
||||
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.
|
||||
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>
|
||||
|
||||
|
||||
|
||||
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,
|
||||
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>
|
||||
|
||||
|
||||
|
||||
<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:
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
<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}
|
||||
|
||||
|
||||
## Translate _plural_ and _select_
|
||||
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.
|
||||
In this example, you know the translation unit for the `select` must be just below the translation unit for the logo.
|
||||
|
||||
|
||||
{@a translate-plural}
|
||||
|
||||
|
||||
### Translate _plural_
|
||||
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>
|
||||
|
||||
|
||||
|
||||
{@a translate-select}
|
||||
|
||||
|
||||
### Translate _select_
|
||||
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>
|
||||
|
||||
|
||||
|
||||
The extraction tool broke that into _two_ translation units.
|
||||
|
||||
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.
|
||||
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>
|
||||
|
||||
|
||||
|
||||
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>
|
||||
|
||||
|
||||
|
||||
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>
|
||||
|
||||
### 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
|
||||
time to incorporate that translation into the application.
|
||||
|
||||
|
||||
<div id='app-pre-translation'>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<a id='app-pre-translation'></a>
|
||||
|
||||
### The app before translation
|
||||
|
||||
When the previous steps finish, the sample app _and_ its translation file are as follows:
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/app/app.component.html" path="i18n/src/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.ts" path="i18n/src/app/app.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.module.ts" path="i18n/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/main.ts" path="i18n/src/main.1.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/locale/messages.es.xlf" path="i18n/src/locale/messages.es.xlf.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
{@a merge}
|
||||
|
||||
|
||||
|
||||
## Merge the completed translation file into the app
|
||||
|
||||
To merge the translated text into component templates,
|
||||
compile the application with the completed translation file.
|
||||
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:
|
||||
|
||||
@ -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 [AOT](guide/i18n#aot), you pass the information as `ngc` options.
|
||||
|
||||
|
||||
{@a jit}
|
||||
|
||||
|
||||
|
||||
### Merge with the JIT compiler
|
||||
|
||||
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:
|
||||
|
||||
<code-example path="i18n/src/index.html" region="i18n" title="index.html (launch script)" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
In this sample, the user's language is hardcoded as a global `document.locale` variable
|
||||
In this sample, the user's language is hard-coded as a global `document.locale` variable
|
||||
in the `index.html`.
|
||||
|
||||
|
||||
{@a 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`.
|
||||
With the help of a text plugin, SystemJS can read any file as raw text and
|
||||
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:
|
||||
|
||||
<code-example path="i18n/src/systemjs-text-plugin.js" title="src/systemjs-text-plugin.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a create-translation-providers}
|
||||
|
||||
|
||||
### Create translation providers
|
||||
|
||||
Three providers tell the JIT compiler how to translate the template texts for a particular language
|
||||
while compiling the application:
|
||||
|
||||
* `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.
|
||||
|
||||
The `getTranslationProviders()` function in the following `src/app/i18n-providers.ts`
|
||||
creates those providers based on the user's _locale_
|
||||
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>
|
||||
|
||||
|
||||
|
||||
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.
|
||||
@ -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.
|
||||
|
||||
<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}
|
||||
|
||||
|
||||
### Bootstrap the app with translation providers
|
||||
### Bootstrap with translation providers
|
||||
|
||||
The Angular `bootstrapModule()` method has a second _options_ parameter
|
||||
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:
|
||||
|
||||
<code-example path="i18n/src/main.ts" title="src/main.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Notice that it waits for the `getTranslationProviders()` promise to resolve before
|
||||
bootstrapping the app.
|
||||
|
||||
The app is now _internationalized_ for English and Spanish and there is a clear path for adding
|
||||
more languages.
|
||||
|
||||
|
||||
{@a aot}
|
||||
|
||||
|
||||
|
||||
### _Internationalization_ with the AOT compiler
|
||||
|
||||
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
|
||||
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.
|
||||
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.
|
||||
Start with the application project as shown
|
||||
[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.
|
||||
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">
|
||||
./node_modules/.bin/ngc --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Windows users may have to quote the command:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
"./node_modules/.bin/ngc" --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
</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}
|
||||
|
||||
|
||||
## Translation file maintenance and _id_ changes
|
||||
## File maintenance and _id_ changes
|
||||
|
||||
As the application evolves, you will change the _i18n_ markup
|
||||
and re-run the `ng-xi18n` extraction tool many times.
|
||||
The _new_ markup that you add is not a problem;
|
||||
but _most_ changes to existing markup trigger
|
||||
generation of new `id`s for the affected translation units.
|
||||
The _new_ markup that you add is not a problem.
|
||||
But the `id` _can be a serious problem!_
|
||||
|
||||
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.
|
||||
**All translated versions of the application will fail** during re-compilation.
|
||||
The error messages identify the old `id`s that are no longer valid but
|
||||
they don't tell you what the new `id`s should be.
|
||||
Because of that, you get some warning messages during re-compilation.
|
||||
The warning messages identify that some translations are missing, but they don't tell you which
|
||||
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`.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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_.
|
||||
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:
|
||||
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>
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
|
||||
<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">
|
||||
|
||||
|
||||
|
||||
Try this **<live-example noDownload>QuickStart example on Plunker</live-example>** without installing anything.
|
||||
Try it locally with the [***QuickStart seed***](guide/setup "Setup for local development with the QuickStart seed")
|
||||
and prepare for development of a real Angular application.
|
||||
Patience please.
|
||||
It takes time to set up a new project, most of it spent installing npm packages.
|
||||
|
||||
|
||||
</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>
|
||||
|
||||
|
||||
|
||||
The `template` property defines a message inside an `<h1>` header.
|
||||
The message starts with "Hello" and ends with `{{name}}`,
|
||||
which is an Angular [interpolation binding](guide/displaying-data) expression.
|
||||
At runtime, Angular replaces `{{name}}` with the value of the component's `name` property.
|
||||
Interpolation binding is one of many Angular features you'll discover in this documentation.
|
||||
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:
|
||||
|
||||
|
||||
In the example, change the component class's `name` property from `'Angular'` to `'World'` and see what happens.
|
||||
|
||||
|
||||
<div class="callout is-helpful">
|
||||
<figure>
|
||||
<img src='generated/images/guide/cli-quickstart/app-works.png' alt="The app works!">
|
||||
</figure>
|
||||
|
||||
|
||||
|
||||
<header>
|
||||
A word about TypeScript
|
||||
</header>
|
||||
|
||||
<h2 id='first-component'>
|
||||
Step 4: Edit your first Angular component
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
This example is written in <a href="http://www.typescriptlang.org/" title="TypeScript">TypeScript</a>, a superset of JavaScript. Angular
|
||||
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.
|
||||
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`.
|
||||
|
||||
</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>
|
||||
|
||||
|
||||
|
||||
<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">
|
||||
|
||||
### Next Step
|
||||
|
||||
|
||||
### Next step
|
||||
|
||||
Start the [**tutorial**](tutorial "Tour of Heroes tutorial").
|
||||
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>
|
||||
|
||||
|
@ -3,11 +3,11 @@
|
||||
{@a develop-locally}
|
||||
|
||||
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.
|
||||
|
||||
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?").
|
||||
@ -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.
|
||||
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").
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
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.
|
||||
It is the **root** component of what will become a tree of nested components
|
||||
as the application evolves.
|
||||
as the application evolves.
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
@ -253,7 +253,7 @@ The following are all in `src/`
|
||||
<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`.
|
||||
Soon there will be more components to declare.
|
||||
</td>
|
||||
@ -270,7 +270,7 @@ The following are all in `src/`
|
||||
|
||||
|
||||
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 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.
|
||||
@ -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.
|
||||
Older versions produce errors.
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
It creates the equivalent of `app.module.ts` and `main.ts` internally _for the playground only_.
|
||||
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 ...
|
||||
|
||||
@ -343,7 +343,7 @@ As much fun as this is ...
|
||||
* transpiling TypeScript in the browser is slow
|
||||
* 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.
|
||||
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
|
||||
|
@ -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).
|
||||
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}
|
||||
## HTML in templates
|
||||
|
||||
@ -104,7 +111,7 @@ including:
|
||||
Other notable differences from JavaScript syntax include:
|
||||
|
||||
* 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}
|
||||
|
||||
@ -1927,6 +1934,42 @@ The display is blank, but the app keeps rolling without errors.
|
||||
</code-example>
|
||||
|
||||
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>
|
||||
|
||||
<hr/>
|
||||
|
@ -160,6 +160,7 @@ This guide describes specific choices that are known to work well.
|
||||
### Setup
|
||||
|
||||
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 with the
|
||||
|
@ -66,7 +66,7 @@ Anything you can import from `@angular` is a nested member of this `ng` object:
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="ng2import">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="ng2import">
|
||||
</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-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="appexport">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="appexport">
|
||||
</code-pane>
|
||||
@ -121,7 +121,7 @@ In _ES5_ you use the shared namespace object to access "exported" entities from
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="appimport">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="appimport">
|
||||
</code-pane>
|
||||
@ -167,7 +167,7 @@ Use the constructor function pattern instead, adding methods to the prototype.
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="class">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="class">
|
||||
</code-pane>
|
||||
@ -193,7 +193,7 @@ See these variations side-by-side:
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="metadata">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="metadata">
|
||||
</code-pane>
|
||||
@ -213,7 +213,7 @@ The component, `HeroTitleComponent` in this case, then references the template f
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts" region="templateUrl">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6" region="templateUrl">
|
||||
</code-pane>
|
||||
@ -322,7 +322,7 @@ Just implement the methods and ignore interfaces when translating code samples f
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-lifecycle.component.ts">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-lifecycle.component.es6">
|
||||
</code-pane>
|
||||
@ -354,7 +354,7 @@ combined in the metadata `inputs` and `outputs` _arrays_.
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/confirm.component.ts">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/confirm.component.es6">
|
||||
</code-pane>
|
||||
@ -412,7 +412,7 @@ This format should be familiar to AngularJS developers.
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di.component.ts">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di.component.es6">
|
||||
</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.
|
||||
In the following example, the token is the string `'heroName'`.
|
||||
|
||||
The other JavaScript dialects add a `parameters` array to the class contructor function.
|
||||
Each item constains a new instance of `Inject`:
|
||||
The other JavaScript dialects add a `parameters` array to the class constructor function.
|
||||
Each item constrains a new instance of `Inject`:
|
||||
|
||||
* _Plain ES6_—each item is a new instance of `Inject(token)` in a sub-array.
|
||||
* _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-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di-inject.component.ts">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di-inject.component.es6">
|
||||
</code-pane>
|
||||
@ -475,7 +475,7 @@ array as before. Use a nested array to define a parameter's complete injection s
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6">
|
||||
</code-pane>
|
||||
@ -522,7 +522,7 @@ The `host` value is an object whose properties are host property and listener b
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host.component.ts">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-host.component.es6">
|
||||
</code-pane>
|
||||
@ -545,7 +545,7 @@ These particular _TypeScript_ and _ES6_ code snippets happen to be identical.
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host-meta.component.ts">
|
||||
</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-tabs>
|
||||
|
||||
@ -578,7 +578,7 @@ The `queries` property value is a hash map.
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="view">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="view">
|
||||
</code-pane>
|
||||
@ -597,7 +597,7 @@ They can be added in the same way as [`@ViewChild`](api/core/ViewChild) and
|
||||
<code-tabs>
|
||||
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="content">
|
||||
</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 title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="content">
|
||||
</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 |