Compare commits

..

218 Commits
6.0.3 ... 6.0.9

Author SHA1 Message Date
9e45589085 release: cut the v6.0.9 release 2018-07-11 14:34:14 -07:00
3c93d07124 fix(common): format fractional seconds (#24844)
fix a bug introduced in #24831

PR Close #24844
2018-07-11 14:32:33 -07:00
024aba075c release: cut the v6.0.8 release 2018-07-11 13:43:59 -07:00
a86d038875 docs(forms): update API reference for form validators (#24734)
PR Close #24734
2018-07-10 18:52:40 -07:00
bc8a93e842 docs(forms): added missing backtick (#24451)
Fixed trivial markdown problem with a missing backtick.

PR Close #24451
2018-07-10 18:51:09 -07:00
4c18f637ae docs: unified string chaining (#22735)
PR Close #22735
2018-07-10 18:50:45 -07:00
fc189b2577 docs(aio): unified string chaining (#22735)
PR Close #22735
2018-07-10 18:50:45 -07:00
778ddb257a docs: fix incorrect forms selector references (#22631)
PR Close #22631
2018-07-10 18:50:18 -07:00
2d4f4b5d12 fix(router): add ability to recover from malformed url (#23283)
Fixes #21468

PR Close #23283
2018-07-10 18:48:53 -07:00
912742f1ca docs: fix typos referencing inline component styles (#22557)
PR Close #22557
2018-07-10 18:48:30 -07:00
0746485136 fix(common): do not round factional seconds (#24831)
fixes #24384

PR Close #24831
2018-07-10 18:48:06 -07:00
265489518e build: update to latest nodejs bazel rules (#24817)
PR Close #24817
2018-07-10 18:47:40 -07:00
00dd566b47 docs: correct project definition (#24807)
PR Close #24807
2018-07-10 18:47:20 -07:00
59fd91d785 Revert "build: make internal-angular karma reporter compatible with latest karma (#24803)" (#24809)
This reverts commit 98c509fecb.
Part of reverting PR #24803 on branch `6.0.x`, because that PR is a
follow-up to PR #19904, which was only merged into master.

PR Close #24809
2018-07-10 15:00:42 -07:00
56712aa771 Revert "build: remove unnecessary internal-angular karma reporter (#24803)" (#24809)
This reverts commit d7c4898081.
Part of reverting PR #24803 on branch `6.0.x`, because that PR is a
follow-up to PR #19904, which was only merged into master.

PR Close #24809
2018-07-10 15:00:42 -07:00
529e4b1565 docs: fix typo in Universal guide (#24812)
PR Close #24812
2018-07-10 11:12:45 -07:00
9ff4617956 docs: add tree-shakable providers (#24481)
PR Close #24481
2018-07-10 11:12:08 -07:00
8887d75723 docs: clarify wording in architecture overview (#24481)
Closes #23463
Closes #22158

PR Close #24481
2018-07-10 11:12:08 -07:00
7717ff187a fix(compiler-cli): Use typescript to resolve modules for metadata (#22856)
The current module resolution simply attaches .ts to the import/export path, which does
not work if the path is using Node / CommonJS behavior to resolve to an index.ts file.
This patch uses typescript's module resolution logic, and will attempt to load the original
typescript file if this resolution returns a .js or .d.ts file

PR Close #22856
2018-07-10 11:11:48 -07:00
98b18cd49f docs: unified console.log single string style (#22737)
PR Close #22737
2018-07-10 11:11:30 -07:00
fe23a6e77e docs(aio): unified console.log single string style (#22737)
PR Close #22737
2018-07-10 11:11:30 -07:00
d7c4898081 build: remove unnecessary internal-angular karma reporter (#24803)
The reporter was added in 87d56acda, with the purpose of fixing
source-map paths (which was apparently needed back then). Things have
moved around a lot since then and the custom reporter doesn't seem to be
necessary any more. By removing the reporter, we have one less thing to
worry about while upgrading karma; plus we get improvements in built-in
reporters for free.

Output with the custom reporter:
```
at someMethod (packages/core/.../some-file.ts:13:37)
```

Output with the built-in reporter:
```
at someMethod (packages/core/.../some-file.ts:13.37 <- dist/all/@angular/core/.../some-file.js:1:337)
```

PR Close #24803
2018-07-09 15:14:02 -07:00
98c509fecb build: make internal-angular karma reporter compatible with latest karma (#24803)
Due to changes in karma@1.0.0, `internal-angular` karma reporter stopped
showing browser logs (such as `console.log()` etc.).
Related to d571a5173.

PR Close #24803
2018-07-09 15:10:49 -07:00
a92f111b66 fix(common): use correct currency format for locale de-AT (#24658)
Fixes #24609
PR Close #24658
2018-07-09 15:10:07 -07:00
de1c44f6e3 fix(language-service): do not overwrite native Reflect (#24299)
Fixes #21420

PR Close #24299
2018-07-09 15:09:17 -07:00
183b079175 fix(service-worker): avoid network requests when looking up hashed resources in cache (#24127)
PR Close #24127
2018-07-06 13:50:38 -07:00
8f8caa13b7 refactor(service-worker): avoid unnecessary operations and remove unused code (#24127)
PR Close #24127
2018-07-06 13:50:38 -07:00
195dc0748b docs: update Angular Boot Camp description (#23653)
PR Close #23653
2018-07-06 13:49:57 -07:00
2c6f84b25d docs: refactored ng-container code (#22742)
PR Close #22742
2018-07-06 13:49:35 -07:00
8e726f7d7b build(bazel): update to rule_nodejs 0.10.0 (#24759)
PR Close #24759
2018-07-06 10:18:21 -07:00
2d1102f5bf docs: add workspace and related cli terms (#24633)
PR Close #24633
2018-07-06 10:13:40 -07:00
0437598609 docs(common): fix in the documentation of PUT (#24528)
PR Close #24528
2018-07-06 10:13:20 -07:00
bc2bf184a2 docs: describe rounding behaviour of 'DecimalPipe' (#24303)
PR Close #24303
2018-07-06 10:13:00 -07:00
b51ce62c58 docs(aio): added a link to Angular Zero online course (Traditional Chinese) (#24228)
PR Close #24228
2018-07-06 10:11:02 -07:00
25b532e819 docs: clarify faqs about services (#24079)
PR Close #24079
2018-07-06 10:10:41 -07:00
69c8226a9f docs: add app.module to changed documents (#23876)
PR Close #23876
2018-07-06 10:10:21 -07:00
5326537985 docs(router): add paramsInheritanceStrategy documentation (#22590)
PR Close #22590
2018-07-06 10:10:02 -07:00
ada486a1dd docs: fix typos in 'Httpclient' docs (#19127)
PR Close #19127
2018-07-06 10:09:41 -07:00
563e8e3e56 docs: fix documention for attributes directive (#24367)
fix:update documentation for attributes directive to fix error

PR Close #24367
2018-07-03 18:34:59 -04:00
dd931c73ec ci: fix broken build (#24747) 2018-07-03 13:30:17 -07:00
b8975a90ca fix(core): use addCustomEqualityTester instead of overriding toEqual (#22983)
This propagates other custom equality testers added by users. Additionally, if
an Angular project is using jasmine 2.6+, it will allow Jasmine's custom object
differ to print out pretty test error messages.

fixes #22939

PR Close #22983
2018-07-03 08:40:00 -07:00
f44161503a docs(aio): update contributors entry (#23786)
PR Close #23786
2018-07-02 15:45:39 -07:00
6c55a130b1 feat(core): add support for ShadowDOM v1 (#24718)
add a new ViewEncapsulation.ShadowDom option that uses the v1 Shadow DOM API to provide style encapsulation.

PR Close #24718
2018-07-02 14:37:42 -07:00
144a624088 docs: update HTTP error test example again (#24701)
This has somehow regressed since angular/angular#22844 was merged.

PR Close #24701
2018-07-02 14:37:18 -07:00
f561f5a460 docs: fix typo in pipes guide (#24452)
PR Close #24452
2018-07-02 14:36:55 -07:00
916914be13 docs: fix docregion in attribute directives for highlight directive (#23972)
Fixes #23503

PR Close #23972
2018-07-02 14:36:24 -07:00
9a98de941d fix(common): properly update collection reference in NgForOf (#24684)
closes #24155

PR Close #24684
2018-06-29 06:43:45 -07:00
0f1de35604 docs(core): rephrase doc for Injector.get (#24670)
PR Close #24670
2018-06-29 06:43:19 -07:00
d89f57f9d5 build(docs-infra): render short description of parameters in API docs (#24537)
PR Close #24537
2018-06-28 15:03:15 -07:00
ac5b69f783 fix(docs-infra): use clean package.json template when generating zips (#24691)
Closes #24689

PR Close #24691
2018-06-28 15:01:01 -07:00
5ddd6dcedd docs: include ts-loader as shared example dependency (#24691)
Closes #24671

PR Close #24691
2018-06-28 15:01:01 -07:00
ad68332fa0 docs: consistent spacing in tutorial html files (#23105) (#24497)
- Removed surrounding spaces in interpolation expressions following the styleguide
- Consistant spacing of two spaces in html

Fixes #23105

PR Close #24497
2018-06-28 17:56:20 -04:00
2880cf9ef1 release: cut the v6.0.7 release 2018-06-27 16:54:22 -07:00
64a8584a92 fix(common): use correct ICU plural for locale mk (#24659)
PR Close #24659
2018-06-27 15:03:34 -07:00
97897ab738 refactor(upgrade): fix examples for strictPropertyInitialization and remove internal comments (#18487)
PR Close #18487
2018-06-27 14:57:54 -07:00
9378f44d6d docs(aio): tech edits to upgrade-lazy (#18487)
PR Close #18487
2018-06-27 14:53:24 -07:00
afa46af4c6 docs(upgrade): use a class for upgraded service (#18487)
This makes the resulting use in Angular more ideomatic, since we can just
use the class type as the injection indicator.

PR Close #18487
2018-06-27 14:53:24 -07:00
dbffdcc442 docs(upgrade): fix sub-ordered-list syntax (#18487)
We must always use 1., 2. etc, to indicate ordered lists, even for sub-lists.
We can change the sublist to display as a., b. etc, via CSS.

PR Close #18487
2018-06-27 14:53:24 -07:00
06d68a1b9f docs(upgrade): add guide about downgradeModule() (#18487)
PR Close #18487
2018-06-27 14:53:24 -07:00
75dd3c5ca5 docs(upgrade): add API docs for downgradeModule() (#18487)
PR Close #18487
2018-06-27 14:53:24 -07:00
23f56198a5 docs(upgrade): add API docs for propagateDigest (#18487)
PR Close #18487
2018-06-27 14:53:24 -07:00
69167e4519 docs(upgrade): update API docs for upgrade/static (#18487)
PR Close #18487
2018-06-27 14:53:22 -07:00
10feafcf27 docs: minor fixes in docs-style-guide (#18487)
PR Close #18487
2018-06-27 14:49:14 -07:00
3f3fed95be test: minor improvements in examples e2e tests script (#18487)
PR Close #18487
2018-06-27 14:49:13 -07:00
94433f3b9e docs: fix unit tests in toh-pt6 (#24491)
Resolves #20373

PR Close #24491
2018-06-27 14:33:26 -07:00
aa753878e6 docs: add explanation for enableResourceInlining (#24644)
PR Close #24644
2018-06-27 14:31:54 -07:00
3513ae40cc docs(aio): fix adding to template driven forms (#23743)
PR Close #23743
2018-06-26 11:03:36 -07:00
979e7b6086 docs(aio): fix issues suggested by Brandon (#23743)
PR Close #23743
2018-06-26 11:03:36 -07:00
41f008d109 docs(aio): fix issues suggested by Kara (#23743)
PR Close #23743
2018-06-26 11:03:36 -07:00
c950410ee1 docs(aio): address pr review issues (#23743)
PR Close #23743
2018-06-26 11:03:36 -07:00
b0fa504d39 docs(aio): add cross field validation example (#23743)
PR Close #23743
2018-06-26 11:03:36 -07:00
426f9710a0 build(docs-infra): support hiding constructors of injectable classes (#24529)
Classes that are injectable often have constructors that should not be
called by the application developer. It is the responsibility of the
injector to instantiate the class and the constructor often contains
private implementation details that may need to change.

This commit removes constructors from the docs for API items that are
both:

a) Marked with an injectable decorator (e.g. Injectable, Directive,
Component, Pipe), and
b) Have no constructor description

This second rule allows the developer to override the removal if there
is something useful to say about the constructor.

Note that "normal" classes such as `angimations/HttpHeaders` do not have
their constructor removed, despite (at this time) having no description.

PR Close #24529
2018-06-26 10:58:11 -07:00
ae01c70bba ci: fix broken build do to bad merge (#24662)
PR Close #24662
2018-06-25 13:11:16 -07:00
3341a97154 docs: test doc for decorator templates (#23902)
PR Close #23902
2018-06-25 10:58:00 -07:00
2056e1f05c Revert "docs: test doc for decorator templates (#23902)"
This reverts commit 3938a8be75.
2018-06-25 10:54:47 -07:00
3938a8be75 docs: test doc for decorator templates (#23902)
PR Close #23902
2018-06-25 10:09:15 -07:00
393db94b8d docs: fix misdirected group links (#24569)
PR Close #24569
2018-06-25 10:03:43 -07:00
65744e4ae1 docs: test api doc for pipes (#24141)
PR Close #24141
2018-06-25 09:37:30 -07:00
56bc86992c test(aio): fix upgrade-phonecat examples e2e tests (#24583)
Closes #19625

PR Close #24583
2018-06-25 09:30:46 -07:00
9426c02648 build: upgrade AngularJS typings (#24583)
Previously, we were using [@types/angularjs][1], which is deprecated and
outdated (hasn't been updated for over two years). This PR switches to
[@types/angular][2], which is regularly updated (based on the
definitions on [DefinitelyTyped][3]).

[1]: https://www.npmjs.com/package/@types/angularjs
[2]: https://www.npmjs.com/package/@types/angular
[3]: https://github.com/DefinitelyTyped/DefinitelyTyped

PR Close #24583
2018-06-25 09:30:46 -07:00
0b356d4163 fix(animations): set animations styles properly on platform-server (#24624)
Animations styles weren't getting properly set on platform-server because of erroneous checks and absence of reflection of style property to attribute on the server.

The fix corrects the check for platform and explicitly reflects the style property to the attribute.

PR Close #24624
2018-06-25 07:58:12 -07:00
a886659444 docs: add guide-angular.wishtack.io to education resources (#24585)
PR Close #24585
2018-06-25 07:57:34 -07:00
3649958595 build(docs-infra): move overload short description above syntax (#24526)
PR Close #24526
2018-06-25 07:56:37 -07:00
8919577c54 docs: update Angular CLI option for sourcemaps (#24437)
PR Close #24437
2018-06-25 07:53:27 -07:00
84eff4219e docs: update lowercase pipe example in "AngularJS to Angular" guide (#24588)
PR Close #24588
2018-06-21 13:14:31 -07:00
c11e84ee18 build(docs-infra): redirect removed webpack guide to v5.angular.io (#24595)
The outdated webpack guide has been removed in #24478, but people might
still try to access it (via direct links or search-engine results).

Instead of returning 404, we will now redirect `/guide/webpack` to the
archived version of the guide at `v5.angular.io/guide/webpack`.

PR Close #24595
2018-06-20 16:51:34 -07:00
1ce5a495d3 docs(aio): add elana olson to contributor.json file (#24579)
Add new contributor, elana olson, to the contributors list.

PR Close #24579
2018-06-20 16:50:54 -07:00
1f532aaa5a feat(docs-infra): Add GitHub and Twitter external icon links to topnav toolbar (#24542)
PR Close #24542
2018-06-20 16:50:15 -07:00
e81982ef90 release: cut the v6.0.6 release 2018-06-20 15:57:10 -07:00
776bc38999 test(animations): properly reference body node for SSR environments (#23300)
PR Close #23300
2018-06-20 11:00:42 -07:00
7e7ef8ee25 docs: More edits (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
dd90d92573 docs: More form control API edits (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
1b862820e9 docs: Added multicast to observable descriptions (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
1a642231cd docs: formatting (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
138e0d79cd docs: More form control API references fixes (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
f0a43716e2 docs(docs-infra): Update with review changes (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
2be27fb888 docs(forms): update API reference for FormControl (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
74f07f40e0 docs: Remove outdated Webpack guide and example (#24478)
A supporting Webpack guide will be introduced as part of the guidance
for ejecting from the Angular CLI.

Closes #23937

PR Close #24478
2018-06-18 15:03:22 -07:00
aa66e84e44 docs: push animation api doc changes back to stable (#24525)
PR Close #24525
2018-06-15 09:55:58 -07:00
e1bc3f5c1a build(docs-infra): ensure all headings are sentence cased (#24527)
PR Close #24527
2018-06-15 09:13:46 -07:00
f5b366147b fix(core): Injector correctly honors the @Self flag (#24520)
Injector was incorrectly returning instance from parent injector even
when `@Self` was specified.

PR Close #24520
2018-06-14 16:42:08 -07:00
3147a92ee9 build: fix broken circleci build (#24513)
Bazel 0.14 allocates memory differently and runs out of RAM on a 4G circleci worker
so use an xlarge machine for the integration_test job.
Cherry-pick of #24512 onto patch branch.

PR Close #24513
2018-06-14 14:15:20 -07:00
ffedbde0b3 test(bazel): fix flakey bazel integration e2e test (#24522)
PR Close #24522
2018-06-14 14:15:00 -07:00
e543c734ab fix(compiler): support . in import statements. (#20634)
fix #20363

PR Close #20634
2018-06-13 20:29:22 -07:00
fbe6871a94 build(aio): add github links to API doc members (#24000)
This change adds Github edit and view links to methods
and decorator options.

It is possible to add these to properties also but the
UI is rather tight as these are displayed in a table.

PR Close #24000
2018-06-13 16:51:59 -07:00
f43cb9398c build(aio): compute breadcrums for all API doc types (#24000)
PR Close #24000
2018-06-13 16:51:59 -07:00
1e04df9ac7 build(aio): fix decorator doc "inherited from" heading (#24000)
We should not include the package path in the inherited
from heading for decorator API docs

PR Close #24000
2018-06-13 16:51:59 -07:00
840ca05fe8 fix(aio): tidy up API doc styles (#24000)
* Code anchors should inherit the font size from their container
* Table headings should align with content

PR Close #24000
2018-06-13 16:51:59 -07:00
facc9d498d build(aio): fix broken doc-gen unit test (#24000)
PR Close #24000
2018-06-13 16:51:59 -07:00
9d0999027f build(aio): remove invalid H3 usage notes heading (#24000)
This heading is too high for the section because the
method name is a H3 but it cannot be a H4 because
usage notes may contain H4 headings.

PR Close #24000
2018-06-13 16:51:59 -07:00
c00dd5a3f3 build(aio): rearrange processors to ensure we catch all content errors (#24000)
PR Close #24000
2018-06-13 16:51:59 -07:00
3908a63381 docs: fix invalid headings (#24000)
PR Close #24000
2018-06-13 16:51:54 -07:00
20f9e51b8f build(aio): map H3 headings into H4 headings for certain templates (#24000)
The sections such as methods and decorator options are already headed
by a H3 heading so we need to map the H3 headings in the API doc source
down to H4 headings.

This commit includes general heading mapping functionality accessible via
the `marked` Nunjucks filter.

PR Close #24000
2018-06-13 16:47:42 -07:00
232203242a build(aio): rearrange decorator API doc template (#24000)
The overview of the decorator options is now a table.
The detailed description of each option is now a full section.

PR Close #24000
2018-06-13 16:47:42 -07:00
0ca634e697 build(aio): remove unused @linkDocs alias for @link jsdoc tag (#24000)
PR Close #24000
2018-06-13 16:47:42 -07:00
7fd9918024 docs: remove unnecessary @linkDocs tags (#24000)
It is cleaner and simpler to use just a straightforward link.

PR Close #24000
2018-06-13 16:47:42 -07:00
b0aacb81d4 build(aio): improve automatic linking of code items (#24000)
This commit adds new link disambiguators that mean that more
code links can be generated automatically in a sensible way.

The best example is the use of properties within class, interface and
enum documentation.

PR Close #24000
2018-06-13 16:47:42 -07:00
6c850eb031 docs(aio): remove unused guide doc (#24000)
This was erroneously committed into master, when it was really only
supposed to demo what the pages might look like.

PR Close #24000
2018-06-13 16:47:42 -07:00
0df61ad107 build(aio): refactor the decorator doc processing (#24000)
PR Close #24000
2018-06-13 16:47:42 -07:00
fa985ac067 build(aio): do not allow @usageNotes on properties (#24000)
PR Close #24000
2018-06-13 16:47:42 -07:00
06f9197361 build(aio): update to latest dgeni-packages@0.26.2 (#24000)
This update allows us to autolink to methods and properties, which
means that we can change things like `{@link transition transition()}`
to just `transition()`.

PR Close #24000
2018-06-13 16:47:42 -07:00
c2bad1249e build(aio): add content rule to prevent usageNotes in non-export API docs (#24000)
This commit also factors out `API_CONTAINED_DOC_TYPES` to be used by
both `filterContainedDocs` and `addAllowedPropertiesRules`.

PR Close #24000
2018-06-13 16:47:42 -07:00
9d69ff8ddd build(aio): don't constrain checkContentRules to run before another processor (#24000)
We don't really care when this processor runs as long as it happens
after the tags have been extracted.
By not constraining its `runBefore` property we can ensure that other
processors can be run before it.

PR Close #24000
2018-06-13 16:47:42 -07:00
3fd33f8eb0 build(aio): do not try to auto-link to internal API items (#24000)
This would cause dangling links since the target, being internal,
would not exist in the docs.

PR Close #24000
2018-06-13 16:47:42 -07:00
501a243b3f build(aio): don't render @Annotation tags (#24000)
Because we were "ignoring" these tags they were being
rendered as part of the previous tag.
What we really want to do is know about them, so that we
don't break the doc-gen but then ignore them when rendering.

PR Close #24000
2018-06-13 16:47:42 -07:00
b91b9efc91 release: cut the v6.0.5 release 2018-06-13 15:00:28 -07:00
03718c95ce docs: change capitalization for css hex color values (#23511)
PR Close #23511
2018-06-13 13:31:30 -07:00
0834710c18 docs(aio): remove links to outdated live examples from the API documenation (#23966)
Closes #21525

PR Close #23966
2018-06-13 13:29:13 -07:00
9a9a7de9a4 docs: add message property to compose-message component (#24310)
PR Close #24310
2018-06-13 13:28:47 -07:00
ff51691221 docs: fix typo (#24470)
PR Close #24470
2018-06-13 11:54:26 -07:00
2ad90ab0d3 docs: fix wording in 4-10 (#24385)
PR Close #24385
2018-06-13 11:53:20 -07:00
c5872e6782 docs(aio): Reorganize style guide sections on prefixing components/directives (#22571)
Closes https://github.com/angular/angular/issues/22081

PR Close #22571
2018-06-13 11:20:43 -07:00
d20877bf3f fix(router): fix lazy loading of aux routes (#23459)
Fixes #10981

PR Close #23459
2018-06-13 11:20:20 -07:00
b3089b4963 build: update buildifier to latest (#24296) (#24453)
this matches the version in ngcontainer:0.3.1

PR Close #24296

PR Close #24453
2018-06-13 11:19:59 -07:00
880b03101e build: update to Bazel 0.14.0 (#24296) (#24453)
Also update usage of the ctx.actions.args to a newer preferred API

PR Close #24296

PR Close #24453
2018-06-13 11:19:59 -07:00
451d996414 docs: change aio scope to docs-infra (#24410)
Related to #24295

PR Close #24410
2018-06-12 11:36:14 -07:00
ea3669e334 fix(bazel): Allow ng_module to depend on targets w no deps (#24446)
PR Close #24446
2018-06-12 11:35:53 -07:00
ea2987c7af fix(service-worker): fix SwPush.unsubscribe() (#24162)
Fixes #24095

PR Close #24162
2018-06-11 14:04:31 -04:00
5b823dedcc test(service-worker): allow SwPush tests to run on Node.js (#24162)
PR Close #24162
2018-06-11 14:04:30 -04:00
80f7c83bdd test(service-worker): add tests for SwPush (#24162)
PR Close #24162
2018-06-11 14:04:30 -04:00
53072b10da refactor(service-worker): minor mocks refactoring (#24162)
PR Close #24162
2018-06-11 14:04:30 -04:00
30c2f560b1 build(docs-infra): ensure dist/ directory is cleaned before running tsc --watch (#24372)
PR Close #24372
2018-06-11 09:18:46 -07:00
18c4976f3b build(docs-infra): upgrade preview server to latest @types/shelljs (#24372)
PR Close #24372
2018-06-11 09:18:46 -07:00
0139173c7c fix(animations): always render end-state styles for orphaned DOM nodes (#24236)
This patch ensures that any destination animation styling (state values)
are always applied even if the DOM node is not apart of the DOM.

PR Close #24236
2018-06-08 16:35:27 -07:00
f3c9954a68 docs: adds information about the VSCode clang-format extension (#24351)
PR Close #24351
2018-06-08 16:35:06 -07:00
e8765352e8 fix(docs-infra): use script nomodule to load IE polyfills, skip other polyfills (#24317)
This commit includes two changes:
1. It changes the unreliable dynamic way of loading IE polyfills to use
   `<script nomodule>` instead - for IE it's equivalent to a regular script tag
   while modern browsers will ignore it.
2. It removes other polyfills for browsers not supporting `Object.assign` as
   this API is supported by Chrome 45+, Firefox 34+ and Safari 9+ i.e. it's been
   supported for some time.

Note that as of June 2018 Googlebot uses Chrome 41 to render sites to be
indexed. Chrome 41 doesn't support `Object.assign` but it also doesn't support
ES6 modules so it'll load polyfills meant for IE - which it should do anyway
as it doesn't support most of ES6.

Fixes #23647

PR Close #24317
2018-06-08 13:34:06 -07:00
9e61ad897e build(docs-infra): ensure stability is computed before the API list (#24356)
Previously the API list was being generated before the stability had
been computed. This meant that the API list page showed no API docs
when filtering by `stable` stability status.

Closes #24329

PR Close #24356
2018-06-08 13:33:32 -07:00
0d81151cbc docs(aio): add mix and connect to front page campaigns (#24357)
PR Close #24357
2018-06-08 13:31:28 -07:00
70319722a1 docs(aio): Added resource link to Amexio Canvas Web Based IDE (#24336)
PR Close #24336
2018-06-07 18:46:32 -04:00
cfa5b6567d build(bazel): fix ng_package rollup root dir for fesm2015 output (#24298)
PR Close #24298
2018-06-07 17:56:10 -04:00
41698bf5fd release: cut the v6.0.4 release 2018-06-06 11:49:25 -07:00
23c50e27fc build(docs-infra): log warning rather than error if content errors are not fatal (#24320)
PR Close #24320
2018-06-06 10:25:05 -07:00
0ae8ea254a build(aio): ensure the correct decorator properties are merged (#24289)
Previously only the `description` and `usageNotes` were being copied over
from the call-member of the decorator interface. Important properties such
as `shortDescription` were missed.

These are now added and the code has been refactored to make it simpler and
clearer to update which properties get copied as the requirements change.

PR Close #24289
2018-06-06 10:23:47 -07:00
19deca159b fix(animations): retain trigger-state for nodes that are moved around (#24238)
This patch ensures that if a list of nodes (that contain
animation triggers) are moved around then they will retain their
trigger-value state when animated again at a later point.

PR Close #24238
2018-06-05 18:29:47 -07:00
dc3e8aa0fb fix(forms): properly handle special properties in FormGroup.get (#22249)
closes #17195

PR Close #22249
2018-06-05 18:28:13 -07:00
a9222c0ade docs(aio): Add null type to form validation example (#23949)
Closes #20282

PR Close #23949
2018-06-05 17:32:36 -07:00
ea3127e3f9 build(bazel): ran format (#24279)
PR Close #24279
2018-06-05 13:36:27 -07:00
8e30f7b1aa build(bazel): ran buildifier (#24279)
PR Close #24279
2018-06-05 13:36:27 -07:00
46d81b48ac build(bazel): fix //packages/platform-browser/test:test_web (#24279)
PR Close #24279
2018-06-05 13:36:27 -07:00
3e51a2cb26 build(bazel): enable manual ts_web_test_suite tests that require static_files (#24279)
PR Close #24279
2018-06-05 13:36:27 -07:00
faf60d9310 docs: rename the "aio" component to "docs-infra" (#24295)
The legacy "aio" is still active for currently pending PRs,
The GH label has been renamed as well

PR Close #24295
2018-06-04 17:25:13 -07:00
0639cb9de1 fix(aio): remove unnecessary scrollbar in code-tabs (#24207)
PR Close #24207
2018-06-04 12:07:25 -07:00
810d025488 fix(aio): add right-margin to .home link (#24207)
PR Close #24207
2018-06-04 12:07:25 -07:00
efe49c141a docs(aio): clean up frequent ng-modules (#24025)
Closes #24017

PR Close #24025
2018-06-04 10:13:19 -07:00
a3d9878c9d docs(aio): remove an extraneous apostrophe (#24293)
PR Close #24293
2018-06-04 10:11:28 -07:00
10213d0ca0 docs(common): improve deprecation notices to be parsed by tslint
Closes: #24237
2018-06-04 09:37:05 -07:00
0e1919c2db build(bazel): update bazel integration test to test secondary angular imports such as @angular/common/http (#24170)
PR Close #24170
2018-06-01 13:40:48 -07:00
d579b8ce05 build(bazel): fix bazel built es5 ngfactory with secondary entry-point angular imports (#24170)
PR Close #24170
2018-06-01 13:40:48 -07:00
d69ba735ee feat(compiler-cli): update tsickle to 0.29.x (#24241)
PR Close #24241
2018-06-01 08:37:46 -07:00
2991b1b217 fix(platform-server): avoid dependency cycle when using http interceptor (#24229)
Fixes #23023.

When a HTTP Interceptor injects HttpClient it causes a DI cycle. This fix is to use Injector to lazily inject HTTP_INTERCEPTORS while setting up the HttpHandler on the server so as to break the cycle.

PR Close #24229
2018-06-01 08:33:46 -07:00
b18cf21e99 build(bazel): re-enable packages/upgrade/test:test_web test with static_files in ts_web_test_suite (#24214)
PR Close #24214
2018-05-31 16:13:06 -07:00
c17098dae6 fix(platform-server): don't reflect innerHTML property to attibute (#24213)
Fixes #19278.

innerHTML is conservatively marked as an attribute for security purpose so that it's sanitized when set. However this same mapping is used by the server renderer to decide whether the `innerHTML` property needs to be reflected to the `innerhtml` attribute. The fix is to just skip the property to attribute reflection for `innerHTML`.

PR Close #24213
2018-05-31 10:08:29 -07:00
43e3073687 build: update to rules_nodejs 0.9.1 and rules_typescript 0.15.0 (#24212)
PR Close #24212
2018-05-31 10:08:07 -07:00
f28878f92f build: sync g3 exclude list from copybara to ngbot (#24224)
PR Close #24224
2018-05-31 10:07:45 -07:00
a10bdefa8b docs(aio): Add GDE Kim Maida to contributors 2018-05-30 17:34:15 -07:00
2f377dbcdd style(compiler-cli): fix typo error (#23897)
PR Close #23897
2018-05-30 17:29:04 -07:00
e2e7b4943e docs: fix typo (#24210)
closes #24191

PR Close #24210
2018-05-30 17:06:13 -07:00
b8a1363bb2 docs(forms): fix API doc (#24210)
closes #24090

PR Close #24210
2018-05-30 17:06:13 -07:00
e9e6a58dd0 docs: fix typo (#24210)
closes #23891

PR Close #24210
2018-05-30 17:06:12 -07:00
5932a79713 refactor(animations): fix typo (#24210)
closes #22459

PR Close #24210
2018-05-30 17:06:12 -07:00
7c6a082afd docs: fix typo if FAQ section (#24210)
closes #22360

PR Close #24210
2018-05-30 17:06:12 -07:00
8a2fe5b7c9 docs: fix WebStorm name (#24210)
closes #21900

PR Close #24210
2018-05-30 17:06:12 -07:00
c9eb4910eb fix(animations): Fix browser detection logic (#24188)
Element type is being polyfilled on the server now and cannot be used to detect browser environment.

PR Close #24188
2018-05-30 16:39:09 -07:00
a634a5abbc Revert "docs: update docs to use HttpClientModule instead of HttpModule (#22727)"
This reverts commit b5533e0ee5.
2018-05-30 16:13:59 -07:00
41225026e4 docs: remove unfinished observables file (#23801)
PR Close #23801
2018-05-30 14:44:29 -07:00
e9f2203347 fix(platform-server): avoid clash between server and client style encapsulation attributes (#24158)
Previously the style encapsulation attributes(_nghost-* and _ngcontent-*) created on the server could overlap with the attributes and styles created by the client side app when it botstraps. In case the client is bootstrapping a lazy route, the client side styles are added before the server-side styles are removed. If the components on the client are bootstrapped in a different order than on the server, the styles generated by the client will cause the elements on the server to have the wrong styles.

The fix puts the styles and attributes generated on the server in a completely differemt space so that they are not affected by the client generated styles. The client generated styles will only affect elements bootstrapped on the client.

PR Close #24158
2018-05-30 14:39:10 -07:00
906b3ec8e7 fix(platform-server): provide Domino DOM types globally (#24116)
Fixes #23280, #23133.

This fix lets code access DOM types like Node, HTMLElement in the code. These are invariant across requests and the corresponding classes from Domino can be safely provided during platform initialization.

This is needed for the current sanitizer to work properly on platform-server. Also allows HTML types in injection - Ex. `@inject(DOCUMENT) doc: Document`.

PR Close #24116
2018-05-30 14:38:57 -07:00
1cb0c4644a feat(platform-server): use EventManagerPlugin on the server (#24132)
Previously event handlers on the server were setup directly. This change makes it so that the event registration on the server go through EventManagerPlugin just like on client. This allows us to add custom event registration handlers on the server which allows us to hook up preboot event handlers cleanly.

PR Close #24132
2018-05-30 14:38:39 -07:00
9d28a27215 test(animations): fix Node.js detection in animation tests (#24139)
PR Close #24139
2018-05-30 14:36:35 -07:00
f04aef48f2 build: replace hard-coded master branch with the variable (#24199)
PR Close #24199
2018-05-30 11:31:39 -07:00
d249852f4a build: update rules_webtesting (#24198)
this includes a fix for spammy browser installs that makes our CI logs hard to read

PR Close #24198
2018-05-30 11:31:03 -07:00
707dd59767 build: update brotli version in WORKSPACE (#24194)
The updated version includes the fix for google/brotli#671.

PR Close #24194
2018-05-30 11:30:40 -07:00
4d2570576a docs(aio): fix typo for @NgModuledecorator to @NgModule decorator (#24201)
closes #23974

PR Close #24201
2018-05-30 11:24:12 -07:00
76e58e6cca docs: fix typo (#24201)
closes #23853

PR Close #24201
2018-05-30 11:24:12 -07:00
a27066b9d2 style(compiler): fix up grammar in error message (#24201)
closes #22746

PR Close #24201
2018-05-30 11:24:12 -07:00
29dfc8f3ac docs(bazel): improve error message for ng_package with no metadata (#22964)
PR Close #22964
2018-05-30 10:04:35 -07:00
b5533e0ee5 docs: update docs to use HttpClientModule instead of HttpModule (#22727)
Updated most examples to use HttpClientModule instead of deprecated HttpModule

fix #19280

PR Close #22727
2018-05-30 10:03:14 -07:00
b275d378df docs(aio): add blox material library to resources (#20539)
PR Close #20539
2018-05-30 10:02:32 -07:00
96655f7aac style(compiler): fix typo and formatting (#23729)
PR Close #23729
2018-05-29 18:48:55 -04:00
253f509493 refactor(core): use Partial<T> for MetadataOverride (#24103)
Allows to write:

const fixture = TestBed
      .overridePipe(DisplayNamePipe, { set: { pure: false } })
      .createComponent(MenuComponent);

when you only want to set the `pure` metadata,
instead of currently:

const fixture = TestBed
      .overridePipe(DisplayNamePipe, { set: { name: 'displayName', pure: false } })
      .createComponent(MenuComponent);

which forces you to redefine the name of the pipe even if it is useless.

Fixes #24102

PR Close #24103
2018-05-29 18:40:05 -04:00
5a02ae2f84 docs: update lts and labs practices (#23922)
PR Close #23922
2018-05-29 18:01:31 -04:00
f860752902 refactor(aio): rename method (loadContainingCustomElements --> loadContainedCustomElements) (#23944)
PR Close #23944
2018-05-29 18:00:34 -04:00
efa126f157 fix(aio): avoid loading the ToC component until it is necessary (#23944)
PR Close #23944
2018-05-29 18:00:34 -04:00
715135b117 fix(aio): show embedded ToC (#23944)
On narrow screens (where there is not enough room on the right to show
the floating ToC), an embedded ToC is shown (via an `<aio-toc embedded>`
element in the document). Since ToC was not a custom element, the
component was not instantiated for the embedded element.

This commit fixes it by making `aio-toc` a custom element and loading it
manually for the floating ToC (if necessary).

PR Close #23944
2018-05-29 18:00:34 -04:00
c30fc52d99 feat(aio): add component for lazy-loading custom element (#23944)
PR Close #23944
2018-05-29 18:00:34 -04:00
434eb971e4 refactor(aio): order custom elements by selector (#23944)
PR Close #23944
2018-05-29 18:00:34 -04:00
6e31e22d41 fix(aio): do not load custom elements again while already loading (#23944)
PR Close #23944
2018-05-29 18:00:34 -04:00
8fef926cd2 build(aio): update payload size limits (#23944)
PR Close #23944
2018-05-29 18:00:34 -04:00
7698afedb1 docs(http): correct spelling error (#23675)
Correct a spelling error. I changed HttpParms to HttpParams
PR Close #23675
2018-05-29 16:55:07 -04:00
a583d12660 feat(aio): display code-tabs in a Material Design "card" (#24027)
This helps to connect the "content" of the tab to its label.

Closes #23985

PR Close #24027
2018-05-29 16:52:06 -04:00
a867d71ece feat(aio): render hover status on code-tabs (#24027)
The Material Design spec states that there should be a change
of background when hovering over a tab label.

See https://material.io/design/components/tabs.html#states

Related to #23985

PR Close #24027
2018-05-29 16:52:06 -04:00
84b43daf65 build: pick up rules_typescript karma fix (#24184)
Error was Cannot find module 'karma/bin/karma'

PR Close #24184
2018-05-29 16:50:11 -04:00
9b3423b50d docs(aio): fix link to correct bio image (#24150)
PR Close #24150
2018-05-29 16:27:49 -04:00
d6041d83ec docs(aio): Added Mashhood as GDE in contributors (#24157)
PR Close #24157
2018-05-29 16:20:05 -04:00
a638f504eb docs(aio): add material community components (#24042)
PR Close #24042
2018-05-25 13:45:40 -04:00
a29c756251 refactor(aio): improve logging output in update-preview-server.sh (#24071)
PR Close #24071
2018-05-25 13:44:44 -04:00
f206eb94bb docs(aio): add Juri Strumpflohner to GDE resources (#24086)
PR Close #24086
2018-05-25 13:43:50 -04:00
3d6e82eccd docs(aio): remove outdated rangle link (#24108)
PR Close #24108
2018-05-25 13:41:59 -04:00
437 changed files with 8518 additions and 6043 deletions

View File

@ -12,8 +12,8 @@
## IMPORTANT
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.3.0
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.0
var_1: &docker_image angular/ngcontainer:0.3.2
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.2
# Define common ENV vars
var_3: &define_env_vars
@ -80,7 +80,7 @@ jobs:
- run: ls /home/circleci/bazel_repository_cache || true
- run: bazel info release
- run: bazel run @yarn//:yarn
- run: bazel run @nodejs//:yarn
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
# This avoids waiting for the slowest build target to finish before running the first test
# See https://github.com/bazelbuild/bazel/issues/4257
@ -131,7 +131,7 @@ jobs:
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- run: bazel run @yarn//:yarn
- run: bazel run @nodejs//:yarn
- run: scripts/build-packages-dist.sh
# Save the npm packages from //packages/... for other workflow jobs to read
@ -149,6 +149,10 @@ jobs:
# See comments inside the integration/run_tests.sh script.
integration_test:
<<: *job_defaults
# Note: we run Bazel in one of the integration tests, and it can consume >2G
# of memory. Together with the system under test, this can exhaust the RAM
# on a 4G worker so we use a larger machine here too.
resource_class: xlarge
steps:
- *define_env_vars
- checkout:

View File

@ -45,10 +45,12 @@ merge:
- "packages/language-service/**"
- "**/.gitignore"
- "**/.gitkeep"
- "**/package.json"
- "**/tsconfig-build.json"
- "**/tsconfig.json"
- "**/rollup.config.js"
- "**/BUILD.bazel"
- "packages/**/integrationtest/**"
- "packages/**/test/**"
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable

View File

@ -11,7 +11,7 @@ exports_files([
# This ensures that package.json in subdirectories get installed as well.
alias(
name = "install",
actual = "@yarn//:yarn",
actual = "@nodejs//:yarn",
)
node_modules_filegroup(
@ -44,14 +44,16 @@ filegroup(
"//:node_modules/zone.js/dist/zone.js",
"//:node_modules/zone.js/dist/zone-testing.js",
"//:node_modules/zone.js/dist/task-tracking.js",
"//:test-events.js",
],
)
filegroup(
name = "angularjs",
# do not sort
name = "angularjs_scripts",
srcs = [
"//:node_modules/angular/angular.js",
"//:node_modules/angular-1.5/angular.js",
"//:node_modules/angular-mocks-1.5/angular-mocks.js",
"//:node_modules/angular-mocks/angular-mocks.js",
"//:node_modules/angular/angular.js",
],
)

View File

@ -1,3 +1,85 @@
<a name="6.0.9"></a>
## [6.0.9](https://github.com/angular/angular/compare/6.0.8...6.0.9) (2018-07-11)
### Bug Fixes
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([3c93d07](https://github.com/angular/angular/commit/3c93d07)), closes [#24831](https://github.com/angular/angular/issues/24831)
<a name="6.0.8"></a>
## [6.0.8](https://github.com/angular/angular/compare/6.0.7...6.0.8) (2018-07-11)
### Bug Fixes
* **common:** do not round factional seconds ([#24831](https://github.com/angular/angular/issues/24831)) ([0746485](https://github.com/angular/angular/commit/0746485)), closes [#24384](https://github.com/angular/angular/issues/24384)
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([9a98de9](https://github.com/angular/angular/commit/9a98de9)), closes [#24155](https://github.com/angular/angular/issues/24155)
* **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([a92f111](https://github.com/angular/angular/commit/a92f111)), closes [#24609](https://github.com/angular/angular/issues/24609)
* **compiler-cli:** Use typescript to resolve modules for metadata ([#22856](https://github.com/angular/angular/issues/22856)) ([7717ff1](https://github.com/angular/angular/commit/7717ff1))
* **core:** use addCustomEqualityTester instead of overriding toEqual ([#22983](https://github.com/angular/angular/issues/22983)) ([b8975a9](https://github.com/angular/angular/commit/b8975a9)), closes [#22939](https://github.com/angular/angular/issues/22939)
* **language-service:** do not overwrite native `Reflect` ([#24299](https://github.com/angular/angular/issues/24299)) ([de1c44f](https://github.com/angular/angular/commit/de1c44f)), closes [#21420](https://github.com/angular/angular/issues/21420)
* **router:** add ability to recover from malformed url ([#23283](https://github.com/angular/angular/issues/23283)) ([2d4f4b5](https://github.com/angular/angular/commit/2d4f4b5)), closes [#21468](https://github.com/angular/angular/issues/21468)
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([183b079](https://github.com/angular/angular/commit/183b079))
### Features
* **core:** add support for ShadowDOM v1 ([#24718](https://github.com/angular/angular/issues/24718)) ([6c55a13](https://github.com/angular/angular/commit/6c55a13))
<a name="6.0.7"></a>
## [6.0.7](https://github.com/angular/angular/compare/6.0.6...6.0.7) (2018-06-27)
### Bug Fixes
* **animations:** set animations styles properly on platform-server ([#24624](https://github.com/angular/angular/issues/24624)) ([0b356d4](https://github.com/angular/angular/commit/0b356d4))
* **common:** use correct ICU plural for locale mk ([#24659](https://github.com/angular/angular/issues/24659)) ([64a8584](https://github.com/angular/angular/commit/64a8584))
<a name="6.0.6"></a>
## [6.0.6](https://github.com/angular/angular/compare/6.0.5...6.0.6) (2018-06-20)
### Bug Fixes
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([e543c73](https://github.com/angular/angular/commit/e543c73)), closes [#20363](https://github.com/angular/angular/issues/20363)
* **core:** Injector correctly honors the @Self flag ([#24520](https://github.com/angular/angular/issues/24520)) ([f5b3661](https://github.com/angular/angular/commit/f5b3661))
<a name="6.0.5"></a>
## [6.0.5](https://github.com/angular/angular/compare/6.0.4...6.0.5) (2018-06-13)
### Bug Fixes
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([0139173](https://github.com/angular/angular/commit/0139173))
* **bazel:** Allow ng_module to depend on targets w no deps ([#24446](https://github.com/angular/angular/issues/24446)) ([ea3669e](https://github.com/angular/angular/commit/ea3669e))
* **docs-infra:** use script nomodule to load IE polyfills, skip other polyfills ([#24317](https://github.com/angular/angular/issues/24317)) ([e876535](https://github.com/angular/angular/commit/e876535)), closes [#23647](https://github.com/angular/angular/issues/23647)
* **router:** fix lazy loading of aux routes ([#23459](https://github.com/angular/angular/issues/23459)) ([d20877b](https://github.com/angular/angular/commit/d20877b)), closes [#10981](https://github.com/angular/angular/issues/10981)
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([ea2987c](https://github.com/angular/angular/commit/ea2987c)), closes [#24095](https://github.com/angular/angular/issues/24095)
<a name="6.0.4"></a>
## [6.0.4](https://github.com/angular/angular/compare/6.0.3...6.0.4) (2018-06-06)
### Bug Fixes
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([c9eb491](https://github.com/angular/angular/commit/c9eb491))
* **animations:** retain trigger-state for nodes that are moved around ([#24238](https://github.com/angular/angular/issues/24238)) ([19deca1](https://github.com/angular/angular/commit/19deca1))
* **forms:** properly handle special properties in FormGroup.get ([#22249](https://github.com/angular/angular/issues/22249)) ([dc3e8aa](https://github.com/angular/angular/commit/dc3e8aa)), closes [#17195](https://github.com/angular/angular/issues/17195)
* **platform-server:** avoid clash between server and client style encapsulation attributes ([#24158](https://github.com/angular/angular/issues/24158)) ([e9f2203](https://github.com/angular/angular/commit/e9f2203))
* **platform-server:** avoid dependency cycle when using http interceptor ([#24229](https://github.com/angular/angular/issues/24229)) ([2991b1b](https://github.com/angular/angular/commit/2991b1b)), closes [#23023](https://github.com/angular/angular/issues/23023)
* **platform-server:** don't reflect innerHTML property to attibute ([#24213](https://github.com/angular/angular/issues/24213)) ([c17098d](https://github.com/angular/angular/commit/c17098d)), closes [#19278](https://github.com/angular/angular/issues/19278)
* **platform-server:** provide Domino DOM types globally ([#24116](https://github.com/angular/angular/issues/24116)) ([906b3ec](https://github.com/angular/angular/commit/906b3ec)), closes [#23280](https://github.com/angular/angular/issues/23280) [#23133](https://github.com/angular/angular/issues/23133)
<a name="6.0.3"></a>
## [6.0.3](https://github.com/angular/angular/compare/6.0.2...6.0.3) (2018-05-22)
@ -42,7 +124,7 @@
Angular v6 is the first release of Angular that unifies the Framework, Material and CLI.
To learn about the release highlights and our new CLI-powered update workflow for your projects please check out the [v6 release announcement](https://blog.angular.io/version-6-0-0-of-angular-now-available-cc56b0efa7a4).
To learn about the release highlights and our new CLI-powered update workflow for your projects please check out the [v6 release announcement](https://blog.angular.io/version-6-0-0-of-angular-now-available-cc56b0efa7a4).
@ -193,10 +275,10 @@ To learn about the release highlights and our new CLI-powered update workflow fo
This change removes support for `<template>`. `<ng-template>` should be used instead.
BEFORE:
<!-- html template -->
<template>some template content</template>
# tsconfig.json
{
# ...
@ -206,12 +288,12 @@ To learn about the release highlights and our new CLI-powered update workflow fo
"enableLegacyTemplate": [true|false]
}
}
AFTER:
<!-- html template -->
<ng-template>some template content</ng-template>
* **core:** it is no longer possible to import animation-related functions from @angular/core. All animation symbols must now be imported from @angular/animations.
@ -224,35 +306,35 @@ To learn about the release highlights and our new CLI-powered update workflow fo
Previously, ngModelChange was emitted before its underlying control was updated.
This was fine if you passed through the value directly through the $event keyword, e.g.
```
<input [(ngModel)]="name" (ngModelChange)="onChange($event)">
onChange(value) {
console.log(value); // would log updated value
}
```
However, if you had a handler for the ngModelChange event that checked the value through the control,
you would get the old value rather than the updated value. e.g:
```
<input #modelDir="ngModel" [(ngModel)]="name" (ngModelChange)="onChange(modelDir)">
onChange(ngModel: NgModel) {
console.log(ngModel.value); // would log old value, not updated value
}
```
Now the value and validity will be updated before the ngModelChange event is emitted,
so the same setup will log the updated value.
```
onChange(ngModel: NgModel) {
console.log(ngModel.value); // will log updated value
}
```
We think this order will be less confusing when the control is checked directly.
You will only need to update your app if it has relied on this bug to keep track of the old control value.
If that is the case, you should be able to track the old value directly by saving it on your component.

View File

@ -227,10 +227,15 @@ The following is the list of supported scopes:
There are currently a few exceptions to the "use package name" rule:
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g.
public path changes, package.json changes done to all packages, d.ts file/format changes, changes
to bundles, etc.
* **changelog**: used for updating the release notes in CHANGELOG.md
* **aio**: used for docs-app (angular.io) related changes within the /aio directory of the repo
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`)
* **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
repo
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all
packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a
specific package (e.g. `docs: fix typo in tutorial`).
### Subject
The subject contains a succinct description of the change:
@ -269,7 +274,7 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise
* https://help.github.com/articles/about-commit-email-addresses/
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
<hr>

View File

@ -6,23 +6,23 @@ workspace(name = "angular")
http_archive(
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.8.0.zip",
strip_prefix = "rules_nodejs-0.8.0",
sha256 = "4e40dd49ae7668d245c3107645f2a138660fcfd975b9310b91eda13f0c973953",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.10.1.zip",
strip_prefix = "rules_nodejs-0.10.1",
sha256 = "634206524d90dc03c52392fa3f19a16637d2bcf154910436fe1d669a0d9d7b9c",
)
http_archive(
name = "io_bazel_rules_webtesting",
url = "https://github.com/bazelbuild/rules_webtesting/archive/cfcaaf98553fee8e7063b5f5c11fd1b77e43d683.zip",
strip_prefix = "rules_webtesting-cfcaaf98553fee8e7063b5f5c11fd1b77e43d683",
sha256 = "636c7a9ac2ca13a04d982c2f9c874876ecc90a7b9ccfe4188156122b26ada7b3",
url = "https://github.com/bazelbuild/rules_webtesting/archive/v0.2.0.zip",
strip_prefix = "rules_webtesting-0.2.0",
sha256 = "cecc12f07e95740750a40d38e8b14b76fefa1551bef9332cb432d564d693723c",
)
http_archive(
name = "build_bazel_rules_typescript",
url = "https://github.com/bazelbuild/rules_typescript/archive/v0.13.0.zip",
strip_prefix = "rules_typescript-0.13.0",
sha256 = "8f2767ff56ad68c80c62e9a1cdc2ba2c2ba0b19d350f713365e5333045df02e3",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.15.0.zip",
strip_prefix = "rules_typescript-0.15.0",
sha256 = "1aa75917330b820cb239b3c10a936a10f0a46fe215063d4492dd76dc6e1616f4",
)
http_archive(
@ -34,13 +34,13 @@ http_archive(
# This commit matches the version of buildifier in angular/ngcontainer
# If you change this, also check if it matches the version in the angular/ngcontainer
# version in /.circleci/config.yml
BAZEL_BUILDTOOLS_VERSION = "fd9878fd5de921e0bbab3dcdcb932c2627812ee1"
BAZEL_BUILDTOOLS_VERSION = "82b21607e00913b16fe1c51bec80232d9d6de31c"
http_archive(
name = "com_github_bazelbuild_buildtools",
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
sha256 = "27bb461ade23fd44ba98723ad98f84ee9c83cd3540b773b186a1bc5037f3d862",
sha256 = "edb24c2f9c55b10a820ec74db0564415c0cf553fa55e9fc709a6332fb6685eff",
)
# Fetching the Bazel source code allows us to compile the Skylark linter
@ -66,9 +66,9 @@ http_archive(
http_archive(
name = "org_brotli",
url = "https://github.com/google/brotli/archive/c6333e1e79fb62ea088443f192293f964409b04e.zip",
strip_prefix = "brotli-c6333e1e79fb62ea088443f192293f964409b04e",
sha256 = "3f781988dee7dd3bcce2bf238294663cfaaf3b6433505bdb762e24d0a284d1dc",
url = "https://github.com/google/brotli/archive/f9b8c02673c576a3e807edbf3a9328e9e7af6d7c.zip",
strip_prefix = "brotli-f9b8c02673c576a3e807edbf3a9328e9e7af6d7c",
sha256 = "8a517806d2b7c8505ba5c53934e7d7c70d341b68ffd268e9044d35b564a48828",
)
#
@ -77,7 +77,7 @@ http_archive(
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
check_bazel_version("0.13.0")
check_bazel_version("0.14.0")
node_repositories(package_json = ["//:package.json"])
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")

View File

@ -52,8 +52,7 @@ export class BuildCleaner {
protected removeDir(dir: string) {
try {
if (shell.test('-d', dir)) {
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
(shell as any).chmod('-R', 'a+w', dir);
shell.chmod('-R', 'a+w', dir);
shell.rm('-rf', dir);
}
} catch (err) {

View File

@ -106,8 +106,7 @@ export class BuildCreator extends EventEmitter {
}
try {
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
(shell as any).chmod('-R', 'a-w', outputDir);
shell.chmod('-R', 'a-w', outputDir);
shell.rm('-f', inputFile);
resolve();
} catch (err) {

View File

@ -98,8 +98,7 @@ class Helper {
const prDir = this.getPrDir(pr, isPublic);
if (fs.existsSync(prDir)) {
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
(shell as any).chmod('-R', 'a+w', prDir);
shell.chmod('-R', 'a+w', prDir);
shell.rm('-rf', prDir);
}
}

View File

@ -8,7 +8,7 @@
"scripts": {
"prebuild": "yarn clean-dist",
"build": "tsc",
"build-watch": "yarn tsc --watch",
"build-watch": "yarn build --watch",
"clean-dist": "node --eval \"require('shelljs').rm('-rf', 'dist')\"",
"dev": "concurrently --kill-others --raw --success first \"yarn build-watch\" \"yarn test-watch\"",
"lint": "tslint --project tsconfig.json",
@ -33,7 +33,7 @@
"@types/jasmine": "^2.6.0",
"@types/jsonwebtoken": "^7.2.3",
"@types/node": "^8.0.30",
"@types/shelljs": "^0.7.4",
"@types/shelljs": "^0.8.0",
"@types/supertest": "^2.0.3",
"concurrently": "^3.5.0",
"nodemon": "^1.12.1",

View File

@ -69,9 +69,9 @@
"@types/express-serve-static-core" "*"
"@types/mime" "*"
"@types/shelljs@^0.7.4":
version "0.7.4"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.4.tgz#137b5f31306eaff4de120ffe5b9d74b297809cfc"
"@types/shelljs@^0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.0.tgz#0caa56b68baae4f68f44e0dd666ab30b098e3632"
dependencies:
"@types/glob" "*"
"@types/node" "*"

View File

@ -3,7 +3,7 @@
set -eux -o pipefail
exec 3>&1
echo "\n\n[`date`] - Updating the preview server..."
echo -e "\n\n[`date`] - Updating the preview server..."
# Input
readonly HOST_REPO_DIR=$1

View File

@ -60,6 +60,8 @@ dist/
!rollup-config.js
aot-compiler/**/*.d.ts
aot-compiler/**/*.factory.d.ts
upgrade-phonecat-2-hybrid/aot/**/*
!upgrade-phonecat-2-hybrid/aot/index.html
# i18n
!i18n/src/systemjs-text-plugin.js

View File

@ -40,5 +40,7 @@ export class HighlightDirective {
// #docregion color-2
@Input() appHighlight: string;
// #enddocregion color-2
}
// #docregion
}
// #enddocregion

View File

@ -16,6 +16,7 @@ describe('Form Validation Tests', function () {
tests('Template-Driven Form');
bobTests();
crossValidationTests();
});
describe('Reactive form', () => {
@ -25,6 +26,7 @@ describe('Form Validation Tests', function () {
tests('Reactive Form');
bobTests();
crossValidationTests();
});
});
@ -42,7 +44,8 @@ let page: {
powerOption: ElementFinder,
errorMessages: ElementArrayFinder,
heroFormButtons: ElementArrayFinder,
heroSubmitted: ElementFinder
heroSubmitted: ElementFinder,
crossValidationErrorMessage: ElementFinder,
};
function getPage(sectionTag: string) {
@ -59,7 +62,8 @@ function getPage(sectionTag: string) {
powerOption: section.element(by.css('#power option')),
errorMessages: section.all(by.css('div.alert')),
heroFormButtons: buttons,
heroSubmitted: section.element(by.css('.submitted-message'))
heroSubmitted: section.element(by.css('.submitted-message')),
crossValidationErrorMessage: section.element(by.css('.cross-validation-error-message')),
};
}
@ -172,3 +176,29 @@ function bobTests() {
expectFormIsValid();
});
}
function crossValidationTests() {
const emsg = 'Name cannot match alter ego.';
it(`should produce "${emsg}" error after setting name and alter ego to the same value`, function () {
page.nameInput.clear();
page.nameInput.sendKeys('Batman');
page.alterEgoInput.clear();
page.alterEgoInput.sendKeys('Batman');
expectFormIsInvalid();
expect(page.crossValidationErrorMessage.getText()).toBe(emsg);
});
it('should be ok again with different values', function () {
page.nameInput.clear();
page.nameInput.sendKeys('Batman');
page.alterEgoInput.clear();
page.alterEgoInput.sendKeys('Superman');
expectFormIsValid();
expect(page.crossValidationErrorMessage.isPresent()).toBe(false);
});
}

View File

@ -7,7 +7,7 @@ import { AppComponent } from './app.component';
import { HeroFormTemplateComponent } from './template/hero-form-template.component';
import { HeroFormReactiveComponent } from './reactive/hero-form-reactive.component';
import { ForbiddenValidatorDirective } from './shared/forbidden-name.directive';
import { IdentityRevealedValidatorDirective } from './shared/identity-revealed.directive';
@NgModule({
imports: [
@ -19,7 +19,8 @@ import { ForbiddenValidatorDirective } from './shared/forbidden-name.directive';
AppComponent,
HeroFormTemplateComponent,
HeroFormReactiveComponent,
ForbiddenValidatorDirective
ForbiddenValidatorDirective,
IdentityRevealedValidatorDirective
],
bootstrap: [ AppComponent ]
})

View File

@ -0,0 +1,42 @@
/* tslint:disable: member-ordering forin */
// #docplaster
// #docregion
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { forbiddenNameValidator } from '../shared/forbidden-name.directive';
@Component({
selector: 'app-hero-form-reactive',
templateUrl: './hero-form-reactive.component.html',
styleUrls: ['./hero-form-reactive.component.css'],
})
export class HeroFormReactiveComponent implements OnInit {
powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
hero = {name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0]};
heroForm: FormGroup;
// #docregion form-group
ngOnInit(): void {
// #docregion custom-validator
this.heroForm = new FormGroup({
'name': new FormControl(this.hero.name, [
Validators.required,
Validators.minLength(4),
forbiddenNameValidator(/bob/i) // <-- Here's how you pass in the custom validator.
]),
'alterEgo': new FormControl(this.hero.alterEgo),
'power': new FormControl(this.hero.power, Validators.required)
});
// #enddocregion custom-validator
}
get name() { return this.heroForm.get('name'); }
get power() { return this.heroForm.get('power'); }
// #enddocregion form-group
}
// #enddocregion

View File

@ -0,0 +1,5 @@
/* #docregion cross-validation-error-css */
.cross-validation-error input {
border-left: 5px solid red;
}
/* #enddocregion cross-validation-error-css */

View File

@ -7,33 +7,41 @@
<div [hidden]="formDir.submitted">
<div class="form-group">
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
<div class="form-group">
<label for="name">Name</label>
<!-- #docregion name-with-error-msg -->
<input id="name" class="form-control"
formControlName="name" required >
<label for="name">Name</label>
<!-- #docregion name-with-error-msg -->
<input id="name" class="form-control"
formControlName="name" required >
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert alert-danger">
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert alert-danger">
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors.forbiddenName">
Name cannot be Bob.
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors.forbiddenName">
Name cannot be Bob.
</div>
</div>
<!-- #enddocregion name-with-error-msg -->
</div>
<!-- #enddocregion name-with-error-msg -->
</div>
<div class="form-group">
<label for="alterEgo">Alter Ego</label>
<input id="alterEgo" class="form-control"
formControlName="alterEgo" >
<div class="form-group">
<label for="alterEgo">Alter Ego</label>
<input id="alterEgo" class="form-control"
formControlName="alterEgo" >
</div>
<!-- #docregion cross-validation-error-message -->
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
Name cannot match alter ego.
</div>
<!-- #enddocregion cross-validation-error-message -->
</div>
<div class="form-group">

View File

@ -1,40 +1,36 @@
/* tslint:disable: member-ordering forin */
// #docplaster
// #docregion
import { Component, OnInit } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { forbiddenNameValidator } from '../shared/forbidden-name.directive';
import { identityRevealedValidator } from '../shared/identity-revealed.directive';
@Component({
selector: 'app-hero-form-reactive',
templateUrl: './hero-form-reactive.component.html'
templateUrl: './hero-form-reactive.component.html',
styleUrls: ['./hero-form-reactive.component.css'],
})
export class HeroFormReactiveComponent implements OnInit {
powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
hero = {name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0]};
hero = { name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0] };
heroForm: FormGroup;
// #docregion form-group
ngOnInit(): void {
// #docregion custom-validator
this.heroForm = new FormGroup({
'name': new FormControl(this.hero.name, [
Validators.required,
Validators.minLength(4),
forbiddenNameValidator(/bob/i) // <-- Here's how you pass in the custom validator.
forbiddenNameValidator(/bob/i)
]),
'alterEgo': new FormControl(this.hero.alterEgo),
'power': new FormControl(this.hero.power, Validators.required)
});
// #enddocregion custom-validator
}, { validators: identityRevealedValidator }); // <-- add custom validator at the FormGroup level
}
get name() { return this.heroForm.get('name'); }
get power() { return this.heroForm.get('power'); }
// #enddocregion form-group
}
// #enddocregion

View File

@ -5,7 +5,7 @@ import { AbstractControl, NG_VALIDATORS, Validator, ValidatorFn, Validators } fr
// #docregion custom-validator
/** A hero's name can't match the given regular expression */
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} => {
return (control: AbstractControl): {[key: string]: any} | null => {
const forbidden = nameRe.test(control.value);
return forbidden ? {'forbiddenName': {value: control.value}} : null;
};
@ -22,7 +22,7 @@ export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
export class ForbiddenValidatorDirective implements Validator {
@Input('appForbiddenName') forbiddenName: string;
validate(control: AbstractControl): {[key: string]: any} {
validate(control: AbstractControl): {[key: string]: any} | null {
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
: null;
}

View File

@ -0,0 +1,25 @@
// #docregion
import { Directive } from '@angular/core';
import { AbstractControl, FormGroup, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn } from '@angular/forms';
// #docregion cross-validation-validator
/** A hero's name can't match the hero's alter ego */
export const identityRevealedValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
const name = control.get('name');
const alterEgo = control.get('alterEgo');
return name && alterEgo && name.value === alterEgo.value ? { 'identityRevealed': true } : null;
};
// #enddocregion cross-validation-validator
// #docregion cross-validation-directive
@Directive({
selector: '[appIdentityRevealed]',
providers: [{ provide: NG_VALIDATORS, useExisting: IdentityRevealedValidatorDirective, multi: true }]
})
export class IdentityRevealedValidatorDirective implements Validator {
validate(control: AbstractControl): ValidationErrors {
return identityRevealedValidator(control)
}
}
// #enddocregion cross-validation-directive

View File

@ -0,0 +1,4 @@
/* #docregion */
.cross-validation-error input {
border-left: 5px solid red;
}

View File

@ -2,41 +2,48 @@
<div class="container">
<h1>Template-Driven Form</h1>
<!-- #docregion form-tag-->
<form #heroForm="ngForm">
<!-- #enddocregion form-tag-->
<!-- #docregion cross-validation-register-validator -->
<form #heroForm="ngForm" appIdentityRevealed>
<!-- #enddocregion cross-validation-register-validator -->
<div [hidden]="heroForm.submitted">
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
<div class="form-group">
<label for="name">Name</label>
<!-- #docregion name-with-error-msg -->
<!-- #docregion name-input -->
<input id="name" name="name" class="form-control"
required minlength="4" appForbiddenName="bob"
[(ngModel)]="hero.name" #name="ngModel" >
<!-- #enddocregion name-input -->
<div class="form-group">
<label for="name">Name</label>
<!-- #docregion name-with-error-msg -->
<!-- #docregion name-input -->
<input id="name" name="name" class="form-control"
required minlength="4" appForbiddenName="bob"
[(ngModel)]="hero.name" #name="ngModel" >
<!-- #enddocregion name-input -->
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert alert-danger">
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert alert-danger">
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors.forbiddenName">
Name cannot be Bob.
</div>
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors.forbiddenName">
Name cannot be Bob.
</div>
<!-- #enddocregion name-with-error-msg -->
</div>
<!-- #enddocregion name-with-error-msg -->
</div>
<div class="form-group">
<label for="alterEgo">Alter Ego</label>
<input id="alterEgo" class="form-control"
name="alterEgo" [(ngModel)]="hero.alterEgo" >
<div class="form-group">
<label for="alterEgo">Alter Ego</label>
<input id="alterEgo" class="form-control"
name="alterEgo" [(ngModel)]="hero.alterEgo" >
</div>
<!-- #docregion cross-validation-error-message -->
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
Name cannot match alter ego.
</div>
<!-- #enddocregion cross-validation-error-message -->
</div>
<div class="form-group">
@ -62,5 +69,4 @@
<button (click)="heroForm.resetForm({})">Add new hero</button>
</div>
</form>
</div>

View File

@ -3,9 +3,11 @@
// #docregion
import { Component } from '@angular/core';
// #docregion component
@Component({
selector: 'app-hero-form-template',
templateUrl: './hero-form-template.component.html'
templateUrl: './hero-form-template.component.html',
styleUrls: ['./hero-form-template.component.css'],
})
export class HeroFormTemplateComponent {
@ -14,3 +16,4 @@ export class HeroFormTemplateComponent {
hero = {name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0]};
}
// #enddocregion

View File

@ -2,6 +2,7 @@
"description": "Validation",
"files":[
"!**/*.d.ts",
"!**/*.js"
"!**/*.js",
"!**/*.[1].*"
]
}

View File

@ -4,7 +4,8 @@ button {
font-size: 100%;
}
code, .code {
code,
.code {
background-color: #eee;
color: black;
font-family: Courier, sans-serif;
@ -21,14 +22,18 @@ div.code {
}
hr {
margin: 40px 0
margin: 40px 0;
}
td, th {
td,
th {
text-align: left;
vertical-align: top;
}
/* #docregion p-span */
p span { color: red; font-size: 70%; }
p span {
color: red;
font-size: 70%;
}
/* #enddocregion p-span */

View File

@ -132,7 +132,7 @@
<!-- #docregion select-span -->
<select [(ngModel)]="hero">
<span *ngFor="let h of heroes">
<span *ngIf="showSad || h?.emotion != 'sad'">
<span *ngIf="showSad || h?.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h?.emotion}})</option>
</span>
</span>
@ -147,7 +147,7 @@
<!-- #docregion select-ngcontainer -->
<select [(ngModel)]="hero">
<ng-container *ngFor="let h of heroes">
<ng-container *ngIf="showSad || h?.emotion != 'sad'">
<ng-container *ngIf="showSad || h?.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h?.emotion}})</option>
</ng-container>
</ng-container>

View File

@ -6,14 +6,15 @@ import { heroes } from './hero';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
styleUrls: ['./app.component.css']
})
export class AppComponent {
heroes = heroes;
hero = this.heroes[0];
heroTraits = [ 'honest', 'brave', 'considerate' ];
heroTraits = ['honest', 'brave', 'considerate'];
// flags for the table
attrDirs = true;
strucDirs = true;
divNgIf = false;

View File

@ -1,9 +1,9 @@
// #docregion
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
import { ContentComponent } from './content.component';
import { heroComponents } from './hero.components';

View File

@ -1,5 +1,6 @@
// #docregion
import { Component, Input } from '@angular/core';
import { Hero } from './hero';
@Component({
@ -33,11 +34,15 @@ export class ConfusedHeroComponent {
export class UnknownHeroComponent {
@Input() hero: Hero;
get message() {
return this.hero && this.hero.name ?
`${this.hero.name} is strange and mysterious.` :
'Are you feeling indecisive?';
return this.hero && this.hero.name
? `${this.hero.name} is strange and mysterious.`
: 'Are you feeling indecisive?';
}
}
export const heroComponents =
[ HappyHeroComponent, SadHeroComponent, ConfusedHeroComponent, UnknownHeroComponent ];
export const heroComponents = [
HappyHeroComponent,
SadHeroComponent,
ConfusedHeroComponent,
UnknownHeroComponent
];

View File

@ -6,8 +6,8 @@ export class Hero {
}
export const heroes: Hero[] = [
{ id: 1, name: 'Mr. Nice', emotion: 'happy'},
{ id: 2, name: 'Narco', emotion: 'sad' },
{ id: 1, name: 'Mr. Nice', emotion: 'happy' },
{ id: 2, name: 'Narco', emotion: 'sad' },
{ id: 3, name: 'Windstorm', emotion: 'confused' },
{ id: 4, name: 'Magneta'}
{ id: 4, name: 'Magneta' }
];

View File

@ -15,6 +15,7 @@ export class ComposeMessageComponent {
@HostBinding('style.position') position = 'absolute';
details: string;
message: string;
sending = false;
constructor(private router: Router) {}

View File

@ -3,15 +3,15 @@
<!-- #enddocregion show-hero-1 -->
<!-- #docregion show-hero-2 -->
<h2>{{ hero.name }} Details</h2>
<h2>{{hero.name}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div><span>name: </span>{{hero.name}}</div>
<!-- #enddocregion show-hero-2 -->
<!-- #docregion name-input -->
<div>
<label>name:
<input [(ngModel)]="hero.name" placeholder="name">
</label>
<label>name:
<input [(ngModel)]="hero.name" placeholder="name">
</label>
</div>
<!-- #enddocregion name-input -->

View File

@ -1,10 +1,10 @@
<!-- #docregion -->
<!-- #docregion pipe -->
<h2>{{ hero.name | uppercase }} Details</h2>
<h2>{{hero.name | uppercase}} Details</h2>
<!-- #enddocregion pipe -->
<div><span>id: </span>{{hero.id}}</div>
<div>
<label>name:
<input [(ngModel)]="hero.name" placeholder="name">
</label>
<label>name:
<input [(ngModel)]="hero.name" placeholder="name">
</label>
</div>

View File

@ -14,7 +14,7 @@
<div *ngIf="selectedHero">
<!-- #docregion selectedHero-details -->
<h2>{{ selectedHero.name | uppercase }} Details</h2>
<h2>{{selectedHero.name | uppercase}} Details</h2>
<div><span>id: </span>{{selectedHero.id}}</div>
<div>
<label>name:

View File

@ -1,6 +1,6 @@
<div *ngIf="hero">
<h2>{{ hero.name | uppercase }} Details</h2>
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label>name:

View File

@ -1,5 +1,5 @@
<div *ngIf="hero">
<h2>{{ hero.name | uppercase }} Details</h2>
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label>name:

View File

@ -18,11 +18,11 @@ nav a {
border-radius: 4px;
}
nav a:visited, a:link {
color: #607D8B;
color: #607d8b;
}
nav a:hover {
color: #039be5;
background-color: #CFD8DC;
background-color: #cfd8dc;
}
nav a.active {
color: #039be5;

View File

@ -33,11 +33,11 @@ h4 {
color: #eee;
max-height: 120px;
min-width: 120px;
background-color: #607D8B;
background-color: #607d8b;
border-radius: 2px;
}
.module:hover {
background-color: #EEE;
background-color: #eee;
cursor: pointer;
color: #607d8b;
}

View File

@ -1,5 +1,5 @@
<div *ngIf="hero">
<h2>{{ hero.name | uppercase }} Details</h2>
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label>name:

View File

@ -1,16 +1,36 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DashboardComponent } from './dashboard.component';
import { HeroSearchComponent } from '../hero-search/hero-search.component';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { HEROES } from '../mock-heroes';
import { HeroService } from '../hero.service';
describe('DashboardComponent', () => {
let component: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
let heroService;
let getHeroesSpy;
beforeEach(async(() => {
heroService = jasmine.createSpyObj('HeroService', ['getHeroes']);
getHeroesSpy = heroService.getHeroes.and.returnValue( of(HEROES) );
TestBed.configureTestingModule({
declarations: [ DashboardComponent ]
declarations: [
DashboardComponent,
HeroSearchComponent
],
imports: [
RouterTestingModule.withRoutes([])
],
providers: [
{ provide: HeroService, useValue: heroService }
]
})
.compileComponents();
}));
beforeEach(() => {
@ -22,4 +42,17 @@ describe('DashboardComponent', () => {
it('should be created', () => {
expect(component).toBeTruthy();
});
it('should display "Top Heroes" as headline', () => {
expect(fixture.nativeElement.querySelector('h3').textContent).toEqual('Top Heroes');
});
it('should call heroService', async(() => {
expect(getHeroesSpy.calls.any()).toBe(true);
}));
it('should display 4 links', async(() => {
expect(fixture.nativeElement.querySelectorAll('a').length).toEqual(4);
}));
});

View File

@ -1,5 +1,5 @@
<div *ngIf="hero">
<h2>{{ hero.name | uppercase }} Details</h2>
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label>name:

View File

@ -1,14 +1,18 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { HeroSearchComponent } from './hero-search.component';
describe('HeroSearchComponent', () => {
let component: HeroSearchComponent;
let fixture: ComponentFixture<HeroSearchComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HeroSearchComponent ]
declarations: [ HeroSearchComponent ],
imports: [RouterTestingModule.withRoutes([]), HttpClientTestingModule]
})
.compileComponents();
}));

View File

@ -40,7 +40,7 @@ export class HeroService {
// #enddocregion getHeroes-1
.pipe(
// #enddocregion getHeroes-2
tap(heroes => this.log(`fetched heroes`)),
tap(heroes => this.log('fetched heroes')),
// #docregion getHeroes-2
catchError(this.handleError('getHeroes', []))
);
@ -151,7 +151,7 @@ export class HeroService {
// #docregion log
/** Log a HeroService message with the MessageService */
private log(message: string) {
this.messageService.add('HeroService: ' + message);
this.messageService.add(`HeroService: ${message}`);
}
// #enddocregion log
}

View File

@ -20,7 +20,7 @@
</a>
<!-- #docregion delete -->
<button class="delete" title="delete hero"
(click)="delete(hero)">x</button>
(click)="delete(hero)">x</button>
<!-- #enddocregion delete -->
</li>
</ul>

View File

@ -1,6 +1,7 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { HeroesComponent } from './heroes.component';
import { HttpClientTestingModule } from '@angular/common/http/testing';
describe('HeroesComponent', () => {
let component: HeroesComponent;
@ -8,7 +9,8 @@ describe('HeroesComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HeroesComponent ]
declarations: [ HeroesComponent ],
imports: [RouterTestingModule.withRoutes([]), HttpClientTestingModule],
})
.compileComponents();
}));

View File

@ -30,7 +30,7 @@ export class HeroService {
getHeroes (): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
tap(heroes => this.log(`fetched heroes`)),
tap(heroes => this.log('fetched heroes')),
catchError(this.handleError('getHeroes', []))
);
}
@ -123,6 +123,6 @@ export class HeroService {
/** Log a HeroService message with the MessageService */
private log(message: string) {
this.messageService.add('HeroService: ' + message);
this.messageService.add(`HeroService: ${message}`);
}
}

View File

@ -8,6 +8,7 @@
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true
}
}

View File

@ -8,10 +8,8 @@
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [
"./node_modules/@types/"
]
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true
},
"compileOnSave": true,
"exclude": [

View File

@ -1,6 +1,6 @@
// #docregion
import { platformBrowser } from '@angular/platform-browser';
import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory';
import { AppModuleNgFactory } from './app.module.ngfactory';
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

View File

@ -3,7 +3,7 @@
import { ActivatedRoute } from '@angular/router';
// #enddocregion activatedroute
import { Observable } from 'rxjs';
import { Observable, of } from 'rxjs';
import { async, TestBed } from '@angular/core/testing';
@ -21,7 +21,7 @@ function xyzPhoneData(): PhoneData {
class MockPhone {
get(id: string): Observable<PhoneData> {
return Observable.of(xyzPhoneData());
return of(xyzPhoneData());
}
}

View File

@ -2,7 +2,7 @@
// #docregion
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { Observable, of } from 'rxjs';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SpyLocation } from '@angular/common/testing';
@ -15,7 +15,7 @@ class ActivatedRouteMock {
class MockPhone {
query(): Observable<PhoneData[]> {
return Observable.of([
return of([
{name: 'Nexus S', snippet: '', images: []},
{name: 'Motorola DROID', snippet: '', images: []}
]);

View File

@ -9,10 +9,8 @@
"lib": ["es2015", "dom"],
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [
"./node_modules/@types/"
]
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true
},
"files": [
@ -21,7 +19,6 @@
],
"angularCompilerOptions": {
"genDir": "aot",
"skipMetadataEmit" : true
"skipMetadataEmit" : true
}
}

View File

@ -8,10 +8,8 @@
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [
"./node_modules/@types/"
]
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true
},
"compileOnSave": true,
"exclude": [

View File

@ -3,7 +3,7 @@
import { ActivatedRoute } from '@angular/router';
// #enddocregion activatedroute
import { Observable } from 'rxjs';
import { Observable, of } from 'rxjs';
import { async, TestBed } from '@angular/core/testing';
@ -21,7 +21,7 @@ function xyzPhoneData(): PhoneData {
class MockPhone {
get(id: string): Observable<PhoneData> {
return Observable.of(xyzPhoneData());
return of(xyzPhoneData());
}
}

View File

@ -2,7 +2,7 @@
// #docregion routestuff
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { Observable, of } from 'rxjs';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SpyLocation } from '@angular/common/testing';
@ -17,7 +17,7 @@ class ActivatedRouteMock {
class MockPhone {
query(): Observable<PhoneData[]> {
return Observable.of([
return of([
{name: 'Nexus S', snippet: '', images: []},
{name: 'Motorola DROID', snippet: '', images: []}
]);

View File

@ -8,10 +8,8 @@
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [
"./node_modules/@types/"
]
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true
},
"compileOnSave": true,
"exclude": [

View File

@ -1,12 +0,0 @@
// #docregion
var path = require('path');
var _root = path.resolve(__dirname, '..');
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [_root].concat(args));
}
exports.root = root;
// #enddocregion

View File

@ -1,17 +0,0 @@
// #docregion
Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/zone-testing');
var appContext = require.context('../src', true, /\.spec\.ts/);
appContext.keys().forEach(appContext);
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());

View File

@ -1,39 +0,0 @@
// #docregion
var webpackConfig = require('./webpack.test');
module.exports = function (config) {
var _config = {
basePath: '',
frameworks: ['jasmine'],
files: [
{pattern: './config/karma-test-shim.js', watched: false}
],
preprocessors: {
'./config/karma-test-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
singleRun: true
};
config.set(_config);
};
// #enddocregion

View File

@ -1,81 +0,0 @@
// #docplaster
// #docregion
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');
module.exports = {
// #docregion entries, one-entry, two-entries
entry: {
// #enddocregion one-entry, two-entries
'polyfills': './src/polyfills.ts',
// #docregion two-entries
'vendor': './src/vendor.ts',
// #docregion one-entry
'app': './src/main.ts'
},
// #enddocregion entries, one-entry, two-entries
// #docregion resolve
resolve: {
extensions: ['.ts', '.js']
},
// #enddocregion resolve
// #docregion loaders
module: {
rules: [
{
test: /\.ts$/,
loaders: [
{
loader: 'awesome-typescript-loader',
options: { configFileName: helpers.root('src', 'tsconfig.json') }
} , 'angular2-template-loader'
]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[hash].[ext]'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader?sourceMap' })
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw-loader'
}
]
},
// #enddocregion loaders
// #docregion plugins
plugins: [
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)@angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
// #enddocregion plugins
};
// #enddocregion

View File

@ -1,26 +0,0 @@
// #docregion
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
module.exports = webpackMerge(commonConfig, {
devtool: 'cheap-module-eval-source-map',
output: {
path: helpers.root('dist'),
publicPath: '/',
filename: '[name].js',
chunkFilename: '[id].chunk.js'
},
plugins: [
new ExtractTextPlugin('[name].css')
],
devServer: {
historyApiFallback: true,
stats: 'minimal'
}
});
// #enddocregion

View File

@ -1,41 +0,0 @@
// #docregion
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
module.exports = webpackMerge(commonConfig, {
devtool: 'source-map',
output: {
path: helpers.root('dist'),
publicPath: '/',
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].chunk.js'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
mangle: {
keep_fnames: true
}
}),
new ExtractTextPlugin('[name].[hash].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
}),
new webpack.LoaderOptionsPlugin({
htmlLoader: {
minimize: false // workaround for ng2
}
})
]
});
// #enddocregion

View File

@ -1,55 +0,0 @@
// #docregion
var webpack = require('webpack');
var helpers = require('./helpers');
module.exports = {
devtool: 'inline-source-map',
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
loaders: [
{
loader: 'awesome-typescript-loader',
options: { configFileName: helpers.root('src', 'tsconfig.json') }
} , 'angular2-template-loader'
]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'null-loader'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: 'null-loader'
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw-loader'
}
]
},
plugins: [
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)@angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
)
]
}
// #enddocregion

View File

@ -1,21 +0,0 @@
'use strict'; // necessary for es6 output in node
import { browser, element, by } from 'protractor';
describe('QuickStart E2E Tests', function () {
let expectedMsg = 'Hello from Angular App with Webpack';
beforeEach(function () {
browser.get('');
});
it(`should display: ${expectedMsg}`, function () {
expect(element(by.css('h1')).getText()).toEqual(expectedMsg);
});
it('should display an image', function () {
expect(element(by.css('img')).isPresent()).toBe(true);
});
});

View File

@ -1,5 +0,0 @@
{
"build": "build:webpack",
"run": "serve:cli",
"projectType": "systemjs"
}

View File

@ -1,2 +0,0 @@
// #docregion
module.exports = require('./config/karma.conf.js');

View File

@ -1,49 +0,0 @@
{
"name": "angular2-webpack",
"version": "1.0.0",
"description": "A webpack starter for Angular",
"scripts": {
"start": "webpack-dev-server --inline --progress --port 8080",
"test": "karma start",
"build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
},
"license": "MIT",
"dependencies": {
"@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"
},
"devDependencies": {
"@types/node": "^6.0.45",
"@types/jasmine": "2.5.36",
"angular2-template-loader": "^0.6.0",
"awesome-typescript-loader": "^3.0.4",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "2.0.0-beta.5",
"file-loader": "^0.9.0",
"html-loader": "^0.4.3",
"html-webpack-plugin": "^2.16.1",
"jasmine-core": "^2.4.1",
"karma": "^1.2.0",
"karma-chrome-launcher": "^2.0.0",
"karma-jasmine": "^1.0.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.1",
"null-loader": "^0.1.1",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.2",
"style-loader": "^0.13.1",
"typescript": "~2.3.1",
"webpack": "2.2.1",
"webpack-dev-server": "2.4.1",
"webpack-merge": "^3.0.0"
}
}

View File

@ -1,9 +0,0 @@
/* #docregion */
main {
padding: 1em;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
margin-top: 50px;
display: block;
}
/* #enddocregion */

View File

@ -1,7 +0,0 @@
<!-- #docregion -->
<main>
<h1>Hello from Angular App with Webpack</h1>
<img src="../assets/images/angular.png">
</main>
<!-- #enddocregion -->

View File

@ -1,16 +0,0 @@
// #docregion
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('App', () => {
beforeEach(() => {
TestBed.configureTestingModule({ declarations: [AppComponent]});
});
it ('should work', () => {
let fixture = TestBed.createComponent(AppComponent);
expect(fixture.componentInstance instanceof AppComponent).toBe(true, 'should create AppComponent');
});
});
// #enddocregion

View File

@ -1,16 +0,0 @@
// #docplaster
// #docregion
// #docregion component
import { Component } from '@angular/core';
// #enddocregion component
import '../assets/css/styles.css';
// #docregion component
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent { }
// #enddocregion

View File

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

View File

@ -1,6 +0,0 @@
/* #docregion */
body {
background: #0147A7;
color: #fff;
}
/* #enddocregion */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,14 +0,0 @@
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<base href="/">
<title>Angular With Webpack</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
<!-- #enddocregion -->

View File

@ -1,14 +0,0 @@
// #docregion
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app/app.module';
// #docregion enable-prod
if (process.env.ENV === 'production') {
enableProdMode();
}
// #enddocregion enable-prod
platformBrowserDynamic().bootstrapModule(AppModule);
// #enddocregion

View File

@ -1,12 +0,0 @@
// #docregion
import 'core-js/es6';
import 'core-js/es7/reflect';
require('zone.js/dist/zone');
if (process.env.ENV === 'production') {
// Production
} else {
// Development and test
Error['stackTraceLimit'] = Infinity;
require('zone.js/dist/long-stack-trace-zone');
}

View File

@ -1,13 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es2015", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}

View File

@ -1,18 +0,0 @@
// TODO(i): this no longer works. we need to review this example and if absolutely necessary rewrite it to use the
// rxjs-compat package
// #docregion
// Angular
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
import '@angular/router';
// RxJS
import 'rxjs';
// Other vendors for example jQuery, Lodash or Bootstrap
// You can import js, ts, css, sass, ...
// #enddocregion

View File

@ -1,3 +0,0 @@
// #docregion
module.exports = require('./config/webpack.dev.js');
// #enddocregion

View File

@ -1,12 +0,0 @@
{
"files":[
"!**/*.d.ts",
"!**/*.js",
"!**/*.[0-9].*",
"config/**/*",
"webpack.config.js",
"karma.webpack.conf.js"
],
"removeSystemJsConfig": true,
"type": "webpack"
}

View File

@ -895,7 +895,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### lowercase
<code-example hideCopy>
&lt;div>{{movie.title | lowercase}}&lt;/div>
&lt;td>{{movie.title | lowercase}}&lt;/td>
</code-example>

View File

@ -97,6 +97,9 @@ You can control your app compilation by providing template compiler options in t
}
}
```
### *enableResourceInlining*
This options tell the compiler to replace the `templateUrl` and `styleUrls` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
When enabled, the `.js` output of ngc will have no lazy-loaded `templateUrl` or `styleUrls`.
### *skipMetadataEmit*
@ -236,14 +239,14 @@ Tells the compiler to generate all the possible generated files even if they are
how `bazel` rules track file dependencies. It is not recommended to use this option outside of the `bazel`
rules.
### *enableIvy*
### *enableIvy*
Tells the compiler to generate definitions using the Render3 style code generation. This option defaults to `false`.
Tells the compiler to generate definitions using the Render3 style code generation. This option defaults to `false`.
Not all features are supported with this option enabled. It is only supported
for experimentation and testing of Render3 style code generation.
Not all features are supported with this option enabled. It is only supported
for experimentation and testing of Render3 style code generation.
*Note*: Is it not recommended to use this option as it is not yet feature complete with the Render2 code generation.
*Note*: Is it not recommended to use this option as it is not yet feature complete with the Render2 code generation.
## Angular Metadata and AOT

View File

@ -1,175 +0,0 @@
<div class="breadcrumb">
<a href="#">API<a> / <a href="#">@core<a>
</div>
<header class="api-header">
<h1><label class="api-status-label experimental">experimental</label><label class="api-type-label class">class</label>Class Name</h1>
</header>
<div class="page-actions">
<a href="#"><label class="raised page-label"><i class="material-icons">mode_edit</i>suggest edits</label></a>
<a href="#"><label class="raised page-label"><i class="material-icons">code</i>view source</label></a>
</div>
<p>Class description goes here. This is a short and to the point one or two sentence description that easily introduces the reader to the class.</p>
<div class="api-body">
<section>
<h2>Overview</h2>
<code-example language="ts" hidecopy="true" ng-version="5.2.0"><aio-code class="simple-code" ng-reflect-ng-class="[object Object]" ng-reflect-code="
class <a href=&quot;api/core/Compi" ng-reflect-hide-copy="true" ng-reflect-language="ts" ng-reflect-linenums="" ng-reflect-path="" ng-reflect-region="" ng-reflect-title=""><pre class="prettyprint lang-ts">
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/core/Compiler" class="code-anchor"><span class="typ">Compiler</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleSync"><span class="pln">compileModuleSync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">NgModuleFactory</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAsync"><span class="pln">compileModuleAsync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun">&lt;</span><span class="typ">NgModuleFactory</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsSync"><span class="pln">compileModuleAndAllComponentsSync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">ModuleWithComponentFactories</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsAsync"><span class="pln">compileModuleAndAllComponentsAsync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun">&lt;</span><span class="typ">ModuleWithComponentFactories</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#clearCache"><span class="pln">clearCache</span><span class="pun">():</span><span class="pln"> </span><span class="kwd">void</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#clearCacheFor"><span class="pln">clearCacheFor</span><span class="pun">(</span><span class="pln">type</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">any</span><span class="pun">&gt;)</span></a><span class="pln">
</span><span class="pun">}</span></code>
</pre></aio-code></code-example>
</section>
<section>
<h2>Description</h2>
<p>The longer class description goes here which can include multiple paragraphs.</p>
</p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
<h3>Subclasses</h3>
<ul>
<li><a href="#">Subclass1</a></li>
<li><a href="#">Subclass2</a></li>
<li><a href="#">Subclass3</a></li>
</ul>
<h3>See Also</h3>
<ul>
<li><a href="#">Link1</a></li>
<li><a href="#">Link2</a></li>
</ul>
</section>
<section>
<h2>Constructor</h2>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
</section>
<section>
<h2>Properties</h2>
<table class="is-full-width list-table">
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code><strong>Property1</strong></code>
</td>
<td><label class="property-type-label type">Type</label></td>
<td>Description goes here</td>
</tr>
<tr>
<td>
<code><strong>Property2</strong></code>
</td>
<td>Type</td>
<td>Description goes here</td>
</tr>
<tr>
<td>
<code><strong>Property3</strong></code>
</td>
<td>Type</td>
<td>Description goes here</td>
</tr>
</tbody>
</table>
</section>
<section class="api-method">
<h2>Methods</h2>
<table class="is-full-width item-table">
<thead>
<tr>
<th>Method1Name( )</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Description goes here</p>
<br>
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
</td>
</tr>
</tbody>
</table>
<table class="is-full-width api-method item-table">
<thead>
<tr>
<th>Method2Name( )</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Description goes here</p>
<hr>
<h5>Declaration</h5>
<code-example language="ts" hidecopy="true" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-ts">
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/animations/AnimationBuilder" class="code-anchor"><span class="typ">AnimationBuilder</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln"></span><a class="code-anchor" href="api/animations/AnimationBuilder#build"><span class="pln">build</span><span class="pun">(</span><span class="pln">animation</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pun">[]):</span><span class="pln"> </span><span class="typ">AnimationFactory</span></a><span class="pln"></span><span class="pun">}</span></code></pre>
</aio-code>
</code-example>
<h6>Parameters</h6>
<h6>Returns</h6>
<p>Returns information and results goes here.</p>
<h6>Errors</h6>
<p>Error information goes here</p>
<hr>
<p>Further details provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p><hr>
<h6>Overloads</h6>
<table class="is-full-width">
<tbody>
<tr>
<td>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
</td>
<td>Description goes here</td>
</tr>
<tr>
<td>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
</td>
<td>Description goes here</td>
</tr>
</tbody>
</table>
<hr>
<h5>Example: Descriptive Title of Method Example</h5>
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
</td>
</tr>
</tbody>
</table>
</section>
<section>
<h2>Example: Descriptive Title of Combined Example Goes Here</h2>
<p>Intro description text about what the example is and how it can be used.</p>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
<p>Further explanation provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p>
</section>
</div>

View File

@ -8,9 +8,10 @@ A _component_ controls a patch of screen called a *view*. For example, individua
* The list of heroes.
* The hero editor.
You define a component's application logic&mdash;what it does to support the view&mdash;inside a class. The class interacts with the view through an API of properties and methods.
You define a component's application logic&mdash;what it does to support the view&mdash;inside a class.
The class interacts with the view through an API of properties and methods.
For example, the `HeroListComponent` has a `heroes` property that returns an array of heroes that it acquires from a service. `HeroListComponent` also has a `selectHero()` method that sets a `selectedHero` property when the user clicks to choose a hero from that list.
For example, the `HeroListComponent` has a `heroes` property that holds an array of heroes. It also has a `selectHero()` method that sets a `selectedHero` property when the user clicks to choose a hero from that list. The component acquires the heroes from a service, which is a TypeScript [parameter property[(http://www.typescriptlang.org/docs/handbook/classes.html#parameter-properties) on the constructor. The service is provided to the component through the dependency injection system.
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" title="src/app/hero-list.component.ts (class)" region="class"></code-example>
@ -39,8 +40,7 @@ Angular inserts an instance of the `HeroListComponent` view between those tags.
* `templateUrl`: The module-relative address of this component's HTML template. Alternatively, you can provide the HTML template inline, as the value of the `template` property. This template defines the component's _host view_.
* `providers`: An array of **dependency injection providers** for services that the component requires. In the example, this tells Angular that the component's constructor requires a `HeroService` instance
in order to get the list of heroes to display.
* `providers`: An array of **dependency injection providers** for services that the component requires. In the example, this tells Angular how provide the `HeroService` instance that the component's constructor uses to get the list of heroes to display.
<hr/>

View File

@ -88,7 +88,8 @@ For example, import Angular's `Component` decorator from the `@angular/core` lib
<code-example path="architecture/src/app/app.component.ts" region="import" linenums="false"></code-example>
You also import NgModules from Angular _libraries_ using JavaScript import statements:
You also import NgModules from Angular _libraries_ using JavaScript import statements.
For example, the following code imports the `BrowserModule` NgModule from the `platform-browser` library:
<code-example path="architecture/src/app/mini-app.ts" region="import-browser-module" linenums="false"></code-example>

View File

@ -60,11 +60,29 @@ The process of `HeroService` injection looks something like this:
### Providing services
You must register at least one *provider* of any service you are going to use. You can register providers in modules or in components.
You must register at least one *provider* of any service you are going to use. A service can register providers itself, making it available everywhere, or you can register providers with specific modules or components. You register providers in the metadata of the service (in the `@Injectable` decorator), or in the `@NgModule` or `@Component` metadata
* When you add providers to the [root module](guide/architecture-modules), the same instance of a service is available to all components in your app.
* By default, the Angular CLI command `ng generate service` registers a provider with the root injector for your service by including provider metadata in the `@Injectable` decorator. The tutorial uses this method to register the provider of HeroService class definition:
<code-example path="architecture/src/app/app.module.ts" linenums="false" title="src/app/app.module.ts (module providers)" region="providers"></code-example>
```
@Injectable({
providedIn: 'root',
})
```
When you provide the service at the root level, Angular creates a single, shared instance of HeroService and injects into any class that asks for it. Registering the provider in the `@Injectable` metadata also allows Angular to optimize an app by removing the service if it turns out not to be used after all.
* When you register a provider with a [specific NgModule](guide/architecture-modules), the same instance of a service is available to all components in that NgModule. To register at this level, use the `providers` property of the `@NgModule` decorator:
```
@NgModule({
providers: [
BackendService,
Logger
],
...
})
```
* When you register a provider at the component level, you get a new instance of the
service with each new instance of that component. At the component level, register a service provider in the `providers` property of the `@Component` metadata:

View File

@ -96,7 +96,7 @@ Now edit the generated `src/app/highlight.directive.ts` to look as follows:
The `import` statement specifies an additional `ElementRef` symbol from the Angular `core` library:
You use the `ElementRef`in the directive's constructor
You use the `ElementRef` in the directive's constructor
to [inject](guide/dependency-injection) a reference to the host DOM element,
the element to which you applied `appHighlight`.

View File

@ -164,7 +164,7 @@ They are _not inherited_ by any components nested within the template nor by any
</div>
The CLI defines an empty `styles` array when you create the component with the `--inline-styles` flag.
The CLI defines an empty `styles` array when you create the component with the `--inline-style` flag.
<code-example language="sh" class="code-shell">
ng generate component hero-app --inline-style
@ -189,7 +189,7 @@ They are _not inherited_ by any components nested within the template nor by any
<div class="l-sub-section">
You can specify more than one styles file or even a combination of `style` and `styleUrls`.
You can specify more than one styles file or even a combination of `styles` and `styleUrls`.
</div>
@ -280,12 +280,14 @@ To control how this encapsulation happens on a *per
component* basis, you can set the *view encapsulation mode* in the component metadata.
Choose from the following modes:
* `Native` view encapsulation uses the browser's native shadow DOM implementation (see
* `ShadowDom` view encapsulation uses the browser's native shadow DOM implementation (see
[Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)
on the [MDN](https://developer.mozilla.org) site)
to attach a shadow DOM to the component's host element, and then puts the component
view inside that shadow DOM. The component's styles are included within the shadow DOM.
* `Native` view encapsulation uses a now deprecated version of the browser's native shadow DOM implementation - [learn about the changes](https://hayato.io/2016/shadowdomv1/).
* `Emulated` view encapsulation (the default) emulates the behavior of shadow DOM by preprocessing
(and renaming) the CSS code to effectively scope the CSS to the component's view.
For details, see [Appendix 1](guide/component-styles#inspect-generated-css).
@ -300,8 +302,8 @@ To set the components encapsulation mode, use the `encapsulation` property in th
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.native" title="src/app/quest-summary.component.ts" linenums="false">
</code-example>
`Native` view encapsulation only works on browsers that have native support
for shadow DOM (see [Shadow DOM v0](http://caniuse.com/#feat=shadowdom) on the
`ShadowDom` view encapsulation only works on browsers that have native support
for shadow DOM (see [Shadow DOM v1](https://caniuse.com/#feat=shadowdomv1) on the
[Can I use](http://caniuse.com) site). The support is still limited,
which is why `Emulated` view encapsulation is the default mode and recommended
in most cases.

View File

@ -32,7 +32,7 @@ from the [The Tour of Heroes](tutorial/).
</code-tabs>
The `HeroesComponent` is the top-level heroes component.
It's only purpose is to display the `HeroListComponent`
Its only purpose is to display the `HeroListComponent`
which displays a list of hero names.
This version of the `HeroListComponent` gets its `heroes` from the `HEROES` array, an in-memory collection

View File

@ -152,7 +152,7 @@ Install `source-map-explorer`:
Build your app for production _including the source maps_
<code-example language="none" class="code-shell">
ng build --prod --sourcemaps
ng build --prod --source-map
</code-example>
List the generated bundles in the `dist/` folder.

View File

@ -31,6 +31,8 @@ Here are a few essential commands for guide page authors.
1. http://localhost:4200/ &mdash; browse to the app running locally.
You can combine `yarn docs-watch` and `yarn start` into one command with `yarn serve-and-sync`.
## Guide pages
All but a few guide pages are [markdown](https://daringfireball.net/projects/markdown/syntax "markdown") files with an `.md` extension.

View File

@ -92,7 +92,7 @@ built-in validators&mdash;this time, in function form. See below:
{@a reactive-component-class}
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="form-group" title="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="form-group" title="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
</code-example>
Note that:
@ -148,7 +148,7 @@ at which point the form uses the last value emitted for validation.
In reactive forms, custom validators are fairly simple to add. All you have to do is pass the function directly
to the `FormControl`.
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="custom-validator" title="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="custom-validator" title="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
</code-example>
### Adding to template-driven forms
@ -208,5 +208,80 @@ set the color of each form control's border.
</code-example>
## Cross field validation
This section shows how to perform cross field validation. It assumes some basic knowledge of creating custom validators.
<div class="l-sub-section">
If you haven't created custom validators before, start by reviewing the [custom validators section](guide/form-validation#custom-validators).
</div>
In the following section, we will make sure that our heroes do not reveal their true identities by filling out the Hero Form. We will do that by validating that the hero names and alter egos do not match.
### Adding to reactive forms
The form has the following structure:
```javascript
const heroForm = new FormGroup({
'name': new FormControl(),
'alterEgo': new FormControl(),
'power': new FormControl()
});
```
Notice that the name and alterEgo are sibling controls. To evaluate both controls in a single custom validator, we should perform the validation in a common ancestor control: the `FormGroup`. That way, we can query the `FormGroup` for the child controls which will allow us to compare their values.
To add a validator to the `FormGroup`, pass the new validator in as the second argument on creation.
```javascript
const heroForm = new FormGroup({
'name': new FormControl(),
'alterEgo': new FormControl(),
'power': new FormControl()
}, { validators: identityRevealedValidator });
```
The validator code is as follows:
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-validator" title="shared/identity-revealed.directive.ts" linenums="false">
</code-example>
The identity validator implements the `ValidatorFn` interface. It takes an Angular control object as an argument and returns either null if the form is valid, or `ValidationErrors` otherwise.
First we retrieve the child controls by calling the `FormGroup`'s [get](api/forms/AbstractControl#get) method. Then we simply compare the values of the `name` and `alterEgo` controls.
If the values do not match, the hero's identity remains secret, and we can safely return null. Otherwise, the hero's identity is revealed and we must mark the form as invalid by returning an error object.
Next, to provide better user experience, we show an appropriate error message when the form is invalid.
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="cross-validation-error-message" title="reactive/hero-form-template.component.html" linenums="false">
</code-example>
Note that we check if:
- the `FormGroup` has the cross validation error returned by the `identityRevealed` validator,
- the user is yet to [interact](guide/form-validation#why-check-dirty-and-touched) with the form.
### Adding to template driven forms
First we must create a directive that will wrap the validator function. We provide it as the validator using the `NG_VALIDATORS` token. If you are not sure why, or you do not fully understand the syntax, revisit the previous [section](guide/form-validation#adding-to-template-driven-forms).
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-directive" title="shared/identity-revealed.directive.ts" linenums="false">
</code-example>
Next, we have to add the directive to the html template. Since the validator must be registered at the highest level in the form, we put the directive on the `form` tag.
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-register-validator" title="template/hero-form-template.component.html" linenums="false">
</code-example>
To provide better user experience, we show an appropriate error message when the form is invalid.
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-error-message" title="template/hero-form-template.component.html" linenums="false">
</code-example>
Note that we check if:
- the form has the cross validation error returned by the `identityRevealed` validator,
- the user is yet to [interact](guide/form-validation#why-check-dirty-and-touched) with the form.
This completes the cross validation example. We managed to:
- validate the form based on the values of two sibling controls,
- show a descriptive error message after the user interacted with the form and the validation failed.
**You can run the <live-example></live-example> to see the complete reactive and template-driven example code.**

View File

@ -152,7 +152,8 @@ nothing to distinguish it from any component you've written before.
Understanding this component requires only the Angular concepts covered in previous pages.
* The code imports the Angular core library and the `Hero` model you just created.
* The `@Component` selector value of "hero-form" means you can drop this form in a parent template with a `<hero-form>` tag.
* The `@Component` selector value of "app-hero-form" means you can drop this form in a parent
template with a `<app-hero-form>` tag.
* The `templateUrl` property points to a separate file for the template HTML.
* You defined dummy data for `model` and `powers`, as befits a demo.

View File

@ -44,25 +44,25 @@ of some of the things they contain:
<tr>
<td><code>FormsModule</code></td>
<td><code>@angular/forms</code></td>
<td>When you build template driven forms (includes <code>NgModel</code>)</td>
<td>When you want to build template driven forms (includes <code>NgModel</code>)</td>
</tr>
<tr>
<td><code>ReactiveFormsModule</code></td>
<td><code>@angular/forms</code></td>
<td>When building reactive forms</td>
<td>When you want to build reactive forms</td>
</tr>
<tr>
<td><code>RouterModule</code></td>
<td><code>@angular/router</code></td>
<td>For Routing and when you want to use <code>RouterLink</code>,<code>.forRoot()</code>, and <code>.forChild()</code></td>
<td>When you want to use <code>RouterLink</code>, <code>.forRoot()</code>, and <code>.forChild()</code></td>
</tr>
<tr>
<td><code>HttpClientModule</code></td>
<td><code>@angular/common/http</code></td>
<td>When you to talk to a server</td>
<td>When you want to talk to a server</td>
</tr>
</table>

View File

@ -114,19 +114,23 @@ The following class types can be declared:
A [decorator](guide/glossary#decorator) statement immediately before a field in a class definition that declares the type of that field. Some examples are `@Input` and `@Output`.
{@a cli}
## CLI
The [Angular CLI](https://cli.angular.io/) is a command-line tool that can create a project, add files, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
The [Angular CLI](https://cli.angular.io/) is a command-line tool for managing the Angular development cycle. Use it to create the initial filesystem scaffolding for a [workspace](guide/glossary#workspace) or [project](guide/glossary#project), and to run [schematics](guide/glossary#schematic) that add and modify code for initial generic versions of various elements. The tool supports all stages of the development cycle, including building, testing, bundling, and deployment.
Learn more in the [Getting Started](guide/quickstart) guide.
* To begin using the CLI for a new project, see [Getting Started](guide/quickstart) guide.
* To learn more about the full capabilities of the CLI, see the [Angular CLI documentation].(https://github.com/angular/angular-cli/wiki).
{@a component}
## Component
A class with the `@Component` [decorator](guide/glossary#decorator) that associates it with a companion [template](guide/glossary#template).
A class with the `@Component` [decorator](guide/glossary#decorator) that associates it with a companion [template](guide/glossary#template). Together, the component and template define a [view](guide/glossary#view).
A component is a special type of [directive](guide/glossary#directive) that represents a [view](guide/glossary#view).The `@Component` decorator extends the `@Directive` decorator with template-oriented features.
A component is a special type of [directive](guide/glossary#directive).
The `@Component` decorator extends the `@Directive` decorator with template-oriented features.
An Angular component class is responsible for exposing data and handling most of the view's display and user-interaction logic through [data binding](guide/glossary#data-binding).
@ -208,7 +212,8 @@ See [Class decorator](guide/glossary#class-decorator), [Class field decorator](g
A design pattern and mechanism for creating and delivering parts of an application (dependencies) to other parts of an application that require them.
In Angular, dependencies are typically services, but can also be values, such as strings or functions. An [injector](guide/glossary#injector) for an app (created automatically during bootstrap) creates dependencies when needed, using a registered [provider](guide/glossary#provider) of the service or value. Different providers can provide different implementations of the same service.
In Angular, dependencies are typically services, but can also be values, such as strings or functions.
An [injector](guide/glossary#injector) for an app (created automatically during bootstrap) instantiates dependencies when needed, using a configured [provider](guide/glossary#provider) of the service or value.
Learn more in the [Dependency Injection](guide/dependency-injection) guide.
@ -280,7 +285,7 @@ Compare [Custom element](guide/glossary#custom-element).
## Entry point
A JavaScript ID that makes parts of an NPM package available for import by other code.
A JavaScript symbol that makes parts of an npm package available for import by other code.
The Angular [scoped packages](guide/glossary#scoped-package) each have an entry point named `index`.
Within Angular, use [NgModules](guide/glossary#ngmodule) to achieve the same result.
@ -310,7 +315,17 @@ Both a [service](guide/glossary#service) and a [component](guide/glossary#compon
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). Injectors are created for NgModules automatically as part of the bootstrap process, and inherited through the component hierarchy.
using a configured [provider](guide/glossary#provider).
Injectors are created for NgModules automatically as part of the bootstrap process
and are inherited through the component hierarchy.
* An injector provides a singleton instance of a dependency, and can inject this same instance in multiple components.
* A hierarchy of injectors at the NgModule and component level can provide different instances of a dependency to their own components and child components.
* You can configure injectors with different providers that can provide different implementations of the same dependency.
Learn more about the injector hierarchy in the [Dependency Injection guide](guide/hierarchical-dependency-injection).
## Input
@ -373,6 +388,17 @@ Lazy loading speeds up application load time by splitting the application into m
For example, dependencies can be lazy-loaded as needed&emdash;as opposed to "eager-loaded" modules that are required by the root module, and are thus loaded on launch.
Similarly, the [router](guide/glossary#router) can load child views only when the parent view is activated, and you can build custom elements that can be loaded into an Angular app when needed.
{@a library}
## Library
In Angular, a [project](guide/glossary#project) that provides functionality that can be included in other Angular apps. A library is not a complete Angular app, and it cannot run independently.
* Library developers can use the [CLI](guide/glossary#cli) to `generate` scaffolding for a new library in an existing [workspace](guide/glossary#workspace), and can publish a library as an `npm` package.
* App developers can use the [CLI](guide/glossary#cli) to `add` a published library for use with an app in the same [workspace](guide/glossary#workspace).
## Lifecycle hook
An interface that allows you to tap into the lifecycle of [directives](guide/glossary#directive) and [components](guide/glossary#component) as they are created, updated, and destroyed.
@ -402,7 +428,7 @@ In general, a module collects a block of code dedicated to a single purpose. Ang
In JavaScript (ECMAScript), each file is a module and all objects defined in the file belong to that module. Objects can exported, making them public, and public objects can be imported for use by other modules.
Angular ships as a collection of JavaScript modules, or libraries. Each Angular library name begins with the `@angular` prefix. Install them with the NPM package manager and import parts of them with JavaScript `import` declarations.
Angular ships as a collection of JavaScript modules, or libraries. Each Angular library name begins with the `@angular` prefix. Install them with the npm package manager and import parts of them with JavaScript `import` declarations.
Compare the Angular [NgModule](guide/glossary#ngmodule).
@ -470,8 +496,13 @@ To learn more, see the [pipes](guide/pipes) page.
## Polyfill
An [NPM package](guide/npm-packages) that plugs gaps in a browser's JavaScript implementation. See the [Browser Support](guide/browser-support) guide for polyfills that support particular functionality for particular platforms.
An [npm package](guide/npm-packages) that plugs gaps in a browser's JavaScript implementation. See the [Browser Support](guide/browser-support) guide for polyfills that support particular functionality for particular platforms.
{@a project}
## Project
In Angular, a folder within a [workspace](guide/glossary#workspace) that contains an Angular app or [library](guide/glossary#library). A workspace can contain multiple projects. All apps in a workspace can use libraries in the same workspace.
## Provider
@ -531,9 +562,24 @@ For more information, see the [Routing & Navigation](guide/router) page.
{@a S}
{@a schematic}
## Schematic
A scaffolding library that defines how to generate or transform a programming project by creating, modifying, refactoring, or moving files and code.
The Angular [CLI](guide/glossary#cli) uses schematics to generate and modify [Angular projects](guide/glossary#project) and parts of projects.
* Angular provides a set of schematics for use with the CLI.
For details, see [Angular CLI documentation].(https://github.com/angular/angular-cli/wiki).
* Library developers can create schematics that enable the CLI to generate their published libraries.
For more information, see https://www.npmjs.com/package/@angular-devkit/schematics.
## Scoped package
A way to group related NPM packages.
A way to group related npm packages.
NgModules are delivered within *scoped packages* whose names begin with the Angular *scope name* `@angular`. For example, `@angular/core`, `@angular/common`, `@angular/http`, and `@angular/router`.
Import a scoped package in the same way that you import a normal package.
@ -677,6 +723,12 @@ The view hierarchy does not imply a component hierarchy. Views that are embedded
See [Custom element](guide/glossary#custom-element)
{@a workspace}
## Workspace
In Angular, a folder that contains [projects](guide/glossary#project) (that is, apps and libraries).
The [CLI](guide/glossary#cli) `new` command creates a workspace to contain projects. Commands such as `add` and `generate`, that create or operate on apps and libraries, must be executed from within a workspace folder.
{@a X}

View File

@ -450,7 +450,7 @@ Here is a `searchHeroes` method that queries for heroes whose names contain the
If there is a search term, the code constructs an options object with an HTML URL-encoded search parameter. If the term were "foo", the GET request URL would be `api/heroes/?name=foo`.
The `HttpParms` are immutable so you'll have to use the `set()` method to update the options.
The `HttpParams` are immutable so you'll have to use the `set()` method to update the options.
### Debouncing requests
@ -1034,7 +1034,7 @@ Call `request.flush()` with an error message, as seen in the following example.
<code-example
path="http/src/testing/http-client.spec.ts"
region="network-error"
region="404"
linenums="false">
</code-example>
@ -1044,4 +1044,4 @@ Alternatively, you can call `request.error()` with an `ErrorEvent`.
path="http/src/testing/http-client.spec.ts"
region="network-error"
linenums="false">
</code-example>
</code-example>

View File

@ -219,7 +219,7 @@ configure services in root and feature modules respectively.
Angular doesn't recognize these names but Angular developers do.
Follow this convention when you write similar modules with configurable service providers.
<!--KW--I don't understand how Angular doesn't understand these methods...-->
<hr/>
@ -233,9 +233,8 @@ When you import an NgModule,
Angular adds the module's service providers (the contents of its `providers` list)
to the application root injector.
This makes the provider visible to every class in the application that knows the provider's lookup token, or knows its name.
This makes the provider visible to every class in the application that knows the provider's lookup token, or name.
This is by design.
Extensibility through NgModule imports is a primary goal of the NgModule system.
Merging NgModule providers into the application injector
makes it easy for a module library to enrich the entire application with new services.
@ -247,6 +246,8 @@ If the `HeroModule` provides the `HeroService` and the root `AppModule` imports
any class that knows the `HeroService` _type_ can inject that service,
not just the classes declared in the `HeroModule`.
To limit access to a service, consider lazy loading the NgModule that provides that service. See [How do I restrict service scope to a module?](guide/ngmodule-faq#service-scope) for more information.
<hr/>
{@a q-lazy-loaded-module-provider-visibility}
@ -288,6 +289,7 @@ The `AppModule` always wins.
<hr/>
{@a service-scope}
## How do I restrict service scope to a module?
@ -335,6 +337,8 @@ You can embed the child components in the top component's template.
Alternatively, make the top component a routing host by giving it a `<router-outlet>`.
Define child routes and let the router load module components into that outlet.
Though you can limit access to a service by providing it in a lazy loaded module or providing it in a component, providing services in a component can lead to multiple instances of those services. Thus, the lazy loading is preferable.
<hr/>
{@a q-root-component-or-module}

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