Compare commits

...

98 Commits
5.0.1 ... 5.0.4

Author SHA1 Message Date
cbd93fe0d0 docs: add changelog for 5.0.4 2017-11-30 21:13:58 -08:00
e1dfd9b17a release: cut the 5.0.4 release 2017-11-30 21:11:45 -08:00
e95b5d77bc revert: docs(aio): add service worker guide content and update nav (#20021) (#20716)
* revert: style: broken build due to missing new lines

This reverts commit ba6af2a6dd.
The commit that introduced these files (48300067f) will also get
reverted.

* revert: docs(aio): add service worker guide content and update nav (#20021)

This reverts commit 48300067fb.
This commit has some issues (e.g. breaks some e2e tests, adds images
to the wrong directories, breaks linting, etc).
Reverting in order to investigate and fix.
2017-11-30 20:16:22 -08:00
9e69d97b77 style: broken build due to missing new lines 2017-11-29 20:27:06 -08:00
b450c83091 docs(aio): remove services plurality (#20696)
remove services plurality for the sentence formation to be proper

PR Close #20696
2017-11-29 21:37:32 -06:00
38be44df9f fix(compiler-cli): fix memory leak in program creation (#20692)
Saving `oldProgram` in `AngularCompilerProgram` instances is causing a memory leak for unemitted programs.

It's not actually used so simply not saving it fixes the memory leak.

Fix #20691

PR Close #20692
2017-11-29 21:37:23 -06:00
e4ce695b66 test(aio): cleaner approach to reliable Google Analytics e2e tests (#20661)
PR Close #20661
2017-11-29 21:37:14 -06:00
4da184c29b test(aio): fix e2e API test due to #20607 (#20661)
PR Close #20661
2017-11-29 21:37:14 -06:00
647ca64216 docs(aio): Updating with Ignite UI for Angular (#20663)
PR Close #20663
2017-11-29 16:23:29 -06:00
53aff1fb83 docs(aio): add service worker guide content and update nav (#20021)
PR Close #20021
2017-11-29 16:23:23 -06:00
71a6f1768e docs(aio): add class attribute to example referenced in Structural Directive guide (#19446)
See https://github.com/angular/angular/blob/master/aio/content/guide/structural-directives.md

From the structural-directives.md:
The rest of the <div>, including its class attribute, moved inside the <ng-template> element.

Maybe this made sense at one time but it has become out of sync.

PR Close #19446
2017-11-29 16:19:14 -06:00
108b6e77dd build(aio): upgrade codelyzer to 4.0.x and angular/cli to 1.5.4 (#20392)
PR Close #20392
2017-11-29 16:18:56 -06:00
ead759670b fix(common): don't strip XSSI prefix for if error isn't JSON (#19958)
This changes XhrBackend to not strip the XSSI prefix from error text
if such a prefix is present but the remaining body does not parse as
JSON.

PR Close #19958
2017-11-29 16:18:48 -06:00
bdaee508cf fix(common): treat an empty body as null when parsing JSON in HttpClient (#19958)
Previously, XhrBackend would call JSON.parse('') if the response body was
empty (a 200 status code with content-length 0). This changes the XhrBackend
to attempt the JSON parse only if the response body is non-empty. Otherwise,
the body is left as null.

Fixes #18680.
Fixes #19413.
Fixes #19502.
Fixes #19555.

PR Close #19958
2017-11-29 16:18:48 -06:00
e099911dd0 fix(common): remove useless guard in HttpClient (#19958)
An invalid "if" condition is always true, and is thus useless. This
change removes it. No behavior changes.

Fixes #19223.

PR Close #19958
2017-11-29 16:18:48 -06:00
66fd1f8ce6 fix(common): accept falsy values as HTTP bodies (#19958)
Previously, HttpClient used the overly clever test "body || null"
to determine when a body parameter was provided. This breaks when
the valid bodies '0' or 'false' are provided.

This change tests directly against 'undefined' to detect the presence
of the body parameter, and thus correctly allows falsy values through.

Fixes #19825.
Fixes #19195.

PR Close #19958
2017-11-29 16:18:48 -06:00
0e8f0288cb docs: fix grammar and wording (#18530)
PR Close #18530
2017-11-29 16:18:39 -06:00
c7b211ca3c fix(animations): ensure multi-level leave animations work (#19455)
PR Close #19455
2017-11-27 18:52:56 -06:00
22bbd6e045 fix(animations): ensure multi-level enter animations work (#19455)
PR Close #19455
2017-11-27 18:52:56 -06:00
2a5b6194bb build(aio): prevent comments in code from leaking into doc-gen code snippets (#20607)
The new version of dgeni-packages (0.22.1) does a better job of rendering
code nodes, which do not include comments.

Fixes #19751

PR Close #20607
2017-11-27 18:24:58 -06:00
264260f997 docs(aio): update homepage tooling image (#20593)
Fix #19831

PR Close #20593
2017-11-27 18:24:50 -06:00
c70cd258d5 build(aio): ensure downloadable zip filenames are unique (#20586)
Fixes #16227

PR Close #20586
2017-11-27 18:24:42 -06:00
2b0c896d78 fix(compiler-cli): normalize sourcepaths for i18n extracted files (#20417)
Fixes #20416
PR Close #20417
2017-11-27 18:24:35 -06:00
c0bf1b0545 docs(core): fix broken NgZone code example (#19291)
The current code example was broken as there were a couple of syntax errors. This commit fixes the demo.

PR Close #19291
2017-11-27 18:24:26 -06:00
65a40e659b docs: add changelog for 5.0.3 2017-11-22 13:09:12 -08:00
215832d8c6 release: cut the 5.0.3 release 2017-11-22 13:08:11 -08:00
686c4efe6d docs(aio): add ngATL header (#20590)
Fix #20568

PR Close #20590
2017-11-22 15:04:09 -06:00
efce39605b docs(aio): add a French onsite training ressource (#19889)
PR Close #19889
2017-11-22 10:49:12 -06:00
b567f9cc21 docs(aio): add a French onsite training ressource (#19889)
PR Close #19889
2017-11-22 10:49:12 -06:00
4ff60c3562 docs(aio): fix filename (#20569)
PR Close #20569
2017-11-22 10:48:57 -06:00
bc904b19a4 fix(common): return ISubscription from Location.subscribe() (#20429)
Fix #20406

PR Close #20429
2017-11-22 10:48:38 -06:00
135cf226bf ci: Update 1% payload size test (#20524)
PR Close #20524
2017-11-22 10:48:26 -06:00
0550383fc9 build(aio): filter out ambiguous directives from auto code linking (#20512)
Closes #20466

PR Close #20512
2017-11-22 10:48:19 -06:00
07699cbaec build(aio): do not store duplicate metadata aliases (#20512)
Having duplicates was causing the code auto-linking
to ignore `ngForm` directives.

PR Close #20512
2017-11-22 10:48:18 -06:00
e4bb077d27 build(aio): better parsing of selectors as aliases for directives/components (#20512)
PR Close #20512
2017-11-22 10:48:18 -06:00
27e7439c3b docs(aio): add angularfirebase.com to education resources (#20302)
PR Close #20302
2017-11-22 10:48:09 -06:00
66d160215e ci: update pullapprove (#20540)
PR Close #20540
2017-11-22 10:48:02 -06:00
0feba49c4b fix(core): fix #20532, should be able to cancel listener from mixed zone (#20538)
PR Close #20538
2017-11-22 10:47:53 -06:00
9ca6ee9eed fix(benchpress): Allow ignoring navigationStart events in perflog metric. (#20312)
PR Close #20312
2017-11-22 10:46:34 -06:00
a5a82296b7 docs(aio): fix typo in Attribute Directives documentation (#20143)
changed "appHightlight" to "appHighlight"

PR Close #20143
2017-11-22 10:45:41 -06:00
f9f2c20a57 fix(forms): updateOn should check if change occurred (#20358)
Fixes #20259.

PR Close #20358
2017-11-22 10:45:22 -06:00
662422a67e docs: NgModule guide prose for CLI (partial) (#19776)
Also replaces “Angular Module” with “NgModule” wherever that is clarifying.
Continue using “module” when qualified as in “feature module”, “root module”, “routing module”, etc.

PR Close #19776
2017-11-22 10:44:58 -06:00
b53ead4c45 fix(compiler): support event bindings in fullTemplateTypeCheck (#20490)
The type-check block now disables type checking event access instead
of generating a reference to an undefined variable.

PR Close #20490
2017-11-21 10:47:08 -06:00
d0abfa3acc docs: update the triaging doc with the latest process (#20128)
PR Close #20128
2017-11-21 10:43:28 -06:00
3bf36e9492 docs: add description for target labels + add LTS target label (#20128)
PR Close #20128
2017-11-21 10:43:28 -06:00
82aace63ea fix(core): should support event.stopImmediatePropagation (#20469)
PR Close #20469
2017-11-17 18:19:34 -06:00
15795d09cf fix(animations): validate against trigger() names that use @ symbols (#20326)
PR Close #20326
2017-11-17 18:19:28 -06:00
8ddbed8f7b build(aio): tighten up code autolinking (#20468)
Do not match code "words" that are part of a hyphenated
string of characters: e.g. `platform-browser-dynamic` should
not auto-link `browser`.

Do not match code "words" that correspond to pipe names
but are not preceded by a pipe `|` character. E.g. `package.json` should
not auto link `json` to the `JsonPipe`.

Closes #20187

PR Close #20468
2017-11-17 18:19:22 -06:00
81f1d42328 fix(compiler): emit correct type-check-blocks with TemplateRef's (#20463)
The type-check block generated with `"fullTemplateTypeCheck"` was
invalid if the it contained a template ref as would be generated
using the `else` micro-syntax of `NgIf`.

Fixes: #19485

PR Close #20463
2017-11-17 18:19:13 -06:00
3df1542c87 docs(aio): fix a typo to improve readability (#20435)
Remove a comma and space

PR Close #20435
2017-11-17 18:19:06 -06:00
8e1e7faef4 docs(aio): Clearing array with [] (#20369) (#20395)
Convert remaining references to directly use LoggerServices logs.

PR Close #20395
2017-11-17 18:18:59 -06:00
27f8c69d8a docs(aio): Removing reference to LoggerService property (#20369) (#20395)
The reference removed so that calling LoggerService clear() method
behaves as intended in SpyComponent.

PR Close #20395
2017-11-17 18:18:59 -06:00
5d0dd97402 docs(aio): Clearing array with [] (#20369) (#20395)
Clearing array with setting length to 0 replaced with [] for being short
and marginally efficient. For reference: [] is turned into a sequence of
around 15 machine instructions on x64 (if bump pointer allocation succeeds),
whereas a.length=0 is a C++ runtime function call, which requires 10-100x as
many instructions.
Benedikt Meurer

PR Close #20395
2017-11-17 18:18:59 -06:00
814f06289b fix(animations): always fire inner trigger callbacks even if blocked by parent animations (#19753)
Closes #19100

PR Close #19753
2017-11-17 18:17:46 -06:00
b1f8eb14c8 docs: add changelog for 5.0.2 2017-11-16 11:24:02 -08:00
f983d1cc50 release: cut the 5.0.2 release 2017-11-16 11:20:49 -08:00
12857922c5 fix(aio): fix window title on Home page (#20440)
Using `display: none` on the `<h1>` causes `innerText` to not work as expected
and include the icon ligature (`link`) in the title. This caused the window
title on the angular.io Home page to appear as "Angular - link".
This commit fixes it by not generating anchors at all for headings with the
`no-anchor` class.

Fixes #20427

PR Close #20440
2017-11-15 22:26:20 -06:00
dbdf9f76be docs(aio): add missing closing backtick (#20446)
PR Close #20446
2017-11-15 22:26:12 -06:00
d5eaf4de3c Revert "fix(animations): always fire inner trigger callbacks even if blocked by parent animations (#19753)"
This reverts commit bc4b4b5b55.
2017-11-15 22:25:30 -06:00
2d6126ec1b style(core): fix comment format for linter 2017-11-15 11:51:56 -08:00
259f6bf638 style(core): fix max line length to pass linting (#20441)
Accidentally introduced in #19920, where other linting errors (unrelated to the
PR) prevented proper linting.

PR Close #20441
2017-11-15 11:45:02 -08:00
03d549be05 Revert "fix(core): should support event.stopImmediatePropagation"
This reverts commit 5e0eb5e3d94bd7077c4d6657b89bfc8d900f2bc6.
2017-11-15 11:35:52 -08:00
bc4b4b5b55 fix(animations): always fire inner trigger callbacks even if blocked by parent animations (#19753)
Closes #19100

PR Close #19753
2017-11-14 16:00:01 -08:00
00f2055c59 docs(aio): fix wrong copy (#20431)
PR Close #20431
2017-11-14 15:59:57 -08:00
91efc7f70b docs(core): change from deprecated renderer to renderer2 (#19920)
We now show the proper class instead of the deprecated Renderer

Fixes #19806


PR Close #19920
2017-11-14 13:45:04 -08:00
8b1a6b1f24 fix(animations): ensure final state() styles are applied within @.disabled animations (#20267)
Closes #20266

PR Close #20267
2017-11-14 12:13:38 -08:00
b732fb935b fix(router): 'merge' queryParamHandling strategy should be able to remove query params (#19733)
Closes #18463, #17202

PR Close #19733
2017-11-14 12:13:30 -08:00
0e2d962acb ci: tighten package limits (#20364)
PR Close #20364
2017-11-14 12:13:22 -08:00
7acbc19b94 docs(aio): fix broken link in guide/component-interaction (#20411)
add a blank line before line with markdown link
PR Close #20411
2017-11-14 10:03:24 -08:00
c69eda8f60 docs(aio): make it clear we are talking about <a> tags (#20410)
As is, it could be seen as a typo at first glance. Wrapping the "a" in carets and backticks for formatting adds some clarity.

PR Close #20410
2017-11-14 10:03:21 -08:00
210ff78f4d docs(aio): fix typo in filename (packages.json --> package.json) (#20377)
PR Close #20377
2017-11-14 10:03:17 -08:00
96766f7336 docs(aio): fix not found schema (#20347)
Fixes #20338

PR Close #20347
2017-11-14 10:03:14 -08:00
52b50c4b6c docs(aio): fix rxjs import (#20350)
closes #20349

PR Close #20350
2017-11-14 10:02:08 -08:00
398690d47c docs: Dependency Injection guides for CLI (#19892)
PR Close #19892
2017-11-14 10:02:05 -08:00
dc01fb167b docs(aio): update template forms to CLI (#20014)
PR Close #20014
2017-11-14 10:02:02 -08:00
7c26c06495 docs(aio): update reactive-forms to CLI (#20019)
PR Close #20019
2017-11-14 10:01:59 -08:00
82dc7fa628 docs(aio): update displaying-data for CLI (#19574)
PR Close #19574
2017-11-14 10:01:56 -08:00
3101e89cf5 docs(aio): update glossary for CLI (#20017)
PR Close #20017
2017-11-14 10:01:53 -08:00
79c3e1b968 docs(aio): update ajs-quick-reference for CLI (#19552)
PR Close #19552
2017-11-14 10:01:49 -08:00
c96967b235 docs(aio): remove trailing underscore from provide_ (#20356)
_provide_ was already emphasized in the previous paragraph

PR Close #20356
2017-11-14 10:01:06 -08:00
422cd0b665 docs(aio): fix missed grave accent (#20379)
PR Close #20379
2017-11-14 10:01:03 -08:00
eea2039bce docs: AttributeDirectives guide for CLI (#19771)
PR Close #19771
2017-11-14 10:01:00 -08:00
612f508dff refactor(animations): uses a loop instead Array.map() which creates and (#19910)
returns a new array that is discarded.

This pattern will become a compilation error in google3.

PR Close #19910
2017-11-10 13:54:20 -08:00
aa3d75ba83 build: update to google-closure-compiler@20171023.0.1 (#20321)
added externs

remove externs

PR Close #20321
2017-11-10 11:53:21 -08:00
4cc6abbbf8 fix(compiler): recognize @NgModule with a redundant @Injectable (#20320)
The compiler now, again, recognizes `@NgModule()` decorators on
classes with a redundant `@Injectable()` decorator.

Fixes: #19544

PR Close #20320
2017-11-10 11:53:17 -08:00
222758bed3 fix(aio): markdown typo in Tour of Heroes tutorial (#20288)
PR Close #20288
2017-11-10 11:53:13 -08:00
516107fd04 docs(common): update default display value for CurrencyPipe (#20246)
PR Close #20246
2017-11-10 11:53:09 -08:00
bd70aece52 refactor(core): remove prolyfill from error message (#20121)
PR Close #20121
2017-11-10 11:53:03 -08:00
2ca6bdd110 docs(aio): typo fix (#20318)
tutorial part 0 app component template file extention fix

PR Close #20318
2017-11-10 11:12:18 -08:00
2aefac841f docs(aio): empty line between HTML tag and content (#20341)
PR Close #20341
2017-11-10 11:09:35 -08:00
ec496c2fda docs(aio): fix typo (#20103)
PR Close #20103
2017-11-10 11:09:27 -08:00
346dbcf24a docs(aio): show correct path for mock-heroes code (#20323)
PR Close #20323
2017-11-10 11:09:23 -08:00
48843a9f47 docs(aio): Fix typo in tutorial (#20295)
PR Close #20295
2017-11-10 11:09:05 -08:00
8f2fb02048 docs(aio): fix toh-pt3 typos (#20307)
PR Close #20307
2017-11-10 11:08:54 -08:00
89e4262188 docs(aio): fix -mm- to -MM- for month in DatePipe (#20315)
PR Close #20315
2017-11-10 11:08:43 -08:00
424a323316 fix(compiler): show explanatory text in template errors (#20313)
Fixes: #20076

PR Close #20313
2017-11-09 15:48:58 -08:00
28985cb2de test(compiler): do not use a as a content selector
As it might trigger false positive in the RegExp from `_makeScopeMatcher`

closes #20256
2017-11-08 15:53:13 -08:00
5d1cd57787 fix(compiler): fix corner cases in shadow CSS
`cmp:host {}` and `cmp:host some-other-selector {}` were not handled
consistently.

Note those should not match anything but are made equivalent to respectively
`:host(cmp)` and `:host(cmp) some-other-selector` to avoid breaking legacy apps.
2017-11-08 15:53:05 -08:00
254 changed files with 4189 additions and 3600 deletions

View File

@ -22,7 +22,6 @@
# petebacondarwin - Pete Bacon Darwin
# pkozlowski-opensource - Pawel Kozlowski
# robwormald - Rob Wormald
# tbosch - Tobias Bosch
# tinayuangao - Tina Gao
# vicb - Victor Berchet
# vikerman - Vikram Subramanian
@ -100,7 +99,6 @@ groups:
users:
- alexeagle
- mhevery
- tbosch
- vicb
- IgorMinar #fallback
@ -109,8 +107,7 @@ groups:
files:
- "packages/core/*"
users:
- tbosch #primary
- chuckjaz
- chuckjaz #primary
- mhevery
- vicb
- IgorMinar #fallback
@ -132,7 +129,7 @@ groups:
- "packages/compiler/src/i18n/*"
users:
- vicb #primary
- tbosch
- chuckjaz
- IgorMinar #fallback
- mhevery #fallback
@ -141,9 +138,8 @@ groups:
files:
- "packages/compiler/*"
users:
- tbosch #primary
- chuckjaz #primary
- vicb
- chuckjaz
- mhevery
- IgorMinar #fallback
@ -163,12 +159,11 @@ groups:
- "packages/compiler-cli/*"
- "packages/bazel/*"
exclude:
- "packages/compiler-cli/src/ngtools*"
- "packages/compiler-cli/src/ngtools*"
users:
- alexeagle
- chuckjaz
- vicb
- tbosch
- IgorMinar #fallback
- mhevery #fallback
@ -212,7 +207,7 @@ groups:
- "packages/language-service/*"
users:
- chuckjaz #primary
- tbosch #secondary
# needs secondary
- vicb
- IgorMinar #fallback
- mhevery #fallback
@ -242,8 +237,8 @@ groups:
files:
- "packages/platform-browser/*"
users:
- tbosch #primary
- vicb #secondary
- vicb #primary
# needs secondary
- IgorMinar #fallback
- mhevery #fallback
@ -253,9 +248,9 @@ groups:
- "packages/platform-server/*"
users:
- vikerman #primary
# needs secondary
- alxhub
- vicb
- tbosch
- IgorMinar #fallback
- mhevery #fallback
@ -265,7 +260,7 @@ groups:
- "packages/platform-webworker/*"
users:
- vicb #primary
- tbosch #secondary
# needs secondary
- IgorMinar #fallback
- mhevery #fallback
@ -284,7 +279,7 @@ groups:
files:
- "packages/benchpress/*"
users:
- tbosch #primary
- alxhub #primary
# needs secondary
- IgorMinar #fallback
- mhevery #fallback

View File

@ -1,3 +1,52 @@
<a name="5.0.4"></a>
## [5.0.4](https://github.com/angular/angular/compare/5.0.3...5.0.4) (2017-12-01)
### Bug Fixes
* **animations:** ensure multi-level enter animations work ([#19455](https://github.com/angular/angular/issues/19455)) ([22bbd6e](https://github.com/angular/angular/commit/22bbd6e))
* **animations:** ensure multi-level leave animations work ([#19455](https://github.com/angular/angular/issues/19455)) ([c7b211c](https://github.com/angular/angular/commit/c7b211c))
* **common:** accept falsy values as HTTP bodies ([#19958](https://github.com/angular/angular/issues/19958)) ([66fd1f8](https://github.com/angular/angular/commit/66fd1f8)), closes [#19825](https://github.com/angular/angular/issues/19825) [#19195](https://github.com/angular/angular/issues/19195)
* **common:** don't strip XSSI prefix for if error isn't JSON ([#19958](https://github.com/angular/angular/issues/19958)) ([ead7596](https://github.com/angular/angular/commit/ead7596))
* **common:** remove useless guard in HttpClient ([#19958](https://github.com/angular/angular/issues/19958)) ([e099911](https://github.com/angular/angular/commit/e099911)), closes [#19223](https://github.com/angular/angular/issues/19223)
* **common:** treat an empty body as null when parsing JSON in HttpClient ([#19958](https://github.com/angular/angular/issues/19958)) ([bdaee50](https://github.com/angular/angular/commit/bdaee50)), closes [#18680](https://github.com/angular/angular/issues/18680) [#19413](https://github.com/angular/angular/issues/19413) [#19502](https://github.com/angular/angular/issues/19502) [#19555](https://github.com/angular/angular/issues/19555)
* **compiler-cli:** fix memory leak in program creation ([#20692](https://github.com/angular/angular/issues/20692)) ([38be44d](https://github.com/angular/angular/commit/38be44d)), closes [#20691](https://github.com/angular/angular/issues/20691)
* **compiler-cli:** normalize sourcepaths for i18n extracted files ([#20417](https://github.com/angular/angular/issues/20417)) ([2b0c896](https://github.com/angular/angular/commit/2b0c896)), closes [#20416](https://github.com/angular/angular/issues/20416)
<a name="5.0.3"></a>
## [5.0.3](https://github.com/angular/angular/compare/5.0.2...5.0.3) (2017-11-22)
### Bug Fixes
* **animations:** always fire inner trigger callbacks even if blocked by parent animations ([#19753](https://github.com/angular/angular/issues/19753)) ([814f062](https://github.com/angular/angular/commit/814f062)), closes [#19100](https://github.com/angular/angular/issues/19100)
* **animations:** validate against trigger() names that use @ symbols ([#20326](https://github.com/angular/angular/issues/20326)) ([15795d0](https://github.com/angular/angular/commit/15795d0))
* **benchpress:** Allow ignoring navigationStart events in perflog metric. ([#20312](https://github.com/angular/angular/issues/20312)) ([9ca6ee9](https://github.com/angular/angular/commit/9ca6ee9))
* **common:** return ISubscription from Location.subscribe() ([#20429](https://github.com/angular/angular/issues/20429)) ([bc904b1](https://github.com/angular/angular/commit/bc904b1)), closes [#20406](https://github.com/angular/angular/issues/20406)
* **compiler:** emit correct type-check-blocks with TemplateRef's ([#20463](https://github.com/angular/angular/issues/20463)) ([81f1d42](https://github.com/angular/angular/commit/81f1d42))
* **compiler:** support event bindings in `fullTemplateTypeCheck` ([#20490](https://github.com/angular/angular/issues/20490)) ([b53ead4](https://github.com/angular/angular/commit/b53ead4))
* **core:** fix [#20532](https://github.com/angular/angular/issues/20532), should be able to cancel listener from mixed zone ([#20538](https://github.com/angular/angular/issues/20538)) ([0feba49](https://github.com/angular/angular/commit/0feba49))
* **core:** should support event.stopImmediatePropagation ([#20469](https://github.com/angular/angular/issues/20469)) ([82aace6](https://github.com/angular/angular/commit/82aace6))
* **forms:** updateOn should check if change occurred ([#20358](https://github.com/angular/angular/issues/20358)) ([f9f2c20](https://github.com/angular/angular/commit/f9f2c20)), closes [#20259](https://github.com/angular/angular/issues/20259)
<a name="5.0.2"></a>
## [5.0.2](https://github.com/angular/angular/compare/5.0.1...5.0.2) (2017-11-16)
### Bug Fixes
* **animations:** ensure final state() styles are applied within @.disabled animations ([#20267](https://github.com/angular/angular/issues/20267)) ([8b1a6b1](https://github.com/angular/angular/commit/8b1a6b1)), closes [#20266](https://github.com/angular/angular/issues/20266)
* **compiler:** fix corner cases in shadow CSS ([5d1cd57](https://github.com/angular/angular/commit/5d1cd57))
* **compiler:** recognize @NgModule with a redundant @Injectable ([#20320](https://github.com/angular/angular/issues/20320)) ([4cc6abb](https://github.com/angular/angular/commit/4cc6abb))
* **compiler:** show explanatory text in template errors ([#20313](https://github.com/angular/angular/issues/20313)) ([424a323](https://github.com/angular/angular/commit/424a323))
* **router:** 'merge' queryParamHandling strategy should be able to remove query params ([#19733](https://github.com/angular/angular/issues/19733)) ([b732fb9](https://github.com/angular/angular/commit/b732fb9)), closes [#18463](https://github.com/angular/angular/issues/18463) [#17202](https://github.com/angular/angular/issues/17202)
<a name="5.0.1"></a>
## [5.0.1](https://github.com/angular/angular/compare/5.0.0...5.0.1) (2017-11-08)

View File

@ -0,0 +1,62 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "angular.io-example"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
// #docregion styles
"styles": [
"styles.css"
],
// #enddocregion styles
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json",
"exclude": "**/node_modules/**"
},
{
"project": "src/tsconfig.spec.json",
"exclude": "**/node_modules/**"
},
{
"project": "e2e/tsconfig.e2e.json",
"exclude": "**/node_modules/**"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"component": {}
}
}

View File

@ -5,9 +5,6 @@
<meta charset="UTF-8">
<title>AngularJS to Angular Quick Reference</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- #docregion style -->
<link rel="stylesheet" href="styles.css">
<!-- #enddocregion style -->
</head>
<body>

View File

@ -4,7 +4,7 @@
"files":[
"!**/*.d.ts",
"!**/*.js",
"!app/*.[1,2,3].*"
"!app/*.[0,1,2,3].*"
],
"tags": ["attribute", "directive"]
}

View File

@ -1,14 +1,14 @@
<!-- #docregion -->
<h1>My First Attribute Directive</h1>
<!-- #docregion applied -->
<p appHightlight>Highlight me!</p>
<p appHighlight>Highlight me!</p>
<!-- #enddocregion applied, -->
<!-- #docregion color-1 -->
<p appHightlight highlightColor="yellow">Highlighted in yellow</p>
<p appHightlight [highlightColor]="'orange'">Highlighted in orange</p>
<p appHighlight highlightColor="yellow">Highlighted in yellow</p>
<p appHighlight [highlightColor]="'orange'">Highlighted in orange</p>
<!-- #enddocregion color-1 -->
<!-- #docregion color-2 -->
<p appHightlight [highlightColor]="color">Highlighted with parent component's color</p>
<p appHighlight [highlightColor]="color">Highlighted with parent component's color</p>
<!-- #enddocregion color-2 -->

View File

@ -0,0 +1,9 @@
// #docregion
import { Directive } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor() { }
}

View File

@ -1,8 +1,10 @@
/* tslint:disable:no-unused-variable */
// #docregion
import { Directive, ElementRef, Input } from '@angular/core';
import { Directive, ElementRef } from '@angular/core';
@Directive({ selector: '[appHighlight]' })
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';

View File

@ -1,7 +1,10 @@
/* tslint:disable:no-unused-variable member-ordering */
// #docplaster
// #docregion imports,
import { Directive, ElementRef, HostListener } from '@angular/core';
// #enddocregion imports,
import { Input } from '@angular/core';
// #docregion
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[appHighlight]'
@ -35,7 +38,7 @@ export class HighlightDirective {
// #enddocregion color
// #docregion color-2
@Input() myHighlight: string;
@Input() appHighlight: string;
// #enddocregion color-2
}

View File

@ -1,6 +1,7 @@
/* tslint:disable:member-ordering */
// #docregion
// #docregion, imports
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
// #enddocregion imports
@Directive({
selector: '[appHighlight]'

View File

@ -1,7 +1,5 @@
/* tslint:disable:member-ordering */
// #docregion imports,
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
// #enddocregion imports
@Directive({
selector: '[appHighlight]'

View File

@ -4,7 +4,8 @@
"files":[
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1,2].*"
"!**/*.[0,1,2].*",
"**/dummy.module.ts"
],
"tags": ["dependency", "di"]
}

View File

@ -0,0 +1,10 @@
/*
Must put this interface in its own file instead of app.config.ts
or else TypeScript gives a (bogus) warning:
WARNING in ./src/app/... .ts
"export 'AppConfig' was not found in './app.config'
*/
export interface AppConfig {
apiEndpoint: string;
title: string;
}

View File

@ -1,7 +1,5 @@
// Early versions
// #docregion
import { Component } from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',

View File

@ -1,7 +1,6 @@
// #docregion
// #docregion imports
import { Component } from '@angular/core';
import { Inject } from '@angular/core';
import { Component, Inject } from '@angular/core';
import { APP_CONFIG, AppConfig } from './app.config';
// #enddocregion imports
@ -23,3 +22,5 @@ export class AppComponent {
}
// #enddocregion ctor
}
// #enddocregion

View File

@ -4,7 +4,6 @@
import { Component, Inject } from '@angular/core';
import { APP_CONFIG, AppConfig } from './app.config';
import { Logger } from './logger.service';
import { UserService } from './user.service';
// #enddocregion imports
@ -23,8 +22,7 @@ import { UserService } from './user.service';
<app-heroes id="authorized" *ngIf="isAuthorized"></app-heroes>
<app-heroes id="unauthorized" *ngIf="!isAuthorized"></app-heroes>
<app-providers></app-providers>
`,
providers: [Logger]
`
})
export class AppComponent {
title: string;

View File

@ -1,15 +1,13 @@
import { AppConfig } from './app-config';
export { AppConfig } from './app-config';
// #docregion token
import { InjectionToken } from '@angular/core';
export let APP_CONFIG = new InjectionToken<AppConfig>('app.config');
export const APP_CONFIG = new InjectionToken<AppConfig>('app.config');
// #enddocregion token
// #docregion config
export interface AppConfig {
apiEndpoint: string;
title: string;
}
export const HERO_DI_CONFIG: AppConfig = {
apiEndpoint: 'api.heroes.com',
title: 'Dependency Injection'

View File

@ -1,32 +1,24 @@
// #docplaster
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { APP_CONFIG, HERO_DI_CONFIG } from './app.config';
import { AppComponent } from './app.component';
import { CarComponent } from './car/car.component';
import { HeroesComponent } from './heroes/heroes.component';
import { HeroListComponent } from './heroes/hero-list.component';
import { InjectorComponent } from './injector.component';
import { Logger } from './logger.service';
import { TestComponent } from './test.component';
import { APP_CONFIG, HERO_DI_CONFIG } from './app.config';
import { UserService } from './user.service';
import {
ProvidersComponent,
Provider1Component,
Provider3Component,
Provider4Component,
Provider5Component,
Provider6aComponent,
Provider6bComponent,
Provider7Component,
Provider8Component,
Provider9Component,
Provider10Component,
} from './providers.component';
import { ProvidersModule } from './providers.module';
// #docregion ngmodule
@NgModule({
imports: [
BrowserModule
BrowserModule,
ProvidersModule
],
declarations: [
AppComponent,
@ -35,26 +27,19 @@ import {
// #enddocregion ngmodule
HeroListComponent,
InjectorComponent,
TestComponent,
ProvidersComponent,
Provider1Component,
Provider3Component,
Provider4Component,
Provider5Component,
Provider6aComponent,
Provider6bComponent,
Provider7Component,
Provider8Component,
Provider9Component,
Provider10Component,
TestComponent
// #docregion ngmodule
],
// #docregion ngmodule-providers
// #docregion providers, providers-2
providers: [
// #enddocregion providers
Logger,
// #docregion providers
UserService,
{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }
],
// #enddocregion ngmodule-providers
// #enddocregion providers, providers-2
exports: [ CarComponent, HeroesComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -0,0 +1,25 @@
/// Dummy modules to satisfy Angular Language Service
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AppModule } from './app.module';
////////
import { AppComponent as AppComponent1 } from './app.component.1';
@NgModule({
imports: [ CommonModule, AppModule ],
declarations: [ AppComponent1 ]
})
export class DummyModule1 {}
/////////
import { AppComponent as AppComponent2 } from './app.component.2';
@NgModule({
imports: [ CommonModule, AppModule ],
declarations: [ AppComponent2 ]
})
export class DummyModule2 {}

View File

@ -0,0 +1,35 @@
/// Dummy modules to satisfy Angular Language Service
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
////////
import { HeroListComponent as HeroListComponent1 } from './hero-list.component.1';
@NgModule({
imports: [ CommonModule ],
declarations: [ HeroListComponent1 ],
exports: [ HeroListComponent1 ]
})
export class DummyModule1 {}
/////////
import { HeroListComponent as HeroListComponent2 } from './hero-list.component.2';
@NgModule({
imports: [ CommonModule ],
declarations: [ HeroListComponent2 ]
})
export class DummyModule2 {}
/////////
import { HeroesComponent as HeroesComponent1 } from './heroes.component.1';
@NgModule({
imports: [ CommonModule, DummyModule1 ],
declarations: [ HeroesComponent1 ]
})
export class DummyModule3 {}

View File

@ -1,16 +1,17 @@
// #docregion
import { Component } from '@angular/core';
import { HEROES } from './mock-heroes';
@Component({
selector: 'app-hero-list',
template: `
<div *ngFor="let hero of heroes">
{{hero.id}} - {{hero.name}}
</div>
<div *ngFor="let hero of heroes">
{{hero.id}} - {{hero.name}}
</div>
`
})
// #docregion class
export class HeroListComponent {
heroes = HEROES;
}
// #enddocregion class

View File

@ -1,7 +1,6 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
import { Hero } from './hero';
// #enddocregion
import { HeroService } from './hero.service.1';
@ -15,9 +14,9 @@ import { HeroService } from './hero.service';
@Component({
selector: 'app-hero-list',
template: `
<div *ngFor="let hero of heroes">
{{hero.id}} - {{hero.name}}
</div>
<div *ngFor="let hero of heroes">
{{hero.id}} - {{hero.name}}
</div>
`
})
export class HeroListComponent {

View File

@ -1,17 +1,16 @@
/* tslint:disable:one-line */
// #docregion
import { Component } from '@angular/core';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@Component({
selector: 'app-hero-list',
template: `
<div *ngFor="let hero of heroes">
{{hero.id}} - {{hero.name}}
({{hero.isSecret ? 'secret' : 'public'}})
</div>
<div *ngFor="let hero of heroes">
{{hero.id}} - {{hero.name}}
({{hero.isSecret ? 'secret' : 'public'}})
</div>
`,
})
export class HeroListComponent {

View File

@ -0,0 +1,6 @@
import { Injectable } from '@angular/core';
@Injectable()
export class HeroService {
constructor() { }
}

View File

@ -1,6 +1,5 @@
// #docregion
import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes';
@Injectable()

View File

@ -1,6 +1,5 @@
// #docregion
import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes';
import { Logger } from '../logger.service';

View File

@ -1,6 +1,5 @@
// #docregion
import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes';
import { Logger } from '../logger.service';

View File

@ -1,21 +1,18 @@
// #docplaster
// #docregion full, v1
import { Component } from '@angular/core';
// #docregion, v1
import { Component } from '@angular/core';
// #enddocregion v1
import { HeroService } from './hero.service';
import { HeroService } from './hero.service';
// #enddocregion full
// #docregion full, v1
// #docregion v1
@Component({
selector: 'app-heroes',
// #enddocregion v1
providers: [HeroService],
providers: [ HeroService ],
// #docregion v1
template: `
<h2>Heroes</h2>
<app-hero-list></app-hero-list>
<h2>Heroes</h2>
<app-hero-list></app-hero-list>
`
})
export class HeroesComponent { }

View File

@ -1,14 +1,13 @@
// #docregion
import { Component } from '@angular/core';
import { heroServiceProvider } from './hero.service.provider';
@Component({
selector: 'app-heroes',
providers: [ heroServiceProvider ],
template: `
<h2>Heroes</h2>
<app-hero-list></app-hero-list>
`,
providers: [heroServiceProvider]
<h2>Heroes</h2>
<app-hero-list></app-hero-list>
`
})
export class HeroesComponent { }

View File

@ -1,19 +1,21 @@
/* tslint:disable:one-line:check-open-brace*/
// Examples of provider arrays
// #docplaster
/*
* A collection of demo components showing different ways to provide services
* in @Component metadata
*/
import { Component, Inject, Injectable, OnInit } from '@angular/core';
import { APP_CONFIG, AppConfig,
HERO_DI_CONFIG } from './app.config';
import {
APP_CONFIG,
AppConfig,
HERO_DI_CONFIG } from './app.config';
import { HeroService } from './heroes/hero.service';
import { heroServiceProvider } from './heroes/hero.service.provider';
import { Logger } from './logger.service';
import { UserService } from './user.service';
import { HeroService } from './heroes/hero.service';
import { heroServiceProvider } from './heroes/hero.service.provider';
import { Logger } from './logger.service';
import { UserService } from './user.service';
let template = '{{log}}';
const template = '{{log}}';
//////////////////////////////////////////
@Component({
selector: 'provider-1',
template: template,
@ -30,6 +32,7 @@ export class Provider1Component {
}
//////////////////////////////////////////
@Component({
selector: 'provider-3',
template: template,
@ -47,7 +50,7 @@ export class Provider3Component {
}
//////////////////////////////////////////
class BetterLogger extends Logger {}
export class BetterLogger extends Logger {}
@Component({
selector: 'provider-4',
@ -66,9 +69,10 @@ export class Provider4Component {
}
//////////////////////////////////////////
// #docregion EvenBetterLogger
@Injectable()
class EvenBetterLogger extends Logger {
export class EvenBetterLogger extends Logger {
constructor(private userService: UserService) { super(); }
log(message: string) {
@ -96,8 +100,10 @@ export class Provider5Component {
}
//////////////////////////////////////////
class NewLogger extends Logger {}
class OldLogger {
export class NewLogger extends Logger {}
export class OldLogger {
logs: string[] = [];
log(message: string) {
throw new Error('Should not call the old logger!');
@ -149,11 +155,14 @@ export class Provider6bComponent {
}
//////////////////////////////////////////
// #docregion silent-logger
// An object in the shape of the logger service
let silentLogger = {
export function SilentLoggerFn() {}
const silentLogger = {
logs: ['Silent logger says "Shhhhh!". Provided via "useValue"'],
log: () => {}
log: SilentLoggerFn
};
// #enddocregion silent-logger
@ -172,6 +181,7 @@ export class Provider7Component {
this.log = logger.logs[0];
}
}
/////////////////
@Component({
@ -189,6 +199,7 @@ export class Provider8Component {
}
/////////////////
@Component({
selector: 'provider-9',
template: template,
@ -218,6 +229,7 @@ export class Provider9Component implements OnInit {
this.log = 'APP_CONFIG Application title is ' + this.config.title;
}
}
//////////////////////////////////////////
// Sample providers 1 to 7 illustrate a required logger dependency.
// Optional logger, can be null
@ -248,6 +260,7 @@ export class Provider10Component implements OnInit {
}
/////////////////
@Component({
selector: 'app-providers',
template: `

View File

@ -0,0 +1,33 @@
import { NgModule } from '@angular/core';
import {
Provider1Component,
Provider3Component,
Provider4Component,
Provider5Component,
Provider6aComponent,
Provider6bComponent,
Provider7Component,
Provider8Component,
Provider9Component,
Provider10Component,
ProvidersComponent,
} from './providers.component';
@NgModule({
declarations: [
Provider1Component,
Provider3Component,
Provider4Component,
Provider5Component,
Provider6aComponent,
Provider6bComponent,
Provider7Component,
Provider8Component,
Provider9Component,
Provider10Component,
ProvidersComponent,
],
exports: [ ProvidersComponent ]
})
export class ProvidersModule {}

View File

@ -2,10 +2,11 @@
// Simulate a simple test
// Reader should look to the testing chapter for the real thing
import { Component } from '@angular/core';
import { Component } from '@angular/core';
import { HeroService } from './heroes/hero.service';
import { HeroListComponent } from './heroes/hero-list.component';
import { Hero } from './heroes/hero';
import { HeroService } from './heroes/hero.service';
import { HeroListComponent } from './heroes/hero-list.component';
@Component({
selector: 'app-tests',
@ -22,12 +23,13 @@ export class TestComponent {
function runTests() {
// #docregion spec
let expectedHeroes = [{name: 'A'}, {name: 'B'}]
let mockService = <HeroService> {getHeroes: () => expectedHeroes }
const expectedHeroes = [{name: 'A'}, {name: 'B'}]
const mockService = <HeroService> {getHeroes: () => expectedHeroes }
it('should have heroes when HeroListComponent created', () => {
let hlc = new HeroListComponent(mockService);
expect(hlc.heroes.length).toEqual(expectedHeroes.length);
// Pass the mock to the constructor as the Angular injector would
const component = new HeroListComponent(mockService);
expect(component.heroes.length).toEqual(expectedHeroes.length);
});
// #enddocregion spec

View File

@ -0,0 +1 @@
<app-hero-form></app-hero-form>

View File

@ -3,6 +3,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: '<app-hero-form></app-hero-form>'
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent { }

View File

@ -4,7 +4,7 @@ import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HeroFormComponent } from './hero-form.component';
import { HeroFormComponent } from './hero-form/hero-form.component';
@NgModule({
imports: [
@ -15,6 +15,7 @@ import { HeroFormComponent } from './hero-form.component';
AppComponent,
HeroFormComponent
],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -2,11 +2,12 @@
// #docregion , v1, final
import { Component } from '@angular/core';
import { Hero } from './hero';
import { Hero } from '../hero';
@Component({
selector: 'app-hero-form',
templateUrl: './hero-form.component.html'
templateUrl: './hero-form.component.html',
styleUrls: ['./hero-form.component.css']
})
export class HeroFormComponent {

View File

@ -0,0 +1 @@
@import url('https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css');

View File

@ -93,22 +93,20 @@ export class AfterContentComponent implements AfterContentChecked, AfterContentI
<h4>-- AfterContent Logs --</h4>
<p><button (click)="reset()">Reset</button></p>
<div *ngFor="let msg of logs">{{msg}}</div>
<div *ngFor="let msg of logger.logs">{{msg}}</div>
</div>
`,
styles: ['.parent {background: burlywood}'],
providers: [LoggerService]
})
export class AfterContentParentComponent {
logs: string[];
show = true;
constructor(private logger: LoggerService) {
this.logs = logger.logs;
constructor(public logger: LoggerService) {
}
reset() {
this.logs.length = 0;
this.logger.clear();
// quickly remove and reload AfterContentComponent which recreates it
this.show = false;
this.logger.tick_then(() => this.show = true);

View File

@ -95,22 +95,20 @@ export class AfterViewComponent implements AfterViewChecked, AfterViewInit {
<h4>-- AfterView Logs --</h4>
<p><button (click)="reset()">Reset</button></p>
<div *ngFor="let msg of logs">{{msg}}</div>
<div *ngFor="let msg of logger.logs">{{msg}}</div>
</div>
`,
styles: ['.parent {background: burlywood}'],
providers: [LoggerService]
})
export class AfterViewParentComponent {
logs: string[];
show = true;
constructor(private logger: LoggerService) {
this.logs = logger.logs;
constructor(public logger: LoggerService) {
}
reset() {
this.logs.length = 0;
this.logger.clear();
// quickly remove and reload AfterViewComponent which recreates it
this.show = false;
this.logger.tick_then(() => this.show = true);

View File

@ -27,7 +27,7 @@ export class MyCounterComponent implements OnChanges {
// Empty the changeLog whenever counter goes to zero
// hint: this is a way to respond programmatically to external value changes.
if (this.counter === 0) {
this.changeLog.length = 0;
this.changeLog = [];
}
// A change to `counter` is the only change we care about

View File

@ -68,7 +68,7 @@ export class DoCheckComponent implements DoCheck {
reset() {
this.changeDetected = true;
this.changeLog.length = 0;
this.changeLog = [];
}
}

View File

@ -18,7 +18,7 @@ export class LoggerService {
}
}
clear() { this.logs.length = 0; }
clear() { this.logs = []; }
// schedules a view refresh to ensure display catches up
tick() { this.tick_then(() => { }); }

View File

@ -43,7 +43,7 @@ export class OnChangesComponent implements OnChanges {
}
// #enddocregion ng-on-changes
reset() { this.changeLog.length = 0; }
reset() { this.changeLog = []; }
}
/***************************************/

View File

@ -12,5 +12,5 @@
</div>
<!-- #enddocregion template -->
<h4>-- Spy Lifecycle Hook Log --</h4>
<div *ngFor="let msg of spyLog">{{msg}}</div>
<div *ngFor="let msg of logger.logs">{{msg}}</div>
</div>

View File

@ -15,10 +15,8 @@ import { LoggerService } from './logger.service';
export class SpyParentComponent {
newName = 'Herbie';
heroes: string[] = ['Windstorm', 'Magneta'];
spyLog: string[];
constructor(private logger: LoggerService) {
this.spyLog = logger.logs;
constructor(public logger: LoggerService) {
}
addHero() {
@ -34,7 +32,7 @@ export class SpyParentComponent {
}
reset() {
this.logger.log('-- reset --');
this.heroes.length = 0;
this.heroes = [];
this.logger.tick();
}
}

View File

@ -14,7 +14,7 @@
"app/contact/contact.component.html",
"app/contact/contact.component.3.ts",
"app/contact/contact.service.ts",
"app/contact/highlight.directive.ts",
"app/contact/contact-highlight.directive.ts",
"main.1b.ts",
"styles.css",

View File

@ -16,7 +16,7 @@
"app/contact/awesome.pipe.ts",
"app/contact/contact.component.3.ts",
"app/contact/contact.module.2.ts",
"app/contact/highlight.directive.ts",
"app/contact/contact-highlight.directive.ts",
"main.2.ts",
"styles.css",

View File

@ -15,7 +15,7 @@ describe('NgModule', function () {
return {
title: element.all(by.tagName('h1')).get(0),
subtitle: element.all(by.css('app-title p i')).get(0),
welcome: element.all(by.css('app-title p i')).get(0),
contactButton: buttons.get(0),
crisisButton: buttons.get(1),
heroesButton: buttons.get(2)
@ -67,7 +67,7 @@ describe('NgModule', function () {
it('should welcome us', function () {
const commons = getCommonsSectionStruct();
expect(commons.subtitle.getText()).toBe('Welcome, ' + (name || 'Sherlock Holmes'));
expect(commons.welcome.getText()).toBe('Welcome, ' + (name || 'Sherlock Holmes'));
});
};
}

View File

@ -19,7 +19,7 @@
"app/contact/contact.component.3.ts",
"app/contact/contact.module.3.ts",
"app/contact/contact-routing.module.3.ts",
"app/contact/highlight.directive.ts",
"app/contact/contact-highlight.directive.ts",
"app/crisis/*.ts",

View File

@ -1,14 +1,19 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [
import { ContactModule } from './contact/contact.module.3';
const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
{ path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
{ path: 'heroes', loadChildren: 'app/hero/hero.module.3#HeroModule' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
imports: [
ContactModule,
RouterModule.forRoot(routes)
],
exports: [RouterModule]
})
export class AppRoutingModule {}

View File

@ -2,18 +2,29 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [
import { ContactModule } from './contact/contact.module';
// #docregion routes
const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
// #docregion lazy-routes
// #docregion lazy-routes
{ path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
{ path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule' }
// #enddocregion lazy-routes
// #enddocregion lazy-routes
];
// #enddocregion routes
// #docregion forRoot
@NgModule({
imports: [RouterModule.forRoot(routes)],
// #docregion imports
imports: [
ContactModule,
// #docregion forRoot
RouterModule.forRoot(routes),
// #enddocregion forRoot
],
// #enddocregion imports
// #docregion exports
exports: [RouterModule]
// #enddocregion exports
})
export class AppRoutingModule {}
// #enddocregion forRoot

View File

@ -6,5 +6,5 @@ import { Component } from '@angular/core';
template: '<h1>{{title}}</h1>',
})
export class AppComponent {
title = 'Minimal NgModule';
title = 'Angular Modules';
}

View File

@ -11,9 +11,7 @@ import { Component } from '@angular/core';
// #enddocregion template
*/
// #docregion
template: '<app-title [subtitle]="subtitle"></app-title>'
template: '<app-title></app-title>'
})
export class AppComponent {
subtitle = '(v1)';
}
export class AppComponent {}
// #enddocregion

View File

@ -5,11 +5,9 @@ import { Component } from '@angular/core';
selector: 'app-root',
// #docregion template
template: `
<app-title [subtitle]="subtitle"></app-title>
<app-title></app-title>
<app-contact></app-contact>
`
// #enddocregion template
})
export class AppComponent {
subtitle = '(v1)';
}
export class AppComponent {}

View File

@ -3,10 +3,8 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-title [subtitle]="subtitle"></app-title>
<app-title></app-title>
<app-contact></app-contact>
`
})
export class AppComponent {
subtitle = '(v2)';
}
export class AppComponent {}

View File

@ -4,7 +4,7 @@ import { Component } from '@angular/core';
selector: 'app-root',
// #docregion template
template: `
<app-title [subtitle]="subtitle"></app-title>
<app-title></app-title>
<nav>
<a routerLink="contact" routerLinkActive="active">Contact</a>
<a routerLink="crisis" routerLinkActive="active">Crisis Center</a>
@ -14,6 +14,4 @@ import { Component } from '@angular/core';
`
// #enddocregion template
})
export class AppComponent {
subtitle = '(v3)';
}
export class AppComponent {}

View File

@ -5,7 +5,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-title [subtitle]="subtitle"></app-title>
<app-title></app-title>
<nav>
<a routerLink="contact" routerLinkActive="active">Contact</a>
<a routerLink="crisis" routerLinkActive="active">Crisis Center</a>
@ -14,6 +14,4 @@ import { Component } from '@angular/core';
<router-outlet></router-outlet>
`
})
export class AppComponent {
subtitle = '(Final)';
}
export class AppComponent {}

View File

@ -1,17 +1,7 @@
// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import
// #enddocregion
{ AppComponent } from './app.component.0';
/*
// #docregion
{ AppComponent } from './app.component';
// #enddocregion
*/
// #docregion
import { AppComponent } from './app.component.0';
@NgModule({
// #docregion imports

View File

@ -1,14 +1,15 @@
// #docplaster
// #docregion
/* Angular Imports */
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import
/* App Imports */
// #enddocregion
{ AppComponent } from './app.component.1';
import { AppComponent } from './app.component.1';
/*
// #docregion
{ AppComponent } from './app.component';
import { AppComponent } from './app.component';
// #enddocregion
*/
// #docregion
@ -21,12 +22,9 @@ import { FormsModule } from '@angular/forms';
import { AwesomePipe } from './contact/awesome.pipe';
import { ContactComponent } from './contact/contact.component.3';
// #docregion import-contact-directive
import {
HighlightDirective as ContactHighlightDirective
} from './contact/highlight.directive';
// #enddocregion import-contact-directive
ContactHighlightDirective as ContactHighlightDirective
} from './contact/contact-highlight.directive';
@NgModule({
// #docregion imports

View File

@ -1,15 +1,16 @@
// #docplaster
// #docregion
/* Angular Imports */
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
/* App Root */
import
/* App Imports */
// #enddocregion
{ AppComponent } from './app.component.1b';
import { AppComponent } from './app.component.1b';
/*
// #docregion
{ AppComponent } from './app.component';
import { AppComponent } from './app.component';
// #enddocregion
*/
// #docregion
@ -18,25 +19,17 @@ import { TitleComponent } from './title.component';
import { UserService } from './user.service';
/* Contact Imports */
import
// #enddocregion
{ ContactComponent } from './contact/contact.component.3';
import { ContactComponent } from './contact/contact.component.3';
/*
// #docregion
{ ContactComponent } from './contact/contact.component';
import { ContactComponent } from './contact/contact.component';
// #enddocregion
*/
// #docregion
import { ContactService } from './contact/contact.service';
import { AwesomePipe } from './contact/awesome.pipe';
// #docregion import-alias
import {
HighlightDirective as ContactHighlightDirective
} from './contact/highlight.directive';
// #enddocregion import-alias
import { FormsModule } from '@angular/forms';
import { AwesomePipe } from './contact/awesome.pipe';
import { ContactService } from './contact/contact.service';
import { ContactHighlightDirective } from './contact/contact-highlight.directive';
@NgModule({
imports: [ BrowserModule, FormsModule ],

View File

@ -1,15 +1,15 @@
// #docplaster
// #docregion
/* Angular Imports */
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
/* App Root */
import
/* App Imports */
// #enddocregion
{ AppComponent } from './app.component.2';
import { AppComponent } from './app.component.2';
/*
// #docregion
{ AppComponent } from './app.component';
import { AppComponent } from './app.component';
// #enddocregion
*/
// #docregion
@ -18,12 +18,11 @@ import { TitleComponent } from './title.component';
import { UserService } from './user.service';
/* Contact Imports */
import
// #enddocregion
{ ContactModule } from './contact/contact.module.2';
import { ContactModule } from './contact/contact.module.2';
/*
// #docregion
{ ContactModule } from './contact/contact.module';
import { ContactModule } from './contact/contact.module';
// #enddocregion
*/
// #docregion

View File

@ -1,25 +1,36 @@
// #docplaster
// #docregion
/* Angular Imports */
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
/* App Root */
/* App Imports */
// #enddocregion
import { AppComponent } from './app.component.3';
/*
// #docregion
import { AppComponent } from './app.component';
// #enddocregion
*/
// #docregion
import { HighlightDirective } from './highlight.directive';
import { TitleComponent } from './title.component';
import { UserService } from './user.service';
/* Feature Modules */
import { ContactModule } from './contact/contact.module.3';
/* Routing Module */
// #enddocregion
import { AppRoutingModule } from './app-routing.module.3';
/*
// #docregion
import { AppRoutingModule } from './app-routing.module';
// #enddocregion
*/
// #docregion
@NgModule({
// #docregion imports
imports: [
BrowserModule,
ContactModule,
AppRoutingModule
],
// #enddocregion imports

View File

@ -1,14 +1,14 @@
// #docplaster
// #docregion
// #docregion v4
/* Angular Imports */
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
/* App Root */
/* App Imports */
import { AppComponent } from './app.component';
/* Feature Modules */
import { ContactModule } from './contact/contact.module';
/* Core Modules */
import { CoreModule } from './core/core.module';
/* Routing Module */
@ -18,7 +18,6 @@ import { AppRoutingModule } from './app-routing.module';
// #docregion import-for-root
imports: [
BrowserModule,
ContactModule,
// #enddocregion v4
// #enddocregion import-for-root
/*

View File

@ -1,4 +1,4 @@
/* tslint:disable */
// #docplaster
// Same directive name and selector as
// HighlightDirective in parent AppModule
// It selects for both input boxes and 'highlight' attr
@ -7,12 +7,14 @@
// #docregion
import { Directive, ElementRef } from '@angular/core';
// Highlight the host element or any InputElement in blue
@Directive({ selector: '[highlight], input' })
/** Highlight the attached element or an InputElement in blue */
export class HighlightDirective {
export class ContactHighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'powderblue';
console.log(
`* Contact highlight called for ${el.nativeElement.tagName}`);
// #enddocregion
console.log(`* Contact highlight called for ${el.nativeElement.tagName}`);
// #docregion
}
}
// #enddocregion

View File

@ -3,10 +3,12 @@ import { RouterModule } from '@angular/router';
import { ContactComponent } from './contact.component.3';
const routes = [
{ path: 'contact', component: ContactComponent}
];
@NgModule({
imports: [RouterModule.forChild([
{ path: 'contact', component: ContactComponent}
])],
exports: [RouterModule]
imports: [ RouterModule.forChild(routes) ],
exports: [ RouterModule ]
})
export class ContactRoutingModule {}

View File

@ -4,11 +4,13 @@ import { RouterModule } from '@angular/router';
import { ContactComponent } from './contact.component';
// #docregion routing
const routes = [
{ path: 'contact', component: ContactComponent}
];
@NgModule({
imports: [RouterModule.forChild([
{ path: 'contact', component: ContactComponent }
])],
exports: [RouterModule]
imports: [ RouterModule.forChild(routes) ],
exports: [ RouterModule ]
})
export class ContactRoutingModule {}
// #enddocregion

View File

@ -21,7 +21,7 @@ export class ContactComponent implements OnInit {
}
ngOnInit() {
this.contactService.getContacts().then(contacts => {
this.contactService.getContacts().subscribe(contacts => {
this.msg = '';
this.contacts = contacts;
this.contact = contacts[0];

View File

@ -27,3 +27,6 @@
margin-bottom: 20px;
}
.button-group {
padding-top: 12px;
}

View File

@ -6,18 +6,32 @@
<!-- #docregion awesome -->
<h3 highlight>{{ contact.name | awesome }}</h3>
<!-- #enddocregion awesome -->
<div class="form-group">
<label for="name">Name</label>
<!-- #docregion ngModel -->
<input type="text" class="form-control" required
[(ngModel)]="contact.name"
name="name" #name="ngModel" >
name="name" #name="ngModel" >
<!-- #enddocregion ngModel -->
<div [hidden]="name.valid" class="alert alert-danger">
Name is required
</div>
</div>
<br>
<button type="submit" class="btn btn-default" [disabled]="!contactForm.form.valid">Save</button>
<button type="button" class="btn" (click)="next()" [disabled]="!contactForm.form.valid">Next Contact</button>
<button type="button" class="btn" (click)="newContact()">New Contact</button>
<div class="button-group">
<button type="submit" class="btn btn-default"
[disabled]="!contactForm.form.valid">
Save</button>
<button type="button" class="btn" (click)="next()"
[disabled]="!contactForm.form.valid">
Next Contact</button>
<button type="button" class="btn" (click)="newContact()">
New Contact</button>
</div>
</form>
<!-- #enddocregion -->

View File

@ -22,7 +22,7 @@ export class ContactComponent implements OnInit {
}
ngOnInit() {
this.contactService.getContacts().then(contacts => {
this.contactService.getContacts().subscribe(contacts => {
this.msg = '';
this.contacts = contacts;
this.contact = contacts[0];

View File

@ -0,0 +1,11 @@
// #docregion
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [
CommonModule
],
declarations: []
})
export class ContactModule { }

View File

@ -5,25 +5,32 @@ import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AwesomePipe } from './awesome.pipe';
import
// #enddocregion
{ ContactComponent } from './contact.component.3';
import { ContactComponent } from './contact.component.3';
/*
// #docregion
{ ContactComponent } from './contact.component';
import { ContactComponent } from './contact.component';
// #enddocregion
*/
// #docregion
import { ContactHighlightDirective } from './contact-highlight.directive';
import { ContactService } from './contact.service';
import { HighlightDirective } from './highlight.directive';
// #docregion class
@NgModule({
imports: [ CommonModule, FormsModule ],
declarations: [ ContactComponent, HighlightDirective, AwesomePipe ],
exports: [ ContactComponent ],
providers: [ ContactService ]
imports: [
CommonModule,
FormsModule
],
declarations: [
AwesomePipe,
ContactComponent,
ContactHighlightDirective
],
// #docregion exports
exports: [ ContactComponent ],
// #enddocregion exports
providers: [ ContactService ]
})
export class ContactModule { }
// #enddocregion class

View File

@ -1,21 +1,43 @@
// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AwesomePipe } from './awesome.pipe';
// #enddocregion
import { ContactComponent } from './contact.component.3';
/*
// #docregion
import { ContactComponent } from './contact.component';
// #enddocregion
*/
// #docregion
import { ContactHighlightDirective } from './contact-highlight.directive';
import { ContactService } from './contact.service';
import { HighlightDirective } from './highlight.directive';
// #enddocregion
import { ContactRoutingModule } from './contact-routing.module.3';
/*
// #docregion
import { ContactRoutingModule } from './contact-routing.module';
// #enddocregion
*/
// #docregion
// #docregion class
@NgModule({
imports: [ CommonModule, FormsModule, ContactRoutingModule ],
declarations: [ ContactComponent, HighlightDirective, AwesomePipe ],
providers: [ ContactService ]
imports: [
CommonModule,
FormsModule,
ContactRoutingModule
],
declarations: [
AwesomePipe,
ContactComponent,
ContactHighlightDirective
],
providers: [ ContactService ]
})
export class ContactModule { }
// #enddocregion class

View File

@ -8,7 +8,10 @@ import { ContactRoutingModule } from './contact-routing.module';
// #docregion class
@NgModule({
imports: [ SharedModule, ContactRoutingModule ],
imports: [
SharedModule,
ContactRoutingModule
],
declarations: [ ContactComponent ],
providers: [ ContactService ]
})

View File

@ -1,5 +1,10 @@
// #docplaster
// #docregion
import { Injectable } from '@angular/core';
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { delay } from 'rxjs/operators';
export class Contact {
constructor(public id: number, public name: string) { }
@ -13,17 +18,21 @@ const CONTACTS: Contact[] = [
const FETCH_LATENCY = 500;
/** Simulate a data service that retrieves contacts from a server */
@Injectable()
export class ContactService {
export class ContactService implements OnDestroy {
// #enddocregion
constructor() { console.log('ContactService instance created.'); }
ngOnDestroy() { console.log('ContactService instance destroyed.'); }
getContacts() {
return new Promise<Contact[]>(resolve => {
setTimeout(() => { resolve(CONTACTS); }, FETCH_LATENCY);
});
// #docregion
getContacts(): Observable<Contact[]> {
return of(CONTACTS).pipe(delay(FETCH_LATENCY));
}
getContact(id: number | string) {
return this.getContacts()
.then(heroes => heroes.find(hero => hero.id === +id));
getContact(id: number | string): Observable<Contact> {
return of(CONTACTS.find(contact => contact.id === +id))
.pipe(delay(FETCH_LATENCY));
}
}
// #enddocregion

View File

@ -1,5 +1,5 @@
<!-- Exact copy from earlier app.component.html -->
<h1 highlight>{{title}} {{subtitle}}</h1>
<h1 highlight>{{title}}</h1>
<p *ngIf="user">
<i>Welcome, {{user}}</i>
<p>

View File

@ -7,7 +7,6 @@ import { UserService } from '../core/user.service';
templateUrl: './title.component.html',
})
export class TitleComponent {
@Input() subtitle = '';
title = 'Angular Modules';
user = '';

View File

@ -1,22 +1,21 @@
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Crisis,
CrisisService } from './crisis.service';
CrisisService } from './crisis.service';
@Component({
template: `
<h3 highlight>Crisis List</h3>
<div *ngFor='let crisis of crisises | async'>
<div *ngFor='let crisis of crises | async'>
<a routerLink="{{'../' + crisis.id}}">{{crisis.id}} - {{crisis.name}}</a>
</div>
`
})
export class CrisisListComponent implements OnInit {
crisises: Promise<Crisis[]>;
export class CrisisListComponent {
crises: Observable<Crisis[]>;
constructor(private crisisService: CrisisService) { }
ngOnInit() {
this.crisises = this.crisisService.getCrises();
constructor(private crisisService: CrisisService) {
this.crises = this.crisisService.getCrises();
}
}

View File

@ -1,4 +1,8 @@
import { Injectable } from '@angular/core';
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { delay } from 'rxjs/operators';
export class Crisis {
constructor(public id: number, public name: string) { }
@ -13,18 +17,18 @@ const CRISES: Crisis[] = [
const FETCH_LATENCY = 500;
/** Simulate a data service that retrieves crises from a server */
@Injectable()
export class CrisisService {
export class CrisisService implements OnDestroy {
constructor() { console.log('CrisisService instance created.'); }
ngOnDestroy() { console.log('CrisisService instance destroyed.'); }
getCrises() {
return new Promise<Crisis[]>(resolve => {
setTimeout(() => { resolve(CRISES); }, FETCH_LATENCY);
});
getCrises(): Observable<Crisis[]> {
return of(CRISES).pipe(delay(FETCH_LATENCY));
}
getCrisis(id: number | string) {
return this.getCrises()
.then(heroes => heroes.find(hero => hero.id === +id));
getCrisis(id: number | string): Observable<Crisis> {
return of(CRISES.find(crisis => crisis.id === +id))
.pipe(delay(FETCH_LATENCY));
}
}

View File

@ -26,6 +26,6 @@ export class HeroDetailComponent implements OnInit {
ngOnInit() {
let id = parseInt(this.route.snapshot.paramMap.get('id'), 10);
this.heroService.getHero(id).then(hero => this.hero = hero);
this.heroService.getHero(id).subscribe(hero => this.hero = hero);
}
}

View File

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Hero,
HeroService } from './hero.service';
@ -11,11 +12,9 @@ import { Hero,
</div>
`
})
export class HeroListComponent implements OnInit {
heroes: Promise<Hero[]>;
constructor(private heroService: HeroService) { }
ngOnInit() {
export class HeroListComponent {
heroes: Observable<Hero[]>;
constructor(private heroService: HeroService) {
this.heroes = this.heroService.getHeroes();
}
}

View File

@ -5,9 +5,10 @@ import { FormsModule } from '@angular/forms';
import { HeroComponent } from './hero.component.3';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroListComponent } from './hero-list.component';
import { HighlightDirective } from './highlight.directive';
import { HeroRoutingModule } from './hero-routing.module.3';
import { HighlightDirective } from './highlight.directive';
// #docregion class
@NgModule({
imports: [ CommonModule, FormsModule, HeroRoutingModule ],

View File

@ -1,4 +1,8 @@
import { Injectable } from '@angular/core';
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { delay } from 'rxjs/operators';
export class Hero {
constructor(public id: number, public name: string) { }
@ -15,18 +19,19 @@ const HEROES: Hero[] = [
const FETCH_LATENCY = 500;
/** Simulate a data service that retrieves heroes from a server */
@Injectable()
export class HeroService {
export class HeroService implements OnDestroy {
getHeroes() {
return new Promise<Hero[]>(resolve => {
setTimeout(() => { resolve(HEROES); }, FETCH_LATENCY);
});
constructor() { console.log('HeroService instance created.'); }
ngOnDestroy() { console.log('HeroService instance destroyed.'); }
getHeroes(): Observable<Hero[]> {
return of(HEROES).pipe(delay(FETCH_LATENCY));
}
getHero(id: number | string) {
return this.getHeroes()
.then(heroes => heroes.find(hero => hero.id === +id));
getHero(id: number | string): Observable<Hero> {
return of(HEROES.find(hero => hero.id === +id))
.pipe(delay(FETCH_LATENCY));
}
}

View File

@ -1,12 +1,15 @@
// #docplaster
// #docregion
import { Directive, ElementRef } from '@angular/core';
// Highlight the host element in gold
@Directive({ selector: '[highlight]' })
/** Highlight the attached element in gold */
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'gold';
console.log(
`* AppRoot highlight called for ${el.nativeElement.tagName}`);
// #enddocregion
console.log(`* AppRoot highlight called for ${el.nativeElement.tagName}`);
// #docregion
}
}
// #enddocregion

View File

@ -1,9 +1,8 @@
/* tslint:disable */
// Exact copy of contact/highlight.directive except for color and message
import { Directive, ElementRef } from '@angular/core';
@Directive({ selector: '[highlight], input' })
/** Highlight the attached element or an InputElement in gray */
// Highlight the host element or any InputElement in gray
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'lightgray';

View File

@ -1,6 +1,6 @@
<!-- #docregion -->
<!-- #docregion v1 -->
<h1 highlight>{{title}} {{subtitle}}</h1>
<h1 highlight>{{title}}</h1>
<!-- #enddocregion v1 -->
<!-- #docregion ngIf -->
<p *ngIf="user">

View File

@ -1,18 +1,17 @@
// #docplaster
// #docregion
// #docregion v1
import { Component, Input } from '@angular/core';
import { Component } from '@angular/core';
// #enddocregion v1
import { UserService } from './user.service';
// #docregion v1
@Component({
selector: 'app-title',
templateUrl: './title.component.html',
templateUrl: './title.component.html'
})
export class TitleComponent {
@Input() subtitle = '';
title = 'NgModules';
title = 'Angular Modules';
// #enddocregion v1
user = '';

View File

@ -0,0 +1,3 @@
[1030/162525.401:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022)
[1030/162525.402:ERROR:exception_snapshot_win.cc(87)] thread ID 26896 not found in process
[1030/162525.402:WARNING:crash_report_exception_handler.cc(62)] ProcessSnapshotWin::Initialize failed

View File

@ -0,0 +1,4 @@
<div class="container">
<h1>Reactive Forms</h1>
<app-hero-detail></app-hero-detail>
</div>

View File

@ -1,12 +0,0 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div class="container">
<h1>Reactive Forms</h1>
<app-hero-detail></app-hero-detail>
</div>`
})
export class AppComponent { }

View File

@ -0,0 +1,4 @@
<div class="container">
<h1>Reactive Forms</h1>
<app-hero-list></app-hero-list>
</div>

View File

@ -3,10 +3,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div class="container">
<h1>Reactive Forms</h1>
<app-hero-list></app-hero-list>
</div>`
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent { }

View File

@ -6,9 +6,9 @@ import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms'; // <-- #1 import module
import { AppComponent } from './app.component';
import { HeroDetailComponent } from './hero-detail.component'; // <-- #1 import component
import { HeroDetailComponent } from './hero-detail/hero-detail.component'; // <-- #1 import component
// #enddocregion v1
import { HeroListComponent } from './hero-list.component';
import { HeroListComponent } from './hero-list/hero-list.component';
import { HeroService } from './hero.service'; // <-- #1 import service
// #docregion v1
@ -20,7 +20,7 @@ import { HeroService } from './hero.service'; // <-- #1 import service
],
declarations: [
AppComponent,
HeroDetailComponent, // <-- #3 declare app component
HeroDetailComponent,
// #enddocregion v1
HeroListComponent
// #docregion v1

View File

@ -4,14 +4,14 @@ import { ReactiveFormsModule } from '@angular/forms';
import { AppModule } from './app.module';
import { DemoComponent } from './demo.component';
import { HeroDetailComponent1 } from './hero-detail-1.component';
import { HeroDetailComponent2 } from './hero-detail-2.component';
import { HeroDetailComponent3 } from './hero-detail-3.component';
import { HeroDetailComponent4 } from './hero-detail-4.component';
import { HeroDetailComponent5 } from './hero-detail-5.component';
import { HeroDetailComponent6 } from './hero-detail-6.component';
import { HeroDetailComponent7 } from './hero-detail-7.component';
import { HeroDetailComponent8 } from './hero-detail-8.component';
import { HeroDetailComponent1 } from './hero-detail/hero-detail-1.component';
import { HeroDetailComponent2 } from './hero-detail/hero-detail-2.component';
import { HeroDetailComponent3 } from './hero-detail/hero-detail-3.component';
import { HeroDetailComponent4 } from './hero-detail/hero-detail-4.component';
import { HeroDetailComponent5 } from './hero-detail/hero-detail-5.component';
import { HeroDetailComponent6 } from './hero-detail/hero-detail-6.component';
import { HeroDetailComponent7 } from './hero-detail/hero-detail-7.component';
import { HeroDetailComponent8 } from './hero-detail/hero-detail-8.component';
@NgModule({
imports: [

View File

@ -1,8 +1,9 @@
/* tslint:disable:component-class-suffix */
// #docregion imports
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
// #enddocregion
import { Component } from '@angular/core';
// #docregion import
import { FormControl } from '@angular/forms';
// #enddocregion import
@Component({
selector: 'app-hero-detail-1',

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