Compare commits

...

469 Commits

Author SHA1 Message Date
63149810c1 docs: translate guide/creating-libraries 2020-08-24 21:19:26 -04:00
e3bc073f7b Merge branch 'creating-libraries' of github.com:angular-hispano/angular into creating-libraries 2020-08-23 20:06:24 -04:00
4b9b094c47 docs: translate guide/creating-libraries 2020-08-23 20:03:23 -04:00
75e59cc837 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:29:18 -04:00
6ad701074a Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:29:07 -04:00
fb4df0a54c Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:28:52 -04:00
7b0fba0983 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:28:40 -04:00
7bd65e5f1b Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:28:29 -04:00
c90d9fd468 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:28:18 -04:00
4bd3debef2 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:28:06 -04:00
43b1210f86 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:27:53 -04:00
189686bea1 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:26:38 -04:00
66592ac5a3 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:26:26 -04:00
066da01295 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:26:12 -04:00
03ca38a478 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:26:04 -04:00
6452285a71 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:25:56 -04:00
a81e82028a Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:25:14 -04:00
958d06fa69 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:25:05 -04:00
15b311ac9f Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:24:56 -04:00
5717054caa Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:24:44 -04:00
44cf633cb1 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:24:30 -04:00
957e152656 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:24:22 -04:00
9ccf7631c6 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:24:06 -04:00
225fdf9ac8 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:23:58 -04:00
b206732b25 Update aio/content/guide/creating-libraries.es.md
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-08-23 19:23:35 -04:00
efef4b7dc1 docs: translate guide/creating-libraries 2020-08-21 03:59:48 -04:00
92c7145139 fix(pr): template (#47)
Co-authored-by: Alejandro Lora <alejandrofpo@gmail.com>
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
Co-authored-by: Michael Prentice <splaktar@gmail.com>
2020-07-30 03:57:48 -04:00
d133525502 docs: update typo for bootstraping word 2020-07-28 23:43:28 -04:00
cd1817bf6d Update aio/content/guide/cheatsheet.md
Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-07-28 23:43:28 -04:00
0d1491b1a6 docs: implement feedback PR 2020-07-28 23:43:28 -04:00
f67774d84b Update aio/content/guide/cheatsheet.md
Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-07-28 23:43:28 -04:00
37668d159e docs: translat cheatsheet.md file to Spanish 2020-07-28 23:43:28 -04:00
38554288f5 docs(readme): aplicar sugerencias de revisión de código 2020-07-28 23:23:46 -04:00
04dcc3bceb Update README.md
Traducción del README.md al español.
2020-07-28 23:23:46 -04:00
0910a2fc0d fix(file): based on pr comments 2020-07-28 23:18:53 -04:00
3325cb2f86 fix(code): based on comments from PR reviewrs 2020-07-28 23:18:53 -04:00
a1e8443bfb fix(files): removed unecessary files 2020-07-28 23:18:53 -04:00
599d34b41e fix(comment): based on PR 2020-07-28 23:18:53 -04:00
7fd1733882 fix(pr): comments 2020-07-28 23:18:53 -04:00
2e42123870 fix(merge): conflict 2020-07-28 23:18:53 -04:00
4cbb90daf7 feat(github): traduccion de templates para issues 2020-07-28 23:18:53 -04:00
cf2663b034 docs: translate the app-shell.md file (#41)
* docs: translate the app-shell.md file

* Update aio/content/guide/app-shell.md

Co-authored-by: Christian Morante <christianmorante@outlook.com>

* Update aio/content/guide/app-shell.md

Co-authored-by: Christian Morante <christianmorante@outlook.com>

* Update aio/content/guide/app-shell.md

Co-authored-by: Christian Morante <christianmorante@outlook.com>

* add PR feedback

* docs: update 'usted'-'tú' (Grammatical person)

Co-authored-by: Christian Morante <christianmorante@outlook.com>
2020-07-27 16:21:00 -04:00
95681b16bd fix(docs): changed the way to express the idea
Changed the way to express the idea from "usted" to "tu"
2020-07-26 20:43:54 -04:00
e620827fa8 docs: traducir página de inicio, navegación, cuadro de búsqueda y pie de página 2020-07-23 01:50:03 -04:00
7f82a2c1c8 docs: fix type in lazy-load callout (#38153)
PR Close #38153
2020-07-21 14:30:46 -07:00
a9910f5991 docs: fix DOCUMENT import path (#38158) (#38159)
PR Close #38159
2020-07-21 11:35:41 -07:00
ad7046b934 feat(forms): AbstractControl to store raw validators in addition to combined validators function (#37881)
This commit refactors the way we store validators in AbstractControl-based classes:
in addition to the combined validators function that we have, we also store the original list of validators.
This is needed to have an ability to clean them up later at destroy time (currently it's problematic since
they are combined in a single function).

The change preserves backwards compatibility by making sure public APIs stay the same.
The only public API update is the change to the `AbstractControl` class constructor to extend the set
of possible types that it can accept and process (which should not be breaking).

PR Close #37881
2020-07-21 10:30:19 -07:00
d72b1e44c6 refactor(core): rename synthetic host property and listener instructions (#37145)
This commit updates synthetic host property and listener instruction names to better align with other instructions.
The `ɵɵupdateSyntheticHostBinding` instruction was renamed to `ɵɵsyntheticHostProperty` (to match the `ɵɵhostProperty`
instruction name) and `ɵɵcomponentHostSyntheticListener` was renamed to `ɵɵsyntheticHostListener` since this
instruction is generated for both Components and Directives (so 'component' is removed from the name).
This PR is a followup after PR #35568.

PR Close #37145
2020-07-21 09:09:24 -07:00
eae13e42f3 docs: add routing terms to glossary (#38053)
Update glossary to add term definitions for routing; componentless route, link parameters array, router outlet.

PR Close #38053
2020-07-20 17:09:33 -07:00
3373453736 feat(common): add ReadonlyMap in place of Map in keyValuePipe (#37311)
ReadonlyMap is a superset of Map, in keyValuePipe we do not change the value of the object so ReadonlyPipe Works right in this case and we can accomodate more types. To accomodate more types added ReadonlyMap in Key Value pipe.

Fixes #37308

PR Close #37311
2020-07-20 14:13:15 -07:00
4a6dcd006b docs(router): fix typos (#38132)
PR Close #38132
2020-07-20 14:12:21 -07:00
7c3c8d6d10 docs(common): fix selector field in NgIfAs example component (#35854)
PR Close #35854
2020-07-20 13:35:04 -07:00
655da32837 build: update pullapprove to remove @matsko from reviewer lists (#38146)
With @matsko leaving the Angular team, we need to update the pullapprove
configuration to reflect his no longer being a reviewer for file groups
throughout the repository.

PR Close #38146
2020-07-20 13:33:58 -07:00
5b31a0a294 docs: separate template syntax into multiple docs (#36954)
This is part of a re-factor of template syntax and
structure. The first phase breaks out template syntax
into multiple documents. The second phase will be
a rewrite of each doc.

Specifically, this PR does the following:

- Breaks sections of the current template syntax document each into their own page.
- Corrects the links to and from these new pages.
- Adds template syntax subsection to the left side NAV which contains all the new pages.
- Adds the new files to pullapprove.

PR Close #36954
2020-07-20 11:16:44 -07:00
5d3d8b8330 docs: add known issue for bazel (#38074)
This commit adds a known issue for windows, when running tests using
`bazal run`, instead of using `bazel test`

PR Close #38074
2020-07-20 11:15:36 -07:00
c8c74153b1 refactor(dev-infra): Update triage labels documentation (#38081)
Add new type: confusing and type: use-case labels to the triage readme as well
as clarify that freq and severity are only required for type: bug/fix

PR Close #38081
2020-07-20 11:14:46 -07:00
9dc5e8e7e2 refactor(dev-infra): allow use-case and confusing types to be marked as 'triaged' (#38081)
Some issue reports don't really fall into any of the current buckets that count
towards triage level 2: bug/fix, feature, or refactor. Some reports are:
* working as intended but confusing - the labels might be 'type: confusing', 'comp: docs', 'comp: router'
* generally working as originally designed but a use-case could be argued for a different implementation.
 This type of report is a little hard to triage; it may be neither a bug, nor feature but more of a
 'type: use-case'. These may eventually turn into a bug/fix or feature, but can't necessarily be
 put in those buckets immediately.

PR Close #38081
2020-07-20 11:14:46 -07:00
1a7a7360b0 fix(compiler): properly associate source spans for implicitly closed elements (#38126)
HTML is very lenient when it comes to closing elements, so Angular's parser has
rules that specify which elements are implicitly closed when closing a tag.
The parser keeps track of the nesting of tag names using a stack and parsing
a closing tag will pop as many elements off the stack as possible, provided
that the elements can be implicitly closed.

For example, consider the following templates:

- `<div><br></div>`, the `<br>` is implicitly closed when parsing `</div>`,
  because `<br>` is a void element.
- `<div><p></div>`, the `<p>` is implicitly closed when parsing `</div>`,
  as `<p>` is allowed to be closed by the closing of its parent element.
- `<ul><li>A <li>B</ul>`, the first `<li>` is implicitly closed when parsing
  the second `<li>`, whereas the second `<li>` would be implicitly closed when
  parsing the `</ul>`.

In all the cases above the parsed structure would be correct, however the source
span of the closing `</div>` would incorrectly be assigned to the element that
is implicitly closed. The problem was that closing an element would associate
the source span with the element at the top of the stack, however this may not
be the element that is actually being closed if some elements would be
implicitly closed.

This commit fixes the issue by assigning the end source span with the element
on the stack that is actually being closed. Any implicitly closed elements that
are popped off the stack will not be assigned an end source span, as the
implicit closing implies that no ending element is present.

Note that there is a difference between self-closed elements such as `<input/>`
and implicitly closed elements such as `<input>`. The former does have an end
source span (identical to its start source span) whereas the latter does not.

Fixes #36118
Resolves FW-2004

PR Close #38126
2020-07-20 10:02:06 -07:00
8edf5ba29d refactor(compiler): remove unused parser methods (#38126)
These methods are no longer used so they can safely be removed.

PR Close #38126
2020-07-20 10:02:06 -07:00
72f1eec3ad docs(core): add note about not mutating multi provider arrays (#37645)
Adds a note to the provider docs that users shouldn't mutate an array that
is returned from a `multi` provider, because it can cause unforeseen
consequences in other parts of the app.

Closes #37481.

PR Close #37645
2020-07-20 10:00:05 -07:00
136acdfab6 docs: correct flag default values in --strict (#37982)
Docs state that `strictInjectionParameters` is true by default in `ng new`, however this is not the case in `10.0.1`. It is only set when `--strict` is provided. Clarified that the `--strict` flag is required.

`strictTemplates` does not mention anything about `--strict`, so I included a similar point that it is `true` when a new project is generated with `--strict`.

PR Close #37982
2020-07-17 16:26:49 -07:00
095cfd961d build: Ignore .history for the xyz.local-history VSCode extension (#38121)
Ignore .history for the xyz.local-history VSCode extension

PR Close #38121
2020-07-17 13:33:39 -07:00
38a7021d5e fix(core): error due to integer overflow when there are too many host bindings (#38014)
We currently use 16 bits to store information about nodes in a view.
The 16 bits give us 65536 entries in the array, but the problem is that while
the number is large, it can be reached by ~4300 directive instances with host
bindings which could realistically happen is a very large view, as seen in #37876.
Once we hit the limit, we end up overflowing which eventually leads to a runtime error.

These changes bump to using 20 bits which gives us around 1048576 entries in
the array or 16 times more than the current amount which could still technically
be reached, but is much less likely and the user may start hitting browser limitations
by that point.

I picked the 20 bit number since it gives us enough buffer over the 16 bit one,
while not being as massive as a 24 bit or 32 bit.

I've also added a dev mode assertion so it's easier to track down if it happens
again in the future.

Fixes #37876.

PR Close #38014
2020-07-17 12:58:15 -07:00
b3b03c35b5 fix(docs-infra): correctly display SVG icons in IE11 (#38046)
Fix two issues that affected displaying of SVG icons in IE11:

1. All SVG icons except for one appeared empty. This was related how the
CustomIconRegistry re-used the same <div> element to create all
SVG elements.

2. The GitHub and Twitter buttons next to the search bar were not sized
properly.

Fixes #37847

PR Close #38046
2020-07-17 11:44:34 -07:00
fd45f7485d docs(docs-infra): reformat redundant sentence (#38109)
reformat sentence uses the npm package manager since npm is node package manager

Fixes #38106

PR Close #38109
2020-07-17 11:39:16 -07:00
58f6079873 build(language-service): add script to build package locally (#38103)
This commit adds a script to build @angular/language-service
locally so that it can be consumed by the Angular extension for
local development.

PR Close #38103
2020-07-16 16:39:54 -07:00
e382632473 build: fix symbol extractor not dealing with ES2015 classes (#38093)
We recently reworked our `ng_rollup_bundle` rule to no longer output
ESM5 and to optimize applications properly (previously applications were
not optimized properly due to incorrect build optimizer setup).

This change meant that a lot of symbols have been removed from the
golden correctly. See: fd65958b88

Unfortunately though, a few symbols have been accidentally removed
because they are now part of the bundle as ES2015 classes which the
symbol extractor does not pick up. This commit fixes the symbol
extractor to capture ES2015 classes. We also update the golden to
reflect this change.

PR Close #38093
2020-07-16 13:54:23 -07:00
cf9a47ba53 feat(localize): allow duplicate messages to be handled during extraction (#38082)
Previously, the i18n message extractor just quietly ignored messages that
it extracted that had the same id. It can be helpful to identify these
to track down messages that have the same id but different message text.

Now the messages are checked for duplicate ids with different message text.
Any that are found can be reported based on the new `--duplicateMessageHandling`
command line option (or `duplicateMessageHandling` API options property).

* "ignore" - no action is taken
* "warning" - a diagnostic warning is written to the logger
* "error" - the extractor throws an error and exits

Fixes #38077

PR Close #38082
2020-07-16 13:53:38 -07:00
56dd3e77ac refactor(localize): remove unnecessary ! operator (#38082)
The messages property always exists so there is no need for the ! operator.

PR Close #38082
2020-07-16 13:53:38 -07:00
6c9401c338 docs: update router api documentation (#37980)
Edit descriptions, usage examples, and add links to be complete and consistent with API reference doc style

PR Close #37980
2020-07-16 13:52:40 -07:00
019a696a6a Revert "build: remove obsolete Bazel function ctx.new_file (#38080)" (#38101)
This reverts commit 406f801b70.

The reason for the revert is the breakage in i18n subsystem in g3.

PR Close #38101
2020-07-16 11:06:23 -07:00
8b25a64200 build(language-service): remove typescript from ivy bundle (#38088)
Currently the Ivy language service bundle is [10MB](
https://unpkg.com/browse/@angular/language-service@10.0.4/bundles/) because we
accidentally included typescript in the bundle.

With this change, the bundle size goes down to 1.6MB, which is even smaller
than the View Engine bundle (1.8MB).

```bash
$ yarn bazel build //packages/language-service/bundles:ivy
$ ls -lh dist/bin/packages/language-service/bundles/ivy.umd.js
1.6M Jul 15 15:49 dist/bin/packages/language-service/bundles/ivy.umd.js
```

PR Close #38088
2020-07-16 11:04:57 -07:00
bd71f10234 build(language-service): Remove ls_rollup_bundle (#38086)
`ls_rollup_bundle` is no longer needed since we could invoke `ng_rollup_bundle`
directly.

Background: language service runs rollup to produce a single file to reduce
startup time in the editor. However, due to the need to load dynamic versions
of typescript at runtime (think the case where users can change typescript
version in their editor), we hack the "banner" to export a CommonJS default function,
so that we could dynamically load the typescript module provided at runtime via AMD
and use it throughout the implementation.

PR Close #38086
2020-07-16 11:04:28 -07:00
e0b35bfc18 ci: add more owners for some categories (#37994)
* Add petebacondarwin to public-api, size-tracking, and circular-dependencies
* Add mhevery, josephperrott, and jelbourn to code-ownership

PR Close #37994
2020-07-16 11:03:55 -07:00
c1539b16ae docs: add Ajit Singh to the collaborators (#37792)
Ajit Singh is a newly added collborator after a few months of contributing add him to the contributors.json

PR Close #37792
2020-07-16 11:02:07 -07:00
737506e79c fix(core): Allow modification of lifecycle hooks any time before bootstrap (#35464)
Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix #30497

PR Close #35464
2020-07-15 16:22:46 -07:00
469aba0140 docs: add Emma Twersky to DevRel Contributor page (#38084)
This commit adds Emma Twersky to the Angular Contributors page along with a bio & a photograph.

PR Close #38084
2020-07-15 13:50:39 -07:00
d8c47b971c docs: fix typo in "Creating libraries" guide (by publishing...ensures --> publishing...ensures) (#38032)
PR Close #38032
2020-07-15 13:12:14 -07:00
24b420527a docs(service-worker): fix typos in SwRegistrationOptions API docs (#38047)
PR Close #38047
2020-07-15 13:10:25 -07:00
bf641e1b4b fix(core): incorrectly validating properties on ng-content and ng-container (#37773)
Fixes the following issues related to how we validate properties during JIT:
- The invalid property warning was printing `null` as the node name
for `ng-content`. The problem is that when generating a template from
 `ng-content` we weren't capturing the node name.
- We weren't running property validation on `ng-container` at all.
This used to be supported on ViewEngine and seems like an oversight.

In the process of making these changes, I found and cleaned up a
few places where we were passing in `LView` unnecessarily.

PR Close #37773
2020-07-15 12:39:39 -07:00
406f801b70 build: remove obsolete Bazel function ctx.new_file (#38080)
The function was removed by default in Bazel 0.27.
It is still accessible with the flag `--incompatible_new_actions_api`
(which is set in Google code base), but the flag will be deleted very soon.

This change should be a no-op for Bazel users. The change was tested in
Google (cl/318277076) and should be safe as well.

PR Close #38080
2020-07-15 12:39:00 -07:00
c8e77d8536 ci(docs-infra): increase minimum a11y scores for various pages (#37899)
As part of our CI checks, we ensure the a11y score on certain angular.io
pages do not fall below some thresholds.

This commit increases these thresholds based on our current scores to
ensure we do not regress below current values.

PR Close #37899
2020-07-15 12:38:07 -07:00
6ea2d1e20e build(docs-infra): upgrade lighthouse to 6.1.0 (#37899)
To take advantage of lazy loaded images `img[loading=lazy]`, this commit
upgrades lighthouse to version 6.1.0.

Closes #35965

PR Close #37899
2020-07-15 12:38:07 -07:00
09eee5b312 fix(dev-infra): add missing BUILD file to dev-infra/bazel:files (#38026)
* Without this BUILD file we were seeing errors about the reference to
  expand_template.bzl in ng_rollup_bundle.bzl because dev-infra/bazel
  was not considered a package.

PR Close #38026
2020-07-15 12:34:46 -07:00
904ebfebf3 fix(dev-infra): fix broken zone.js substitution for dev-infra:npm_package (#38026)
* fix substitution that was broken by PR #36540 to match
  the new import path

PR Close #38026
2020-07-15 12:34:46 -07:00
545f1dbac9 feat(dev-infra): add bazel firefox browser with RBE compatibility (#38029)
Adds Firefox as browser to `dev-infra/browsers` with RBE
compatibility. The default Firefox browser is not compatible similar to
the default Chromium version exposed by `rules_webtesting`.

The Angular Components repository will use this browser target as
it enables RBE support. Also it gives us more flexibility about
the Firefox version we test against. The version provided by
`rules_webtesting` is very old and most likely not frequently
updated (based on past experience).

PR Close #38029
2020-07-15 12:34:05 -07:00
b00121c9a6 docs: update reference doc for router guards and resolvers (#38079)
Complete and clarify descriptions and example of the guard and resolver functions in Router API documentation.

PR Close #38079
2020-07-15 12:32:10 -07:00
45d79efc3f docs: remove all references to Angular Console (#37608)
Angular Console has been renamed and links no longer work. It has been decided to remove references to this third-party tool from the AIO documentation.

Closes #37604

PR Close #37608
2020-07-15 12:30:59 -07:00
1d9e56eba0 docs: release notes for the v10.0.4 release 2020-07-15 11:22:18 -07:00
e7c722574f release: cut the v10.1.0-next.1 release 2020-07-15 10:07:43 -07:00
b358495a6c fix(ngcc): report a warning if ngcc tries to use a solution-style tsconfig (#38003)
In CLI v10 there was a move to use the new solution-style tsconfig
which became available in TS 3.9.

The result of this is that the standard tsconfig.json no longer contains
important information such as "paths" mappings, which ngcc might need to
correctly compute dependencies.

ngcc (and ngc and tsc) infer the path to tsconfig.json if not given an
explicit tsconfig file-path. But now that means it infers the solution
tsconfig rather than one that contains the useful information it used to
get.

This commit logs a warning in this case to inform the developer
that they might not have meant to load this tsconfig and offer
alternative options.

Fixes #36386

PR Close #38003
2020-07-14 13:21:31 -07:00
f4fac406b9 docs(core): fixes minor typo in initNgDevMode function docs (#38042)
PR Close #38042
2020-07-14 13:17:32 -07:00
5fd2c8f2d6 refactor(forms): remove unnecessary ! operators from validators (#36805)
When we added the strict null checks, the lexer had some `!` operators added to prevent the compilation from failing.

See #24571

PR Close #36805
2020-07-14 11:01:53 -07:00
421e807f80 docs(forms): Fix typos in template-driven forms tutorial (#37933)
Fix two typos in the 'Building a template-driven form` that caused the guide to not be displayed correctly.

PR Close #37933
2020-07-14 11:01:29 -07:00
df8b387570 docs(forms): Minor fix in forms overview guide (#37933)
Remove an article from the `Data flow in forms` section of the forms overview guide. The use of `the` and `a` together
is not syntactically correct.

PR Close #37933
2020-07-14 11:01:29 -07:00
f01b0337d2 docs(router): fix typo in "spotlight on pathmatch" (#38039)
https://angular.io/guide/router-tutorial-toh#pathmatch

PR Close #38039
2020-07-14 09:20:18 -07:00
4ec3026a9a docs(router): fix typo in https://angular.io/guide/router#activated-route (#38034)
In angular.io, it linked to the wrong part of the page. https://angular.io/guide/router#activated-route

PR Close #38034
2020-07-14 09:10:26 -07:00
9021d3f5e1 docs: fix live examples in testing guides (#38038)
In #37957, parts of the testing guide were broken out into separate
guides. As part of that work, the `<live-example>` tags were also copied
to the new guides. These `<live-example>` tags did not specify the
targeted example project via the `name` attribute, thus they were
implicitly targeting the example with the same name as the guide they
were in. See the [Docs style guide][1] for more info.

However, there is only one example project (`testing/`) and all
`<live-example>` tags were supposed to target that. This worked fine on
the `testing.md` guide, but it broke on other guides (which tried to
target non-existing example projects based on their names).

This commit fixes it by explicitly specifying which example is targeted
by the `<live-example>` tags. It also removes the `embedded-style`
attribute that has no effect.

[1]: https://angular.io/guide/docs-style-guide#live-examples

Fixes #38036

PR Close #38038
2020-07-14 09:10:00 -07:00
81542b3b72 docs(core): Fixed typo in Type JSdoc (#37930)
Updated comment doc in packages/core/src/interface/type.ts

PR Close #37930
2020-07-13 14:30:55 -07:00
9185c6e971 fix(router): ensure duplicate popstate/hashchange events are handled correctly (#37674)
The current method of handling duplicate navigations caused by 'hashchange' and 'popstate' events for the same url change does not correctly handle cancelled navigations. Because `scheduleNavigation` is called in a `setTimeout` in the location change subscription, the duplicate navigations are not flushed at the same time. This means that if the initial navigation hits a guard that schedules a new navigation, the navigation for the duplicate event will not compare to the correct transition (because we inserted another navigation between the duplicates). See https://github.com/angular/angular/issues/16710#issuecomment-646919529

Fixes #16710

PR Close #37674
2020-07-13 14:24:53 -07:00
69472a1ed0 refactor(dev-infra): allow for consumption with rules_nodejs v2.0.0 (#37968)
With `rules_nodejs` v2.0.0 being in RC phase currently, we should
make sure that the package is compatible so that we can use it
in the components repo in combination with rules_nodejs v2.0.0.

In v2.0.0 of the NodeJS rules, Bazel workspaces are recommended
to no longer be symlinked under a separate repository. Instead,
bazel rules and targets should be accessed directly from the
user-selected NPM repository. Usually `@npm`, so that the import
changes to `@npm//@angular/dev-infra-private/<..>`.

PR Close #37968
2020-07-13 14:18:22 -07:00
10aba15154 fix(language-service): remove completion for string (#37983)
If the user inputs a string(e.g. `<div [ngClass]="'str~{cursor}'"></div>`), the completion is useless.

PR Close #37983
2020-07-13 14:16:56 -07:00
36dd817913 docs: fixed typo in https://angular.io/guide/glossary (#36220)
PR Close #36220
2020-07-13 14:10:06 -07:00
0eaa084ced docs(router): fix typo 'containa' to 'contains' (#36764)
Closes #36763

PR Close #36764
2020-07-13 14:09:32 -07:00
62e19c8813 docs: Add Scully to resources.json (#37678)
Add Scully to the resource page by adding it to the "Tooling" subcategory in resources.json file

PR Close #37678
2020-07-13 14:08:40 -07:00
95669df4c3 docs: remove Markus Padourek from angular collaborators (#37962)
This person was never onboarded

PR Close #37962
2020-07-13 14:08:13 -07:00
6b311552f0 fix(compiler-cli): ensure file_system handles mixed Windows drives (#37959)
The `fs.relative()` method assumed that the file-system is a single tree,
which is not the case in Windows, where you can have multiple drives,
e.g. `C:`, `D:` etc.

This commit changes `fs.relative()` so that it no longer forces the result
to be a `PathSegment` and then flows that refactoring through the rest of
the compiler-cli (and ngcc).  The main difference is that now, in some cases,
we needed to check whether the result is "rooted", i.e an `AbsoluteFsPath`,
rather than a `PathSegment`, before using it.

Fixes #36777

PR Close #37959
2020-07-13 12:05:21 -07:00
66947cf9fa docs: fix typo in router.md (#37227)
This commit fixes a typo in the router documentation. "Benfits of a routing module" => "Benefits of a routing module"

PR Close #37227
2020-07-13 09:27:28 -07:00
a259a84d3f docs(http): Remove extra semicolons in the http guide (#37228)
An extra semicolon in searchHeroes function was removed in the http guide
found in aio/content/guide/http.md

docs(http): Remove extra semicolon in a code example found in the http guide

Removed extra semicolon in handleError function in the file located at
aio/content/examples/http/src/app/config/config.service.ts, which serves
as a source of code examples for the http guide.

Replace a comma for a dot in the comment at line 79 to ensure consistency
with the rest of the document.

Capitalized and added a dot at the end of the comment at line 84 to
ensure consistency with the other comments.

PR Close #37228
2020-07-13 09:25:19 -07:00
d1aa4678be build(docs-infra): ensure the correct files are in the i18n example (#37947)
The Stackblitz and zip-file include `doc-files` unnecssarily and are missing
the locale files. This commit updates the `stackblitz.json` to fix this.

PR Close #37947
2020-07-13 09:24:33 -07:00
04c220bbdf build(docs-infra): remove unnecessary zipper.json file (#37947)
The `zipper.json` file is only needed if the example does not
have a `stackblitz.json` file, which this (i18n) example does.

Moreover, it appears that having both can cause the generated
zip file to be corrupted and not unzippable.

Fixes #37849

PR Close #37947
2020-07-13 09:24:33 -07:00
72d6032fa4 docs: reformat and update CONTRIBUTING.md (#37951)
This doc is very old and rusty. I'm reformatting it to follow the one-setence-per-line rule.
I also updated a few sections, since they were either poorly written or obsolete.

PR Close #37951
2020-07-13 09:23:03 -07:00
53d4859f48 build: add .gitmessage file with commit message template (#37951)
Git provides a way to create a commit message template via the `.gitmessage` file.

Introduce an Angular-specific .gitmessage template based on the original Commit Message Guidelines.
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-guidelines

If this template workflow is proven in practice, we can move the commit message guidelines into the
.gitmessage file to prevent duplication of the content.

This change is a follow up on #37949 and is inspired by info found in the following blog post:
https://thoughtbot.com/blog/better-commit-messages-with-a-gitmessage-template

PR Close #37951
2020-07-13 09:23:03 -07:00
f66f4a1b3f build: adding shared .ng-dev/gitconfig file for convenience and consistent git config (#37951)
This file is inert unless it's explicitly included into the local git config via:

```
git config --add include.path '../.ng-dev/gitconfig'
```

Calling that command will append the following into `.git/config` of the current git workspace
(i.e. $GIT_DIR, typically `angular/.git/config`):

```
[include]
	path = ../.ng-dev/gitconfig
```

I'm intentionally keeping the config inert for now until we prove that this is a good idea.

Eventually we could roll this change out to all the contributors via an npm post-install script.

PR Close #37951
2020-07-13 09:23:03 -07:00
88d68d2d21 docs: Move router tutorial (toh) from router.md to new file (#37979)
In an effort to make angular documentation easier for users to read,
we are moving the router tutorial currently in router.md to a new file.
To support this change, we have done the following:

* Update files to fix any broken links caused by moving the file
* Updated the new file to follow tutorial guidelines
* Add the new file to the table of  contents under, Tutorials.

PR Close #37979
2020-07-10 15:04:55 -07:00
4783a071f3 docs(router): fix routerLink docs (#37997)
The current content for the routerLink commands input does not make it to aio.
fixes #35414

PR Close #37997
2020-07-10 11:24:28 -07:00
9322b9a060 fix(compiler): check more cases for pipe usage inside host bindings (#37883)
Builds on top of #34655 to support more cases that could be using a pipe inside host bindings (e.g. ternary expressions or function calls).

Fixes #37610.

PR Close #37883
2020-07-10 11:00:20 -07:00
9bd4b74b06 feat(dev-infra): commit message validation should skip lines consisting of URLs (#37890)
The dev-infra commit message validation optionally can check for lines
to not exceed a given amount of characters. This is desired for most
commit messages, but sometimes not actionable if a long URL is inserted
into the commit message. With this commit, we skip the max line length
check for lines that start with an URL.

PR Close #37890
2020-07-10 10:59:28 -07:00
e6afcf1f94 build: split dev-infra configuration into individual files (#37890)
Splits the dev-infra configurations into individual files inside the
`.ng-dev/` folder. This helps with clarity as there is no single
configuration file that becomes extremely large and difficult to
maintain.

Additionally, more explicit configuration types are now used. This
fixed the max-line length setting for commit message validation.
This option is currently named incorrectly and a noop.

PR Close #37890
2020-07-10 10:59:28 -07:00
4b4b74548d fix(dev-infra): include bazel utility files in npm package (#37891)
We recently added a new folder for common bazel utilities
to `dev-infra`. The `ng_rollup_bundle` rule relies on an
utility that is provided by this `bazel/` folder.

Unfortunately though it looks like this folder is currently
not included in the NPM package, so that the `ng_rollup_bundle`
rule does not work as expected. This commit fixes that by
including the bazel utilities in the NPM package.

PR Close #37891
2020-07-10 10:06:11 -07:00
1550663b9e fix(bazel): ng_module rule does not expose flat module information in Ivy (#36971)
The `ng_module` rule supports the generation of flat module bundles. In
View Engine, information about this flat module bundle is exposed
as a Bazel provider. This is helpful as other rules like `ng_package`
could rely on this information to determine entry-points for the APF.

With Ivy this currently does not work because the flat module
information is not exposed in the provider. The reason for this is
unclear. We should also provide this information in Ivy so that rules
like `ng_package` can also determine the correct entry-points when a
package is built specifically with `--config=ivy`.

PR Close #36971
2020-07-09 22:11:17 +00:00
c40cbecdd1 docs(animations): Added consistency in code examples (#37081)
PR Close #37081
2020-07-09 22:08:00 +00:00
209a365511 docs: add explanation for providedIn any (#35283)
Angular 9 introduces a new value for providedIn called `any` which lets us use unique instance
for servicec in each lazy loaded module, this PR is to document the same

fixes #35179

PR Close #35283
2020-07-09 10:12:00 -07:00
fb735d625b refactor(service-worker): use nominal type for normalized URLs (#37922)
Some ServiceWorker operations and methods require normalized URLs.
Previously, the generic `string` type was used.

This commit introduces a new `NormalizedUrl` type, a special kind of
`string`, to make this requirement explicit and use the type system to
enforce it.

PR Close #37922
2020-07-09 09:44:57 -07:00
d19ef6534f fix(service-worker): correctly handle relative base href (#37922)
In some cases, it is useful to use a relative base href in the app (e.g.
when an app has to be accessible on different URLs, such as on an
intranet and the internet - see #25055 for a related discussion).

Previously, the Angular ServiceWorker was not able to handle relative
base hrefs (for example when building the with `--base-href=./`).

This commit fixes this by normalizing all URLs from the ServiceWorker
configuration wrt the ServiceWorker's scope.

Fixes #25055

PR Close #37922
2020-07-09 09:44:57 -07:00
667aba7508 test(service-worker): make mock implementations more similar to actual ones (#37922)
This commit makes the mock implementations used is ServiceWorker tests
behave more similar to the actual ones.

PR Close #37922
2020-07-09 09:44:57 -07:00
d380e93b82 refactor(service-worker): move asset URL normalization to Adapter (#37922)
This is in preparation of enabling the ServiceWorker to handle
relative paths in `ngsw.json` (as discussed in #25055), which will
require normalizing URLs in other parts of the ServiceWorker.

PR Close #37922
2020-07-09 09:44:56 -07:00
2156beed0c fix(service-worker): correctly serve ngsw/state with a non-root SW scope (#37922)
The Angular ServiceWorker can serve requests to a special virtual path,
`ngsw/state`, showing [information about its internal state][1], which
can be useful for debugging.

Previously, this would only work if the ServiceWorker's [scope][2] was
the root directory (`/`). Otherwise, (e.g. when building the app with
`--baseHref=/some/path/`), the ServiceWorker would fail to detect a
request to `/some/path/ngsw/state` as matching `ngsw/state` and would
not serve it with the debugging information.

This commit fixes it by ensuring that the ServiceWorker's scope is taken
into account when detecting a request to `ngsw/state`.

[1]: https://angular.io/guide/service-worker-devops#locating-and-analyzing-debugging-information
[2]: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/scope

Fixes #30505

PR Close #37922
2020-07-09 09:44:56 -07:00
b98314e306 docs: add Formly library to the list of resources (#37257)
This commit adds the Formly library to the Angular list of resources at aio/content/marketing/resources.json.

PR Close #37257
2020-07-09 09:19:48 -07:00
e50c7dcc4c docs(router): get rid of unnecessary line in wildcard route example and fixing wildcard docregions (#37127)
The wildcard example leads to display a 404 page with the PageNotFoundComponent. But before, there is a wildcard to redirect to the FirstComponent and because of the routes order the FirstComponent will be displayed; which it is not the target of the wildcard route example code. Also, fixing some wildcard docregions
PR Close #37127
2020-07-08 16:04:51 -07:00
6b731a067a test: fix test failure in saucelabs ivy ie10 (#37892)
One of the ivy acceptance tests currently fails in IE10. This
is because we recently added a new test that asserts that injecting
`ViewRef` results in a `NullInjectorError`.

Due to limitations in TypeScript and in polyfills for `setPrototypeOf`,
the error cannot be thrown as `ViewRef` is always considered injectable.
In reality, `ViewRef` should not be injectable, as explicitly noted
in c00f4ab2ae.

There seems no way to simulate the proper prototype chain in such
browsers that do not natively support `__proto__`, so TypeScript
and `core-js` polyfills simply break the prototype chain and
assign inherited properties directly on `ViewRef`. i.e. so that
`ViewRef.__NG_ELEMENT_ID__` exists and DI picks it up.

There is a way for TypeScript to theoretically generate proper
prototype chain in ES5 output, but they intend to only bother
about the proper prototype chain in ES6 where `setPrototypeOf`
etc. are offically standarized. See the response:

https://github.com/microsoft/TypeScript/issues/1601#issuecomment-94892833.

PR Close #37892
2020-07-08 16:03:33 -07:00
0a3dbc1e8a build(docs-infra): update @angular/cli to 10.0.1 (#37898)
This commit updates the version of Angular CLI used in angular.io to
version 10.0.1. It also reverts some changes (namely commits 38dfbc775f
and eee2fd22e0) which were made due to an older bug that is fixed in
the latest version. See #37688 for more details.

Fixes #37699

PR Close #37898
2020-07-08 16:02:46 -07:00
b24a24ec58 refactor(docs-infra): avoid Material style duplication warning (#37898)
This commit removes some duplicate imports of Material themes and
theming-related utilities. While this change does not have any impact on
the size of the generated `styles.css` file, it silences a build warning
pointing to [Avoiding duplicated theming styles][1].

[1]: db4b0cd1bf/guides/duplicate-theming-styles.md

PR Close #37898
2020-07-08 16:02:46 -07:00
13ef5d6c7d build(docs-infra): update @angular/material to 10.0.1 (#37898)
This commit updates the version of Angular Components used in angular.io
to version 10.0.1. It also updates the angular.io app to adapt to
breaking changes.

PR Close #37898
2020-07-08 16:02:46 -07:00
54373cc895 build(docs-infra): update @angular/core to 10.0.2 (#37898)
This commit updates the version of Angular framework used in angular.io
to version 10.0.2. It also features a commit message with a 100+ chars
long body.

PR Close #37898
2020-07-08 16:02:46 -07:00
bbe3543c69 refactor(core): remove duplicated WrappedValue class (#37940)
Before this refactoring we had the WrappedValue class in
2 separate places:
- packages/core/src/change_detection/change_detection_util.ts
- packages/core/src/util/WrappedValue.ts

This commit removes the duplicate, leaving the class that has
the deprecation notice.

PR Close #37940
2020-07-08 16:02:16 -07:00
bdbbff6a1a docs: break testing doc into multiple docs (#37957)
This commit breaks up the testing document into nine total documents, with each document focusing on an existing section of the current testing documentation. There are no content changes.

PR Close #37957
2020-07-08 16:01:49 -07:00
f81d3f6199 docs(elements): fix typo (you custom element --> your custom element) (#37966)
PR Close #37966
2020-07-08 16:01:22 -07:00
d0c0f25a48 ci: decrease the minBodyLength commit message limit to 20 chars (#37949)
The motivation behind this change is to improve the productivity in the angular/angular repo
without sacrificing the original goal of having better understanding of changes within
the repo.

When the minBodyLength limit was originally introduced the goal was simple: force
committers to provide more contextual information for each change coming into the
repo. Too often we found ourselves in a situation where nobody understood what
motivated some of the changes and we needed more contextual info to know if the
change was correct, desirable, and still relevant (at a later point in time).

When the limit was introduced, we needed to pick a minimum body length - given no
data, and frustration with even big changes being committed with just a words in
the subject (along the lines of "fix(core): fixing a bug"), we overcompensated
and started off with a really high bar of minBodyLength set to 100 chars.

This turned out to be impractical and created a big friction point in making valid
changes in the angular/angular repo, and in fact caused some of the refactorings
and smaller changes to be either skipped or combined into other commits which
increased the burden for code reviewers.

The evidence in the friction points can be seen in the number of PRs that fail to pass
the current lint check on the first try, but more importantly also in the "creative"
writing that some of the committers are forced to resort to in order to satisfy the
current checks. Examples:

- 286fbf42c6
- b2816a1536

Given that we primarily care to document the motivation behind each change
(the answer to the ultimate question: WHY?), I've collected several *common* &
*valid* commit messages that are minimalistic and capture the WHY sufficiently:

```
Refactoring for readability.  => 28 chars
Improving variable naming.    => 26 chars
Additional test coverage.     => 25 chars
Cleaning up the code.         => 21 chars
Simplified the code.          => 20 chars
```

These commit message bodies in addition to the commit message subject should
sufficiently satisfy the need to capture the context and motivation behind each
change without creating an undue burden on committers.

Example minimalistic commit message:

------

refactor(core): cleanup the expression parser

Simplifying the code.

----

Given this research, I'm decreasing the minBodyLenth in angular/angular to 20 chars.

The commit message quality can be additionally improved by implementing a commit message
template via `.gitmessage` that will guide the committers in following our commit message
guidelines via instructions provided in the form of in-the-flow help rather than as an after
the fact lint check.

More info: https://thoughtbot.com/blog/better-commit-messages-with-a-gitmessage-template

I'm intentionally deferring such change for a separate PR as not to complicate or delay the
minBodyLength limit decrease.

PR Close #37949
2020-07-08 15:43:02 -07:00
1f796e9479 release: cut the v10.1.0-next.0 release 2020-07-08 14:21:29 -07:00
1237d9cbea docs: release notes for the v10.0.3 release 2020-07-08 14:00:58 -07:00
b3969e9654 docs: release notes for the v9.1.12 release 2020-07-08 13:40:27 -07:00
6eb868b63a build(compiler-cli): fix bazel deps rules for ngtsc testing packages (#37977)
The ngtsc testing packages for file_system and logging were missing from the bazel deps rules, which means that they were not included in the releases

PR Close #37977
2020-07-08 12:05:22 -07:00
82a2207f4a build: filter out duplicate cherry-picked commits in changelog (#37956)
Often changelogs are generated from the patch branch and then
cherry-picked into the `CHANGELOG.md` file in `master` for
better access and readability. This is problematic though as
`conventional-changelog` (the tool we use for generating the
changelog), will duplicate commits when a future changelog
is generated from `master` then (i.e. for a new minor release).

This happens because conventional-changelog always generates the
changelog from the latest tag in a given branch to `HEAD`. The
tag in the patch branch does not correspond to any SHA in `master`
so the intersection of commits is not automatically omitted.

We work around this naively (until we have a better tool provided
by dev-infra), by deduping commits that are already part of the
changelog. This has proven to work as expected in the components
repo.

PR Close #37956
2020-07-08 12:04:46 -07:00
289a96b078 docs: minor fixes to docs related to updating to v10 (#37897)
This commit includes a couple of minor fixes to docs related to updating
to v10:
- Fix markdown link in "Updating to Angular version 10" guide.
- Correctly display numbered list in
  "Solution-style `tsconfig.json` migration" guide.

PR Close #37897
2020-07-07 12:17:04 -07:00
cb2ab26296 feat(dev-infra): merge script should link to original commit when cherry-picking with API strategy (#37889)
The merge script uses `git cherry-pick` for both the API merge strategy
and the autosquash strategy. It uses cherry-pick to push commits to
different target branches (e.g. into the `10.0.x` branch).

Those commits never point to the commits that landed in the primary
Github branch though. For the autosquash strategy the pull request number
is always included, so there is a way to go back to the source. On the other
hand though, for commits cherry-picked in the API merge strategy, the
pull request number might not always be included (due to Github's
implementation of the rebase merge method).

e.g.
27f52711c0

For those cases we'd want to link the cherry-picked commits to the
original commits so that the corresponding PR is easier to track
down. This is not needed for the autosquash strategy (as outlined
before), but it would have been good for consistency. Unfortunately
though this would rather complicate the strategy as the autosquash
strategy cherry-picks directly from the PR head, so the SHAs that
are used in the primary branch are not known.

PR Close #37889
2020-07-07 12:16:21 -07:00
79850983e6 fix(docs-infra): prevent search-bar from overlapping nav-items (#37938)
As part of angular.io's responsive layout, the menu shown in the top-bar
is collapsed into the sidenav on narrow screens at the point where the
search-bar (on the right side of the top-bar) would overlap with the
menu's nav-items.

Previously, the value used as break-point would work on marketing pages,
where the hamburger button is not shown on wide screens. However, on
docs pages (where the hamburger button is always shown, pushing the menu
further to the right), the search-bar would still overlap the menu
nav-items on some resolutions.

This commit fixes it by raising the screen width threshold at a value
that ensures there is no overlap even on pages where the hamburger
button is visible alongside the top-bar menu.

Fixes #37937

PR Close #37938
2020-07-06 13:57:37 -07:00
fc7e77934f refactor(docs-infra): decouple showing the top-menu in top-bar from showing the sidenav (#37938)
As part of angular.io's responsive layout, the following rules are
applied:
- On wide screens, a menu is shown in the top-bar and the sidenav is
  shown side-by-side with the docs content.
- On narrow screens, the top-menu is moved from the top-bar to the
  sidenav and the sidenav is closed by default and floats over the
  content when manually opened.

Previously, the break-points at which the top-menu was shown in the
top-bar and the sidenav was shown side-by-side with the content were the
same (using a single variable).

This commit decouples the two break-points to make it possible to use
different values in the future.

PR Close #37938
2020-07-06 13:57:37 -07:00
90b93da743 refactor(docs-infra): use Sass variable for top-bar hamburger button show/hide threshold (#37938)
Use a Sass variable for the screen width break-point at which the
top-bar hamburger button is hidden/shown. This allows more easily
updating the break-point.

PR Close #37938
2020-07-06 13:57:37 -07:00
ec32eba02c feat(localize): expose canParse() diagnostics (#37909)
When loading a translation file we ask each `TranslationParser`
whether it can parse the file. Occasionally, this check can find
errors in the file that would be useful to the developer. For example
if the file has invalid XML.

This commit deprecates the previous `canParse()` method and replaces it
with a new `analyze()` method. This returns an object that includes a
boolean `canParse` and then either a `hint` if it can parse the file,
or a `diagnostics` object filled with any messages that can be used to
diagnose problems with the format of the file.

Closes #37901

PR Close #37909
2020-07-06 13:56:39 -07:00
596fbb3f06 build(docs-infra): improve applying post-install patches (#37896)
In `aio/`, we have a mechanism to apply patches in a `postinstall` hook.
See `aio/tools/cli-patches/README.md` for more info.

Previously, we had to update `aio/tools/cli-patches/patch.js` to list
each `.patch` file separately. While working on #37688, I found it
helpful for the script to automatically pick up `.patch` files.

This commit updates the script to automatically pick up and apply
`.patch` files from the `aio/tools/cli-patches/` directory. If one wants
to keep a `.patch` file but not apply it, they can change the file's
extension or move it to a sub-directory (without having to update the
script).

PR Close #37896
2020-07-06 13:56:15 -07:00
aed6b131bb fix(core): handle spaces after select and plural ICU keywords (#37866)
Currently when the `plural` or `select` keywords in an ICU contain trailing spaces (e.g. `{count, select , ...}`), these spaces are also included into the key names in ICU vars (e.g. "VAR_SELECT "). These trailing spaces are not desirable, since they will later be converted into `_` symbols while normalizing placeholder names, thus causing mismatches at runtime (i.e. placeholder will not be replaced with the correct value). This commit updates the code to trim these spaces while generating an object with placeholders, to make sure the runtime logic can replace these placeholders with the right values.

PR Close #37866
2020-07-06 13:55:47 -07:00
d148fdccf2 fix(dev-infra): fix typo in ng-dev config (#37862)
The logic to exclude certain types of commits (specifically 'docs' ones) was implemented in c5b125b7db. The ng-dev config was updated in the followup commit acf3cff9ee, but there was a typo that prevented the new logic from being activated. This commit updates the name of the config option in the ng-dev config to the right one (minBodyLengthTypeExcludes).

PR Close #37862
2020-07-06 13:55:18 -07:00
1801d0c650 fix(router): properly compare array queryParams for equality (#37709) (#37860)
queryParams will be judged different if the arrays do not contain the same frequency of elements and the same otherwise.

PR Close #37860
2020-07-06 13:50:32 -07:00
a5c30733cb docs: mention for depreciation for Testbed.get() (#37815)
As mention in https://angular.io/guide/deprecations for this API, it may be important mention for this to make developers migrate or avoid using it

PR Close #37815
2020-07-06 13:42:27 -07:00
d7dd2959c8 perf(router): apply prioritizedGuardValue operator to optimize CanLoad guards (#37523)
CanLoad guards are processed in asynchronous manner with the following rules:
* If all guards return `true`, operator returns `true`;
* `false` and `UrlTree` values wait for higher priority guards to resolve;
* Highest priority `false` or `UrlTree` value will be returned.

`prioritizedGuardValue` uses `combineLatest` which in order subscribes to each Observable immediately (not waiting when previous one completes that `concatAll` do). So it makes some advantages in order to run them concurrently. Respectively, a time to resolve all guards will be reduced.

PR Close #37523
2020-07-06 13:41:11 -07:00
a5ffca0576 fix(router): fix navigation ignoring logic to compare to the browser url (#37716)
This PR changes the logic for determining when to skip route processing from
using the URL of the last attempted navigation to the actual resulting URL after
that transition.

Because guards may prevent navigation and reset the browser URL, the raw
URL of the previous transition may not match the actual URL of the
browser at the end of the navigation process. For that reason, we need to use
`urlAfterRedirects` instead.

Other notes:
These checks in scheduleNavigation were added in eb2ceff4ba
The test still passes and, more surprisingly, passes if the checks are removed
completely. There have likely been changes to the navigation handling that
handle the test in a different way. That said, it still appears to be important
to keep the checks there in some capacity because it does affect how many
navigation events occur. This addresses an issue that came up in #16710: https://github.com/angular/angular/issues/16710#issuecomment-634869739
This also partially addresses #13586 in fixing history for imperative
navigations that are cancelled by guards.

PR Close #37716
2020-07-06 09:38:10 -07:00
196bfa8fae docs: restore link to lightweight token page in left nav (#37855)
After recent correction to left nav TOC, the link to this new page was temporarily removed. This restores it to next, because the page is not yet available in stable.

PR Close #37855
2020-07-01 11:55:36 -07:00
1d5ca55aab docs(changelog): remove empty sections (#36264)
The changelog contains some empty sections (such as `### Bug Fixes`). This change removes these empty sections.

PR Close #36264
2020-07-01 09:22:56 -07:00
e0033f1e10 docs(changelog): remove duplicate entries (#36264)
Remove duplicate entries in the changelog, keeping only the earliest instance of changes that appear multiple times.

PR Close #36264
2020-07-01 09:22:56 -07:00
9206a26e1d docs: clean up api doc in core (#37053)
Add introductions to usage examples and edit descriptions to be more complete and consistent with current API reference styles

PR Close #37053
2020-06-30 12:11:15 -07:00
11dd2bef2d docs: add missing single quote (#37854)
The current code is missing a single quote at the end of the import.

(cherry picked from commit e13171ea2960dd0fa0666cb964b53799d2883e3a)

PR Close #37854
2020-06-30 12:10:13 -07:00
6fc80690ae docs: release notes for the v10.0.2 release 2020-06-30 11:57:17 -07:00
f6d2705942 docs: add Sonu Kapoor to the collaborator list (#37777)
After 6 months of continuous contributions, Sonu Kapoor did finally make
it into the collaborator list.

PR Close #37777
2020-06-30 10:47:54 -07:00
79dc14199b docs: update /config/app-package-json redirect (#37774)
With this change we change the redirect for `/config/app-package-json` from `https://webpack.js.org/configuration/optimization/#optimizationsideeffects` to `https://angular.io/guide/strict-mode#non-local-side-effects-in-applications`

The latter page has more details.

PR Close #37774
2020-06-30 10:45:52 -07:00
71956250dd perf(compiler-cli): fix memory leak in retained incremental state (#37835)
Incremental compilation allows for the output state of one compilation to be
reused as input to the next compilation. This involves retaining references
to instances from prior compilations, which must be done carefully to avoid
memory leaks.

This commit fixes such a leak with a complicated retention chain:

* `TrackedIncrementalBuildStrategy` unnecessarily hangs on to the previous
  `IncrementalDriver` (state of the previous compilation) once the current
  compilation completes.

  In general this is unnecessary, but should be safe as long as the chain
  only goes back one level - if the `IncrementalDriver` doesn't retain any
  previous `TrackedIncrementalBuildStrategy` instances. However, this does
  happen:

* `NgCompiler` indirectly causes retention of previous `NgCompiler`
  instances (and thus previous `TrackedIncrementalBuildStrategy` instances)
  through accidental capture of the `this` context in a closure created in
  its constructor. This closure is wrapped in a `ts.ModuleResolutionCache`
  used to create a `ModuleResolver` class, which is passed to the program's
  `TraitCompiler` on construction.

* The `IncrementalDriver` retains a reference to the `TraitCompiler` of the
  previous compilation, completing the reference chain.

The final retention chain thus looks like:

* `TrackedIncrementalBuildStrategy` of current program
* `.previous`: `IncrementalDriver` of previous program
* `.lastGood.traitCompiler`: `TraitCompiler`
* `.handlers[..].moduleResolver.moduleResolutionCache`: cache
* (via `getCanonicalFileName` closure): `NgCompiler`
* `.incrementalStrategy`: `TrackedIncrementalBuildStrategy` of previous
  program.

The closure link is the "real" leak here. `NgCompiler` is creating a closure
for `getCanonicalFileName`, delegating to its
`this.adapter.getCanonicalFileName`, for the purposes of creating a
`ts.ModuleResolutionCache`. The fact that the closure references
`NgCompiler` thus eventually causes previous `NgCompiler` iterations to be
retained. This is also potentially problematic due to the shared nature of
`ts.ModuleResolutionCache`, which is potentially retained across multiple
compilations intentionally.

This commit fixes the first two links in the retention chain: the build
strategy is patched to not retain a `previous` pointer, and the `NgCompiler`
is patched to not create a closure in the first place, but instead pass a
bound function. This ensures that the `NgCompiler` does not retain previous
instances of itself in the first place, even if the build strategy does
end up retaining the previous incremental state unnecessarily.

The third link (`IncrementalDriver` unnecessarily retaining the whole
`TraitCompiler`) is not addressed in this commit as it's a more
architectural problem that will require some refactoring. However, the leak
potential of this retention is eliminated thanks to fixing the first two
issues.

PR Close #37835
2020-06-29 16:34:51 -07:00
e84539f809 build(docs-infra): update to latest dgeni-packages (#37793)
This update of dgeni-packages to 0.28.4 fixes the
rendering of type initializers for classes and interfaces.

Closes #37694

PR Close #37793
2020-06-29 15:01:14 -07:00
873330b82c docs: correct the spelling mistake in observables error handling code (#36437)
This commit fixes a spelling error in the word error in the
observables.md guide. It is currently
spelled errror  and the mistake is not intentional.

PR Close #36437
2020-06-29 15:00:38 -07:00
a177b1b7b1 docs: change definition of providedIn any (#35292)
change in the definition of providedIn:any any instance creates a singleton instance
for each lazy loaded module and one instance for eager loaded module

PR Close #35292
2020-06-29 15:00:00 -07:00
435a28e937 fix(core): fake_async_fallback should have the same logic with fake-async (#37680)
PR https://github.com/angular/angular/pull/37523 failed when trying to use `rxjs delay` operator
inside `fakeAsync`, and the reasons are:

1. we need to import `rxjs-fake-async` patch to make the integration work.
2. since in `angular` repo, the bazel target `/tools/testing:node` not using `zone-testing` bundle,
instead it load `zone-spec` packages seperately, so it causes one issue which is the `zone.js/testing/fake-async`
package is not loaded, we do have a fallback logic under `packages/core/testing` calles `fake_async_fallback`,
but the logic is out of date with `fake-async` under `zone.js` package.

So this PR, I updated the content of `fake_async_fallback` to make it consistent with
`fake-async`. And I will make another PR to try to remove the `fallback` logic.

PR Close #37680
2020-06-29 12:22:52 -07:00
c2b4d92708 feat(zone.js): patch jasmine.createSpyObj to make properties enumerable to be true (#34624)
Close #33657

in jasmine 3.5, there is a new feature, user can pass a properties object to `jasmine.createSpyObj`

```
const spy = jasmine.createSpyObj('spy', ['method1'], {prop1: 'foo'});
expect(spy.prop1).toEqual('foo');
```

This case will not work for Angular TestBed, for example,

```
describe('AppComponent', () => {
  beforeEach(() => {

    //Note the third parameter
    // @ts-ignore
    const someServiceSpy = jasmine.createSpyObj('SomeService', ['someFunction'], ['aProperty']);

    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      providers: [
        {provide: SomeService, useValue: someServiceSpy},
      ]
    }).compileComponents();

  });

  it('should create the app', () => {
    //spyObj will have someFunction, but will not have aProperty
    let spyObj = TestBed.get(SomeService);
  });
```

Because `jasmine.createSpyObj` will create the `aProperty` with `enumerable=false`,
and `TestBed.configureTestingModule` will try to copy all the properties from spyObj to
the injected service instance. And because `enumerable` is false, so the property (here is aProperty)
will not be copied.

This PR will monkey patch the `jasmine.createSpyObj` and make sure the new property's
`enumerable=true`.

PR Close #34624
2020-06-29 12:22:08 -07:00
a87951a28f fix(ngcc): prevent including JavaScript sources outside of the package (#37596)
When ngcc creates an entry-point program, the `allowJs` option is enabled
in order to operate on the JavaScript source files of the entry-point.
A side-effect of this approach is that external modules that don't ship
declaration files will also have their JavaScript source files loaded
into the program, as the `allowJs` flag allows for them to be imported.
This may pose an issue in certain edge cases, where ngcc would inadvertently
operate on these external modules. This can introduce all sorts of undesirable
behavior and incompatibilities, e.g. the reflection host that is selected for
the entry-point's format could be incompatible with that of the external
module's JavaScript bundles.

To avoid these kinds of issues, module resolution that would resolve to
a JavaScript file located outside of the package will instead be rejected,
as if the file would not exist. This would have been the behavior when
`allowJs` is set to false, which is the case in typical Angular compilations.

Fixes #37508

PR Close #37596
2020-06-29 12:21:22 -07:00
6b565ba8f2 refactor(ngcc): let isWithinPackage operate on paths instead of source files (#37596)
Changes `isWithinPackage` to take an `AbsoluteFsPath` instead of `ts.SourceFile`,
to allow for an upcoming change to use it when no `ts.SourceFile` is available,
but just a path.

PR Close #37596
2020-06-29 12:21:22 -07:00
c29f830c4b docs: correct left nav toc to remove duplicated page links (#37827)
The major sections Angular Libraries, Schematics, and CLI Builders appear twice, in their old location under Techniques, and in the new correct location under Extending Angular

PR Close #37827
2020-06-29 12:19:28 -07:00
cde4653c62 docs: Changing typo Stacblitz into Stackblitz in the Tour of Hereos tutorial docs page (#37794)
Changing the typo of Stacblitz into Stackblitz in the tour of hereos tutorial docs page since that is the actual name of the service

PR Close #37794
2020-06-29 12:17:40 -07:00
e07d940b9b docs: remove first person from 2 sentences (#37768)
This commit removes two instances of the first person in the
Dependency injection providers documentation.

PR Close #37768
2020-06-29 12:17:04 -07:00
ee1526029f docs: add Amadou Sall to GDE page (#36509)
This commit adds Amadou Sall to the Angular GDE page along with a
biography, his role at Air France, and a photograph.

PR Close #36509
2020-06-29 12:16:22 -07:00
eba9dd364e fix(elements): fire custom element output events during component initialization (#37570)
Previously, event listeners for component output events attached on an
Angular custom element before inserting it into the DOM (i.e. before
instantiating the underlying component) didn't fire for events emitted
during initialization lifecycle hooks, such as `ngAfterContentInit`,
`ngAfterViewInit`, `ngOnChanges` (initial call) and `ngOnInit`.
The reason was that `NgElementImpl` [subscribed to events][1] _after_
calling [ngElementStrategy#connect()][2], which is where the
[initial change detection][3] takes place (running the initialization
lifecycle hooks).

This commit fixes this by:
1. Ensuring `ComponentNgElementStrategy#events` is defined and available
   for subscribing to, even before instantiating the component.
2. Changing `NgElementImpl` to subscribe to `NgElementStrategy#events`
   (if available) before calling `NgElementStrategy#connect()` (which
   initializes the component instance) if available.
3. Falling back to the old behavior (subscribing to `events` after
   calling `connect()` for strategies that do not initialize `events`
   before their `connect()` is run).

NOTE:
By falling back to the old behavior when `NgElementStrategy#events` is
not initialized before calling `NgElementStrategy#connect()`, we avoid
breaking existing custom `NgElementStrategy` implementations (with
@remackgeek's [ElementZoneStrategy][4] being a commonly used example).

Jira issue: [FW-2010](https://angular-team.atlassian.net/browse/FW-2010)

[1]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L167-L170)
[2]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L164)
[3]: c0143cb2ab/packages/elements/src/component-factory-strategy.ts (L158)
[4]: f1b6699495/projects/elements-zone-strategy/src/lib/element-zone-strategy.ts

Fixes #36141

PR Close #37570
2020-06-29 10:33:40 -07:00
78a44768e0 fix(ngcc): ensure lockfile is removed when analyzeFn fails (#37739)
Previously an error thrown in the `analyzeFn` would cause
the ngcc process to exit immediately without removing the
lockfile, and potentially before the unlocker process had been
successfully spawned resulting in the lockfile being orphaned
and left behind.

Now we catch these errors and remove the lockfile as needed.

PR Close #37739
2020-06-29 10:29:11 -07:00
98c047b763 ci: decrease payload size limit for integration tests (#37784)
This commit updates the payload size limit for the `hello_world` test app built using Closure. This is likely an effect of the changes in https://github.com/angular/angular/pull/36578 (that reduces the bundle size for most of the apps) and additional changes in subsequent commits.

PR Close #37784
2020-06-26 16:43:03 -07:00
543b679762 fix(core): error when invoking callbacks registered via ViewRef.onDestroy (#37543)
Invoking a callback registered through `ViewRef.onDestroy` throws an error, because we weren't registering it correctly in the internal data structure. These changes also remove the `storeCleanupFn` function, because it was mostly identical to `storeCleanupWithContext` and was only used in one place.

Fixes #36213.

PR Close #37543
2020-06-26 15:02:41 -07:00
c00f4ab2ae fix(core): don't consider inherited NG_ELEMENT_ID during DI (#37574)
Special DI tokens like `ChangeDetectorRef` and `ElementRef` can provide a factory via `NG_ELEMENT_ID`. The problem is that we were reading it off the token as `token[NG_ELEMENT_ID]` which will go up the prototype chain if it couldn't be found on the current token, resulting in the private `ViewRef` API being exposed, because it extends `ChangeDetectorRef`.

These changes fix the issue by guarding the property access with `hasOwnProperty`.

Fixes #36235.

PR Close #37574
2020-06-26 15:01:20 -07:00
2038568f3e ci: decrease expected AIO and integration payload sizes (#36578) (#36578)
The changes in #36687 removed enough code to exceed the CI check limits, so
the expected main-es2015 size needs adjusting.

PR Close #36578
2020-06-26 14:54:09 -07:00
c509243af5 fix(core): determine required DOMParser feature availability (#36578) (#36578)
Verify that HTML parsing is supported in addition to DOMParser existence.
This maybe wasn't as important before when DOMParser was used just as a
fallback on Firefox, but now that DOMParser is the default choice, we need
to be more accurate.

PR Close #36578
2020-06-26 14:54:09 -07:00
d4544da804 refactor(core): split inert strategies to separate classes (#36578) (#36578)
The `inertDocument` member is only needed when using the InertDocument
strategy. By separating the DOMParser and InertDocument strategies into
separate classes, we can easily avoid creating the inert document
unnecessarily when using DOMParser.

PR Close #36578
2020-06-26 14:54:09 -07:00
b950d4675f fix(core): do not trigger CSP alert/report in Firefox and Chrome (#36578) (#36578)
If [innerHTML] is used in a component and a Content-Security-Policy is set
that does not allow inline styles then Firefox and Chrome show the following
message:

> Content Security Policy: The page’s settings observed the loading of a
resource at self (“default-src”). A CSP report is being sent.

This message is caused because Angular is creating an inline style tag to
test for a browser bug that we use to decide what sanitization strategy to
use, which causes CSP violation errors if inline CSS is prohibited.

This test is no longer necessary, since the `DOMParser` is now safe to use
and the `style` based check is redundant.

In this fix, we default to using `DOMParser` if it is available and fall back
to `createHTMLDocument()` if needed. This is the approach used by DOMPurify
too.

The related unit tests in `html_sanitizer_spec.ts`, "should not allow
JavaScript execution when creating inert document" and "should not allow
JavaScript hidden in badly formed HTML to get through sanitization (Firefox
bug)", are left untouched to assert that the behavior hasn't changed in
those scenarios.

Fixes #25214.

PR Close #36578
2020-06-26 14:54:08 -07:00
ae5257cda6 fix(language-service): incorrect autocomplete results on unknown symbol (#37518)
This commit fixes a bug whereby the language service would incorrectly
return HTML elements if autocomplete is requested for an unknown symbol.
This is because we walk through every possible scenario, and fallback to
element autocomplete if none of the scenarios match.

The fix here is to return results from interpolation if we know for sure
we are in a bound text. This means we will now return an empty results if
there is no suggestions.

This commit also refactors the code a little to make it easier to
understand.

PR Close #37518
2020-06-26 14:51:32 -07:00
8fd8143ab8 docs: release notes for the v10.0.1 release 2020-06-26 13:35:40 -07:00
acf3cff9ee ci: exclude "docs" commit type from minBodyLength commit message validation (#37764)
docs commits are sometimes trivial (e.g. an obvious typo fix) and in such cases its very
akward to to write up 100 chars worth of text about why this typo fix is the best thing in the
world and why it is so important and crucial that we must know why we are fixing the typo
at all. After all most typos are not just typos. Or are they? We'll shall see...

PR Close #37764
2020-06-26 11:13:09 -07:00
c5b125b7db feat(dev-infra): add support for minBodyLengthTypeExcludes to commit-message validation (#37764)
This feature will allow us to exclude certain commits from the 100 chars minBodyLength requirement for commit
messages which is hard to satisfy for commits that make trivial changes (e.g. fixing typos in docs or comments).

PR Close #37764
2020-06-26 11:13:09 -07:00
fc5c34d1b8 feat(platform-browser): Allow sms-URLs (#31463)
sms ulr is already supported by google/closure-library and and validations are added to check
if the body passed is safe or not you can refer bb7ea65319/closure/goog/html/safeurl.js (L440-L454) for more details

Fixes #31462

PR Close #31463
2020-06-26 11:12:32 -07:00
0879d2e85d refactor(core): throw more descriptive error message in case of invalid host element (#35916)
This commit replaces an assert with more descriptive error message that is thrown in case `<ng-template>` or `<ng-container>` is used as host element for a Component.

Resolves #35240.

PR Close #35916
2020-06-26 11:10:14 -07:00
83fe963a4b build: move shims_for_IE to third_party directory (#37624)
The shims_for_IE.js file contains vendor code that predates the third_party
directory. This file is currently used for internal karma testing setup. This
change corrects this by moving the shims_for_IE file to //third_part/

PR Close #37624
2020-06-26 11:09:01 -07:00
e0eeb4afcb refactor(compiler-cli): Remove any cast for CompilerHost (#37079)
This commit removes the FIXME for casting CompilerHost to any since
google3 is now already on TS 3.8.

PR Close #37079
2020-06-26 11:08:17 -07:00
c942662d79 fix(language-service): reinstate getExternalFiles() (#37750)
`getExternalFiles()` is an API that could optionally be provided by a tsserver plugin
to notify the server of any additional files that should belong to a particular project.

This API was removed in https://github.com/angular/angular/pull/34260 mainly
due to performance reasons.

However, with the introduction of "solution-style" tsconfig in typescript 3.9,
the Angular extension could no longer reliably detect the owning Project solely
based on the ancestor tsconfig.json. In order to support this use case, we have
to reinstate `getExternalFiles()`.

Fixes https://github.com/angular/vscode-ng-language-service/issues/824

PR Close #37750
2020-06-26 09:57:08 -07:00
6341a837c1 docs: correct outdated dev instructions for public api golds (#37026)
This change updates the dev instructions to reflect the location and generation of public API golds, which changed in #35768.

PR Close #37026
2020-06-26 09:56:32 -07:00
f954ab6f10 docs: add note about the month being zero-based in the Date constructor (#37770)
Because the month is zero based, it may confuse some users that '3'
is in fact 'April'. This comment should clear that up.

PR Close #37770
2020-06-26 09:55:18 -07:00
3ee666580a fix(dev-infra): merge script should not always require full repo permissions (#37718)
We recently added OAuth scope checking to the dev-infra Git client
and started leveraging it for the merge script. We set the `repo` scope
as required for running the merge script. We can loosen this requirement
as in the Angular org where the script is consumed, only pull requests on
public repositories are merged through the script.

This should help with reducing the risk with compromised tokens as no
access had to be granted on `repo:invite`, `repo_deployment` etc.

PR Close #37718
2020-06-26 09:52:33 -07:00
dbc2364d16 fix(dev-infra): support running scripts from within a detached head (#37737)
Scripts provided in the `ng-dev` command might use local `git`
commands. For such scripts, we keep track of the branch that
has been checked out before the command has been invoked.

We do this so that we can later (upon command completion)
restore back to the original branch. We do not want to
leave the Git repository in a dirty state.

It looks like this logic currently only deals with branches
but does not work properly when a command is invoked from
a detached head. We can make it work by just checking out
the previous revision (if no branch is checked out).

PR Close #37737
2020-06-26 09:51:09 -07:00
eee2fd22e0 ci(docs-infra): store JS bundles as CI artifacts to debug size check flakes (#37703)
As reported in #37699, the size of the main angular.io bundle sometimes
ends up bigger than expected on CI. This usually goes away after
rerunning the job a couple of times.

It is unclear what is causing this. In order to help debug the issue,
this commit stores the JS files that are checked as part of the aio
payload-size check as CI artifacts, where they can be retrieved from and
inspected.

PR Close #37703
2020-06-25 17:29:35 -07:00
638dd15f61 build: add wombot proxy for publish config for @angular/benchpress (#37752)
Adds the publishConfig registry value to the package.json of the
@angular/benchpress package to publish it via wombat rather than
through npm directly.

PR Close #37752
2020-06-25 17:08:18 -07:00
9c668e091f docs(elements): fixed command that adds the package @angular/elements (#37681)
I was using schematics with the `--name` parameter instead of the `--project`, I did both ways before sending and my suspicion about outdated documentation was confirmed

PR Close #37681
2020-06-25 17:07:29 -07:00
b2816a1536 docs: typo fixes for schematics-for-libraries.md (#37753)
Addresses small typos such as extra whitespaces.

This change was extracted from #29505.
This change was extracted from #29505.
This change was extracted from #29505.

PR Close #37753
2020-06-25 17:06:37 -07:00
2cbc429291 test(compiler-cli): disable DynamicValue diagnostic tests on Windows (#37763)
This commit disables all diagnostic tests for DynamicValue diagnostics which
make assertions about the diagnostic filename while running tests on Windows.

Such assertions are currently suffering from a case sensitivity issue.

PR Close #37763
2020-06-25 17:04:57 -07:00
4c7f32f28c fix(docs-infra): fix deploy-to-firebase.sh for master and v10.0.x branches (#37762)
The deployment to aio is currently failing because #37721 introduced
"project" entry into the firebase.json which means that we now need to
select the deployment target before deploying to firebase.

This change fixes the issue and refactors the file to be easier to read.

I also added extra echo statements so that the CI logs are easier to
read in case we need to troubleshoot future issues.

PR Close #37762
2020-06-25 17:03:24 -07:00
8572e885b4 test(compiler-cli): fix assertion of diagnostic filename on Windows (#37758)
Several partial_evaluator tests in the diagnostics_spec check assert
correctness of diagnostic filenames. Previously these assertions compared
a resolved (`absoluteFrom`) filename with the TypeScript `ts.SourceFile`'s
`fileName` string, which caused the tests to fail on Windows because the
drive letter case differed.

This commit changes the assertions to use `absoluteFromSourceFile` instead
of the `fileName` string, resulting in an apples-to-apples comparison of
canonicalized paths.

PR Close #37758
2020-06-25 15:40:43 -07:00
0e3e9cd382 fix(docs-infra): fix typo in the deploy-to-firebase.sh script (#37754)
This typo caused the script to fail on Linux (interestingly it works fine on Mac).

This is a painful reminder that we should not write any more Bash scripts EVER. shelljs FTW! :-)

PR Close #37754
2020-06-25 15:21:24 -07:00
9118f49a63 fix(core): cleanup DOM elements when root view is removed (#37600)
Currently when bootstrapped component is being removed using `ComponentRef.destroy` or `NgModuleRef.destroy` methods, DOM nodes may be retained in the DOM tree. This commit fixes that problem by always attaching host element of the internal root view to the component's host view node, so the cleanup can happen correctly.

Resolves #36449.

PR Close #37600
2020-06-25 14:34:35 -07:00
d37049a2a2 feat(platform-server): add option for absolute URL HTTP support (#37539)
In version 10.0.0-next.8, we introduced absolute URL support for
server-based HTTP requests, so long as the fully-resolved URL was
provided in the initial config. However, doing so represents a
breaking change for users who already have their own interceptors
to model this functionality, since our logic executes before all
interceptors fire on a request. See original PR #37071.

Therefore, we introduce a flag to make this change consistent with
v9 behavior, allowing users to opt in to this new behavior. This
commit also fixes two issues with the previous implementation:
1. if the server was initiated with a relative URL, the absolute
URL construction would fail because needed components were empty
2. if the user's absolute URL was on a port, the port would not
be included

PR Close #37539
2020-06-25 14:26:09 -07:00
d12cdb5019 fix(migrations): do not incorrectly add todo for @Injectable or @Pipe (#37732)
As of v10, the `undecorated-classes-with-decorated-fields` migration
generally deals with undecorated classes using Angular features. We
intended to run this migation as part of v10 again as undecorated
classes with Angular features are no longer supported in planned v11.

The migration currently behaves incorrectly in some cases where an
`@Injectable` or `@Pipe` decorated classes uses the `ngOnDestroy`
lifecycle hook. We incorrectly add a TODO for those classes. This
commit fixes that.

Additionally, this change makes the migration more robust to
not migrate a class if it inherits from a component, pipe
injectable or non-abstract directive. We previously did not
need this as the undecorated-classes-with-di migration ran
before, but this is no longer the case.

Last, this commit fixes an issue where multiple TODO's could be
added. This happens when multiple Angular CLI build targets have
an overlap in source files. Multiple programs then capture the
same source file, causing the migration to detect an undecorated
class multiple times (i.e. adding a TODO twice).

Fixes #37726.

PR Close #37732
2020-06-25 14:22:08 -07:00
ce879fc416 refactor(compiler-cli): more accurate reporting of complex function call (#37587)
This commit introduces a dedicated `DynamicValue` kind to indicate that a value
cannot be evaluated statically as the function body is not just a single return
statement. This allows more accurate reporting of why a function call failed
to be evaluated, i.e. we now include a reference to the function declaration
and have a tailor-made diagnostic message.

PR Close #37587
2020-06-25 14:16:35 -07:00
712f1bd0b7 feat(compiler-cli): explain why an expression cannot be used in AOT compilations (#37587)
During AOT compilation, the value of some expressions need to be known at
compile time. The compiler has the ability to statically evaluate expressions
the best it can, but there can be occurrences when an expression cannot be
evaluated statically. For instance, the evaluation could depend on a dynamic
value or syntax is used that the compiler does not understand. Alternatively,
it is possible that an expression could be statically evaluated but the
resulting value would be of an incorrect type.

In these situations, it would be helpful if the compiler could explain why it
is unable to evaluate an expression. To this extend, the static interpreter
in Ivy keeps track of a trail of `DynamicValue`s which follow the path of nodes
that were considered all the way to the node that causes an expression to be
considered dynamic. Up until this commit, this rich trail of information was
not surfaced to a developer so the compiler was of little help to explain
why static evaluation failed, resulting in situations that are hard to debug
and resolve.

This commit adds much more insight to the diagnostic that is produced for static
evaluation errors. For dynamic values, the trail of `DynamicValue` instances
is presented to the user in a meaningful way. If a value is available but not
of the correct type, the type of the resolved value is shown.

Resolves FW-2155

PR Close #37587
2020-06-25 14:16:35 -07:00
d2fb552116 refactor(compiler-cli): create diagnostics using ts.DiagnosticRelatedInformation (#37587)
Previously, an anonymous type was used for creating a diagnostic with related
information. The anonymous type would then be translated into the necessary
`ts.DiagnosticRelatedInformation` shape within `makeDiagnostic`. This commit
switches the `makeDiagnostic` signature over to taking `ts.DiagnosticRelatedInformation`
directly and introduces `makeRelatedInformation` to easily create such objects.
This is done to aid in making upcoming work more readable.

PR Close #37587
2020-06-25 14:16:35 -07:00
5103d908c8 perf(compiler-cli): fix regressions in incremental program reuse (#37641)
Commit 4213e8d5 introduced shim reference tagging into the compiler, and
changed how the `TypeCheckProgramHost` worked under the hood during the
creation of a template type-checking program. This work enabled a more
incremental flow for template type-checking, but unintentionally introduced
several regressions in performance, caused by poor incrementality during
`ts.Program` creation.

1. The `TypeCheckProgramHost` was made to rely on the `ts.CompilerHost` to
   retrieve instances of `ts.SourceFile`s from the original program. If the
   host does not return the original instance of such files, but instead
   creates new instances, this has two negative effects: it incurs
   additional parsing time, and it interferes with TypeScript's ability to
   reuse information about such files.

2. During the incremental creation of a `ts.Program`, TypeScript compares
   the `referencedFiles` of `ts.SourceFile` instances from the old program
   with those in the new program. If these arrays differ, TypeScript cannot
   fully reuse the old program. The implementation of reference tagging
   introduced in 4213e8d5 restores the original `referencedFiles` array
   after a `ts.Program` is created, which means that future incremental
   operations involving that program will always fail this comparison,
   effectively limiting the incrementality TypeScript can achieve.

Problem 1 exacerbates problem 2: if a new `ts.SourceFile` is created by the
host after shim generation has been disabled, it will have an untagged
`referencedFiles` array even if the original file's `referencedFiles` was
not restored, triggering problem 2 when creating the template type-checking
program.

To fix these issues, `referencedFiles` arrays are now restored on the old
`ts.Program` prior to the creation of a new incremental program. This allows
TypeScript to get the most out of reusing the old program's data.

Additionally, the `TypeCheckProgramHost` now uses the original `ts.Program`
to retrieve original instances of `ts.SourceFile`s where possible,
preventing issues when a host would otherwise return fresh instances.

Together, these fixes ensure that program reuse is as incremental as
possible, and tests have been added to verify this for certain scenarios.

An optimization was further added to prevent the creation of a type-checking
`ts.Program` in the first place if no type-checking is necessary.

PR Close #37641
2020-06-25 14:12:20 -07:00
9318e23e64 perf(ngcc): use EntryPointManifest to speed up noop ProgramBaseEntryPointFinder (#37665)
Previously the `ProgramBasedEntryPointFinder` was parsing all the
entry-points referenced by the program for dependencies even if all the
entry-points had been processed already.

Now this entry-point finder will re-use the `EntryPointManifest` to load
the entry-point dependencies when possible which avoids having to parse
them all again, on every invocation of ngcc.

Previously the `EntryPointManifest` was only used in the
`DirectoryWalkerEntryPointFinder`, which also contained the logic for
computing the contents of the manifest. This logic has been factored out
into an `EntryPointCollector` class. Both the `ProgramBasedEntryPointFinder`
and `DirectoryWalkerEntryPointFinder` now use the `EntryPointManifest` and
the `EntryPointCollector`.

The result of this change is that there is a small cost on the first run of
ngcc to compute and store the manifest - the processing takes 102% of the
processing time before this PR. But on subsequent runs there is a
significant benefit on subsequent runs - the processing takes around 50%
of the processing time before this PR.

PR Close #37665
2020-06-25 14:11:03 -07:00
290bc7334d test(localize): add compile time extraction to integration test (#32912)
The integration test for i18n now makes use of the new extraction tooling
from the `@angular/localize` package rather than the old ViewEngine extractor.

PR Close #32912
2020-06-25 14:10:03 -07:00
190561d8a6 feat(localize): implement message extraction tool (#32912)
This tool, which can be run from the node_modules bin folder, can parse
the source files in your compiled app and generate a translation file
formatted with the configured syntax.

For example:

```
./node_modules/.bin/localize-extract -s 'dist/**/*.js' -f xliff1 -o dist/messages.en.xlf
```

PR Close #32912
2020-06-25 14:10:03 -07:00
ddb0a4e2e5 refactor(localize): handle location endings correctly (#32912)
Previously source locations required an ending position but this was not
being computed effectively. Now ending position is optional and it is
computed from an `endPath` passed to `getLocation()`.

PR Close #32912
2020-06-25 14:10:03 -07:00
07a07e34bc fix(compiler-cli): only read source-map comment from last line (#32912)
Source-maps can be linked to from a source-file by a comment at
the end of the file.

Previously the `SourceFileLoader` would read
the first comment that matched `//# sourceMappingURL=` but
this is not valid since some bundlers may include embedded
source-files that contain such a comment.

Now we only look for this comment in the last non-empty line
in the file.

PR Close #32912
2020-06-25 14:10:03 -07:00
dda3f49952 refactor(compiler): add source-map spans to localized strings (#32912)
Previously localized strings were not mapped to their original
source location, so it was not possible to back-trace them
in tools like the i18n message extractor.

PR Close #32912
2020-06-25 14:10:03 -07:00
decd95e7f0 fix(compiler-cli): ensure source-maps can handle webpack:// protocol (#32912)
Webpack and other build tools sometimes inline the contents of the
source files in their generated source-maps, and at the same time
change the paths to be prefixed with a protocol, such as `webpack://`.

This can confuse tools that need to read these paths, so now it is
possible to provide a mapping to where these files originated.

PR Close #32912
2020-06-25 14:10:03 -07:00
6abb8d0d91 feat(compiler-cli): add SourceFile.getOriginalLocation() to sourcemaps package (#32912)
This method will allow us to find the original location given a
generated location, which is useful in fine grained work with
source-mapping. E.g. in `$localize` tooling.

PR Close #32912
2020-06-25 14:10:03 -07:00
2b2146bc58 docs: Uses correct component in the MessageService (#37666)
This commit uses the correct component (`HeroesComponent`) in the.
`MessageService`. Previously, the `MessageService` was using
`HeroeService`.

Closes #37654

PR Close #37666
2020-06-25 13:48:59 -07:00
3a698e2d08 feat(docs-infra): update deploy-to-firebase.sh script to support v9 multisite setup (#37721)
v9.angular.io was used to pilot the firebase hosting multisites setup for angular.io.

The deployments so far have been done manually to control the deployment process.

This change, automates the deployment for v9.angular.io so that future deployments can be made from
the CI.

See https://angular-team.atlassian.net/browse/DEV-125 for more info.

In the process of updating the scripts I rediscovered a bug in the deploy-to-firebase.sh script that
incorrect compared two numbers as strings. This previously worked correctly because we were comparing
single digit numbers. With the release of v10, we now compare 9 > 10 which behaves differently for
strings and numbers. The bug was fixed by switching to an arithmetic comparison of the two variables.

This bug has been fixed on the master branch but not on the 9.1.x branch. I realized this during the
rebase, but found my version to be a bit cleaner, so I kept it.

PR Close #37721
2020-06-25 13:44:52 -07:00
8a74508130 fix(http): avoid abort a request when fetch operation is completed (#37367)
`abort` method is calling, even if fetch operation is completed

Fixes https://github.com/angular/angular/issues/36537

PR Close #37367
2020-06-25 12:09:39 -07:00
ef1fb6dee4 fix(common): date pipe gives wrong week number (#37632)
Date pipe is giving wrong week number when used with the date format 'w'. If first week(according to Iso)  has some days in previous year

Fixes #33961

PR Close #37632
2020-06-25 12:08:46 -07:00
e36d5b201a fix(forms): correct usage of selectedOptions (#37620)
Previously, `registerOnChange` used `hasOwnProperty` to identify if the
property is supported. However, this does not work as the `selectedOptions`
property is an inherited property. This commit fixes this by verifying
the property on the prototype instead.

Closes #37433

PR Close #37620
2020-06-25 12:08:00 -07:00
77b62a52c0 fix(forms): handle form groups/arrays own pending async validation (#22575)
introduce a boolean to track form groups/arrays own pending async validation to distinguish between pending state due to children and pending state due to own validation

Fixes #10064

PR Close #22575
2020-06-25 12:07:25 -07:00
616543ded0 fix(router): add null support for RouterLink directive (#32616)
Value of "undefined" passed as segment in routerLink is stringified to string "undefined".
This change introduces the same behavior for value of "null".

PR Close #32616
2020-06-25 11:58:00 -07:00
2170ea270a fix(router): fix error when calling ParamMap.get function (#31599)
fix this.params.hasOwnProperty is not a function in case of creating an object using Object.create()

PR Close #31599
2020-06-25 11:57:24 -07:00
80d0067048 fix(router): RouterLinkActive should run CD when setting isActive (#21411)
When using the routerLinkActive directive inside a component that is using ChangeDetectionStrategy.OnPush and lazy loaded module routes the routerLinkActive directive does not update after clicking a link to a lazy loaded route that has not already been loaded.

Also the OnPush nav component does not set routerLinkActive correctly when the default route loads, the non-OnPush nav component works fine.

regression caused by #15943
closes #19934

PR Close #21411
2020-06-25 11:56:26 -07:00
5218916a7e feat(dev-infra): add a way to pass assets down to a benchmark application (#37695)
* add a param called ng_assets to the component_benchmark macro to allow static assets to be provided to the base angular app, not just through the ts_devserver

PR Close #37695
2020-06-25 11:51:51 -07:00
1c1eb3045c docs: Add support schedule for v10 (#37745)
This commit adds the support schedule for v10.
v10.0.0 was released on June 24, 2020.
Active support ends six months later, on Dec 24, 2020.
Long term support ends a year after that, on Dec 24, 2021.

PR Close #37745
2020-06-25 11:49:17 -07:00
4967997536 ci(compiler-cli): exempt compiler-cli .bazel files from dev-infra approval (#37558)
Previously, dev-infra approval (via PullApprove) was required for all
.bazel files in the monorepo, including those in packages/compiler-cli.

The compiler-cli package is a little special in this sense:
 * it's not shipped to NPM in the APF
 * it uses lots of internal subpackages to organize and test its code

As a result:
 * changes to compiler-cli BUILD.bazel files are not user visible and
   don't have larger implications for the packages published to NPM,
   unlike changes to other BUILD.bazel files in the repo
 * the requirement for dev-infra approval for BUILD.bazel changes is
   overly burdensome, because compiler-cli build files change more
   rapidly than those of other packages.

This commit exempts the compiler-cli's build files from the requirement
for dev-infra approval. It will be sufficient for such files to be
approved by the normal compiler reviewers.

PR Close #37558
2020-06-25 11:47:50 -07:00
666e6d15fa docs: Replace $emdash; with an actual em dash (#37723)
fix documentation in the lifecycle hooks guide where $emdash; was not being replaced by an actual em dash (-)

PR Close #37723
2020-06-25 11:41:54 -07:00
f3ec37ebbf release(benchpress): bump version to v0.2.1 and update @angular/core peer dependency (#37676)
Updates the version of `@angular/benchpress` to the next patch
version. i.e. `v0.2.1`. Additionally, the peer dependency
on `@angular/core` has been updated to be satisifed with
Angular v10 and v11.

Benchpress should be at least compatibe with the next two major
versions as it does not rely on any deprecated API from `@angular/core`.

PR Close #37676
2020-06-25 11:39:08 -07:00
cc3b1ebd96 refactor: cleanup unused dependencies in benchpress package (#37676)
Removes unused packages from the benchpress `package.json`. That
helps with deduping dependencies, and avoiding unused code
being downloaded.

PR Close #37676
2020-06-25 11:39:08 -07:00
29490cce30 build: set up caretaker note label in merge tooling (#37675)
Leverage the caretaker note label configuration in ng-dev's merge
tooling to prompt the caretaker for confirmation  when a PR has
the `PR action: merge-assistance` label. This should help to
surface for the caretaker, PRs which may need additional steps
taken, announcement messaging, etc.

PR Close #37675
2020-06-25 11:38:21 -07:00
bedc0451a0 docs(ngcc): add additional next steps to an error (#37672)
The file-writing error in the this commit can also be the result
of the ngcc process dying in the middle of writing files.

This commit improves the error message to offer a resolution
in case this is the reason for the error.

Fixes #36393

PR Close #37672
2020-06-25 11:37:43 -07:00
a0595f4b4f fix(forms): change error message (#37643)
Error message mention that ngModel and ngModelChange will be removed in Angular v7 but right not now sure when it will be removed so changed it to a future version

PR Close #37643
2020-06-25 11:36:59 -07:00
8924ec1474 test(docs-infra): add end to end tests for api reference (#37612)
Api search functionality only had unit tests @gkalpak suggested we should have some e2e tests too. Added some end to end tests.

Fixes #35170

PR Close #37612
2020-06-25 11:36:02 -07:00
4481bebb38 docs: add v9.angular.io to the angular.io version picker (#37719)
Now that v10 is out, it's time to add the v9.angular.io link to the version picker, so here we go...

PR Close #37719
2020-06-24 19:53:24 -07:00
f5bbfd7b8c docs(changelog): fix v10 announcement url (#37722)
PR Close #37722
2020-06-24 19:50:44 -07:00
41ce5240f2 docs: release notes for the v10.0.0 release 2020-06-24 16:05:23 -07:00
243824ef74 docs: updating guides and docs related to the v10 release (#37705)
Mostly just adding links to the migrations that were missing, adding the migrations into the navbar,
as well as correcting the @angular/bazel removal in the update guide.

I also added a commented out preamble for the release notes.

PR Close #37705
2020-06-24 09:37:34 -07:00
c95802f26f docs: add lightweight token page to library section of docs (#36144)
adds new DI technique recommendation for libraries to ensure tree-shaking for unused services
includes reasons for packaging schematics with libraries, clarify schematic usage recommendation

PR Close #36144
2020-06-23 16:34:51 -07:00
71c0363bb5 docs: add tslib update migration docs (#37402)
This adds documentation for the v10.0 tooling migration `update-libraries-tslib` contained within the `@schematics/angular` package.

PR Close #37402
2020-06-23 13:07:39 -07:00
e03adaf9b0 docs: add module/target compiler option migration docs (#37429)
This adds documentation for the v10.0 tooling migration `update-module-and-target-compiler-options` contained within the `@schematics/angular` package.

PR Close #37429
2020-06-23 12:46:22 -07:00
38dfbc775f ci(docs-infra): disable flaky tests (#37673)
I could not figure out the root cause of the flakes, so disabling the
flaky tests for now. See
https://github.com/angular/angular/pull/37637#issuecomment-647608149 for
more info.

Fixes #37629

PR Close #37673
2020-06-23 12:45:11 -07:00
5229809adb docs: Initial commit of update guide for v10 release. (#37152)
This update includes modifications to the navigation.json file to
remove unneeded migration guides.

TODO: Redirects from v9 topics to v10; links to removed migration
guides need to point to v9.angular.io.

PR Close #37152
2020-06-23 11:56:49 -07:00
9d88ca07f8 docs: add solution-style tsconfig migration docs (#37512)
This adds documentation for the v10.0 tooling migration `solution-style-tsconfig` contained within the `@schematics/angular` package.

PR Close #37512
2020-06-23 11:55:01 -07:00
97383488e8 docs: add strict-mode.md file to pullapprove (#37679)
When I created the strict-mode.md file, I didn't add it to the
pullapprove list. Now it's there.

The issue was introduced in #37486.

PR Close #37679
2020-06-23 10:05:50 -07:00
cb566add3c docs: Add content for new strict mode for Angular CLI (#37486)
In v10, the Angular CLI supports a strict mode, which turns
on additional flags for the TypeScript and Angular compilers.

PR Close #37486
2020-06-22 16:29:15 -07:00
5c40fd65fa refactor(compiler-cli): tidy up file_system BUILD.bazel file_system (#37114)
* Re-order the `load` and `package` statements
* Make `srcs` glob more generic
* Remove unnecessary dependencies

PR Close #37114
2020-06-22 13:38:47 -07:00
2b53b07c70 refactor(ngcc): move sourcemaps into ngtsc (#37114)
The `SourceFile` and associated code is general and reusable in
other projects (such as `@angular/localize`). Moving it to `ngtsc`
makes it more easily shared.

PR Close #37114
2020-06-22 13:38:47 -07:00
6de5a12a9d refactor(ngcc): move logging code into ngtsc (#37114)
The `Logger` interface and its related classes are general purpose
and could be used by other tooling. Moving it into ngtsc is a more
suitable place from which to share it - similar to the FileSystem stuff.

PR Close #37114
2020-06-22 13:38:47 -07:00
3a418ab63b docs: fix invalid anchor for CLI flags in deprecation guide (#37662)
7521834296 added content for CLI
deprecations to the `angular.io` deprecations guide. It looks
like the anchor for the CLI deprecations is incorrect and
ends up showing up as code in the guide.

This commit fixes the anchor so that it doesn't show
up as code in the guide.

PR Close #37662
2020-06-22 10:57:16 -07:00
c8c0063499 ci: disable saucelabs tests on Firefox ESR while investigating failures (#37647)
Firefox ESR tests fail running the acceptance tests on saucelabs.  These tests are being
disabled while investigating the failure as it is not entirely clear whether this is
saucelabs failure or a something like a memory pressure error in the test itself.

PR Close #37647
2020-06-22 10:56:28 -07:00
34259e90cb build: determine pullapprove fallback with better active group counting (#37636)
Previously, the fallback group simply determined its active state based on the
of active groups during processing.  Instead, we should consider if there are
any active groups after excluding the ones we don't want to be considered, i.e.
the minimum required review group and the global approval groups.  This allows
for an explicit test of the active groups that exist rather than a prone to get
out of date number of expected active groups.

With this change, we additionally need to check to ensure that global approvals
have not caused other groups to no longer be active, causing a false case of
no active groups, when they have simply been superceded by a global approval.

PR Close #37636
2020-06-22 10:56:00 -07:00
d0c69d207c build: update required-minimum-review group to be global approvable (#37636)
Previously, the required-minimum-review group was still considered active when
a global approval was provided.  This would result in global approvers needing
to Reviewd-For both the global approval and minimum review groups.  Instead
when a global approver provides their approval, the minimum review group should
be considered satisified.

PR Close #37636
2020-06-22 10:56:00 -07:00
1f0818002c build: correct listed username for @Splaktar in pullapprove config (#37636)
Previously, Michael Prentice's username was erroneously listed at @michaelprentice
however his Github username is actually @Splaktar.  This issue is corrected by this
change to properly allow him to provide reviews.

PR Close #37636
2020-06-22 10:56:00 -07:00
fd65958b88 test: update symbol goldens to reflect optimized application (#37623)
Interestingly enough, our rollup bundle optimization pipeline
did not work properly before 1b827b058e5060963590628d4735e6ac83c6dfdd.

Unused declarations were not elided because build optimizer did not
consider the Angular packages as side-effect free. Build optimizer has
a hard-coded list of Angular packages that are considered side-effect
free. Though this one did not match in the old version of the rollup
bundle rule, as internal sources were resolved through their resolved
bazel-out paths. Hence build optimizer could not detect the known
Angular framework packages. Now though, since we leverage the
Bazel-idiomatic `@bazel/rollup` implementation, sources are resolved
through linked `node_modules`, and build optimizer is able to properly
detect files as side-effect free.

PR Close #37623
2020-06-22 10:55:29 -07:00
12f674f404 ci: update components-repo-unit-tests job commit (#37623)
Updates to the latest commit of the `angular/components` repository. We
need to do this because we removed the `esm5.bzl` output flavour aspect,
but an old version of the components repo relied on this file to exist.

This is no longer the case, and we can simply update the version of the
components repo we can test against.

PR Close #37623
2020-06-22 10:55:29 -07:00
413a0fb1ae fix(language-service): non-existent module format in package output (#37623)
The language-service package currently sets the `module` `package.json`
property and refers to a folder called `fesm5`. The language-service
though does not build with `ng_package` so this folder never existed.
Now with APF v10, ng package would not generate this folder either.

We should just remove the property as the primary entry-point is
the UMD bundle resolved through `main`. There is no module flavour
exposed to the NPM package as `pkg_npm` uses the named AMD module
devmode output that doesn't work for `module`.

PR Close #37623
2020-06-22 10:55:29 -07:00
85abfd2171 test: remove unused stale ng_package test golden file (#37623)
It looks like there is a leftover golden in the `ng_package`
tests that is no longer used anywhere and does not reflect
the latest Angular Package Format v10 changes. We should be
able to remove it to keep our codebase healthy.

PR Close #37623
2020-06-22 10:55:29 -07:00
1601ee6f6a refactor(dev-infra): ng_rollup_bundle rule should leverage @bazel/rollup (#37623)
Refactors the `ng_rollup_bundle` rule to a macro that relies on
the `@bazel/rollup` package. This means that the rule no longer
deals with custom ESM5 flavour output, but rather only builds
prodmode ES2015 output. This matches the common build output
in Angular projects, and optimizations done in CLI where
ES2015 is the default optimization input.

The motiviation for this change is:

* Not duplicating rollup Bazel rules. Instead leveraging the official
rollup rule.
* Not dealing with a third TS output flavor in Bazel.The ESM5 flavour has the
potential of slowing down local development (as it requires compilation replaying)
* Updating the rule to be aligned with current CLI optimizations.

This also _fixes_ a bug that surfaced in the old rollup bundle rule.
Code that is unused, is not removed properly. The new rule fixes this by
setting the `toplevel` flag. This instructs terser to remove unused
definitions at top-level. This matches the optimization applied in CLI
projects. Notably the CLI doesn't need this flag, as code is always
wrapped by Webpack. Hence, the unused code eliding runs by default.

PR Close #37623
2020-06-22 10:55:28 -07:00
6898eab946 feat(bazel): provide LinkablePackageInfo from ng_module (#37623)
Adds the `LinkablePackageInfo` to the `ng_module` rule. This allows
the linker to properly link `ng_module` targets in Node runtime
actions. Currently this does not work properly and packages like
`@angular/core` are not linked, so we cannot rely on the linker.

9a5de3728b/internal/linker/link_node_modules.bzl (L144-L146).

PR Close #37623
2020-06-22 10:55:28 -07:00
62a85f5e55 refactor(bazel): cleanup ng_package rule to not build fesm5 and esm5 output (#37623)
As of Angular Package Format v10, we no longer ship a `fesm5` and
`fesm5` output in packages. We made this change to the `ng_package`
rule but intentionally did not clean up related build actions.

This follow-up commit cleans this up by:

* No longer building fesm5 bundles, or providing esm2015 output.
* No longer requesting and building a third flavor for ESM5. We can
use TSC to downlevel ES2015 sources/prodmode output similarly to how it
is done in `ng-packagr`.

The third output flavor (ESM5) resulted in a build slow-down as we
required a full recompilation of sources. Now, we only have a single
compilation for prodmode output, and then downlevel it on-demand
to ES5 for the UMD bundles. Here is timing for building the release
packages in `angular/angular` before this change, and afterwards:

* Before: 462.157s = ~7.7min
* After: 339.703s =  ~5.6min

This signifies a time reduction by 27% when running
`./scripts/build/build-packages-dist.sh`.

PR Close #37623
2020-06-22 10:55:28 -07:00
a8af8551ec refactor(dev-infra): migrate github api in GitClient to rely on GithubClient (#37593)
GitClient now uses GithubClient for github API interactions.  GithubClient is
a class which extends Octokit and provides a member which allows for GraphQL
requests against the Github GraphQL api, as well as providing convenience methods
for common/repeated Github API requests.

PR Close #37593
2020-06-22 10:54:43 -07:00
7e0eccc4ef docs: Refactor-i18n (#36924)
Rewrite headings to focus on tasks and separate reference info and best practices from tasks. Add missing steps or procedures, and links to important information. Make the example open in StackBlitz. See i18n Documentation Plan at https://docs.google.com/document/d/1aV2TKsIqry7JnNiHEfhmheu5rNAbNl1IRYVhYErc7Ks/edit?usp=sharing

PR Close #36924
2020-06-22 10:52:59 -07:00
2a970a0af8 Revert "fix(router): fix navigation ignoring logic to compare to the browser url (#37408)" (#37650)
This reverts commit d3a817549b.

The reason for the revert is the problem reported in g3 which requires additional investigation.

PR Close #37650
2020-06-22 10:47:47 -07:00
bd7f440357 perf(ngcc): shortcircuit tokenizing in ESM dependency host (#37639)
This dependency host tokenizes files to identify all the imported
paths. This commit calculates the last place in the source code
where there can be an import path; it then exits the tokenization
when we get to this point in the file.

Testing with a reasonably large project showed that the tokenizer
spends about 2/3 as much time scanning files. For example in a
"noop" hot run of ngcc using the program-based entry-point
finder the percentage of time spent in the `scan()` function of
the TS tokenizer goes down from 9.9% to 6.6%.

PR Close #37639
2020-06-18 16:05:42 -07:00
d0437b3be0 docs: fix grammatical errors in developer docs (#37633)
The CONTRIBUTOR and DEVELOPER markdown docs contained a few typos
and grammatical errors, which are fixed in this commit.

PR Close #37633
2020-06-18 16:04:58 -07:00
1d844b9bd8 docs(core): correct type for opts.read (#37626)
The ContentChildren decorator has a metadata property named "read" which
can be used to read a different token from the queried elements. The
documentation incorrectly says "True to read..." when it should say
"Used to read...".

PR Close #37626
2020-06-18 16:04:09 -07:00
53e95233c3 refactor(dev-infra): cleanup shared package dependencies (#37594)
Cleans up the dependencies used in the shared dev-infra package
configuration. With the recent benchmarking utilities that have
been added, a lot of peer dependencies have been added.

We decided that we don't want to list every used dependencies as
peer dependency as that could result in unnecessary churn/noise
for consumers of the dev-infra package. Additionally, not all parts
of the dev-infra package are necessarily used.

Due to this, we want to apply the following rules for the package
dependencies:

1. If a dependency is only used in a shipped Bazel macro/rule that can be
optionally consumed, omit it from `package.json`. Bazel reports the
missing dependency on its own, so we want to avoid adding it to the
package json file.

2. Otherwise, if the dependency is large and commonly used (like
buildifier), add it to the `peerDependencies`. If not, add it
to the dependencies that are always brought in. We consider it
as acceptable to bring in a few small dependencies that might not
be used or not. Making all of those option would complicate the
use of the dev-infra package.

ds

PR Close #37594
2020-06-18 16:03:14 -07:00
879a674420 refactor(dev-infra): use shelljs instead of fs-extra for benchmark utils (#37594)
We added a new dependency on `fs-extra` to the dev-infra package. We can
remove this dependency and replace it with `shelljs` that is extensively
used in other places already.

The motiviation is that we can reduce dependencies needed for
for consumption of the shared dev-infra package.

PR Close #37594
2020-06-18 16:03:14 -07:00
71f008f906 fix(router): remove parenthesis for primary outlet segment after removing auxiliary outlet segment (#24656) (#37163)
For URLs that use auxiliary route outlets in the second or following path segments,
when removing the auxiliary route segment, parenthesis remain for the primary outlet segment.
This causes the following error when trying to reload an URL: "Cannot match any route".
The commit adds a check for this scenario, serializing the URL as "a/b" instead of "a/(b)".

PR Close #24656

PR Close #37163
2020-06-18 16:02:19 -07:00
1197965e69 docs: move ng-vikings 2020 to the already presented section (#37466)
This commit moves the ng-vikings 2020 event from the currently presenting
section into the already presented section.

PR Close #37466
2020-06-17 11:18:47 -07:00
8154bbd538 feat(dev-infra): support for caretaker note label in merge script (#37595)
Adds support for a caretaker note label to the merge script.
Whenever a configured label is applied, the merge script will
not merge automatically, but instead prompt first in order
to ensure that the caretaker paid attention to the manual
caretaker note on the PR. This helps if a PR needs special
attention.

PR Close #37595
2020-06-16 11:58:55 -07:00
f5e39999d7 docs: add side effect package.json in app structure (#37521)
With this change we add the special `package.json` which is used to mark the application free of non-local side-effects in the application source files section

PR Close #37521
2020-06-16 11:57:40 -07:00
ff33ab1379 docs: @angular/language‑service is no longer a dev-dependencies (#37521)
`@angular/
language‑service` is no longer needed as a dev-dependencies, infact we no longer generate project with this dependency as it can conflict with the https://marketplace.visualstudio.com/items?itemName=Angular.ng-template

PR Close #37521
2020-06-16 11:57:39 -07:00
7521834296 docs: add new section for CLI deprecations (#37332)
Current documentation does not list CLI flag deprecations. This
change adds it for v10.

PR Close #37332
2020-06-16 11:57:04 -07:00
1185aa07a3 docs: wrong example in routerLink (#37590)
In routerLink if a fragment is added than fragment example shows that it is added before the params '/user/bob#education?debug=true' but actually they are added after that '/user/bob?debug=true#education' changed documentation to show correct example

Fixes #18630

PR Close #37590
2020-06-16 09:45:22 -07:00
ceca5dded5 feat(bazel): expose explicit mapping from closure to devmode files (#36262)
This feature is aimed at development tooling that has to translate
production build inputs into their devmode equivalent. The current
process involves guessing the devmode filename based on string
replace patterns. This allows consuming build actions to read the
known mappings instead.

This is a change in anticipation of an update to the general
Typescript build rules to consume this data.

PR Close #36262
2020-06-15 14:32:22 -07:00
2a145f2463 perf(forms): optimize internal method _anyControls in FormGroup (#32534)
The method was previously looping through all controls, even after finding at least one that
satisfies the provided condition. This can be a bottleneck with large forms. The new version
of the method returns as soon as a single control which conforms to the condition is found.

PR Close #32534
2020-06-15 14:31:48 -07:00
e0dfa42d6e ci: include PR author as an approver of all PRs (#36915)
This change adds an implicit approval for any change by the
PR author.  This allows for a PR author to provide the required
owner approval for an area of the code base.

This change helps to align the review methodology with how Google's
internal system works. Where anyone is able to provide the LGTM
for a change if thats all that is needed.

PR Close #36915
2020-06-15 14:29:33 -07:00
cc37af2314 fix(dev-infra): allow for deep merging of pullapprove config aliases (#36915)
Set the yaml parser to support deep merges of yaml aliases,
to support having a default value for all rules to build upon.

PR Close #36915
2020-06-15 14:29:32 -07:00
87a679b210 build: import in-memory-web-api project (#37182)
Moves the `angular-in-memory-web-api` project into the main repository in order to make it easier to maintain and release.

PR Close #37182
2020-06-15 14:28:37 -07:00
a7359d494a docs: release notes for the v10.0.0-rc.6 release 2020-06-15 14:22:30 -07:00
66e6b932d8 refactor(compiler-cli): skip class decorators in tooling constructor parameters transform (#37545)
We recently added a transformer to NGC that is responsible for downleveling Angular
decorators and constructor parameter types. The primary goal was to mitigate a
TypeScript limitation/issue that surfaces in Angular projects due to the heavy
reliance on type metadata being captured for DI. Additionally this is a pre-requisite
of making `tsickle` optional in the Angular bazel toolchain.

See: 401ef71ae5 for more context on this.

Another (less important) goal was to make sure that the CLI can re-use
this transformer for its JIT mode compilation. The CLI (as outlined in
the commit mentioned above), already has a transformer for downleveling
constructor parameters. We want to avoid this duplication and exported
the transform through the tooling-private compiler entry-point.

Early experiments in using this transformer over the current one, highlighted
that in JIT, class decorators cannot be downleveled. Angular relies on those
to be invoked immediately for JIT (so that factories etc. are generated upon loading)

The transformer we exposed, always downlevels such class decorators
though, so that would break CLI's JIT mode. We can address the CLI's
needs by adding another flag to skip class decorators. This will allow
us to continue with the goal of de-duplication.

PR Close #37545
2020-06-15 12:47:57 -07:00
cc49a91de7 Revert "feat(bazel): expose explicit mapping from closure to devmode files (#36262)"
This reverts commit 7ac166ff08.
2020-06-15 10:19:56 -07:00
300c2fec9c refactor(compiler-cli): make IncrementalBuild strategy configurable (#37339)
Commit 24b2f1da2b introduced an `NgCompiler` which operates on a
`ts.Program` independently of the `NgtscProgram`. The NgCompiler got its
`IncrementalDriver` (for incremental reuse of Angular compilation results)
by looking at a monkey-patched property on the `ts.Program`.

This monkey-patching operation causes problems with the Angular indexer
(specifically, it seems to cause the indexer to retain too much of prior
programs, resulting in OOM issues). To work around this, `IncrementalDriver`
reuse is now handled by a dedicated `IncrementalBuildStrategy`. One
implementation of this interface is used by the `NgtscProgram` to perform
the old-style reuse, relying on the previous instance of `NgtscProgram`
instead of monkey-patching. Only for `NgTscPlugin` is the monkey-patching
strategy used, as the plugin sits behind an interface which only provides
access to the `ts.Program`, not a prior instance of the plugin.

PR Close #37339
2020-06-15 09:50:08 -07:00
a7faa6bb65 docs(service-worker): minor fixes/improvements in the SW Communication guide (#37555)
This commit includes various fixes/improvements for the
"Service worker communication" guide.

This partially addresses #37527.

PR Close #37555
2020-06-15 09:48:55 -07:00
bcc0a035cc docs(service-worker): update default value of SwRegistrationOptions#registrationStrategy (#37555)
The default value was changed from `registerWhenStable` to
`registerWhenStable:30000` in 29e8a64cf0,
but the decumentation was not updated to reflect that.

This commit updates the documentation to mention the correct default
value.

PR Close #37555
2020-06-15 09:48:55 -07:00
e99bcbb4d4 fix(language-service): wrong completions in conditional operator (#37505)
In `a ? b.~{cursor}`, the LS will provide the symbols in the scope of the current template, because the `path.tail` is `falseExp` whose value is `EmptyExpr`, and the span of `falseExp` is wider than the `trueExp`, so the value of `path` should be narrowed.

PR Close #37505
2020-06-15 09:41:25 -07:00
adc9d5cdcb docs: describe how to configure CommonJS modules (#37331)
In version 10, we have a new option for the `angular.json` file,
`allowedCommonJsDependencies`, so users can opt in to support
CommonJS modules.

PR Close #37331
2020-06-15 09:40:44 -07:00
d330cd85ac refactor: move hover into a proper @media hover (#37320)
This commit moves the contributor hover into the `@media(hover:hover)`
query. This will help to identify if the user's primary input mechanism
can hover over elements.

PR Close #37320
2020-06-15 09:39:17 -07:00
09d6dc50ef docs: Update documentation to reflect addition of tsconfig.base.json. (#37222)
In version 10, there is a new `tsconfig.json` file, which contains
the paths to all other `tsconfig` files used in a workspace. The
previous `tsconfig.json` file still exists, but has been renamed to
`tsconfig.base.json`.

In addition to documenting this change, I have updated files that
refer to TypeScript configuration files generically to remove specific
references to `tsconfig.json.` This should help avoid confusing users.

PR Close #37222
2020-06-15 09:37:00 -07:00
7ac166ff08 feat(bazel): expose explicit mapping from closure to devmode files (#36262)
This feature is aimed at development tooling that has to translate
production build inputs into their devmode equivalent. The current
process involves guessing the devmode filename based on string
replace patterns. This allows consuming build actions to read the
known mappings instead.

This is a change in anticipation of an update to the general
Typescript build rules to consume this data.

PR Close #36262
2020-06-15 09:35:35 -07:00
ae4f81cbab docs: Change 'function' to 'method' for clarity that getHereos() is (#35998)
intended as a class method

Change 'function' to 'method' for clarity that getHereos() is
intended as a class method in Tour of Heroes part 4.

PR Close #35998
2020-06-15 09:07:51 -07:00
c1fdfd4f14 docs: update CONTRIBUTING.md with info about major docs changes (#35238)
The goal of this change is to clarify definition of major feature submissions to include writing new topics for the docs.

PR Close #35238
2020-06-15 09:05:16 -07:00
62e4acc3d1 docs: fix typo in control_value_accessor.ts (#37057)
This commit updates the `ControlValueAccessor` class description in the `@angular/forms` package to fix a typo.

PR Close #37057
2020-06-12 15:11:11 -07:00
1091ddbb8e build(bazel): check for renderer flag in ng_module() (#37529)
This checks for a Bazel flag in `ng_module()` in the `_renderer` attribute
which specifies the renderer to use for the build.

The main advantage of this flag is that it can be overridden with [Bazel
transitions](https://docs.bazel.build/versions/master/skylark/config.html),
giving much more flexibility for migrating individual applications in a
Bazel workspace to Ivy.

This flag is not intended to replace `--config ivy` or
`--define angular_ivy_enabled=True` (although it technically could). As a
result, this flag is not and will not actually be used anywhere in the
`angular/angular` repo. Instead, a `string_flag()` is provided  internally
which sets the renderer via a transition. See http://cl/315749946.

Note that this does **not** introduce a dependency on Skylib for
`angular/angular`. The dependency isn't actually necessary because
`BuildSettingInfo` is not used externally anyways. By doing this, it is not
necessary for downstream, external workspaces to depend on Skylib.

PR Close #37529
2020-06-12 15:10:39 -07:00
b45acb8d32 feat(dev-infra): add # to outputed list of PRs for discover-new-conflicts (#37556)
Adding in a `#` prepended to each PR number in the list of conflicting PRs
found by the discover-new-conflicts script will allow for users to copy
paste the output from the script into a github comment and have the PRs
automatically link.

PR Close #37556
2020-06-12 15:08:53 -07:00
104abe04ba ci: upload build results to ResultStore for CI linux bazel executions (#37560)
Bazel invocations will upload to ResultStore to allow for us to have better viewing
of execution/build logs.  This is only done on CI as the BES API requires credentials
from service accounts, rather than end user accounts.

PR Close #37560
2020-06-12 15:08:03 -07:00
1bc807c81a style(common): enforce format on newly included files (#36940)
Historically files to be formatted were added to a listing (via matchers)
to be included in formatting.  Instead, this change begins efforts to
instead include all files in format enforcement, relying instead on an
opt out methodology.

PR Close #36940
2020-06-12 15:06:41 -07:00
d3b5e5696f style(dev-infra): enforce format on newly included files (#36940)
Historically files to be formatted were added to a listing (via matchers)
to be included in formatting.  Instead, this change begins efforts to
instead include all files in format enforcement, relying instead on an
opt out methodology.

PR Close #36940
2020-06-12 15:06:41 -07:00
34e4098e85 build: increase scope of files with enforced formatting (#36940)
Historically files to be formatted were added to a listing (via matchers)
to be included in formatting.  Instead, this change begins efforts to
instead include all files in format enforcement, relying instead on an
opt out methodology.

PR Close #36940
2020-06-12 15:06:41 -07:00
8dcf618411 docs: add redirects for cli generated config files (#37533)
With this change we add redirects for config files generated by the Angular CLI. These links form part of a comment in the generated files, thus it is important that they valid for the many years to come.

PR Close #37533
2020-06-12 08:51:24 -07:00
7cc7955b5d docs: fix contributor website links with no protocol (#37528)
Two contributor website links do not have a protocol so they are treated as a relative URL and do not work as expected.

PR Close #37528
2020-06-12 08:50:52 -07:00
a075260751 docs: document how external link icons work (#37025)
After PR #36601 which added icons to all external links. Documented how this is happening via comments in scss file. For details visit PR #36601

PR Close #37025
2020-06-12 08:50:18 -07:00
aba33de5f5 build: fix outdated payload size (#37551)
Updates the payload size for one of the bundles that is currently causing one of the CI tasks to fail on master.

PR Close #37551
2020-06-12 08:49:45 -07:00
fe0782afa9 docs: small change in the Introduction (#35528)
The word "both" is automatically connected with the previous two bullet points and not the following two (because documents are usually read from top to bottom), which made the original sentence confusing for first time readers.

PR Close #35528
2020-06-11 19:11:56 -07:00
3545520e81 docs: fix result of sanitization example (#36059)
This commit fixes sanitization example
in https://angular.io/guide/template-syntax#content-security.

* Escape < and > of interpolation result.
* Fix result of property binding result.

PR Close #36059
2020-06-11 19:11:23 -07:00
5ea9119322 docs: make correction in Tutorial toh-pt6 (#37516)
Fixes issue [29535](https://github.com/angular/angular/issues/29535) for the tutorial (toh-pt6) to remove the phrase that directed the reader to delete mock-heroes.ts when it is still needed for further tutorial steps.

PR Close #37516
2020-06-11 19:10:48 -07:00
2e355fd4d3 fix(compiler): unable to resolve destructuring variable declarations (#37497)
Currently the partial evaluator isn't able to resolve a variable declaration that uses destructuring in the form of `const {value} = {value: 0}; const foo = value;`. These changes add some logic to allow for us to resolve the variable's value.

Fixes #36917.

PR Close #37497
2020-06-11 19:10:04 -07:00
12f2101d08 docs: add link to Angular component/material changelog. (#37491)
At present, users don't have an easy way to discover what
deprecations occurred for Angular CDK or Angular Material.
This change adds a link to the changelog to the deprecations.md
file.

PR Close #37491
2020-06-11 19:04:12 -07:00
d3a817549b fix(router): fix navigation ignoring logic to compare to the browser url (#37408)
This PR changes the logic for determining when to skip route processing from
using the URL of the last attempted navigation to the actual resulting URL after
that transition.

Because guards may prevent navigation and reset the browser URL, the raw
URL of the previous transition may not match the actual URL of the
browser at the end of the navigation process. For that reason, we need to use
`urlAfterRedirects` instead.

Other notes:
These checks in scheduleNavigation were added in eb2ceff4ba
The test still passes and, more surprisingly, passes if the checks are removed
completely. There have likely been changes to the navigation handling that
handle the test in a different way. That said, it still appears to be important
to keep the checks there in some capacity because it does affect how many
navigation events occur. This addresses an issue that came up in #16710: https://github.com/angular/angular/issues/16710#issuecomment-634869739
This also partially addresses #13586 in fixing history for imperative
navigations that are cancelled by guards.

PR Close #37408
2020-06-11 19:03:40 -07:00
c5493c192c docs: differential loading is opt-in (#37327)
With version 10, differential loading changes from `opt-out` to `opt
in`. This change updates the documentation accordingly.

PR Close #37327
2020-06-11 19:02:58 -07:00
d17084bf97 docs: add tslib change to v10 CHANGELOG (#37303)
Previously the tslib 2.0 change was not listed in the CHANGELOG because
it was marked as a refactoring. This change is important enough to be
listed in the changelog even tough it doesn't affect most of the users.

For users that do get unexpectedly affected by this change, it might be
useful to find the change listed in the CHANGELOG.

PR Close #37303
2020-06-11 19:01:25 -07:00
f150a304e8 refactor(compiler): remove extra imports (#37246)
There are some extra imports in the compiler package. These imports are not used anywhere in the file. So, removed those extra imports

PR Close #37246
2020-06-11 19:00:33 -07:00
886e3ebcca docs: update api ref doc for platform browser (#37186)
Edit descriptions, usage examples, and add links to be complete and consistent with API reference doc style

PR Close #37186
2020-06-11 18:59:12 -07:00
bf682d73d4 fix(ngcc): correctly get config for packages in nested node_modules/ (#37040)
Previously, ngcc would only be able to match an ngcc configuration to
packages that were located inside the project's top-level
`node_modules/`. However, if there are multiple versions of a package in
a project (e.g. as a transitive dependency of other packages), multiple
copies of a package (at different versions) may exist in nested
`node_modules/` directories. For example, one at
`<project-root>/node_modules/some-package/` and one at
`<project-root>/node_modules/other-package/node_modules/some-package/`.
In such cases, ngcc was only able to detect the config for the first
copy but not for the second.

This commit fixes this by returning a new instance of
`ProcessedNgccPackageConfig` for each different package path (even if
they refer to the same package name). In these
`ProcessedNgccPackageConfig`, the `entryPoints` paths have been
processed to take the package path into account.

PR Close #37040
2020-06-11 18:58:36 -07:00
8f3695e20e refactor(ngcc): add packageName property to EntryPoint interface (#37040)
This commit adds a `packageName` property to the `EntryPoint` interface.
In a subsequent commit this will be used to retrieve the correct ngcc
configuration for each package, regardless of its path.

PR Close #37040
2020-06-11 18:58:36 -07:00
829ddf95e5 fix(ngcc): correctly retrieve a package's version from its package.json (#37040)
In order to retrieve the ngcc configuration (if any) for an entry-point,
ngcc has to detect the containing package's version.

Previously, ngcc would try to read the version from the entry-point's
`package.json` file, which was different than the package's top-level
`package.json` for secondary entry-points. For example, it would try to
read it from `node_modules/@angular/common/http/package.json` for
entry-point `@angular/common/http`. However, the `package.json` files
for secondary entry-points are not guaranteed to include a `version`
property.

This commit fixes this by first trying to read the version from the
_package's_ `package.json` (falling back to the entry-point's
`package.json`). For example, it will first try to read it from
`@angular/common/package.json` for entry-point `@angular/common/http`.

PR Close #37040
2020-06-11 18:58:36 -07:00
fb10f62efc refactor(ngcc): refactor how info is retrieved from entry-point package.json (#37040)
This commit refactors the way info is retrieved from entry-point
`package.json` files to make it easier to extract more info (such as the
package's name) in the future. It also avoids reading and parsing the
`package.json` file multiple times (as was happening before).

PR Close #37040
2020-06-11 18:58:36 -07:00
8197557fcf refactor(ngcc): rename EntryPoint#package to EntryPoint#packagePath (#37040)
Rename the `package` property to `packagePath` on the `EntryPoint`
interface. This makes it more clear that the `packagePath` property
holds the absolute path to the containing package (similar to how `path`
holds the path to the entry-point). This will also align with the
`packageName` property that will be added in a subsequent commit.

This commit also re-orders the `EntryPoint` properties to group related
properties together and to match the order of properties on instances
with that on the interface.

PR Close #37040
2020-06-11 18:58:36 -07:00
e7a0e87c41 fix(ngcc): correctly get config for sub-entry-points when primary entry-point is ignored (#37040)
Previously, when an entry-point was ignored via an ngcc config, ngcc
would scan sub-directories for sub-entry-points, but would not use the
correct `packagePath`. For example, if `@angular/common` was ignored, it
would look at `@angular/common/http` but incorrectly use
`.../@angular/common/http` as the `packagePath` (instead of
`.../@angular/common`). As a result, it would not retrieve the correct
ngcc config for the actual package.

This commit fixes it by ensuring the correct `packagePath` is used, even
if the primary entry-point corresponding to that path is ignored. In
order to do this, a new return value for `getEntryPointInfo()` is added:
`IGNORED_ENTRY_POINT`. This is used to differentiate between directories
that correspond to no or an incompatible entry-point and those that
correspond to an entry-point that could otherwise be valid but is
explicitly ignored. Consumers of `getEntryPointInfo()` can then use this
info to discard ignored entry-points, but still use the correct
`packagePath` when scanning their sub-directories for secondary
entry-points.

PR Close #37040
2020-06-11 18:58:36 -07:00
ab9bc8a9ec refactor(ngcc): clean up unused imports, unused regex parenthesis, typos (#37040)
This is a follow-up to #37075, because I didn't manage to finish my
review before the PR got merged.

PR Close #37040
2020-06-11 18:58:36 -07:00
469d2b4640 refactor(ngcc): fix typos in comments (#37040)
This is a follow-up to #36944, because I didn't manage to finish my
review before the PR got merged.

PR Close #37040
2020-06-11 18:58:36 -07:00
31796e8e2f fix(zone.js): remove unused Promise overwritten setter logic (#36851)
In the early Zone.js versions (< 0.10.3), `ZoneAwarePromise` did not support `Symbol.species`,
so when user used a 3rd party `Promise` such as `es6-promise`, and try to load the promise library after import of `zone.js`, the loading promise library will overwrite the patched `Promise` from `zone.js` and will break `Promise` semantics with respect to `zone.js`.

Starting with `zone.js` 0.10.3, `Symbol.species` is supported therefore this will not longer be an issue. (https://github.com//pull/34533)

Before 0.10.3, the logic in zone.js tried to handle the case in the wrong way. It did so by overriding the descriptor of `global.Promise`, to allow the 3rd party libraries to override native `Promise` instead of `ZoneAwarePromise`. This is not the correct solution, and since the `Promise.species` is now supported, the 3rd party solution of overriding `global.Promise` is no longer needed.

PR removes the wrong work around logic. (This will improve the bundle size.)

PR Close #36851
2020-06-11 18:56:19 -07:00
284123c6ba fix(core): should fake a top event task when coalescing events to prevent draining microTaskQueue too early. (#36841)
Close #36839.

This is a known issue of zone.js,

```
(window as any)[(Zone as any).__symbol__('setTimeout')](() => {
  let log = '';
  button.addEventListener('click', () => {
    Zone.current.scheduleMicroTask('test', () => log += 'microtask;');
    log += 'click;';
  });
  button.click();
  expect(log).toEqual('click;microtask;');
  done();
});
```

Since in this case, we use native `setTimeout` which is not a ZoneTask,
so zone.js consider the button click handler as the top Task then drain the
microTaskQueue after the click at once, which is not correct(too early).

This case was an edge case and not reported by the users, until we have the
new option ngZoneEventCoalescing, since the event coalescing will happen
in native requestAnimationFrame, so it will not be a ZoneTask, and zone.js will
consider any Task happen in the change detection stage as the top task, and if
there are any microTasks(such as Promise.then) happen in the process, it may be
drained earlier than it should be, so to prevent this situation, we need to schedule
a fake event task and run the change detection check in this fake event task,
so the Task happen in the change detection stage will not be
considered as top ZoneTask.

PR Close #36841
2020-06-11 18:54:22 -07:00
7259208893 docs: Refactor-pipes (#36820)
Language tightened, and headings rewritten to focus on user tasks. Tasks now separated from concepts, and clarified as examples. Content is up-to-date and complete. Links to important information and relevant topics added.

PR Close #36820
2020-06-11 18:45:15 -07:00
7e5f6c2dc1 docs: release notes for the v10.0.0-rc.5 release 2020-06-11 16:08:38 -07:00
97dc85ba5e feat(core): support injection token as predicate in queries (#37506)
Currently Angular internally already handles `InjectionToken` as
predicates for queries. This commit exposes this as public API as
developers already relied on this functionality but currently use
workarounds to satisfy the type constraints (e.g. `as any`).

We intend to make this public as it's low-effort to support, and
it's a significant key part for the use of light-weight tokens as
described in the upcoming guide: https://github.com/angular/angular/pull/36144.

In concrete, applications might use injection tokens over classes
for both optional DI and queries, because otherwise such references
cause classes to be always retained. This was also an issue in View
Engine, but now with Ivy, this pattern became worse, as factories are
directly attached to retained classes (ultimately ending up in the
production bundle, while being unused).

More details in the light-weight token guide and in: https://github.com/angular/angular-cli/issues/16866.

Closes #21152. Related to #36144.

PR Close #37506
2020-06-11 13:21:11 -07:00
a937889c3b refactor(elements): add accessor workaround for build-optimizer (#37456)
Build-optimizer currently uses TypeScript 3.6 which is unable to resolve an 'accessor' in 'getTypeOfVariableOrParameterOrPropertyWorker'.

Unfortunately, in Build optimizer we cannot update the version of TypeScript because of https://github.com/microsoft/TypeScript/issues/38412

PR Close #37456
2020-06-11 12:05:34 -07:00
aa8f1d569b build: add @babel/preset-env to dependencies (#37456)
`@babel/preset-env` is needed by for NGCC tests: 3569fdf451/packages/compiler-cli/ngcc/test/BUILD.bazel (L84)

However this is not as a depedency in the angular repo.

PR Close #37456
2020-06-11 12:05:34 -07:00
5dba3bf1fd build: update CLI packages to the latest RC version for v10 (#37456)
With this change we update the Angular CLI repo and aio packages to the latest RC version for version 10.

PR Close #37456
2020-06-11 12:05:33 -07:00
6651b4171d build: update to typescript 3.9.5 (#37456)
This TypeScript version contains the revert for the classes wrapped in IIFE change that was introduced in version 3.9.

PR Close #37456
2020-06-11 12:05:33 -07:00
8c682c52b1 fix(ngcc): use annotateForClosureCompiler option (#36652)
Adds @nocollapse to static properties added by ngcc
iff annotateForClosureCompiler is true.

The Closure Compiler will collapse static properties
into the global namespace.  Adding this annotation keeps
the properties attached to their respective object, which
allows them to be referenced via a class's constructor.
The annotation is already added by ngtsc and ngc under the
same option, this commit extends the functionality to ngcc.

Closes #36618.

PR Close #36652
2020-06-11 11:12:56 -07:00
e5b09cc49a docs: add example links to 'DoCheck' lifeycle hook docs (#36574)
There were some examples for 'DoCheck' in the lifeCycle hooks guide. Added a link to the relevant section of the guide in the 'DoCheck()' api docs.

Fixes #35596

PR Close #36574
2020-06-11 11:09:58 -07:00
b199ef6bfc feat(zone.js): move all zone optional bundles to plugins folders (#36540)
Zone.js has a lot of optional bundles, such as `zone-patch-message-port`, those
bundles are monkey patch for specified APIs usually for soem experimental APIs or
some old APIs only available for specified platforms. Those bundles will not be
loaded by default.

In this commit, since we have several main `sub packages` such as `zone`, `zone-node`,
`zone-testing`, I put all the optional bundles under `plugins` folders for consistency.

PR Close #36540
2020-06-11 11:08:48 -07:00
583a9d38a1 feat(zone.js): upgrade zone.js to angular package format(APF) (#36540)
Close #35157

In the current version of zone.js, zone.js uses it's own package format, and it is not following the rule
of Angualr package format(APF), so it is not easily to be consumed by Angular CLI or other bundle tools.
For example, zone.js npm package has two bundles,

1. zone.js/dist/zone.js, this is a `es5` bundle.
2. zone.js/dist/zone-evergreen.js, this is a `es2015` bundle.

And Angular CLI has to add some hard-coding code to handle this case, o5376a8b139/packages/schematics/angular/application/files/src/polyfills.ts.template (L55-L58)

This PR upgrade zone.js npm package format to follow APF rule, https://docs.google.com/document/d/1CZC2rcpxffTDfRDs6p1cfbmKNLA6x5O-NtkJglDaBVs/edit#heading=h.k0mh3o8u5hx

The updated points are:

1. in package.json, update all bundle related properties

```
  "main": "./bundles/zone.umd.js",
  "module": "./fesm2015/zone.js",
  "es2015": "./fesm2015/zone.js",
  "fesm2015": "./fesm2015/zone.js",
```

2. re-organize dist folder, for example for `zone.js` bundle, now we have

```
  dist/
      bundles/
             zone.js            // this is the es5 bundle
      fesm2015/
             zone.js            // this is the es2015 bundle (in the old version is `zone-evergreen.js`)
```

3. have several sub-packages.

1. `zone-testing`, provide zone-testing bundles include zone.js and testing libraries
2. `zone-node`, provide zone.js implemention for NodeJS
3. `zone-mix`, provide zone.js patches for both Browser and NodeJS

All those sub-packages will have their own `package.json` and the bundle will reference `bundles(es5)` and `fesm2015(es2015)`.

4. keep backward compatibility, still keep the `zone.js/dist` folder, and all bundles will be redirected to `zone.js/bundles` or `zone.js/fesm2015` folders.

PR Close #36540
2020-06-11 11:08:48 -07:00
1fce6d6bae docs: Minor grammar fix: "bug-free" (#36515)
Change documentation to a more grammatically correct format. "bug-free" is preferred over "bug free".

PR Close #36515
2020-06-11 11:07:54 -07:00
39f973430a docs: remove out of date GDEs (#36467)
Periodic documentation cleanup of GDEs which are no longer in the Angular program.

Removed:
 - "Filip Bruun Bech-Larsen"
 - "Vinci Rufus"
 - "Jeff Cross"

PR Close #36467
2020-06-11 11:04:11 -07:00
20346ff192 build: remove ngcontainer Docker (#36421)
ngcontainer Dockerfile was noted as deprecated ~2 years ago, we no longer
rely on it anymore nor do we publish it.

PR Close #36421
2020-06-10 12:59:07 -07:00
bd9c1e6cfc build: add commit message scope for migration changes (#36390)
This is a proposal commit that adds a separate scope for
migration changes. The motiviation is that migrations aren't
necessarily always affecting `@angular/core`, but are just
stored in the core package for a canonical location when
someone runs `ng update`. Additionally, it rather seems confusing in the
changelog if migration changes are listed under `core`.

PR Close #36390
2020-06-10 12:03:45 -07:00
d76a872efb docs: add Mike Huang as a GDE (#36472)
Update the GDE listing with info abbout Mike Huang.
Update the GDE listing with info abbout Mike Huang.

PR Close #36472
2020-06-10 11:53:25 -07:00
a398d6af45 docs: remove redundant web-worker nav (#37289)
Web- worker was 2 times in the nav pointing towards the same file, just with different names removed one to remove redundancy

PR Close #37289
2020-06-10 11:52:06 -07:00
e836eaf448 fix(docs-infra): preconnect to analytics origins (#37400)
Lighthouse recommends preconnecting to important third-party origins.
See: https://web.dev/uses-rel-preconnect

PR Close #37400
2020-06-10 11:51:43 -07:00
ae364864f6 fix(ngcc): do not scan import expressions in d.ts files (#37503)
It is quite common for the TS compiler to have to add synthetic
types to function signatures, where the developer has not
explicitly provided them.  This results in `import(...)` expressions
appearing in typings files.  For example in `@ngrx/data` there is a
class with a getter that has an implicit type:

```ts
export declare class EntityCollectionServiceBase<...> {
  ...
  get store() {
    return this.dispatcher.store;
  }
  ...
}
```

In the d.ts file for this we get:

```ts
get store(): Store<import("@ngrx/data").EntityCache>;
```

Given that this file is within the `@ngrx/data` package already,
this caused ngcc to believe that there was a circular dependency,
causing it to fail to process the package - and in fact crash!

This commit resolves this problem by ignoring `import()` expressions
when scanning typings programs for dependencies. This ability was
only introduced very recently in a 10.0.0 RC release, and so it has
limited benefit given that up till now ngcc has been able to process
libraries effectively without it. Moreover, in the rare case that a
package does have such a dependency, it should get picked up
by the sync ngcc+CLI integration point.

PR Close #37503
2020-06-10 11:51:18 -07:00
cc552dd702 feat(language-service): Remove HTML entities autocompletion (#37515)
This commit removes the autocompletion feature for HTML entities.
HTML entites are things like `&amp;`, `&lt;` etc.

There are a few reasons for the decision:

1. It is outside the core functionality of Angular LS
2. The implementation relies on regex, which incurs performance cost
3. There isn't much value if users do not already know which entity
   they want to use
4. The list that we provide is not exhaustive

PR Close #37515
2020-06-10 11:50:54 -07:00
021dd33ed8 docs: release notes for the v10.0.0-rc.4 release 2020-06-10 11:45:00 -07:00
684726cdac docs: release notes for the v9.1.11 release
This commit contains the release notes from the 9.1.11 release. They were Copy-pasted from the CHANGELOG in the 9.1.x branch.
2020-06-10 11:26:59 -07:00
7b005bb9cf Revert "fix(elements): fire custom element output events during component initialization (#36161)" (#37524)
This reverts commit e9bff5fe9f. Failures
were detected in Google tests due to this commit

PR Close #37524
2020-06-10 17:28:57 +00:00
401ef71ae5 fix(compiler-cli): downlevel angular decorators to static properties (#37382)
In v7 of Angular we removed `tsickle` from the default `ngc` pipeline.
This had the negative potential of breaking ES2015 output and SSR due
to a limitation in TypeScript.

TypeScript by default preserves type information for decorated constructor
parameters when `emitDecoratorMetadata` is enabled. For example,
consider this snippet below:

```
@Directive()
export class MyDirective {
  constructor(button: MyButton) {}
}

export class MyButton {}
```

TypeScript would generate metadata for the `MyDirective` class it has
a decorator applied. This metadata would be needed in JIT mode, or
for libraries that provide `MyDirective` through NPM. The metadata would
look as followed:

```
let MyDirective = class MyDir {}

MyDirective = __decorate([
  Directive(),
  __metadata("design:paramtypes", [MyButton]),
], MyDirective);

let MyButton = class MyButton {}
```

Notice that TypeScript generated calls to `__decorate` and
`__metadata`. These calls are needed so that the Angular compiler
is able to determine whether `MyDirective` is actually an directive,
and what types are needed for dependency injection.

The limitation surfaces in this concrete example because `MyButton`
is declared after the `__metadata(..)` call, while `__metadata`
actually directly references `MyButton`. This is illegal though because
`MyButton` has not been declared at this point. This is due to the
so-called temporal dead zone in JavaScript. Errors like followed will
be reported at runtime when such file/code evaluates:

```
Uncaught ReferenceError: Cannot access 'MyButton' before initialization
```

As noted, this is a TypeScript limitation because ideally TypeScript
shouldn't evaluate `__metadata`/reference `MyButton` immediately.
Instead, it should defer the reference until `MyButton` is actually
declared. This limitation will not be fixed by the TypeScript team
though because it's a limitation as per current design and they will
only revisit this once the tc39 decorator proposal is finalized
(currently stage-2 at time of writing).

Given this wontfix on the TypeScript side, and our heavy reliance on
this metadata in libraries (and for JIT mode), we intend to fix this
from within the Angular compiler by downleveling decorators to static
properties that don't need to evaluate directly. For example:

```
MyDirective.ctorParameters = () => [MyButton];
```

With this snippet above, `MyButton` is not referenced directly. Only
lazily when the Angular runtime needs it. This mitigates the temporal
dead zone issue caused by a limitation in TypeScript's decorator
metadata output. See: https://github.com/microsoft/TypeScript/issues/27519.

In the past (as noted; before version 7), the Angular compiler by
default used tsickle that already performed this transformation. We
moved the transformation to the CLI for JIT and `ng-packager`, but now
we realize that we can move this all to a single place in the compiler
so that standalone ngc consumers can benefit too, and that we can
disable tsickle in our Bazel `ngc-wrapped` pipeline (that currently
still relies on tsickle to perform this decorator processing).

This transformation also has another positive side-effect of making
Angular application/library code more compatible with server-side
rendering. In principle, TypeScript would also preserve type information
for decorated class members (similar to how it did that for constructor
parameters) at runtime. This becomes an issue when your application
relies on native DOM globals for decorated class member types. e.g.

```
@Input() panelElement: HTMLElement;
```

Your application code would then reference `HTMLElement` directly
whenever the source file is loaded in NodeJS for SSR. `HTMLElement`
does not exist on the server though, so that will become an invalid
reference. One could work around this by providing global mocks for
these DOM symbols, but that doesn't match up with other places where
dependency injection is used for mocking DOM/browser specific symbols.

More context in this issue: #30586. The TL;DR here is that the Angular
compiler does not care about types for these class members, so it won't
ever reference `HTMLElement` at runtime.

Fixes #30106. Fixes #30586. Fixes #30141.
Resolves FW-2196. Resolves FW-2199.

PR Close #37382
2020-06-10 09:24:11 -07:00
0a1d078a74 Revert "build: remove wombot proxy registry from package.jsons for release (#37378)" (#37495)
This reverts commit 26849ca99d.

PR Close #37495
2020-06-10 08:21:45 -07:00
35502c739c docs: release notes for the v9.1.10 release
This commit contains the release notes from the 9.1.10 release. They were copy-pasted from the CHANGELOG in the 9.1.x branch.
2020-06-09 15:25:31 -07:00
b2ccc34f9c perf(core): avoid pulling in jit-specific code in aot bundles (#37372)
In #29083 a call to `getCompilerFacade` was added to `ApplicationRef` which pulls in a bit of JIT-specific code. Since the code path that calls the function can't be hit for an AOT-compiled app, these changes add an `ngJitMode` guard which will allow for dead code elimination to drop it completely. Testing it out against a new CLI project showed a difference of ~1.2kb.

PR Close #37372
2020-06-09 13:34:43 -07:00
eaa38a5adc docs(dev-infra): add comment about what the requiredBaseCommit is (#37509)
Add a comment to describe what the commit was for the given SHA so that we don't have to look it up.

PR Close #37509
2020-06-09 13:29:24 -07:00
cb1373106b docs: wrong links in lifecycle hooks api documentaion (#36557)
lifecycle hooks api detailed documentation contained links which were pointing to onChanges hook only which is removed, made each hook point towards its deafult page link

PR Close #36557
2020-06-09 11:16:43 -07:00
f6ee911cbb docs(core): fix path referenced in comments of both compiler facade interface files (#37370)
Previously the comments for these files referenced a path to "packages/core/src/render3/jit/compiler_facade_interface.ts" that does not exist in the current codebase.

This PR corrects the path in these comments.

PR Close #37370
2020-06-09 08:28:26 -07:00
a3313709ea fix(dev-infra): local changes check not working (#37489)
Looks like we broke the `hasLocalChanges` check in the git client
when we moved it over from the merge script. The problem is that
we are using `git` in the first argument of `git.run`. That
means that we under-the-hood run `git git <..>`.

This commit fixes that, but also switches to a better variant
for ensuring no local changes because it exits with non-zero
when there are local changes.

PR Close #37489
2020-06-09 08:27:32 -07:00
0eacba5829 fix(dev-infra): rebase pr script not working (#37489)
The dev-infra rebase PR script currently does not work due to
the following issues:

1. The push refspec is incorrect. It refers to the `base` of the PR, and
not to the `head` of the PR.
2. The push `--force-with-lease` option does not work in a detached head
as no remote-tracking branch is set up.

PR Close #37489
2020-06-09 08:27:32 -07:00
bb924b63e6 fix(dev-infra): incorrect token sanitization when no token is specified (#37489)
We recently moved over the git client from the merge script to the
common dev-infra utils. This made specifying a token optional, but
it looks like the logic for sanitizing messages doesn't account
for that, and we currently add `<TOKEN>` between every message
character. e.g.

```
Executing: git <TOKEN>g<TOKEN>i<TOKEN>t<TOKEN>
<TOKEN>s<TOKEN>t<TOKEN>a<TOKEN>t<TOKEN>u<TOKEN>s<TOKEN>
```

PR Close #37489
2020-06-09 08:27:31 -07:00
7301e70ddd fix(platform-server): correctly handle absolute relative URLs (#37341)
Previously, we would simply prepend any relative URL with the HREF
for the current route (pulled from document.location). However,
this does not correctly account for the leading slash URLs that
would otherwise be parsed correctly in the browser, or the
presence of a base HREF in the DOM.

Therefore, we use the built-in URL implementation for NodeJS,
which implements the WHATWG standard that's used in the browser.
We also pull the base HREF from the DOM, falling back on the full
HREF as the browser would, to form the correct request URL.

Fixes #37314

PR Close #37341
2020-06-09 08:27:00 -07:00
7edb026619 fix(common): prevent duplicate URL change notifications (#37459)
Prevent duplicate notifications from being emitted when multiple URL change listeners are registered using SpyLocation#onUrlChange.

Use `@internal` annotation for the `_urlChangeSubscription` properties instead of the `private` access modifier. Otherwise, we get in trouble because of  `SpyLocation implements Location`.

PR Close #37459
2020-06-09 08:26:34 -07:00
0b7845964b test(common): prefer TestBed.inject over inject (#37459)
Use the strongly typed TestBed.inject rather than the weakly typed inject test utility function. Reuse injected dependency variables between sibling test cases.

PR Close #37459
2020-06-09 08:26:34 -07:00
55979fe0ae feat(language-service): TS references from template items (#37437)
Keen and I were talking about what it would take to support getting
references at a position in the current language service, since it's
unclear when more investment in the Ivy LS will be available. Getting TS
references from a template is trivial -- we simply need to get the
definition of a symbol, which is already handled by the language
service, and ask the TS language service to give us the references for
that definition.

This doesn't handle references in templates, but that could be done in a
subsequent pass.

Part of https://github.com/angular/vscode-ng-language-service/issues/29

PR Close #37437
2020-06-08 17:23:49 -07:00
6280cf95b4 fix(language-service): Improve signature selection by finding exact match (#37494)
The function signature selection algorithm is totally naive. It'd
unconditionally pick the first signature if there are multiple
overloads. This commit improves the algorithm by returning an exact
match if one exists.

PR Close #37494
2020-06-08 17:23:12 -07:00
8d817daf78 fix(router): Fix relative link generation from empty path components (#37446)
Partial resubmit of #26243
Fixes incorrect url tree generation for empty path components with children.
Adds a test to demonstrate the failure of createUrlTree for those routes.
Fixes #13011
Fixes #35687

PR Close #37446
2020-06-08 17:15:37 -07:00
946f1179e9 docs: release notes for the v10.0.0-rc.3 release
This commit contains the release notes from the 10.0.0-rc.3 release. They were copy-pasted from the CHANGELOG in the 10.0.x branch.
2020-06-08 17:13:37 -07:00
87fdd23157 docs: add note on publishing libraries in ivy (#36556)
Libraries are still build using view engine even after Ivy being the default engine for building angular apps. Added note on why libraries are built using VE and how they will be automatically compiled in Ivy using ngcc making it compatible for both

Fixes #35625

PR Close #36556
2020-06-08 15:05:51 -07:00
713fb3b587 docs(docs-infra): fix small typo (#37258)
The style guide docs had a typo "Alerts and Calllouts". Callouts is
spelled with two l's, not three. This PR fixes the typo.

PR Close #37258
2020-06-08 14:42:49 -07:00
0cb0f66c17 docs: place download section in toh to the top (#36567)
this is part of a larger effort to standardise download sections on angular.io

This commit partially addresses #35459

PR Close #36567
2020-06-08 11:41:52 -07:00
db11a0ddbf docs(service-worker): add staleWhileRevalidate strategy (#37301)
There is great workaround for implementing staleWhileRevalidate strategy in service-worker by setting strategy to freshness and timeout to 0u. Documented this in service worker config where all other strategies are documented

Fixes #20402

PR Close #37301
2020-06-08 11:41:20 -07:00
779344012a refactor(core): assert TNode is not a container when setting attribute on element (#37111)
This PR provides a more helpful error than the one currently present:
`el.setAttribute is not a function`. It is not valid to have directives with host bindings
on `ng-template` or `ng-container` nodes. VE would silently ignore this, while Ivy
attempts to set the attribute and throws an error because these are comment nodes
and do not have `setAttribute` functionality.

It is better to throw a helpful error than to silently ignore this because
putting a directive with host binding on an `ng-template` or `ng-container` is most often a mistake.
Developers should be made aware that the host binding will have no effect in these cases.

Note that an error is already thrown in Ivy, as mentioned above, so this
is not a breaking change and can be merged to both master and patch.

Resolves #35994

PR Close #37111
2020-06-08 11:21:05 -07:00
650974e1b3 test(language-service): Remove all markers from test project (#37475)
This commit removes all markers from the inline template in
`AppComponent` and external template in `TemplateReference`.

Test scenarios should be colocated with the test cases themselves.
Besides, many existing cases are invalid. For example, if we want to
test autocomplete for HTML element, the existing test case is like:
```
<~{cursor} h1>
```
This doesn't make much sense, becasue the language service already sees
the `h1` tag in the template. The correct test case should be:
```
<~{cursor
```
IMO, this reflects the real-world use case better.

This commit also uncovers a bug in the way HTML entities autocompletion
is done. There's an off-by-one error in which a cursor that immediately
trails the ampersand character fails to trigger HTML entities
autocompletion.

PR Close #37475
2020-06-08 10:25:42 -07:00
ed3c549063 ci: remove IgorMinar from reviewers list for pullapprove fallback group (#36456)
Historically we have had a pullapprove group `fallback` which acted as
a catch all for files which did not match any other groups.  This
group assigned reviews to IgorMinar, however it was not apparent that
this group was assigned.  This change removes this assignment.  This
group as active should always coincide with failures of the pullapprove
verification script. We continue to have this group as a secondary test
ensuring all files in the repo are captured by the pullapprove config.

PR Close #36456
2020-06-08 10:07:45 -07:00
3a116179b1 build(docs-infra): upgrade cli command docs sources to b76099083 (#37471)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](89dbc2caa...b76099083):

**Modified**
- help/generate.json

PR Close #37471
2020-06-08 09:33:52 -07:00
5e64c2b1df style(ngcc): post-merge review tidy up (#37461)
This commit tidies up a few of the code comments from a recent commit to
help improve the clarity of the algorithm.

PR Close #37461
2020-06-08 09:32:11 -07:00
d63ecf4c5f fix(service-worker): Don't stay locked in EXISTING_CLIENTS_ONLY if corrupted data (#37453)
**Problem**

After #31109 and #31865, it's still possible to get locked in state
`EXISTING_CLIENTS_ONLY`, without any possibility to get out (even by
pushing new updates on the server).
More specifically, if control doc `/latest` of `ngsw:/:db:control` once
gets a bad value, then the service worker will fail early, and won't be
able to overwrite `/latest` with new, valid values (the ones from future
updates).

For example, once in this state, URL `/ngsw/state` will show:

    NGSW Debug Info:
    Driver state: EXISTING_CLIENTS_ONLY (Degraded due to failed initialization: Invariant violated (initialize): latest hash 8b75… has no known manifest
    Error: Invariant violated (initialize): latest hash 8b75… has no known manifest
        at Driver.<anonymous> (https://my.app/ngsw-worker.js:2302:27)
        at Generator.next (<anonymous>)
        at fulfilled (https://my.app/ngsw-worker.js:175:62))
    Latest manifest hash: 8b75…
    Last update check: 22s971u

... with hash `8b75…` corresponding to no installed version.

**Solution**

Currently, when such a case happens, the service worker [simply fails
with an assertion][1]. Because this failure happens early, and is not
handled, the service worker is not able to update `/latest` to new
installed app versions.

I propose to detect this corrupted case (a `latest` hash that doesn't
match any installed version) a few lines above, so that the service
worker can correctly call its [already existing cleaning code][2].

[1]: https://github.com/angular/angular/blob/3569fdf/packages/service-worker/worker/src/driver.ts#L559-L563
[2]: https://github.com/angular/angular/blob/3569fdf/packages/service-worker/worker/src/driver.ts#L505-L519

This change successfully fixes the problem described above.

Unit test written with the help of George Kalpakas. Thank you!

PR Close #37453
2020-06-08 09:31:34 -07:00
77efddcac3 fix(dev-infra): await setup in runBenchmark (#37428)
* Fix for issue #36986.
* Changes runBenchmark into an async function.
* Awaits config.setup in runBenchmark.

PR Close #37428
2020-06-08 09:17:34 -07:00
d887ba85ad build: update to latest stable Chromium 83.0.4103 in both rules_webtesting and puppeteer (#37427)
Also added in detailed instructions of the process to determine the URLs corresponding to Chromium version desired

PR Close #37427
2020-06-08 09:16:40 -07:00
0c75a06b1e build: upgrade to bazel 3.2.0 and rules_nodejs 1.7.0 (#37358)
Upgrade to rely on bazel version 3.2.0 and rules_nodejs 1.7.0.  This
is part of a routine update as new versions become available.

PR Close #37358
2020-06-08 09:15:50 -07:00
aaa20093b2 ci: special case tooling-cli-shared-api review group (#37467)
The new tooling-cli-shared-api is used to guard changes to packages/compiler-cli/src/tooling.ts
which is a private API sharing channel between Angular FW and CLI.

Changes to this file should be rare and explicitly approved by at least two members
of the CLI team.

PR Close #37467
2020-06-05 19:23:52 -07:00
5568d824dd ci: extend and update the reviewer groups (#37467)
Update the pullapprove config to require multiple reviews for sensitive groups in order
to force distribution of knowledge and improve the review quality.

PR Close #37467
2020-06-05 19:23:52 -07:00
17996bf719 fix(dev-infra): properly determine oauth scopes for git client token (#37462)
Resubmit of b2bd38699b since
85b6c94cc6 accidentally reverted
the fix due to rebasing most likely.

PR Close #37462
2020-06-05 11:04:36 -07:00
2a330a60ed fix(elements): fire custom element output events during component initialization (#36161)
Previously, event listeners for component output events attached on an
Angular custom element before inserting it into the DOM (i.e. before
instantiating the underlying component) didn't fire for events emitted
during initialization lifecycle hooks, such as `ngAfterContentInit`,
`ngAfterViewInit`, `ngOnChanges` (initial call) and `ngOnInit`.
The reason was that that `NgElementImpl` [subscribed to events][1]
_after_ calling [ngElementStrategy#connect()][2], which is where the
[initial change detection][3] takes place (running the initialization
lifecycle hooks).

This commit fixes this by:
1. Ensuring `ComponentNgElementStrategy#events` is defined and available
   for subscribing to, even before instantiating the component.
2. Ensuring `NgElementImpl` subscribes to `NgElementStrategy#events`
   before calling `NgElementStrategy#connect()` (which initializes the
   component instance).

Jira issue: [FW-2010](https://angular-team.atlassian.net/browse/FW-2010)

[1]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L167-L170)
[2]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L164)
[3]: c0143cb2ab/packages/elements/src/component-factory-strategy.ts (L158)

Fixes #36141

PR Close #36161
2020-06-05 10:36:39 -07:00
569d1ef583 refactor(elements): remove unnecessary non-null assertions and as any type-casts (#36161)
This commit removes some unnecessary non-null assertions (`!`) and
`as any` type-casts from the `elements` package.

PR Close #36161
2020-06-05 10:36:39 -07:00
85b6c94cc6 refactor(dev-infra): move GitClient to common util (#37318)
Moves GitClient from merge script into common utils for unified
method of performing git actions throughout the ng-dev toolset.

PR Close #37318
2020-06-05 09:46:40 -07:00
818d93d7e9 fix(ngcc): find decorated constructor params on IIFE wrapped classes (#37436)
Now in TS 3.9, classes in ES2015 can be wrapped in an IIFE.
This commit ensures that we still find the static properties that contain
decorator information, even if they are attached to the adjacent node
of the class, rather than the implementation or declaration.

Fixes #37330

PR Close #37436
2020-06-05 09:22:04 -07:00
d4c0962c7b refactor(dev-infra): use the exec() helper from utils/shelljs whenever possible (#37444)
There is an `exec()` helper provided by `utils/shelljs.ts`, which is a
wrapper around ShellJS' `exec()` with some default options (currently
`silent: true`). The intention is to avoid having to pass these options
to every invocation of the `exec()` function.

This commit updates all code inside `dev-infra/` to use this helper
whenever possible).

NOTE: For simplicity, the `utils/shelljs` helper does not support some
      of the less common call signatures of the original `exec()`
      helper, so in some cases we still need to use the original.

PR Close #37444
2020-06-05 09:21:18 -07:00
e31208beb1 docs: fix minor error in the "Structural directives" guide (#37452)
The sample code used in this guide uses [class.od]="odd".
But, in another portion of the guide, [ngClass]="odd" is mentioned instead.

PR Close #37452
2020-06-05 09:20:43 -07:00
3569fdf451 fix(common): prevent duplicate URL change notifications (#37404)
Prevent duplicate notifications from being emitted when multiple URL change listeners are registered using Location#onUrlChange.

PR Close #37404
2020-06-04 16:45:06 -07:00
eb6ba9ac80 docs: fix various typos (#37443)
This change just fixes various typos and misspellings across several docs.

I've included also a fix for an issue surfaced via #37423.

Closes #37423

PR Close #37443
2020-06-04 16:03:54 -07:00
4e7a4543b8 style(dev-infra): correct tslint failures in dev-infra directory (#37233)
Fixes tslint failures in dev-infra directory as the directory is now
part of the tslint enforced files.

PR Close #37233
2020-06-04 12:44:46 -07:00
753fed285c build: add dev-infra to tslint selected files (#37233)
Adds the dev-infra files to the scope of files on which tslint is
enforced.  This will allow for better code management/conformance.

PR Close #37233
2020-06-04 12:44:46 -07:00
dffcca73e4 fix(dev-infra): clean up usages within pullapprove tooling (#37338)
Clean up pullapprove tooling to use newly created common utils.
Additionally, use newly created logging levels rather than
verbose flagging.

PR Close #37338
2020-06-04 12:43:44 -07:00
c8f7fc22c7 refactor(dev-infra): change required base commit sha (#37424)
Update the commit sha to require that PRs have been rebased beyond the one which has new header requirements so we don't get failures after merging

PR Close #37424
2020-06-04 10:44:14 -07:00
b2bd38699b fix(dev-infra): properly determine oauth scopes for git client token (#37439)
We recently added a better reporting mechanism for oauth tokens
in the dev-infra git util. Unfortunately the logic broke as part
of addressing PR review feedback. Right now, always the empty
promise from `oauthScopes` will be used as `getAuthScopes` considers
it as the already-requested API value. This is not the case as
the default promise is also truthy. We should just fix this by making
the property nullable.

PR Close #37439
2020-06-04 10:42:53 -07:00
c025357fb8 feat(dev-infra): Add oauth scope check to ensure necessary permissions for merge tooling (#37421)
Adds an assertion that the provided TOKEN has OAuth scope permissions for `repo`
as this is required for all merge attempts.

On failure, provides detailed error message with remediation steps for the user.

PR Close #37421
2020-06-04 09:35:59 -07:00
57411c85b9 feat(ngcc): implement a program-based entry-point finder (#37075)
This finder is designed to only process entry-points that are reachable
by the program defined by a tsconfig.json file.

It is triggered by calling `mainNgcc()` with the `findEntryPointsFromTsConfigProgram`
option set to true. It is ignored if a `targetEntryPointPath` has been
provided as well.

It is triggered from the command line by adding the `--use-program-dependencies`
option, which is also ignored if the `--target` option has been provided.

Using this option can speed up processing in cases where there is a large
number of dependencies installed but only a small proportion of the
entry-points are actually imported into the application.

PR Close #37075
2020-06-04 09:22:39 -07:00
07a8016118 fix(ngcc): capture dynamic import expressions as well as declarations (#37075)
Previously we only checked for static import declaration statements.
This commit also finds import paths from dynamic import expressions.

Also this commit should speed up processing: Previously we were parsing
the source code contents into a `ts.SourceFile` and then walking the parsed
AST to find import paths.
Generating an AST is unnecessary work and it is faster and creates less
memory pressure to just scan the source code contents with the TypeScript
scanner, identifying import paths from the tokens.

PR Close #37075
2020-06-04 09:22:39 -07:00
4d69da57ca refactor(ngcc): move shared code into DependencyHostBase (#37075)
The various dependency hosts had a lot of duplicated code.
This commit refactors them to move this into the base class.

PR Close #37075
2020-06-04 09:22:39 -07:00
7f98b87ca0 fix(ngcc): ensure that more dependencies are found by EsmDependencyHost (#37075)
Previously this host was skipping files if they had imports that spanned
multiple lines, or if the import was a dynamic import expression.

PR Close #37075
2020-06-04 09:22:39 -07:00
c61decf7e5 docs: add blank line before header (#37391)
Currently, `Formatting your source code` is not being formatted as a header because of a missing empty line.
PR Close #37391
2020-06-04 09:20:26 -07:00
6e7bd939f6 perf(ngcc): cache parsed tsconfig between runs (#37417)
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Resolves #36882

PR Close #37417
2020-06-04 09:19:38 -07:00
2021ad12cf ci(docs-infra): skip deploying RC version when lexicographically smaller than stable (#37426)
The angular.io production deployment script (`deploy-to-firebase.sh`)
compares the major version corresponding to the current branch (e.g.
`8` for branch `8.1.x`) against the major stable version (e.g. `9` if
the current stable version is `9.1.0`). It then uses the result of that
comparison to determine whether the current branch corresponds to a
newer version than stable (i.e. an RC version) and thus should not be
deployed or to an older version and thus may need to be deployed to an
archive vX.angular.io project.

Previously, the script was using string comparison (`<`) to compare the
two major versions. This could produce incorrect results for an RC major
version that is numerically greater than the stable but
lexicographically smaller. For example, 10 vs 9 (10 is numerically
greater but lexicographically smaller than 9).
Example of a CI job that incorrectly tried to deploy an RC branch to
production: https://circleci.com/gh/angular/angular/726414

This commit fixes it by switching to an integer comparison (i.e. using
the `-lt` operator).

PR Close #37426
2020-06-04 09:17:29 -07:00
c4f4675ebf fix(language-service): Recover from error in analyzing Ng Modules (#37108)
In place of failing to return analyzed Ng Modules when the analyzer
fails, return the previously-analyzed Ng Modules (which may be empty)
and log an error.

Closes https://github.com/angular/vscode-ng-language-service/issues/777

PR Close #37108
2020-06-03 15:56:19 -07:00
34827559b9 docs: update the stackblitz in the GitHub Issue template (#37219)
This commit updates the bug report stackblitz template for opening a new
issue based on the current angular release.

Closes #37063

PR Close #37219
2020-06-03 15:55:44 -07:00
65c3888d01 docs: update file header to be correct (#37425)
The file header should be Google LLC rather than Google Inc. because it is now an LLC after Alphabet Holdings was formed.

PR Close #37425
2020-06-03 15:31:29 -07:00
e648a0c4ca refactor(compiler-cli): extract NgCompilerAdapter interface (#37118)
`NgCompiler` is the heart of ngtsc and can be used to analyze and compile
Angular programs in a variety of environments. Most of these integrations
rely on `NgProgram` and the creation of an `NgCompilerHost` in order to
create a `ts.Program` with the right shape for `NgCompiler`.

However, certain environments (such as the Angular Language Service) have
their own mechanisms for creating `ts.Program`s that don't make use of a
`ts.CompilerHost`. In such environments, an `NgCompilerHost` does not make
sense.

This commit breaks the dependency of `NgCompiler` on `NgCompilerHost` and
extracts the specific interface of the host on which `NgCompiler` depends
into a new interface, `NgCompilerAdapter`. This interface includes methods
from `ts.CompilerHost`, the `ExtendedTsCompilerHost`, as well as APIs from
`NgCompilerHost`.

A consumer such as the language service can implement this API without
needing to jump through hoops to create an `NgCompilerHost` implementation
that somehow wraps its specific environment.

PR Close #37118
2020-06-03 13:29:44 -07:00
965a688c97 fix(compiler-cli): use ModuleWithProviders type if static eval fails (#37126)
When the compiler encounters a function call within an NgModule imports
section, it attempts to resolve it to an NgModule-annotated class by
looking at the function body and evaluating the statements there. This
evaluation can only understand simple functions which have a single
return statement as their body. If the function the user writes is more
complex than that, the compiler won't be able to understand it and
previously the PartialEvaluator would return a "DynamicValue" for
that import.

With this change, in the event the function body resolution fails the
PartialEvaluator will now attempt to use its foreign function resolvers to
determine the correct result from the function's type signtaure instead. If
the function is annotated with a correct ModuleWithProviders type, the
compiler will be able to understand the import without static analysis of
the function body.

PR Close #37126
2020-06-03 13:23:16 -07:00
ab3f4c9fe1 fix(core): infinite loop if injectable using inheritance has a custom decorator (#37022)
If we detect that an injectable class is inheriting from another injectable, we generate code that looks something like this:

```
const baseFactory = ɵɵgetInheritedFactory(Child);

@Injectable()
class Parent {}

@Injectable()
class Child extends Parent {
  static ɵfac = (t) => baseFactory(t || Child)
}
```

This usually works fine, because the `ɵɵgetInheritedFactory` resolves to the factory of `Parent`, but the logic can break down if the `Child` class has a custom decorator. Custom decorators can return a new class that extends the original once, which means that the `ɵɵgetInheritedFactory` call will now resolve to the factory of the `Child`, causing an infinite loop.

These changes fix the issue by changing the inherited factory resolution logic so that it walks up the prototype chain class-by-class, while skipping classes that have the same factory as the class that was passed in.

Fixes #35733.

PR Close #37022
2020-06-03 13:16:25 -07:00
40f3bb5638 refactor(dev-infra): small changes and fixes (#36800)
Rename bazel workspace from npm_dev_infra to npm_angular_dev_infra_private to make it clear that this package is private to angular.
Change driver-utilities module_name to match the new bazel workspace name.
Correct a comment by rewording it from "deployed version" to "published version".
Fix merge conflicts in tmpl-package.json
Make "//packages/bazel/src:esm5.bzl" replacement more generalized so that importing from "//packages/bazel" works.
Deleted "dev_infra/*" path from modules/benchmarks tsconfig.
Moved //dev-infra/benchmark/browsers to //dev-infra/browsers.

PR Close #36800
2020-06-03 13:12:30 -07:00
a08d18a1fe revert: "revert: "build(core): use dev-infra's component_benchmark to show PoC (#36434)" (#36798)" (#36800)
This reverts commit 90a2796a7e.

PR Close #36800
2020-06-03 13:12:30 -07:00
64d6f35f94 revert: "revert: "build(dev-infra): update package.json and :npm_package (#36434)" (#36798)" (#36800)
This reverts commit f5ff2068a4.

PR Close #36800
2020-06-03 13:12:30 -07:00
caa4ab3235 revert: "revert: "feat(dev-infra): exposed new rule 'component_benchmark' via dev_infra (#36434)" (#36798)" (#36800)
This reverts commit ad8c4cdd75.

PR Close #36800
2020-06-03 13:12:30 -07:00
06a8ad28a7 refactor(forms): use a type guard to get rid of casts (#32541)
Use an explicit type guard when checking if a given object is of type AbstractControlOptions,
instead of a simple function returning a boolean value. This allows us to remove manual type
casting when using this function, relying instead on TypeScript to infer correct types.

PR Close #32541
2020-06-03 12:29:26 -07:00
382aa50c54 docs: refactor template-driven forms doc as a tutorial (#36732)
rework content to meet current documentation standards and conventions, structure as tutorial document type

PR Close #36732
2020-06-03 12:27:28 -07:00
044a19966d ci: temporarily disable Android 10 browser unit tests on Saucelabs (#37399)
Disabling Android 10 browser unit tests on Saucelabs due to errors.

After remediation from Saucelabs to correct the discovered failures, this change can be reverted to renable the tests on Android 10.

Example of failures seen:

```
02 06 2020 14:03:05.048:INFO [SaucelabsLauncher]: Chrome 10.0 (Android) session at https://saucelabs.com/tests/54f5fb181db644a3b4779187c2309000

02 06 2020 14:03:06.869:INFO [Chrome Mobile 74.0.3729 (Android 0.0.0)]: Disconnected browser returned on socket E-bi0p0NKtghk-HcAAAO with id 85563367.

Chrome Mobile 74.0.3729 (Android 0.0.0) ERROR: Error: XHR error loading http://angular-ci.local:9876/base/node_modules/rxjs/internal/operators/zip.js

	Error loading http://angular-ci.local:9876/base/node_modules/rxjs/internal/operators/zip.js as "../internal/operators/zip" from http://angular-ci.local:9876/base/node_modules/rxjs/operators/index.js

Error: XHR error loading http://angular-ci.local:9876/base/node_modules/rxjs/internal/operators/zip.js

    at error (http://angular-ci.local:9876/base/node_modules/systemjs/dist/system.src.js?1c6a6c12fec50a8db7aeebe8e06e2b70135c0615:1028:16)

    at XMLHttpRequest.xhr.onreadystatechange [as __zone_symbol__ON_PROPERTYreadystatechange] (http://angular-ci.local:9876/base/node_modules/systemjs/dist/system.src.js?1c6a6c12fec50a8db7aeebe8e06e2b70135c0615:1036:13)

    at XMLHttpRequest.wrapFn (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:809:43)

    at ZoneDelegate.invokeTask (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:432:35)

    at Zone.runTask (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:201:55)

    at ZoneTask.invokeTask [as invoke] (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:514:38)

    at invokeTask (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:1722:18)

    at XMLHttpRequest.globalZoneAwareCallback (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:1748:21)
```

PR Close #37399
2020-06-02 17:32:34 -04:00
17e98198f4 docs(core): remove v10 mention from @Injectable warning (#37383)
In v9, we started showing a console warning when
instantiating a token that inherited its @Injectable
decorator rather than providing its own. This warning
said that the pattern would become an error in v10.

However, we have decided to wait until at least v11
to throw in this case, so this commit updates the
warning to be less prescriptive about the exact
version when the pattern will no longer be supported.

PR Close #37383
2020-06-02 17:30:58 -04:00
561c0f81a0 perf(ngcc): allow immediately reporting a stale lock file (#37250)
Currently, if an ngcc process is killed in a manner that it doesn't clean
up its lock file (or is killed too quickly) the compiler reports that it
is waiting on the PID of a process that doesn't exist, and that it will
wait up to a maximum of N seconds. This PR updates the locking code to
additionally check if the process exists, and if it does not it will
immediately bail out, and print the location of the lock file so a user
may clean it up.

PR Close #37250
2020-06-02 17:30:03 -04:00
4414be77c4 docs: refactor forms overview (#36919)
Reorganize and edit content of existing form overview to conform to current doc standards and styles

PR Close #36919
2020-06-02 17:29:15 -04:00
1b55da10b1 build: fix integration payload sizes 2020-06-02 10:51:06 -07:00
78ea2527a1 docs(router): fix a typo in example code (#37309)
The code in the example docs used TestBed.configureTestModule instead of TestBed.configureTestingModule.

PR Close #37309
2020-06-01 17:19:45 -04:00
4456e7e4de refactor(core): remove looseIdentical in favor of built-in Object.is (#37191)
Remove `looseIdentical` implementation and instead use the ES2015 `Object.is` in its place.
They behave exactly the same way except for `+0`/`-0`.
`looseIdentical(+0, -0)` => `true`
`Object.is(+0, -0)` => `false`

Other than the difference noted above, this is not be a breaking change because:
1. `looseIdentical` is a private API
2. ES2015 is listed as a mandatory polyfill in the [browser support
guide](https://angular.io/guide/browser-support#mandatory-polyfills)
3. Also note that `Ivy` already uses `Object.is` in `bindingUpdated`.

PR Close #37191
2020-06-01 17:19:17 -04:00
92c436dd1a test(language-service): disable ivy ls tests on CI (#37348)
This commit disables the tests for Ivy version of language service on CI
because the compiler APIs are not yet stable, so language service should
not assert against its behavipr.

PR Close #37348
2020-06-01 17:18:51 -04:00
b45f336635 fix(ngcc): do not inline source-maps for non-inline typings source-maps (#37363)
Inline source-maps in typings files can impact IDE performance
so ngcc should only add such maps if the original typings file
contains inline source-maps.

Fixes #37324

PR Close #37363
2020-06-01 17:18:31 -04:00
c3651cec0b docs(core): fix typo in decorators.ts relating to the use of Object.defineProperty. (#37369)
Previously there was a typo in a comment within the PropDecorator function relating to and justifying the use of Object.defineProperty. This PR clears up the wording that comment

PR Close #37369
2020-06-01 17:18:08 -04:00
3b52f7066b docs: fix typo in deprecations (#37379)
This PR fixes a typo in the deprecations guide, changing 'dropped support for of Windows 10...' to 'dropped support for Windows 10...'

PR Close #37379
2020-06-01 17:17:44 -04:00
8bb741198b docs: release notes for the v10.0.0-rc.2 release 2020-06-01 11:14:39 -07:00
26849ca99d build: remove wombot proxy registry from package.jsons for release (#37378)
Due to an outage with the proxy we rely on for publishing, we need
to temporarily directly publish to NPM using our own angular
credentials again.

PR Close #37378
2020-06-01 12:41:19 -04:00
4d0e175a65 fix(core): reenable decorator downleveling for Angular npm packages (#37317)
In #37221 we disabled tsickle passes from transforming the tsc output that is used to publish all
Angular framework and components packages (@angular/*).

This change however revealed a bug in the ngc that caused __decorate and __metadata calls to still
be emitted in the JS code even though we don't depend on them.

Additionally it was these calls that caused code in @angular/material packages to fail at runtime
due to circular dependency in the emitted decorator code documeted as
https://github.com/microsoft/TypeScript/issues/27519.

This change partially rolls back #37221 by reenabling the decorator to static fields (static
properties) downleveling.

This is just a temporary workaround while we are also fixing root cause in `ngc` - tracked as
FW-2199.

Resolves FW-2198.
Related to FW-2196

PR Close #37317
2020-05-29 18:52:01 -04:00
bd7393fc68 docs: Mention Bazel builder and schematics in Deprecations section (#37190)
This commit adds Bazel builder and schematics to the global list of
deprecations in Angular. A link to the migration doc is added.

PR Close #37190
2020-05-28 21:35:40 -04:00
08ff8aa055 docs(bazel): Mention Architect prototype and Slack Channel (#37190)
This commit adds a link to the Bazel prototype for orchestrating
multiple CLI architects and also adds a link to the #angular channel in
the Bazel Slack workspace.

PR Close #37190
2020-05-28 21:35:40 -04:00
f60d159d71 docs: Cleanup Bazel schematics deprecation doc (#37190)
This commit improves some wording in the deprecation doc for Bazel
builder and schematics in `@angular/bazel` and fixes the formatting.

PR Close #37190
2020-05-28 21:35:40 -04:00
6aa5bfa21a refactor(bazel): Remove schematics and builder from package.json (#37190)
This commit removes the fields for ng-add, schematics and builder from
package.json of `@angular/bazel`.

PR Close #37190
2020-05-28 21:35:40 -04:00
227ba625e6 docs: Add guide/bazel to Service Worker navigationUrls (#37190)
This commit adds an exception for "guide/bazel" to the navigationUrls in
the Service Worker config. This is needed for redirection to work.

PR Close #37190
2020-05-28 21:35:40 -04:00
e64176019a docs: Redirect /guide/bazel to deprecation doc in Angular repo (#37190)
This commit adds a 301 redirect for /guide/bazel on angular.io to the
deprecation doc for Angular Bazel schematics in Angular repo.

PR Close #37190
2020-05-28 21:35:40 -04:00
1fc7891add test: remove Bazel schematics integration test (#37190)
This commit removes the integration test for schematics in
`@angular/bazel` that is used to generate a Bazel builder. The Bazel
builder has been deprecated.

PR Close #37190
2020-05-28 21:35:40 -04:00
e7930fcc15 ci: Remove aio/content/guide/bazel.md from pullapprove (#37190)
This commit removes aio/content/guide/bazel.md from the Bazel list in
pullapprove since Bazel builder has been deprecated and the doc has been
deleted.

PR Close #37190
2020-05-28 21:35:40 -04:00
4b40740324 docs: Remove 'Building with Bazel' section (#37190)
This commit removes "Building with Bazel" section from angular.io
navigation list and Angular CLI landing page.

PR Close #37190
2020-05-28 21:35:40 -04:00
a36667d984 refactor(bazel): Remove Schematics for Bazel Builder (#37190)
This commit removes `ng-add` and `ng-new` schematics for the Bazel
Builder, and update the corresponding BUILD files.

PR Close #37190
2020-05-28 21:35:40 -04:00
9791c9ecaf docs: Remove Bazel builder from @angular/bazel (#37190)
This commit adds a deprecation doc for Bazel builder in
`@angular/bazel` and removes the corresponding guide in angular.io.

PR Close #37190
2020-05-28 21:35:39 -04:00
df082307b9 docs: fix typo in committer.md (#37171)
Fix a type of COMMITTER.md, the url of the pullapprove service should be https://docs.pullapprove.com/,
now the document has an additional `https` prefix.

PR Close #37171
2020-05-28 18:43:05 -04:00
98d820030c docs(platform-server): fix renderModule usage guidance with Ivy (#37296)
Before the introduction of the Ivy renderer, users would compile
their applications and use the resulting factories for SSR, since
these post-compilation artifacts ensured faster delivery. Thus,
using the original module as the rendering entrypoint was
considered suboptimal and was discouraged.

However, with the introduction of Ivy, this guidance is no longer
applicable since these factories are no longer generated.
Comparable speed is achieved using the factory-less module
renderer, and so we update the guiance in the docs for the method.

PR Close #37296
2020-05-28 16:07:32 -04:00
f001aef2dc build: update requiredBaseCommit for patch branch merges (#37316)
Updates the requiredBaseCommit for merging to patch branch to the
latest commit message validation fix found in the 10.0.x branch.

Previously, the patch branch commit used was for the 9.1.x branch.

PR Close #37316
2020-05-28 16:06:08 -04:00
64fc8b8ee5 docs: add IE mobile to deprecated browsers (#37313)
Mobile versions of IE should also be deprecated, as the same reasons for deprecating IE 9 and 10 apply.

PR Close #37313
2020-05-27 17:23:18 -04:00
a62c1c441c build: migrate ng-dev config to .ng-dev directory (#37142)
Migrate to using .ng-dev directory for ng-dev configuration to allow
better management of the configuration using multiple files.  The
intention is to prevent the config file from becoming unruly.

PR Close #37142
2020-05-26 16:38:22 -04:00
3d154ab795 fix(dev-infra): migrate dev-infra config loading to .ng-dev directory (#37142)
Migrate to using .ng-dev directory for ng-dev configuration to better
allow management of the configuration using multiple files.  The
intention is to prevent the config file from becoming unruly.

PR Close #37142
2020-05-26 16:38:22 -04:00
d1ea1f4c7f build: update license headers to reference Google LLC (#37205)
Update the license headers throughout the repository to reference Google LLC
rather than Google Inc, for the required license headers.

PR Close #37205
2020-05-26 14:26:58 -04:00
5aeb9a4124 build: Update file-header lint rule to Google LLC (#37205)
Update the file-header lint rule to properly reference Google LLC
rather than Google Inc, for the required headers.

PR Close #37205
2020-05-26 14:26:58 -04:00
ecce99470a build: deprecate old merge script (#37247)
Deprecate the old merge script as it no longer correctly chooses
the patch branch due to relying on numerical sorting order from
git.  Git actually provides a lexicographical sorting order.  This
that 9.0.x will be chosen rather than 10.0.x as it is sorted based
the 9 vs 1, rather than 9 vs 10.

PR Close #37247
2020-05-26 14:25:43 -04:00
540c29cd6b feat(dev-infra): migrate release tool to use new logging system (#37232)
Migrate the release tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
7827501d2a feat(dev-infra): migrate ts-circular-dependencies tool to use new logging system (#37232)
Migrate the ts-circular-dependencies tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
e28f13a102 feat(dev-infra): migrate merge tool to use new logging system (#37232)
Migrate the merge tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
e0002ef9ba feat(dev-infra): migrate ng-dev utils to use new logging system (#37232)
Migrate the ng-dev utils to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
367f6fe12d feat(dev-infra): migrate pullapprove tool to use new logging system (#37232)
Migrate the pullapprove tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
9b3ca19675 feat(dev-infra): migrate rebase tool to use new logging system (#37232)
Migrate the rebase tool in ng-dev to use new logging system rather
than directly calling console.*  to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
9388e47e1e feat(dev-infra): migrate discover-new-conflicts tool to use new logging system (#37232)
Migrate the discover-new-conflicts tool in ng-dev to use new logging system
rather than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
171d967993 feat(dev-infra): migrate commit-message tool to use new logging system (#37232)
Migrate the commit-message tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
40e357411e feat(dev-infra): migrate format tool to use new logging system (#37232)
Migrate the formatting tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
52c7aae4df feat(dev-infra): add group functions to logging system and remove color param (#37232)
Adds .group and .groupEnd functions to each of the logging functions
to allow creating groups in the logged output.  Additionally removes
the color parameter from logging functions, in favor of the color
being applied to the string at the call site.

PR Close #37232
2020-05-21 17:40:34 -04:00
87b1aeac0f build(docs-infra): upgrade cli command docs sources to 89dbc2caa (#37243)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](200a21f8a...89dbc2caa):

**Modified**
- help/generate.json

PR Close #37243
2020-05-21 17:16:05 -04:00
93be1f1543 build: use static patch value for targetting branches in merge config (#37245)
Due to the desired patch branch (10.0.x) being on a semver version
that is unreleased as stable (there is no 10.0.0 on latest, it is on
next) our logic for determining target patch branches does not work.

This change is a workaround to unblock merging in the repo while a
longer term answer is discovered.

PR Close #37245
2020-05-21 17:07:26 -04:00
cdb5d07606 feat(dev-infra): expose script for determining merge branches (#37217)
The components repo and framework repository follow the same patch
branch concept. We should be able to share a script for determining
these merge branches.

Additonally the logic has been improved compared to the old merge script because
we no longer consult `git ls-remote` unless really needed. Currently,
`git ls-remote` is always consulted, even though not necessarily needed.

This can slow down the merge script and the caretaker process when a
couple of PRs are merged (personally saw around ~4 seconds per merge).

Additionally, the new logic is more strict and will ensure (in most
cases) that no wrong patch/minor branch is determined. Previously,
the script just used the lexicographically greatest patch branch.
This _could_ be wrong when a new patch branch has been created too
early, or by accident.

PR Close #37217
2020-05-21 10:35:23 -07:00
3e5fa56956 fix(dev-infra): ensure ts-node is registered with commonjs as module (#37217)
We recently added support for automatic registration of `ts-node`
when the dev-infra configuration is loaded.

In addition to registering ts-node, we should also ensure that the
`commonjs` module is set up. By default, `ts-node` would use ES module
imports that are not supported by default in NodeJS.

PR Close #37217
2020-05-21 10:35:23 -07:00
5057 changed files with 82094 additions and 78696 deletions

View File

@ -1,3 +1,3 @@
2.1.1
3.2.0
# [NB: this comment has to be after the first line, see https://github.com/bazelbuild/bazelisk/issues/117]
# When updating the Bazel version you also need to update the RBE toolchains version in package.bzl

View File

@ -19,4 +19,12 @@ build --local_ram_resources=14336
# All build executed remotely should be done using our RBE configuration.
build:remote --google_default_credentials
# Upload to GCP's Build Status viewer to allow for us to have better viewing of execution/build
# logs. This is only done on CI as the BES (GCP's Build Status viewer) API requires credentials
# from service accounts, rather than end user accounts.
build:remote --bes_backend=buildeventservice.googleapis.com
build:remote --bes_timeout=30s
build:remote --bes_results_url="https://source.cloud.google.com/results/invocations/"
build --config=remote

View File

@ -32,7 +32,7 @@ var_4_win: &cache_key_win_fallback v7-angular-win-node-12-{{ checksum ".bazelver
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
var_5: &components_repo_unit_tests_cache_key v7-angular-components-189d98e8b01b33974328255f085de04251d61567
var_5: &components_repo_unit_tests_cache_key v7-angular-components-f428c00465dfcf8a020237f22532480eedbd2cb6
var_6: &components_repo_unit_tests_cache_key_fallback v7-angular-components-
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
@ -67,9 +67,6 @@ var_10: &only_on_master
# **NOTE 1**: Pin to exact images using an ID (SHA). See https://circleci.com/docs/2.0/circleci-images/#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version.
# (Using the tag in not necessary when pinning by ID, but include it anyway for documentation purposes.)
# **NOTE 2**: If you change the version of the docker images, also change the `cache_key` suffix.
# **NOTE 3**: If you change the version of the `*-browsers` docker image, make sure the
# `--versions.chrome` arg in `integration/bazel-schematics/test.sh` specifies a
# ChromeDriver version that is compatible with the Chrome version in the image.
executors:
default-executor:
parameters:
@ -120,7 +117,7 @@ commands:
sudo apt-get update
# Install GTK+ graphical user interface (libgtk-3-0), advanced linux sound architecture (libasound2)
# and network security service libraries (libnss3) & X11 Screen Saver extension library (libssx1)
# which are dependendies of chrome & needed for karma & protractor headless chrome tests.
# which are dependencies of chrome & needed for karma & protractor headless chrome tests.
# This is a very small install which takes around 7s in comparing to using the full
# circleci/node:x.x.x-browsers image.
sudo apt-get -y install libgtk-3-0 libasound2 libnss3 libxss1
@ -163,7 +160,7 @@ commands:
description: Sets up a domain that resolves to the local host.
steps:
- run:
name: Preparing environment for running tests on Saucelabs.
name: Preparing environment for running tests on Sauce Labs.
command: |
# For SauceLabs jobs, we set up a domain which resolves to the machine which launched
# the tunnel. We do this because devices are sometimes not able to properly resolve
@ -175,13 +172,13 @@ commands:
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
- run:
# Sets up a local domain in the machine's host file that resolves to the local
# host. This domain is helpful in Saucelabs tests where devices are not able to
# host. This domain is helpful in Sauce Labs tests where devices are not able to
# properly resolve `localhost` or `127.0.0.1` through the sauce-connect tunnel.
name: Setting up alias domain for local host.
command: echo "127.0.0.1 $SAUCE_LOCALHOST_ALIAS_DOMAIN" | sudo tee -a /etc/hosts
# Normally this would be an individual job instead of a command.
# But startup and setup time for each invidual windows job are high enough to discourage
# But startup and setup time for each individual windows job are high enough to discourage
# many small jobs, so instead we use a command for setup unless the gain becomes significant.
setup_win:
description: Setup windows node environment
@ -599,8 +596,8 @@ jobs:
- run:
name: Decrypt github credentials
# We need ensure that the same default digest is used for encoding and decoding with
# openssl. Openssl versions might have different default digests which can cause
# decryption failures based on the installed openssl version. https://stackoverflow.com/a/39641378/4317734
# OpenSSL. OpenSSL versions might have different default digests which can cause
# decryption failures based on the installed OpenSSL version. https://stackoverflow.com/a/39641378/4317734
command: 'openssl aes-256-cbc -d -in .circleci/github_token -md md5 -k "${KEY}" -out ~/.git_credentials'
- run: ./scripts/ci/publish-build-artifacts.sh
@ -734,8 +731,8 @@ jobs:
- run: yarn --cwd packages/zone.js promisetest
- run: yarn --cwd packages/zone.js promisefinallytest
- run: yarn bazel build //packages/zone.js:npm_package &&
cp dist/bin/packages/zone.js/npm_package/dist/zone-mix.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/dist/zone-patch-electron.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/ &&
yarn --cwd packages/zone.js electrontest
- run: yarn --cwd packages/zone.js jesttest

View File

@ -74,7 +74,7 @@ setPublicVar COMPONENTS_REPO_TMP_DIR "/tmp/angular-components-repo"
setPublicVar COMPONENTS_REPO_URL "https://github.com/angular/components.git"
setPublicVar COMPONENTS_REPO_BRANCH "master"
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI `config.yml`.
setPublicVar COMPONENTS_REPO_COMMIT "189d98e8b01b33974328255f085de04251d61567"
setPublicVar COMPONENTS_REPO_COMMIT "f428c00465dfcf8a020237f22532480eedbd2cb6"
####################################################################################################

View File

@ -60,14 +60,15 @@ if (require.resolve === module) {
// Helpers
function _main(args) {
triggerWebhook(...args).
then(({statusCode, responseText}) => (200 <= statusCode && statusCode < 400) ?
console.log(`Status: ${statusCode}\n${responseText}`) :
Promise.reject(new Error(`Request failed (status: ${statusCode}): ${responseText}`))).
catch(err => {
console.error(err);
process.exit(1);
});
triggerWebhook(...args)
.then(
({statusCode, responseText}) => (200 <= statusCode && statusCode < 400) ?
console.log(`Status: ${statusCode}\n${responseText}`) :
Promise.reject(new Error(`Request failed (status: ${statusCode}): ${responseText}`)))
.catch(err => {
console.error(err);
process.exit(1);
});
}
function postJson(url, data) {
@ -77,15 +78,12 @@ function postJson(url, data) {
const statusCode = res.statusCode || -1;
let responseText = '';
res.
on('error', reject).
on('data', d => responseText += d).
on('end', () => resolve({statusCode, responseText}));
res.on('error', reject)
.on('data', d => responseText += d)
.on('end', () => resolve({statusCode, responseText}));
};
request(url, opts, onResponse).
on('error', reject).
end(JSON.stringify(data));
request(url, opts, onResponse).on('error', reject).end(JSON.stringify(data));
});
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,22 @@
---
name: "📚Traducir doc al español"
about: Solicitud para traducir ciertos docs al español
---
📚Traducir: <!-- ✍️ editar: --> creating-libraries.md
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
Traducción de la documentación oficial de Angular a español
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
## Nombre del archivo:
<!-- ✍️ editar: --> creating-libraries.md
## Ruta donde se encuentra el archivo dentro del proyecto de Angular
<!-- ✍️ editar: --> https://github.com/angular-hispano/angular/blob/master/aio/content/guide/creating-libraries.md

View File

@ -1,43 +1,35 @@
## PR Checklist
Please check if your PR fulfills the following requirements:
## Lista de Verificación del PR
Comprueba si tu PR cumple los siguientes requisitos:
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)
- [ ] El mensaje de commit conforme con [nuestras reglas](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit)
- [ ] Prueba los cambios que agregaste (arreglo de bugs / funcionalidades)
- [ ] Revisa tus traducciones o cambios de contenido
- [ ] Consulté el [diccionario de términos](https://github.com/angular-hispano/angular/issues/9) en español
- [ ] Se han creado dos archivos con la extensión correspondiente(.en.md para el archivo en inglés y .md para el Archivo en español)
- [ ] PR enlazada con el issue correspondiente
## PR Type
What kind of change does this PR introduce?
## Tipo de PR
¿Qué tipo de cambio introduce este PR?
<!-- Please check the one that applies to this PR using "x". -->
<!-- Marca con una "x" las opciones que aplican. -->
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Documentation content changes
- [ ] angular.io application / infrastructure changes
- [ ] Other... Please describe:
- [ ] Funcionalidad
- [ ] Actualizar el estilo del código (formato, variables locales)
- [ ] Refactorización (no cambios en la funcionalidad, no cambios en el api)
- [ ] Cambios relacionados al build
- [ ] Cambios relacionados al CI (Integración continua)
- [ ] Cambios en el contenido de la documentación
- [ ] Cambios en la aplicación / infrastructura de angular.io
- [ ] Otro... Por favor describela:
## ¿Cuál es el comportamiento actual?
<!-- Describe el comportamiento actual que está modificando o vincule a un problema relevante.
-->
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
Issue Number: N/A
## What is the new behavior?
## Does this PR introduce a breaking change?
- [ ] Yes
- [ ] No
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
## Other information
## ¿Cuál es el nuevo comportamiento?
<!--
Ejemplo: Archivo en inglés traducido al español
-->

View File

@ -154,6 +154,12 @@ triage:
-
- "type: RFC / Discussion / question"
- "comp: *"
-
- "type: confusing"
- "comp: *"
-
- "type: use-case"
- "comp: *"
# options for the triage PR plugin
triagePR:

3
.gitignore vendored
View File

@ -42,3 +42,6 @@ yarn-error.log
.notes.md
baseline.json
# Ignore .history for the xyz.local-history VSCode extension
.history

145
.gitmessage Normal file
View File

@ -0,0 +1,145 @@
<type>(<scope>): <summary>
<Describe the motivation behind this change - explain WHY you are making this change. Wrap all lines
at 100 characters.>
Fixes #<issue number>
# ────────────────────────────────────────── 100 chars ────────────────────────────────────────────┤
# Example Commit Messages
# =======================
# ─── Example: Simple refactor ────────────────────────────────────────────────────────────────────┤
# refactor(core): rename refreshDynamicEmbeddedViews to refreshEmbeddedViews
#
# Improve code readability. The original name no longer matches how the function is used.
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
# ─── Example: Simple docs change ─────────────────────────────────────────────────────────────────┤
# docs: clarify the service limitation in providers.md guide
#
# Fixes #36332
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
# ─── Example: A bug fix ──────────────────────────────────────────────────────────────────────────┤
# fix(ngcc): ensure lockfile is removed when `analyzeFn` fails
#
# Previously an error thrown in the `analyzeFn` would cause the ngcc process to exit immediately
# without removing the lockfile, and potentially before the unlocker process had been successfully
# spawned resulting in the lockfile being orphaned and left behind.
#
# Now we catch these errors and remove the lockfile as needed.
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
# ─── Example: Breaking change ────────────────────────────────────────────────────────────────────┤
# feat(bazel): simplify ng_package by dropping esm5 and fesm5
#
# esm5 and fesm5 distributions are no longer needed and have been deprecated in the past.
#
# https://v9.angular.io/guide/deprecations#esm5-and-fesm5-code-formats-in-angular-npm-packages
#
# This commit modifies ng_package to no longer distribute these two formats in npm packages built by
# ng_package (e.g. @angular/core).
#
# This commit intentionally doesn't fully clean up the ng_package rule to remove all traces of esm5
# and fems5 build artifacts as that is a bigger cleanup and currently we are narrowing down the
# scope of this change to the MVP needed for v10, which in this case is 'do not put esm5 and fesm5'
# into the npm packages.
#
# More cleanup to follow: https://angular-team.atlassian.net/browse/FW-2143
#
# BREAKING CHANGE: esm5 and fesm5 format is no longer distributed in Angular's npm packages e.g.
# @angular/core
#
# Angular CLI will automatically downlevel the code to es5 if differential loading is enabled in the
# Angular project, so no action is required from Angular CLI users.
#
# If you are not using Angular CLI to build your application or library, and you need to be able to
# build es5 artifacts, then you will need to downlevel the distributed Angular code to es5 on your
# own.
#
#
# Fixes #1234
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
# Angular Commit Message Format
# =============================
#
# The full specification of the Angular Commit Message Format can be found at
# https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
#
# The following is an excerpt of the specification with the most commonly needed info.
#
# Each commit message consists of a *header*, a *body*, and a *footer*.
#
# <header>
# <BLANK LINE>
# <body>
# <BLANK LINE>
# <footer>
#
# The header is mandatory.
#
# The body is mandatory for all commits except for those of scope "docs". When the body is required
# it must be at least 20 characters long.
#
# The footer is optional.
#
# Any line of the commit message cannot be longer than 100 characters.
#
#
# Commit Message Header
# ---------------------
#
# <type>(<scope>): <short summary>
# │ │ │
# │ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
# │ │
# │ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
# │ elements|forms|http|language-service|localize|platform-browser|
# │ platform-browser-dynamic|platform-server|platform-webworker|
# │ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
# │ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
# │ https://github.com/angular/angular/blob/master/CONTRIBUTING.md#scope
# │
# └─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
# https://github.com/angular/angular/blob/master/CONTRIBUTING.md#type
#
#
# Commit Message Body
# ---------------------
#
# Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
#
# Explain the motivation for the change in the commit message body. This commit message should
# explain WHY you are making the change. You can include a comparison of the previous behavior with
# the new behavior in order to illustrate the impact of the change.
#
#
# Commit Message Footer
# ---------------------
#
# The footer can contain information about breaking changes and is also the place to reference
# GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
#
# ```
# BREAKING CHANGE: <breaking change summary>
# <BLANK LINE>
# <breaking change description + migration instructions>
# <BLANK LINE>
# <BLANK LINE>
# Fixes #<issue number>
# ```
#
# Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of
# the breaking change, a blank line, and a detailed description of the breaking change that also
# includes migration instructions.
#

View File

@ -1,147 +0,0 @@
import {exec} from 'shelljs';
import {MergeConfig} from './dev-infra/pr/merge/config';
// The configuration for `ng-dev commit-message` commands.
const commitMessage = {
'maxLength': 120,
'minBodyLength': 100,
'types': [
'build',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'release',
'style',
'test',
],
'scopes': [
'animations',
'bazel',
'benchpress',
'changelog',
'common',
'compiler',
'compiler-cli',
'core',
'dev-infra',
'docs-infra',
'elements',
'forms',
'http',
'language-service',
'localize',
'ngcc',
'packaging',
'platform-browser',
'platform-browser-dynamic',
'platform-server',
'platform-webworker',
'platform-webworker-dynamic',
'router',
'service-worker',
'upgrade',
've',
'zone.js',
]
};
// The configuration for `ng-dev format` commands.
const format = {
'clang-format': {
'matchers': [
'dev-infra/**/*.{js,ts}',
'packages/**/*.{js,ts}',
'!packages/zone.js',
'!packages/common/locales/**/*.{js,ts}',
'!packages/common/src/i18n/available_locales.ts',
'!packages/common/src/i18n/currencies.ts',
'!packages/common/src/i18n/locale_en.ts',
'modules/benchmarks/**/*.{js,ts}',
'modules/playground/**/*.{js,ts}',
'tools/**/*.{js,ts}',
'!tools/gulp-tasks/cldr/extract.js',
'!tools/public_api_guard/**/*.d.ts',
'!tools/ts-api-guardian/test/fixtures/**',
'*.{js,ts}',
'!**/node_modules/**',
'!**/dist/**',
'!**/built/**',
'!shims_for_IE.js',
]
},
'buildifier': true
};
/** Github metadata information for `ng-dev` commands. */
const github = {
owner: 'angular',
name: 'angular',
};
/**
* Gets the name of the current patch branch. The patch branch is determined by
* looking for upstream branches that follow the format of `{major}.{minor}.x`.
*/
const getPatchBranchName = (): string => {
const branches =
exec(
`git ls-remote --heads https://github.com/${github.owner}/${github.name}.git`,
{silent: true})
.trim()
.split('\n');
for (let i = branches.length - 1; i >= 0; i--) {
const branchName = branches[i];
const matches = branchName.match(/refs\/heads\/([0-9]+\.[0-9]+\.x)/);
if (matches !== null) {
return matches[1];
}
}
throw Error('Could not determine patch branch name.');
};
// Configuration for the `ng-dev pr merge` command. The command can be used
// for merging upstream pull requests into branches based on a PR target label.
const merge = () => {
const patchBranch = getPatchBranchName();
const config: MergeConfig = {
githubApiMerge: false,
claSignedLabel: 'cla: yes',
mergeReadyLabel: /^PR action: merge(-assistance)?/,
commitMessageFixupLabel: 'commit message fixup',
labels: [
{
pattern: 'PR target: master-only',
branches: ['master'],
},
{
pattern: 'PR target: patch-only',
branches: [patchBranch],
},
{
pattern: 'PR target: master & patch',
branches: ['master', patchBranch],
},
],
requiredBaseCommits: {
// PRs that target either `master` or the patch branch, need to be rebased
// on top of the latest commit message validation fix.
'master': '4341743b4a6d7e23c6f944aa9e34166b701369a1',
[patchBranch]: '2a53f471592f424538802907aca1f60f1177a86d'
},
};
return config;
};
// Export function to build ng-dev configuration object.
module.exports = {
commitMessage,
format,
github,
merge,
};

52
.ng-dev/commit-message.ts Normal file
View File

@ -0,0 +1,52 @@
import {CommitMessageConfig} from '../dev-infra/commit-message/config';
/**
* The configuration for `ng-dev commit-message` commands.
*/
export const commitMessage: CommitMessageConfig = {
maxLineLength: 120,
minBodyLength: 20,
minBodyLengthTypeExcludes: ['docs'],
types: [
'build',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'release',
'style',
'test',
],
scopes: [
'animations',
'bazel',
'benchpress',
'changelog',
'common',
'compiler',
'compiler-cli',
'core',
'dev-infra',
'docs-infra',
'elements',
'forms',
'http',
'language-service',
'localize',
'migrations',
'ngcc',
'packaging',
'platform-browser',
'platform-browser-dynamic',
'platform-server',
'platform-webworker',
'platform-webworker-dynamic',
'router',
'service-worker',
'upgrade',
've',
'zone.js',
]
};

11
.ng-dev/config.ts Normal file
View File

@ -0,0 +1,11 @@
import {commitMessage} from './commit-message';
import {format} from './format';
import {github} from './github';
import {merge} from './merge';
module.exports = {
commitMessage,
format,
github,
merge,
};

22
.ng-dev/format.ts Normal file
View File

@ -0,0 +1,22 @@
import {FormatConfig} from '../dev-infra/format/config';
/**
* Configuration for the `ng-dev format` command.
*/
export const format: FormatConfig = {
'clang-format': {
'matchers': [
'**/*.{js,ts}',
// TODO: burn down format failures and remove aio and integration exceptions.
'!aio/**',
'!integration/**',
// Both third_party and .yarn are directories containing copied code which should
// not be modified.
'!third_party/**',
'!.yarn/**',
// Do not format d.ts files as they are generated
'!**/*.d.ts',
]
},
'buildifier': true
};

15
.ng-dev/gitconfig Normal file
View File

@ -0,0 +1,15 @@
# The file is inert unless it's explicitly included into the local git config via:
#
# ```
# git config --add include.path '../.ng-dev/gitconfig'
# ```
#
# Calling that command will append the following into `.git/config` of the current git workspace
# (i.e. $GIT_DIR, typically `angular/.git/config`):
#
# ```
# [include]
# path = ../.ng-dev/gitconfig
# ```
[commit]
template = .gitmessage

11
.ng-dev/github.ts Normal file
View File

@ -0,0 +1,11 @@
import {GithubConfig} from '../dev-infra/utils/config';
/**
* Github configuration for the `ng-dev` command. This repository is used as
* remote for the merge script and other utilities like `ng-dev pr rebase`.
*/
export const github: GithubConfig = {
owner: 'angular',
name: 'angular'
};

38
.ng-dev/merge.ts Normal file
View File

@ -0,0 +1,38 @@
import {MergeConfig} from '../dev-infra/pr/merge/config';
/**
* Configuration for the merge tool in `ng-dev`. This sets up the labels which
* are respected by the merge script (e.g. the target labels).
*/
export const merge = (): MergeConfig => {
// TODO: resume dynamically determining patch branch
const patch = '10.0.x';
return {
githubApiMerge: false,
claSignedLabel: 'cla: yes',
mergeReadyLabel: /^PR action: merge(-assistance)?/,
caretakerNoteLabel: 'PR action: merge-assistance',
commitMessageFixupLabel: 'commit message fixup',
labels: [
{
pattern: 'PR target: master-only',
branches: ['master'],
},
{
pattern: 'PR target: patch-only',
branches: [patch],
},
{
pattern: 'PR target: master & patch',
branches: ['master', patch],
},
],
requiredBaseCommits: {
// PRs that target either `master` or the patch branch, need to be rebased
// on top of the latest commit message validation fix.
// These SHAs are the commits that update the required license text in the header.
'master': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
[patch]: '27b95ba64a5d99757f4042073fd1860e20e3ed24'
},
};
};

View File

@ -34,41 +34,8 @@
####################################################################################
# GitHub usernames
####################################################################################
# aikidave - Dave Shevitz
# alan-agius4 - Alan Agius
# alxhub - Alex Rickabaugh
# AndrewKushnir - Andrew Kushnir
# andrewseguin - Andrew Seguin
# atscott - Andrew Scott
# ayazhafiz - Ayaz Hafiz
# clydin - Charles Lyding
# crisbeto - Kristiyan Kostadinov
# dennispbrown - Denny Brown
# devversion - Paul Gschwendtner
# dgp1130 - Doug Parker
# filipesilva - Filipe Silva
# gkalpak - Georgios Kalpakas
# gregmagolan - Greg Magolan
# IgorMinar - Igor Minar
# jbogarthyde - Judy Bogart
# jelbourn - Jeremy Elbourn
# JiaLiPassion - Jia Li
# JoostK - Joost Koehoorn
# josephperrott - Joey Perrott
# juleskremer - Jules Kremer
# kapunahelewong - Kapunahele Wong
# kara - Kara Erickson
# kyliau - Keen Yee Liau
# manughub - Manu Murthy
# matsko - Matias Niemela
# mgechev - Minko Gechev
# mhevery - Miško Hevery
# michaelprentice - Michael Prentice
# mmalerba - Miles Malerba
# petebacondarwin - Pete Bacon Darwin
# pkozlowski-opensource - Pawel Kozlowski
# robwormald - Rob Wormald
# StephenFluin - Stephen Fluin
# See reviewer list under `required-minimum-review` group. Team member names and
# usernames are managed there.
####################################################################################
@ -80,8 +47,8 @@
# Used for approving minor changes, large-scale refactorings, and in emergency situations.
#
# IgorMinar
# jelbourn
# josephperrott
# kara
# mhevery
#
# =========================================================
@ -100,8 +67,16 @@ version: 3
# Meta field that goes unused by PullApprove to allow for defining aliases to be
# used throughout the config.
meta:
1: &can-be-global-approved "\"global-approvers\" not in groups.approved"
2: &can-be-global-docs-approved "\"global-docs-approvers\" not in groups.approved"
can-be-global-approved: &can-be-global-approved "\"global-approvers\" not in groups.approved"
can-be-global-docs-approved: &can-be-global-docs-approved "\"global-docs-approvers\" not in groups.approved"
defaults: &defaults
reviews:
# Authors provide their approval implicitly, this approval allows for a reviewer
# from a group not to need a review specifically for an area of the repository
# they own. This is coupled with the `required-minimum-review` group which requires
# that all PRs are reviewed by at least one team member who is not the author of
# the PR.
author_value: 1
# turn on 'draft' support
# https://docs.pullapprove.com/config/github-api-version/
@ -157,10 +132,62 @@ groups:
required: 1
reviewed_for: required
# =========================================================
# Require review on all PRs
#
# All PRs require at least one review. This rule will not
# request any reviewers, however will require that at least
# one review is provided before the group is satisfied.
# =========================================================
required-minimum-review:
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
reviews:
request: 0 # Do not request any reviews from the reviewer group
required: 1 # Require that all PRs have approval from at least one of the users in the group
author_value: 0 # The author of the PR cannot provide an approval for themself
reviewers:
users:
- aikidave # Dave Shevitz
- alan-agius4 # Alan Agius
- alxhub # Alex Rickabaugh
- AndrewKushnir # Andrew Kushnir
- andrewseguin # Andrew Seguin
- atscott # Andrew Scott
- ayazhafiz # Ayaz Hafiz
- clydin # Charles Lyding
- crisbeto # Kristiyan Kostadinov
- dennispbrown # Denny Brown
- devversion # Paul Gschwendtner
- dgp1130 # Doug Parker
- filipesilva # Filipe Silva
- gkalpak # Georgios Kalpakas
- gregmagolan # Greg Magolan
- IgorMinar # Igor Minar
- jbogarthyde # Judy Bogart
- jelbourn # Jeremy Elbourn
- JiaLiPassion # Jia Li
- JoostK # Joost Koehoorn
- josephperrott # Joey Perrott
- juleskremer # Jules Kremer
- kapunahelewong # Kapunahele Wong
- kara # Kara Erickson
- kyliau # Keen Yee Liau
- manughub # Manu Murthy
- mgechev # Minko Gechev
- mhevery # Miško Hevery
- mmalerba # Miles Malerba
- petebacondarwin # Pete Bacon Darwin
- pkozlowski-opensource # Pawel Kozlowski
- Splaktar # Michael Prentice
- StephenFluin # Stephen Fluin
# =========================================================
# Framework: Animations
# =========================================================
fw-animations:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -178,13 +205,16 @@ groups:
])
reviewers:
users:
- matsko
- crisbeto
- IgorMinar
- jelbourn
# =========================================================
# Framework: Compiler
# =========================================================
fw-compiler:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -203,13 +233,13 @@ groups:
- alxhub
- AndrewKushnir
- JoostK
- kara
# =========================================================
# Framework: Compiler / ngcc
# =========================================================
fw-ngcc:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -226,6 +256,7 @@ groups:
# Framework: Migrations
# =========================================================
fw-migrations:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -235,13 +266,13 @@ groups:
- alxhub
- crisbeto
- devversion
- kara
# =========================================================
# Framework: Core
# =========================================================
fw-core:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -285,6 +316,7 @@ groups:
'aio/content/images/guide/dependency-injection-in-action/**',
'aio/content/guide/dependency-injection-navtree.md',
'aio/content/guide/dependency-injection-providers.md',
'aio/content/guide/lightweight-injection-tokens.md',
'aio/content/guide/displaying-data.md',
'aio/content/examples/displaying-data/**',
'aio/content/images/guide/displaying-data/**',
@ -315,26 +347,38 @@ groups:
'aio/content/guide/ngmodule-vs-jsmodule.md',
'aio/content/guide/module-types.md',
'aio/content/guide/template-syntax.md',
'aio/content/guide/built-in-template-functions.md',
'aio/content/examples/built-in-template-functions/**',
'aio/content/guide/event-binding.md',
'aio/content/examples/event-binding/**',
'aio/content/guide/interpolation.md',
'aio/content/examples/interpolation/**',
'aio/content/examples/template-syntax/**',
'aio/content/images/guide/template-syntax/**',
'aio/content/guide/binding-syntax.md',
'aio/content/examples/binding-syntax/**',
'aio/content/guide/property-binding.md',
'aio/content/examples/property-binding/**',
'aio/content/guide/attribute-binding.md',
'aio/content/examples/attribute-binding/**',
'aio/content/guide/two-way-binding.md',
'aio/content/examples/two-way-binding/**',
'aio/content/guide/built-in-directives.md',
'aio/content/examples/built-in-directives/**',
'aio/content/images/guide/built-in-directives/**',
'aio/content/guide/template-reference-variables.md',
'aio/content/examples/template-reference-variables/**',
'aio/content/guide/inputs-outputs.md',
'aio/content/examples/inputs-outputs/**',
'aio/content/images/guide/inputs-outputs/**',
'aio/content/guide/template-expression-operators.md',
'aio/content/examples/template-expression-operators/**',
'aio/content/guide/pipes.md',
'aio/content/examples/pipes/**',
'aio/content/images/guide/pipes/**',
'aio/content/guide/providers.md',
'aio/content/examples/providers/**',
'aio/content/images/guide/providers/**',
'aio/content/guide/singleton-services.md',
'aio/content/guide/set-document-title.md',
'aio/content/examples/set-document-title/**',
@ -342,7 +386,9 @@ groups:
'aio/content/guide/sharing-ngmodules.md',
'aio/content/guide/structural-directives.md',
'aio/content/examples/structural-directives/**',
'aio/content/guide/svg-in-templates.md',
'aio/content/images/guide/structural-directives/**',
'aio/content/guide/template-statements.md',
'aio/content/guide/user-input.md',
'aio/content/examples/user-input/**',
'aio/content/images/guide/user-input/**'
@ -352,7 +398,7 @@ groups:
- alxhub
- AndrewKushnir
- atscott
- kara
- ~kara # do not request reviews from Kara, but allow her to approve PRs
- mhevery
- pkozlowski-opensource
@ -361,6 +407,7 @@ groups:
# Framework: Http
# =========================================================
fw-http:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -382,6 +429,7 @@ groups:
# Framework: Elements
# =========================================================
fw-elements:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -402,6 +450,7 @@ groups:
# Framework: Forms
# =========================================================
fw-forms:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -434,6 +483,7 @@ groups:
# Framework: i18n
# =========================================================
fw-i18n:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -467,6 +517,7 @@ groups:
# Framework: Platform Server
# =========================================================
fw-platform-server:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -486,6 +537,7 @@ groups:
# Framework: Router
# =========================================================
fw-router:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -495,6 +547,7 @@ groups:
'packages/examples/router/**',
'aio/content/guide/router.md',
'aio/content/guide/router-tutorial.md',
'aio/content/guide/router-tutorial-toh.md',
'aio/content/examples/router-tutorial/**',
'aio/content/examples/router/**',
'aio/content/images/guide/router/**'
@ -508,6 +561,7 @@ groups:
# Framework: Service Worker
# =========================================================
fw-service-worker:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -535,6 +589,7 @@ groups:
# Framework: Upgrade
# =========================================================
fw-upgrade:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -565,6 +620,7 @@ groups:
# Framework: Testing
# =========================================================
fw-testing:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -572,6 +628,14 @@ groups:
contains_any_globs(files.exclude('packages/compiler-cli/**'), [
'**/testing/**',
'aio/content/guide/testing.md',
'aio/content/guide/test-debugging.md',
'aio/content/guide/testing-attribute-directives.md',
'aio/content/guide/testing-code-coverage.md',
'aio/content/guide/testing-components-basics.md',
'aio/content/guide/testing-components-scenarios.md',
'aio/content/guide/testing-pipes.md',
'aio/content/guide/testing-services.md',
'aio/content/guide/testing-utility-apis.md',
'aio/content/examples/testing/**',
'aio/content/images/guide/testing/**'
])
@ -579,7 +643,6 @@ groups:
users:
- AndrewKushnir
- IgorMinar
- kara
- pkozlowski-opensource
@ -587,6 +650,7 @@ groups:
# Framework: Benchmarks
# =========================================================
fw-benchmarks:
<<: *defaults
conditions:
- *can-be-global-approved
- >
@ -596,7 +660,6 @@ groups:
reviewers:
users:
- IgorMinar
- kara
- pkozlowski-opensource
@ -604,6 +667,7 @@ groups:
# Framework: Playground
# =========================================================
fw-playground:
<<: *defaults
conditions:
- *can-be-global-approved
- >
@ -613,13 +677,15 @@ groups:
reviewers:
users:
- IgorMinar
- kara
- jelbourn
- pkozlowski-opensource
# =========================================================
# Framework: Security
# =========================================================
fw-security:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -637,18 +703,25 @@ groups:
users:
- IgorMinar
- mhevery
- jelbourn
- pkozlowski-opensource
reviews:
request: -1 # request reviews from everyone
required: 2 # require at least 2 approvals
reviewed_for: required
# =========================================================
# Bazel
# =========================================================
bazel:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
- >
contains_any_globs(files, [
'packages/bazel/**',
'aio/content/guide/bazel.md'
])
reviewers:
users:
@ -661,6 +734,7 @@ groups:
# Language Service
# =========================================================
language-service:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -680,6 +754,7 @@ groups:
# zone.js
# =========================================================
zone-js:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -693,11 +768,27 @@ groups:
- JiaLiPassion
- mhevery
# =========================================================
# in-memory-web-api
# =========================================================
in-memory-web-api:
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
- >
contains_any_globs(files, [
'packages/misc/angular-in-memory-web-api/**',
])
reviewers:
users:
- IgorMinar
- crisbeto
# =========================================================
# Benchpress
# =========================================================
benchpress:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -708,12 +799,14 @@ groups:
reviewers:
users:
- alxhub
- josephperrott
# =========================================================
# Integration Tests
# =========================================================
integration-tests:
<<: *defaults
conditions:
- *can-be-global-approved
- >
@ -724,7 +817,6 @@ groups:
users:
- IgorMinar
- josephperrott
- kara
- mhevery
@ -732,6 +824,7 @@ groups:
# Docs: Gettings Started & Tutorial
# =========================================================
docs-getting-started-and-tutorial:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -764,6 +857,7 @@ groups:
# Docs: Marketing
# =========================================================
docs-marketing:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -786,6 +880,7 @@ groups:
# Docs: Observables
# =========================================================
docs-observables:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -811,6 +906,7 @@ groups:
# Docs: Packaging, Tooling, Releasing
# =========================================================
docs-packaging-and-releasing:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -830,20 +926,47 @@ groups:
'aio/content/guide/migration-localize.md',
'aio/content/guide/migration-module-with-providers.md',
'aio/content/guide/static-query-migration.md',
'aio/content/guide/updating-to-version-9.md',
'aio/content/guide/updating-to-version-10.md',
'aio/content/guide/ivy-compatibility.md',
'aio/content/guide/ivy-compatibility-examples.md'
])
reviewers:
users:
- IgorMinar
- kara
- jelbourn
# =========================================================
# Tooling: Compiler API shared with Angular CLI
#
# Changing this API might break Angular CLI, so we require
# the CLI team to approve changes here.
# =========================================================
tooling-cli-shared-api:
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
- >
contains_any_globs(files, [
'packages/compiler-cli/src/tooling.ts'
])
reviewers:
users:
- alan-agius4
- clydin
- kyliau
- IgorMinar
reviews:
request: -1 # request reviews from everyone
required: 2 # require at least 2 approvals
reviewed_for: required
# =========================================================
# Docs: CLI
# =========================================================
docs-cli:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -860,8 +983,12 @@ groups:
'aio/content/images/guide/deployment/**',
'aio/content/guide/file-structure.md',
'aio/content/guide/ivy.md',
'aio/content/guide/strict-mode.md',
'aio/content/guide/web-worker.md',
'aio/content/guide/workspace-config.md',
'aio/content/guide/migration-solution-style-tsconfig.md',
'aio/content/guide/migration-update-module-and-target-compiler-options.md',
'aio/content/guide/migration-update-libraries-tslib.md',
])
reviewers:
users:
@ -874,6 +1001,7 @@ groups:
# Docs: CLI Libraries
# =========================================================
docs-libraries:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -894,6 +1022,7 @@ groups:
# Docs: Schematics
# =========================================================
docs-schematics:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -916,6 +1045,7 @@ groups:
# Docs-infra
# =========================================================
docs-infra:
<<: *defaults
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
@ -945,14 +1075,16 @@ groups:
# Dev-infra
# =========================================================
dev-infra:
<<: *defaults
conditions:
- *can-be-global-approved
- >
contains_any_globs(files.exclude("CHANGELOG.md"), [
contains_any_globs(files.exclude("CHANGELOG.md").exclude("packages/compiler-cli/**/BUILD.bazel"), [
'*',
'.circleci/**',
'.devcontainer/**',
'.github/**',
'.ng-dev/**',
'.vscode/**',
'.yarn/**',
'dev-infra/**',
@ -968,8 +1100,6 @@ groups:
'docs/TOOLS.md',
'docs/TRIAGE_AND_LABELS.md',
'goldens/*',
'modules/e2e_util/e2e_util.ts',
'modules/e2e_util/perf_util.ts',
'modules/*',
'packages/*',
'packages/examples/test-utils/**',
@ -977,15 +1107,10 @@ groups:
'packages/examples/*',
'scripts/**',
'third_party/**',
'tools/brotli-cli/**',
'tools/browsers/**',
'tools/build/**',
'tools/circular_dependency_test/**',
'tools/contributing-stats/**',
'tools/components/**',
'tools/gulp-tasks/**',
'tools/ng_rollup_bundle/**',
'tools/ngcontainer/**',
'tools/npm/**',
'tools/npm_integration_test/**',
'tools/rxjs/**',
@ -1015,6 +1140,7 @@ groups:
# Public API
# =========================================================
public-api:
<<: *defaults
conditions:
- *can-be-global-approved
- >
@ -1030,13 +1156,21 @@ groups:
reviewers:
users:
- IgorMinar
- kara
- alxhub
- jelbourn
- petebacondarwin
- pkozlowski-opensource
reviews:
request: -1 # request reviews from everyone
required: 3 # require at least 3 approvals
reviewed_for: required
# ================================================
# Size tracking
# ================================================
size-tracking:
<<: *defaults
conditions:
- *can-be-global-approved
- >
@ -1046,13 +1180,21 @@ groups:
reviewers:
users:
- IgorMinar
- kara
- alxhub
- jelbourn
- petebacondarwin
- pkozlowski-opensource
reviews:
request: -1 # request reviews from everyone
required: 2 # require at least 2 approvals
reviewed_for: required
# ================================================
# Circular dependencies
# ================================================
circular-dependencies:
<<: *defaults
conditions:
- *can-be-global-approved
- >
@ -1062,8 +1204,10 @@ groups:
reviewers:
users:
- IgorMinar
- jelbourn
- josephperrott
- kara
- petebacondarwin
- pkozlowski-opensource
####################################################################################
@ -1074,6 +1218,7 @@ groups:
# Code Ownership
# =========================================================
code-ownership:
<<: *defaults
conditions:
- *can-be-global-approved
- >
@ -1083,18 +1228,46 @@ groups:
reviewers:
users:
- IgorMinar
- jelbourn
- josephperrott
- mhevery
# ====================================================
# Catch all for if no groups match the code change
# ====================================================
fallback:
<<: *defaults
# A group is considered to be `active` for a PR if at least one of group's
# conditions matches the PR.
#
# The PullApprove CI check should fail if a PR has no `active` groups, as
# this indicates the PR is modifying a file that has no owner.
#
# This is enforced through the pullapprove verification check done
# as part of the CircleCI lint job. Failures in this lint job should be
# fixed as part of the PR. This can be done by updating the
# `.pullapprove.yml` file cover the unmatched path.
# The pullapprove verification script is part of the ng-dev tool and can be
# run locally with the command: `yarn -s ng-dev pullapprove verify`
#
# For cases in which the verification check fails to ensure coverage, this
# group will be active. The expectation is that this should be remedied
# before merging the PR as described above. In an emergency situation
# `global-approvers` can still approve PRs that match this `fallback` rule,
# but that should be an exception and not an expectation.
conditions:
# The following groups have no file based conditions and will be initially `active` on all PRs
# - `global-approvers`
# - `global-docs-approvers`
# - `required-minimum-review`
#
# By checking the number of active groups when these are excluded, we can determine
# if any other groups are matched.
- len(groups.active.exclude("required-minimum-review").exclude("global-approvers").exclude("global-docs-approvers")) == 0
# When any of the `global-*` groups is approved, they cause other groups to deactivate.
# In those cases, the condition above would evaluate to `true` while in reality, only a global
# approval has been provided. To ensure we don't activate the fallback group in such cases,
# ensure that no explicit global approval has been provided.
- *can-be-global-approved
# Groups which are found to have matching conditions are `active`
# according to PullApprove. If no groups are matched and considered
# active, we still want to have a review occur.
- len(groups.active) == 0
reviewers:
users:
- IgorMinar
- *can-be-global-docs-approved

View File

@ -26,6 +26,7 @@
"**/bazel-out": true,
"**/dist": true,
"**/aio/src/generated": true,
".history": true,
},
"git.ignoreLimitWarning": true,
}
}

View File

@ -2,7 +2,6 @@ package(default_visibility = ["//visibility:public"])
exports_files([
"LICENSE",
"protractor-perf.conf.js",
"karma-js.conf.js",
"browser-providers.conf.js",
"scripts/ci/track-payload-size.sh",
@ -21,11 +20,11 @@ filegroup(
# do not sort
srcs = [
"@npm//:node_modules/core-js/client/core.js",
"//packages/zone.js/dist:zone.js",
"//packages/zone.js/dist:zone-testing.js",
"//packages/zone.js/dist:task-tracking.js",
"//packages/zone.js/bundles:zone.umd.js",
"//packages/zone.js/bundles:zone-testing.umd.js",
"//packages/zone.js/bundles:task-tracking.umd.js",
"//:test-events.js",
"//:shims_for_IE.js",
"//:third_party/shims_for_IE.js",
# Including systemjs because it defines `__eval`, which produces correct stack traces.
"@npm//:node_modules/systemjs/dist/system.src.js",
"@npm//:node_modules/reflect-metadata/Reflect.js",

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
# Contributing to Angular
We would love for you to contribute to Angular and help make it even better than it is
today! As a contributor, here are the guidelines we would like you to follow:
We would love for you to contribute to Angular and help make it even better than it is today!
As a contributor, here are the guidelines we would like you to follow:
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
@ -12,50 +12,63 @@ today! As a contributor, here are the guidelines we would like you to follow:
- [Commit Message Guidelines](#commit)
- [Signing the CLA](#cla)
## <a name="coc"></a> Code of Conduct
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][coc].
Help us keep Angular open and inclusive.
Please read and follow our [Code of Conduct][coc].
## <a name="question"></a> Got a Question or Problem?
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests. You've got much better chances of getting your question answered on [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) where the questions should be tagged with tag `angular`.
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests.
Instead, we recommend using [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) to ask support-related questions. When creating a new question on Stack Overflow, make sure to add the `angular` tag.
Stack Overflow is a much better place to ask questions since:
- there are thousands of people willing to help on Stack Overflow
- questions and answers stay available for public viewing so your question / answer might help someone else
- questions and answers stay available for public viewing so your question/answer might help someone else
- Stack Overflow's voting system assures that the best answers are prominently visible.
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.
If you would like to chat about the question in real-time, you can reach out via [our gitter channel][gitter].
## <a name="issue"></a> Found a Bug?
If you find a bug in the source code, you can help us by
[submitting an issue](#submit-issue) to our [GitHub Repository][github]. Even better, you can
[submit a Pull Request](#submit-pr) with a fix.
If you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github].
Even better, you can [submit a Pull Request](#submit-pr) with a fix.
## <a name="feature"></a> Missing a Feature?
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub
Repository. If you would like to *implement* a new feature, please submit an issue with
a proposal for your work first, to be sure that we can use it.
Please consider what kind of change it is:
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub Repository.
If you would like to *implement* a new feature, please consider the size of the change in order to determine the right steps to proceed:
* For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed.
This process allows us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.
**Note**: Adding a new topic to the documentation, or significantly re-writing a topic, counts as a major feature.
* For a **Major Feature**, first open an issue and outline your proposal so that it can be
discussed. This will also allow us to better coordinate our efforts, prevent duplication of work,
and help you to craft the change so that it is successfully accepted into the project.
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
## <a name="submit"></a> Submission Guidelines
### <a name="submit-issue"></a> Submitting an Issue
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs, we will systematically ask you to provide a minimal reproduction. Having a minimal reproducible scenario gives us a wealth of important information without going back & forth to you with additional questions.
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it.
In order to reproduce bugs, we require that you provide a minimal reproduction.
Having a minimal reproducible scenario gives us a wealth of important information without going back and forth to you with additional questions.
A minimal reproduction allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are fixing the right problem.
We will be insisting on a minimal reproduction scenario in order to save maintainers time and ultimately be able to fix more bugs. Interestingly, from our experience, users often find coding problems themselves while preparing a minimal reproduction. We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
We require a minimal reproduction to save maintainers' time and ultimately be able to fix more bugs.
Often, developers find coding problems themselves while preparing a minimal reproduction.
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced.
@ -63,57 +76,66 @@ You can file new issues by selecting from our [new issue templates](https://gith
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
Before you submit your Pull Request (PR) consider the following guidelines:
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR
that relates to your submission. You don't want to duplicate effort.
1. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
Discussing the design up front helps to ensure that we're ready to accept your work.
1. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
We cannot accept code without this. Make sure you sign with the primary email address of the Git identity that has been granted access to the Angular repository.
1. Fork the angular/angular repo.
1. Make your changes in a new git branch:
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR that relates to your submission.
You don't want to duplicate existing efforts.
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
Discussing the design upfront helps to ensure that we're ready to accept your work.
3. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
We cannot accept code without a signed CLA.
Make sure you author all contributed Git commits with email address associated with your CLA signature.
4. Fork the angular/angular repo.
5. Make your changes in a new git branch:
```shell
git checkout -b my-fix-branch master
```
1. Create your patch, **including appropriate test cases**.
1. Follow our [Coding Rules](#rules).
1. Run the full Angular test suite, as described in the [developer documentation][dev-doc],
and ensure that all tests pass.
1. Commit your changes using a descriptive commit message that follows our
[commit message conventions](#commit). Adherence to these conventions
is necessary because release notes are automatically generated from these messages.
6. Create your patch, **including appropriate test cases**.
7. Follow our [Coding Rules](#rules).
8. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass.
9. Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit).
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
```shell
git commit -a
```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
1. Push your branch to GitHub:
10. Push your branch to GitHub:
```shell
git push origin my-fix-branch
```
1. In GitHub, send a pull request to `angular:master`.
* If we suggest changes then:
* Make the required updates.
* Re-run the Angular test suites to ensure tests are still passing.
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
11. In GitHub, send a pull request to `angular:master`.
```shell
git rebase master -i
git push -f
```
If we ask for changes via code reviews then:
* Make the required updates.
* Re-run the Angular test suites to ensure tests are still passing.
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
```shell
git rebase master -i
git push -f
```
That's it! Thank you for your contribution!
#### After your pull request is merged
After your pull request is merged, you can safely delete your branch and pull the changes
from the main (upstream) repository:
After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
@ -139,55 +161,66 @@ from the main (upstream) repository:
git pull --ff upstream master
```
## <a name="rules"></a> Coding Rules
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
* All public API methods **must be documented**. (Details TBC).
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at
**100 characters**. An automated formatter is available, see
[DEVELOPER.md](docs/DEVELOPER.md#clang-format).
* All public API methods **must be documented**.
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**.
## <a name="commit"></a> Commit Message Guidelines
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#clang-format).
We have very precise rules over how our git commit messages can be formatted. This leads to **more
readable messages** that are easy to follow when looking through the **project history**. But also,
we use the git commit messages to **generate the Angular change log**.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:
## <a name="commit"></a> Commit Message Format
*This specification is inspired and supersedes the [AngularJS commit message format][commit-message-format].*
We have very precise rules over how our Git commit messages must be formatted.
This format leads to **easier to read commit history**.
Each commit message consists of a **header**, a **body**, and a **footer**.
```
<type>(<scope>): <subject>
<header>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The **header** is mandatory and the **scope** of the header is optional.
The `header` is mandatory and must conform to the [Commit Message Header](#commit-header) format.
Any line of the commit message cannot be longer than 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
The `body` is mandatory for all commits except for those of scope "docs".
When the body is required it must be at least 20 characters long.
The footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.
The `footer` is optional.
Samples: (even more [samples](https://github.com/angular/angular/commits/master))
Any line of the commit message cannot be longer than 100 characters.
#### <a href="commit-header"></a>Commit Message Header
```
docs(changelog): update changelog to beta.5
```
```
fix(release): need to depend on latest rxjs and zone.js
The version in our package.json gets copied to the one we publish, and users need the latest of these.
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
│ elements|forms|http|language-service|localize|platform-browser|
│ platform-browser-dynamic|platform-server|platform-webworker|
│ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
│ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
```
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional.
##### Type
### Type
Must be one of the following:
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
@ -200,66 +233,95 @@ Must be one of the following:
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
* **test**: Adding missing tests or correcting existing tests
### Scope
##### Scope
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
The following is the list of supported scopes:
* **animations**
* **bazel**
* **benchpress**
* **common**
* **compiler**
* **compiler-cli**
* **core**
* **elements**
* **forms**
* **http**
* **language-service**
* **localize**
* **platform-browser**
* **platform-browser-dynamic**
* **platform-server**
* **platform-webworker**
* **platform-webworker-dynamic**
* **router**
* **service-worker**
* **upgrade**
* **zone.js**
* `animations`
* `bazel`
* `benchpress`
* `common`
* `compiler`
* `compiler-cli`
* `core`
* `elements`
* `forms`
* `http`
* `language-service`
* `localize`
* `platform-browser`
* `platform-browser-dynamic`
* `platform-server`
* `platform-webworker`
* `platform-webworker-dynamic`
* `router`
* `service-worker`
* `upgrade`
* `zone.js`
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.
* **changelog**: used for updating the release notes in CHANGELOG.md
* **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
repo
* **dev-infra**: used for dev-infra related changes within the directories /scripts, /tools and /dev-infra
* **ngcc**: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
* **ve**: used for changes specific to ViewEngine (legacy compiler/renderer).
* 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`).
* `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.
### Subject
The subject contains a succinct description of the change:
* `changelog`: used for updating the release notes in CHANGELOG.md
* `dev-infra`: used for dev-infra related changes within the directories /scripts, /tools and /dev-infra
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
* `migrations`: used for changes to the `ng update` migrations.
* `ngcc`: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
* `ve`: used for changes specific to ViewEngine (legacy compiler/renderer).
* 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`).
##### Summary
Use the summary field to provide a succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize the first letter
* no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.
#### Commit Message Body
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
Explain the motivation for the change in the commit message body. This commit message should explain _why_ you are making the change.
You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change.
#### Commit Message Footer
The footer can contain information about breaking changes and is also the place to reference GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
```
BREAKING CHANGE: <breaking change summary>
<BLANK LINE>
<breaking change description + migration instructions>
<BLANK LINE>
<BLANK LINE>
Fixes #<issue number>
```
Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
### Revert commits
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
The content of the commit message body should contain:
- information about the SHA of the commit being reverted in the following format: `This reverts commit <SHA>`,
- a clear description of the reason for reverting the commit message.
A detailed explanation can be found in this [document][commit-message-format].
## <a name="cla"></a> Signing the CLA
@ -270,18 +332,17 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise
* For corporations, we'll need you to
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
<hr>
If you have more than one GitHub accounts, or multiple email addresses associated with a single GitHub account, you must sign the CLA using the primary email address of the GitHub account used to author Git commits and send pull requests.
If you have more than one Git identity, you must make sure that you sign the CLA using the primary email address associated with the ID that has been granted access to the Angular repository. Git identities can be associated with more than one email address, and only one is primary. Here are some links to help you sort out multiple Git identities and email addresses:
The following documents can help you sort out issues with GitHub accounts and multiple email addresses:
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
* 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.
<hr>
[angular-group]: https://groups.google.com/forum/#!forum/angular
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md

View File

@ -5,22 +5,21 @@
# Angular
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.
Angular es una plataforma de desarrollo para construir aplicaciones web y móviles que usa TypeScript/JavaScript y otros lenguajes de programación.
## Quickstart
## Guía rápida
[Get started in 5 minutes][quickstart].
[Comienza a usarlo en 5 minutos][quickstart].
## Changelog
## Registro de cambios (Changelog)
[Learn about the latest improvements][changelog].
[Últimas mejoras realizadas][changelog].
## Want to help?
## ¿Quieres ayudar?
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
¿Quieres encontrar fallos, colaborar con código, o mejorar la documentación? ¡Excelente! Lee nuestras
pautas para [colaborar][contributing] y luego revisa algunos de nuestras incidencias (issues) en [ayuda comunitaria](https://github.com/angular-hispano/angular/labels/ayuda%20comunitaria).
[contributing]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md
[quickstart]: https://angular.io/start
[contributing]: https://github.com/angular-hispano/angular/blob/master/CONTRIBUTING.md
[quickstart]: https://docs.angular.lat/start
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
[ng]: https://angular.io

View File

@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Fetch rules_nodejs so we can install our npm dependencies
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "f9e7b9f42ae202cc2d2ce6d698ccb49a9f7f7ea572a78fd451696d03ef2ee116",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.6.0/rules_nodejs-1.6.0.tar.gz"],
sha256 = "84abf7ac4234a70924628baa9a73a5a5cbad944c4358cf9abdb4aab29c9a5b77",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.7.0/rules_nodejs-1.7.0.tar.gz"],
)
# Check the rules_nodejs version and download npm dependencies
@ -17,7 +17,7 @@ http_archive(
# assert on that.
load("@build_bazel_rules_nodejs//:index.bzl", "check_rules_nodejs_version", "node_repositories", "yarn_install")
check_rules_nodejs_version(minimum_version_string = "1.6.0")
check_rules_nodejs_version(minimum_version_string = "1.7.0")
# Setup the Node.js toolchain
node_repositories(
@ -64,7 +64,7 @@ load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories"
web_test_repositories()
load("//tools/browsers:browser_repositories.bzl", "browser_repositories")
load("//dev-infra/browsers:browser_repositories.bzl", "browser_repositories")
browser_repositories()
@ -91,17 +91,18 @@ rbe_autoconfig(
# Need to specify a base container digest in order to ensure that we can use the checked-in
# platform configurations for the "ubuntu16_04" image. Otherwise the autoconfig rule would
# need to pull the image and run it in order determine the toolchain configuration. See:
# https://github.com/bazelbuild/bazel-toolchains/blob/1.1.2/configs/ubuntu16_04_clang/versions.bzl
base_container_digest = "sha256:1ab40405810effefa0b2f45824d6d608634ccddbf06366760c341ef6fbead011",
# https://github.com/bazelbuild/bazel-toolchains/blob/3.2.0/configs/ubuntu16_04_clang/versions.bzl
base_container_digest = "sha256:5e750dd878df9fcf4e185c6f52b9826090f6e532b097f286913a428290622332",
# Note that if you change the `digest`, you might also need to update the
# `base_container_digest` to make sure marketplace.gcr.io/google/rbe-ubuntu16-04-webtest:<digest>
# and marketplace.gcr.io/google/rbe-ubuntu16-04:<base_container_digest> have
# the same Clang and JDK installed. Clang is needed because of the dependency on
# @com_google_protobuf. Java is needed for the Bazel's test executor Java tool.
digest = "sha256:0b8fa87db4b8e5366717a7164342a029d1348d2feea7ecc4b18c780bc2507059",
digest = "sha256:f743114235a43355bf8324e2ba0fa6a597236fe06f7bc99aaa9ac703631c306b",
env = clang_env(),
registry = "marketplace.gcr.io",
# We can't use the default "ubuntu16_04" RBE image provided by the autoconfig because we need
# a specific Linux kernel that comes with "libx11" in order to run headless browser tests.
repository = "google/rbe-ubuntu16-04-webtest",
use_checked_in_confs = "Force",
)

View File

@ -58,7 +58,7 @@
}
],
"styles": [
"src/styles.scss"
"src/styles/main.scss"
],
"scripts": [],
"budgets": [
@ -158,7 +158,7 @@
}
],
"styles": [
"src/styles.scss"
"src/styles/main.scss"
],
"scripts": []
}
@ -193,4 +193,4 @@
}
},
"defaultProject": "site"
}
}

View File

@ -1,6 +1,6 @@
# CLI Overview and Command Reference
The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications. You can use the tool directly in a command shell, or indirectly through an interactive UI such as [Angular Console](https://angularconsole.com).
The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications directly from a command shell.
## Installing Angular CLI
@ -109,9 +109,3 @@ Options that specify files can be given as absolute paths, or as paths relative
The [ng generate](cli/generate) and [ng add](cli/add) commands take as an argument the artifact or library to be generated or added to the current project.
In addition to any general options, each artifact or library defines its own options in a *schematic*.
Schematic options are supplied to the command in the same format as immediate command options.
### Building with Bazel
Optionally, you can configure the Angular CLI to use [Bazel](https://docs.bazel.build) as the build tool. For more information, see [Building with Bazel](guide/bazel).

View File

@ -32,15 +32,15 @@ export const slideInAnimation =
// #enddocregion style-view
// #docregion query
query(':enter', [
style({ left: '-100%'})
style({ left: '-100%' })
]),
query(':leave', animateChild()),
group([
query(':leave', [
animate('300ms ease-out', style({ left: '100%'}))
animate('300ms ease-out', style({ left: '100%' }))
]),
query(':enter', [
animate('300ms ease-out', style({ left: '0%'}))
animate('300ms ease-out', style({ left: '0%' }))
])
]),
query(':enter', animateChild()),
@ -56,15 +56,15 @@ export const slideInAnimation =
})
]),
query(':enter', [
style({ left: '-100%'})
style({ left: '-100%' })
]),
query(':leave', animateChild()),
group([
query(':leave', [
animate('200ms ease-out', style({ left: '100%'}))
animate('200ms ease-out', style({ left: '100%' }))
]),
query(':enter', [
animate('300ms ease-out', style({ left: '0%'}))
animate('300ms ease-out', style({ left: '0%' }))
])
]),
query(':enter', animateChild()),

View File

@ -17,7 +17,7 @@ Toggle All Animations <input type="checkbox" [checked]="!animationsDisabled" (cl
</nav>
<!-- #docregion route-animations-outlet -->
<div [@routeAnimations]="prepareRoute(outlet)" >
<div [@routeAnimations]="prepareRoute(outlet)">
<router-outlet #outlet="outlet"></router-outlet>
</div>
<!-- #enddocregion route-animations-outlet -->

View File

@ -3,7 +3,7 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
import { HeroFormComponent } from './hero-form/hero-form.component';
@NgModule({

View File

@ -200,13 +200,4 @@
(ngModelChange)="model.name = $event">
TODO: remove this: {{model.name}}
<!-- #enddocregion ngModel-3-->
<hr>
<!-- #docregion ngModelName-2 -->
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name"
#spy>
<br>TODO: remove this: {{spy.className}}
<!-- #enddocregion ngModelName-2 -->
</div>

View File

@ -2,7 +2,7 @@
// #docregion , v1, final
import { Component } from '@angular/core';
import { Hero } from '../hero';
import { Hero } from '../hero';
@Component({
selector: 'app-hero-form',

View File

@ -76,15 +76,15 @@ export class ConfigService {
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
// The response body may contain clues as to what went wrong.
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
// Return an observable with a user-facing error message.
return throwError(
'Something bad happened; please try again later.');
};
}
// #enddocregion handleError
makeIntentionalError() {

View File

@ -13,13 +13,13 @@ import { searchUrl } from '../package-search/package-search.service';
/**
* If request is cachable (e.g., package search) and
* If request is cacheable (e.g., package search) and
* response is in cache return the cached response as observable.
* If has 'x-refresh' header that is true,
* then also re-run the package search, using response from next(),
* returning an observable that emits the cached response first.
*
* If not in cache or not cachable,
* If not in cache or not cacheable,
* pass request through to next()
*/
// #docregion v1
@ -28,8 +28,8 @@ export class CachingInterceptor implements HttpInterceptor {
constructor(private cache: RequestCache) {}
intercept(req: HttpRequest<any>, next: HttpHandler) {
// continue if not cachable.
if (!isCachable(req)) { return next.handle(req); }
// continue if not cacheable.
if (!isCacheable(req)) { return next.handle(req); }
const cachedResponse = this.cache.get(req);
// #enddocregion v1
@ -51,11 +51,11 @@ export class CachingInterceptor implements HttpInterceptor {
// #enddocregion v1
/** Is this request cachable? */
function isCachable(req: HttpRequest<any>) {
// Only GET requests are cachable
/** Is this request cacheable? */
function isCacheable(req: HttpRequest<any>) {
// Only GET requests are cacheable
return req.method === 'GET' &&
// Only npm package search is cachable in this app
// Only npm package search is cacheable in this app
-1 < req.url.indexOf(searchUrl);
}

View File

@ -0,0 +1,12 @@
{
"description": "i18n",
"files":[
"!**/*.d.ts",
"!**/*.js",
"!**/*.[0-9].*",
"!doc-files/**/*",
"**/*.xlf"
],
"file": "src/app/app.component.ts",
"tags": ["Angular", "i18n", "internationalization"]
}

View File

@ -1,9 +0,0 @@
{
"files": [
"!dist/",
"!**/*.d.ts",
"!src/**/*.js",
"!doc-files/**/*",
"**/*.xlf"
]
}

View File

@ -6,5 +6,5 @@ import { Component } from '@angular/core';
templateUrl: './app.component.html'
})
export class AppComponent {
birthday = new Date(1988, 3, 15); // April 15, 1988
birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based
}

View File

@ -8,5 +8,5 @@ import { Component } from '@angular/core';
// #enddocregion hero-birthday-template
})
export class HeroBirthdayComponent {
birthday = new Date(1988, 3, 15); // April 15, 1988
birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based
}

View File

@ -12,7 +12,7 @@ import { Component } from '@angular/core';
})
// #docregion class
export class HeroBirthday2Component {
birthday = new Date(1988, 3, 15); // April 15, 1988
birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based
toggle = true; // start with true == shortDate
get format() { return this.toggle ? 'shortDate' : 'fullDate'; }

View File

@ -0,0 +1,7 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'any',
})
export class UserService {
}

View File

@ -6,13 +6,11 @@ import { Routes, RouterModule } from '@angular/router'; // CLI imports router
const routes: Routes = [
{ path: 'first-component', component: FirstComponent },
{ path: 'second-component', component: SecondComponent },
// #enddocregion routes
// #enddocregion routes, routes-with-wildcard
{ path: '', redirectTo: '/first-component', pathMatch: 'full' }, // redirect to `first-component`
{ path: '**', component: FirstComponent },
// #enddocregion redirect
// #docregion routes-with-wildcard
{ path: '**', component: PageNotFoundComponent }, // Wildcard route for a 404 page
// #docregion routes
// #docregion redirect
];
// #enddocregion routes, routes-with-wildcard, redirect

View File

@ -11,7 +11,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>

View File

@ -33,7 +33,7 @@ export class HeroesComponent implements OnInit {
onSelect(hero: Hero): void {
this.selectedHero = hero;
this.messageService.add(`HeroService: Selected hero id=${hero.id}`);
this.messageService.add(`HeroesComponent: Selected hero id=${hero.id}`);
}
// #docregion getHeroes

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -26,7 +26,7 @@
<script src="phone-detail/phone-detail.module.js"></script>
<script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/dist/zone.min.js"></script>
<script src="/node_modules/zone.js/bundles/zone.umd.min.js"></script>
<script>window.module = 'aot';</script>
</head>

View File

@ -3,7 +3,7 @@ var fsExtra = require('fs-extra');
var resources = [
// polyfills
'node_modules/core-js/client/shim.min.js',
'node_modules/zone.js/dist/zone.min.js',
'node_modules/zone.js/bundles/zone.umd.min.js',
// css
'app/app.css',
'app/app.animations.css',
@ -20,6 +20,7 @@ var resources = [
'app/phone-detail/phone-detail.module.js'
];
resources.map(function(sourcePath) {
var destPath = `aot/${sourcePath}`;
// Need to rename zone.umd.min.js to zone.min.js
var destPath = `aot/${sourcePath}`.replace('.umd.min.js', '.min.js');
fsExtra.copySync(sourcePath, destPath);
});

View File

@ -27,7 +27,7 @@
<!-- #docregion angular -->
<script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/dist/zone.js"></script>
<script src="/node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="/node_modules/systemjs/dist/system.src.js"></script>
<!-- #enddocregion angular -->
<script src="/systemjs.config.1.js"></script>

View File

@ -21,8 +21,8 @@ module.exports = function(config) {
'node_modules/core-js/client/shim.js',
// zone.js
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/zone-testing.js',
'node_modules/zone.js/bundles/zone.umd.js',
'node_modules/zone.js/bundles/zone-testing.umd.js',
// RxJs.
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },

View File

@ -31,8 +31,8 @@ module.exports = function(config) {
'node_modules/core-js/client/shim.js',
// zone.js
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/zone-testing.js',
'node_modules/zone.js/bundles/zone.umd.js',
'node_modules/zone.js/bundles/zone-testing.umd.js',
// RxJs
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },

View File

@ -12,7 +12,7 @@
<link rel="stylesheet" href="app.css" />
<script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/dist/zone.js"></script>
<script src="/node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="/node_modules/systemjs/dist/system.src.js"></script>
<!-- #enddocregion full -->
<script src="/systemjs.config.1.js"></script>

View File

@ -31,8 +31,8 @@ module.exports = function(config) {
'node_modules/core-js/client/shim.js',
// zone.js
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/zone-testing.js',
'node_modules/zone.js/bundles/zone.umd.js',
'node_modules/zone.js/bundles/zone-testing.umd.js',
// RxJs
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },

View File

@ -20,7 +20,7 @@ work well for all users, including those who rely on assistive technologies.
Building accessible web experience often involves setting [ARIA attributes](https://developers.google.com/web/fundamentals/accessibility/semantics-aria)
to provide semantic meaning where it might otherwise be missing.
Use [attribute binding](guide/template-syntax#attribute-binding) template syntax to control the values of accessibility-related attributes.
Use [attribute binding](guide/attribute-binding) template syntax to control the values of accessibility-related attributes.
When binding to ARIA attributes in Angular, you must use the `attr.` prefix, as the ARIA
specification depends specifically on HTML attributes rather than properties of DOM elements.
@ -44,7 +44,7 @@ NOTE:
By convention, HTML attributes use lowercase names (`tabindex`), while properties use camelCase names (`tabIndex`).
See the [Template Syntax](guide/template-syntax#html-attribute-vs-dom-property) guide for more background on the difference between attributes and properties.
See the [Binding syntax](guide/binding-syntax#html-attribute-vs-dom-property) guide for more background on the difference between attributes and properties.
</div>

View File

@ -74,8 +74,7 @@ The following table lists some of the key AngularJS template features with their
The context of the binding is implied and is always the
associated component, so it needs no reference variable.
For more information, see the [Interpolation](guide/template-syntax#interpolation)
section of the [Template Syntax](guide/template-syntax) page.
For more information, see the [Interpolation](guide/interpolation) guide.
</td>
</tr>
@ -141,8 +140,8 @@ The following table lists some of the key AngularJS template features with their
Angular has true template input variables that are explicitly defined using the `let` keyword.
For more information, see the [ngFor micro-syntax](guide/template-syntax#microsyntax)
section of the [Template Syntax](guide/template-syntax) page.
For more information, see the [ngFor micro-syntax](guide/built-in-directives#microsyntax)
section of the [Built-in Directives](guide/built-in-directives) page.
</td>
</tr>
@ -258,8 +257,7 @@ The following are some of the key AngularJS built-in directives and their equiva
Angular also has **class binding**, which is a good way to add or remove a single class,
as shown in the third example.
For more information see the [Attribute, class, and style bindings](guide/template-syntax#other-bindings)
section of the [Template Syntax](guide/template-syntax) page.
For more information see [Attribute, class, and style bindings](guide/attribute-binding) page.
</td>
@ -309,8 +307,7 @@ The following are some of the key AngularJS built-in directives and their equiva
For a list of DOM events, see: https://developer.mozilla.org/en-US/docs/Web/Events.
For more information, see the [Event binding](guide/template-syntax#event-binding)
section of the [Template Syntax](guide/template-syntax) page.
For more information, see the [Event binding](guide/event-binding) page.
</td>
@ -407,8 +404,7 @@ The following are some of the key AngularJS built-in directives and their equiva
Angular uses property binding; there is no built-in *href* directive.
Place the element's `href` property in square brackets and set it to a quoted template expression.
For more information see the [Property binding](guide/template-syntax#property-binding)
section of the [Template Syntax](guide/template-syntax) page.
For more information see the [Property binding](guide/property-binding) page.
In Angular, `href` is no longer used for routing. Routing uses `routerLink`, as shown in the following example.
@ -487,8 +483,8 @@ The following are some of the key AngularJS built-in directives and their equiva
and event binding (from the view to the component), thereby providing two-way binding.
For more information on two-way binding with `ngModel`, see the [NgModel&mdash;Two-way binding to
form elements with `[(ngModel)]`](../guide/template-syntax.html#ngModel)
section of the [Template Syntax](guide/template-syntax) page.
form elements with `[(ngModel)]`](../guide/built-in-directives#ngModel)
section of the [Built-in directives](guide/built-in-directives) page.
</td>
</tr>
@ -570,8 +566,7 @@ The following are some of the key AngularJS built-in directives and their equiva
In this example, the `<div>` element is hidden if the `favoriteHero` variable is not truthy.
For more information on property binding, see the [Property binding](guide/template-syntax#property-binding)
section of the [Template Syntax](guide/template-syntax) page.
For more information on property binding, see the [Property binding](guide/property-binding) page.
</td>
</tr>
@ -604,8 +599,7 @@ The following are some of the key AngularJS built-in directives and their equiva
Angular uses property binding; there is no built-in *src* directive.
Place the `src` property in square brackets and set it to a quoted template expression.
For more information on property binding, see the [Property binding](guide/template-syntax#property-binding)
section of the [Template Syntax](guide/template-syntax) page.
For more information on property binding, see the [Property binding](guide/property-binding) page.
</td>
</tr>
@ -644,11 +638,11 @@ The following are some of the key AngularJS built-in directives and their equiva
Angular also has **style binding**, which is good way to set a single style. This is shown in the second example.
For more information on style binding, see the [Style binding](guide/template-syntax#style-binding) section of the
[Template Syntax](guide/template-syntax) page.
For more information on style binding, see the [Style binding](guide/attribute-binding#style-binding) section of the
[Attribute binding](guide/attribute-binding) page.
For more information on the `ngStyle` directive, see [NgStyle](guide/template-syntax#ngStyle)
section of the [Template Syntax](guide/template-syntax) page.
For more information on the `ngStyle` directive, see the [NgStyle](guide/built-in-directives#ngStyle)
section of the [Built-in directives](guide/built-in-directives) page.
</td>
</tr>
@ -704,8 +698,8 @@ The following are some of the key AngularJS built-in directives and their equiva
The (*) before `ngSwitchCase` and `ngSwitchDefault` is required in this example.
For more information, see [The NgSwitch directives](guide/template-syntax#ngSwitch)
section of the [Template Syntax](guide/template-syntax) page.
For more information, see [The NgSwitch directives](guide/built-in-directives#ngSwitch)
section of the [Built-in directives](guide/built-in-directives) page.
</td>
</tr>

View File

@ -1,6 +1,6 @@
# Angular compiler options
When you use [AOT compilation](guide/aot-compiler), you can control how your application is compiled by specifying *template* compiler options in the `tsconfig.json` [TypeScript configuration file](guide/typescript-configuration).
When you use [AOT compilation](guide/aot-compiler), you can control how your application is compiled by specifying *template* compiler options in the [TypeScript configuration file](guide/typescript-configuration).
The template options object, `angularCompilerOptions`, is a sibling to the `compilerOptions` object that supplies standard options to the TypeScript compiler.
@ -21,11 +21,11 @@ The template options object, `angularCompilerOptions`, is a sibling to the `comp
{@a tsconfig-extends}
## Configuration inheritance with extends
Like the TypeScript compiler, The Angular AOT compiler also supports `extends` in the `angularCompilerOptions` section of the TypeScript configuration file, `tsconfig.json`.
Like the TypeScript compiler, The Angular AOT compiler also supports `extends` in the `angularCompilerOptions` section of the TypeScript configuration file.
The `extends` property is at the top level, parallel to `compilerOptions` and `angularCompilerOptions`.
A TypeScript configuration can inherit settings from another file using the `extends` property.
The configuration options from the base file are loaded first, then overridden by those in the inheriting `tsconfig` file.
The configuration options from the base file are loaded first, then overridden by those in the inheriting configuration file.
For example:
@ -186,7 +186,7 @@ For library projects generated with the CLI, the dev configuration default is `t
When `true` (recommended), reports an error for a supplied parameter whose injection type cannot be determined. When `false` (currently the default), constructor parameters of classes marked with `@Injectable` whose type cannot be resolved produce a warning.
When you use the CLI command `ng new`, it is set to `true` by default in the generated project's configuration.
When you use the CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
### `strictTemplates`
@ -194,6 +194,7 @@ When `true`, enables [strict template type checking](guide/template-typecheck#st
Additional strictness flags allow you to enable and disable specific types of strict template type checking. See [troubleshooting template errors](guide/template-typecheck#troubleshooting-template-errors).
When you use the CLI command `ng new --strict`, it is set to `true` in the generated project's configuration.
### `trace`

View File

@ -105,7 +105,7 @@ For help in understanding and resolving these problems, see [AOT Metadata Errors
### Configuring AOT compilation
You can provide options in the `tsconfig.json` [TypeScript configuration file](guide/typescript-configuration) that control the compilation process. See [Angular compiler options](guide/angular-compiler-options) for a complete list of available options.
You can provide options in the [TypeScript configuration file](guide/typescript-configuration) that controls the compilation process. See [Angular compiler options](guide/angular-compiler-options) for a complete list of available options.
## Phase 1: Code analysis
@ -211,7 +211,7 @@ The compiler later reports the error if it needs that piece of metadata to gener
<div class="alert is-helpful">
If you want `ngc` to report syntax errors immediately rather than produce a `.metadata.json` file with errors, set the `strictMetadataEmit` option in the TypeScript configuration file, `tsconfig.json`.
If you want `ngc` to report syntax errors immediately rather than produce a `.metadata.json` file with errors, set the `strictMetadataEmit` option in the TypeScript configuration file.
```
"angularCompilerOptions": {
@ -548,7 +548,7 @@ It does not, however, rewrite the `.d.ts` file, so TypeScript doesn't recognize
One of the Angular compiler's most helpful features is the ability to type-check expressions within templates, and catch any errors before they cause crashes at runtime.
In the template type-checking phase, the Angular template compiler uses the TypeScript compiler to validate the binding expressions in templates.
Enable this phase explicitly by adding the compiler option `"fullTemplateTypeCheck"` in the `"angularCompilerOptions"` of the project's `tsconfig.json`
Enable this phase explicitly by adding the compiler option `"fullTemplateTypeCheck"` in the `"angularCompilerOptions"` of the project's TypeScript configuration file
(see [Angular Compiler Options](guide/angular-compiler-options)).
<div class="alert is-helpful">
@ -623,7 +623,7 @@ For more information about input type narrowing, see [Input setter coercion](gui
### Non-null type assertion operator
Use the [non-null type assertion operator](guide/template-syntax#non-null-assertion-operator) to suppress the `Object is possibly 'undefined'` error when it is inconvenient to use `*ngIf` or when some constraint in the component ensures that the expression is always non-null when the binding expression is interpolated.
Use the [non-null type assertion operator](guide/template-expression-operators#non-null-assertion-operator) to suppress the `Object is possibly 'undefined'` error when it is inconvenient to use `*ngIf` or when some constraint in the component ensures that the expression is always non-null when the binding expression is interpolated.
In the following example, the `person` and `address` properties are always set together, implying that `address` is always non-null if `person` is non-null.
There is no convenient way to describe this constraint to TypeScript and the template compiler, but the error is suppressed in the example by using `address!.street`.

View File

@ -430,7 +430,7 @@ Angular does something similar with the `DOCUMENT` token so you can inject the b
```ts
import { Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
import { DOCUMENT } from '@angular/common';
@Component({ ... })
export class MyComponent {

View File

@ -1,32 +1,32 @@
# App shell
App shell is a way to render a portion of your application via a route at build time.
It can improve the user experience by quickly launching a static rendered page (a skeleton common to all pages) while the browser downloads the full client version and switches to it automatically after the code loads.
App shell es una manera de renderizar una porción de tu aplicación a través de una ruta en tiempo de compilación (build time).
Puede mejorar la experiencia de usuario lanzando rápidamente una página estática renderizada (un esqueleto común a todas las páginas) mientras el navegador descarga la versión completa del cliente y la muestra automáticamente al finalizar su carga.
This gives users a meaningful first paint of your application that appears quickly because the browser can simply render the HTML and CSS without the need to initialize any JavaScript.
Esto da a los usuarios una primera visualización significativa de su aplicación que aparece rápidamente porque el navegador simplemente puede renderizar HTML y CSS sin la necesidad de inicializar JavaScript.
Learn more in [The App Shell Model](https://developers.google.com/web/fundamentals/architecture/app-shell).
Obténga más información en [El modelo de aplicación Shell](https://developers.google.com/web/fundamentals/architecture/app-shell).
## Step 1: Prepare the application
## Paso 1: Prepara la aplicación
You can do this with the following CLI command:
Puedes hacer esto con el siguiente comando CLI:
<code-example language="bash">
ng new my-app --routing
</code-example>
For an existing application, you have to manually add the `RouterModule` and defining a `<router-outlet>` within your application.
Para una aplicación existente, debes agregar manualmente el `RouterModule` y definir un` <router-outlet> `dentro de tu aplicación.
## Step 2: Create the app shell
## Paso 2: Crea el shell de la aplicación
Use the CLI to automatically create the app shell.
Usa la CLI para crear automáticamente el shell de la aplicación.
<code-example language="bash">
ng generate app-shell
</code-example>
* `client-project` takes the name of your client application.
* `client-project` toma el nombre de tu aplicación cliente.
After running this command you will notice that the `angular.json` configuration file has been updated to add two new targets, with a few other changes.
Después de ejecutar este comando, notará que el archivo de configuración `angular.json` se ha actualizado para agregar dos nuevos targets, con algunos otros cambios.
<code-example language="json">
"server": {
@ -53,20 +53,18 @@ After running this command you will notice that the `angular.json` configuration
}
</code-example>
## Step 3: Verify the app is built with the shell content
## Paso 3: Verifica que la aplicación está construida con el contenido del shell
Use the CLI to build the `app-shell` target.
Usa la CLI para construir el `app-shell` target.
<code-example language="bash">
ng run my-app:app-shell
</code-example>
Or to use the production configuration.
O usa la configuración de producción.
<code-example language="bash">
ng run my-app:app-shell:production
</code-example>
To verify the build output, open `dist/my-app/index.html`. Look for default text `app-shell works!` to show that the app shell route was rendered as part of the output.
Para verificar el resultado de la compilación, abre `dist/my-app/index.html`. Busca el texto por defecto `app-shell works!` para mostrar que la ruta del shell de la aplicación se ha renderizado como parte de la carpeta de distribución.

View File

@ -92,7 +92,7 @@ This example from the `HeroListComponent` template uses three of these forms.
* The `{{hero.name}}` [*interpolation*](guide/displaying-data#interpolation)
displays the component's `hero.name` property value within the `<li>` element.
* The `[hero]` [*property binding*](guide/template-syntax#property-binding) passes the value of
* The `[hero]` [*property binding*](guide/property-binding) passes the value of
`selectedHero` from the parent `HeroListComponent` to the `hero` property of the child `HeroDetailComponent`.
* The `(click)` [*event binding*](guide/user-input#binding-to-user-input-events) calls the component's `selectHero` method when the user clicks a hero's name.
@ -126,7 +126,7 @@ Angular pipes let you declare display-value transformations in your template HTM
Angular defines various pipes, such as the [date](https://angular.io/api/common/DatePipe) pipe and [currency](https://angular.io/api/common/CurrencyPipe) pipe; for a complete list, see the [Pipes API list](https://angular.io/api?type=pipe). You can also define new pipes.
To specify a value transformation in an HTML template, use the [pipe operator (|)](https://angular.io/guide/template-syntax#pipe).
To specify a value transformation in an HTML template, use the [pipe operator (|)](https://angular.io/guide/template-expression-operators#pipe).
`{{interpolated_value | pipe_name}}`
@ -179,9 +179,9 @@ The `ngModel` directive, which implements two-way data binding, is an example of
<code-example path="architecture/src/app/hero-detail.component.html" header="src/app/hero-detail.component.html (ngModel)" region="ngModel"></code-example>
Angular has more pre-defined directives that either alter the layout structure
(for example, [ngSwitch](guide/template-syntax#ngSwitch))
(for example, [ngSwitch](guide/built-in-directives#ngSwitch))
or modify aspects of DOM elements and components
(for example, [ngStyle](guide/template-syntax#ngStyle) and [ngClass](guide/template-syntax#ngClass)).
(for example, [ngStyle](guide/built-in-directives#ngStyle) and [ngClass](guide/built-in-directives#ngClass)).
<div class="alert is-helpful">

View File

@ -11,7 +11,7 @@ The basic building blocks are *NgModules*, which provide a compilation context f
* Components use *services*, which provide specific functionality not directly related to views. Service providers can be *injected* into components as *dependencies*, making your code modular, reusable, and efficient.
Both components and services are simply classes, with *decorators* that mark their type and provide metadata that tells Angular how to use them.
Modules, components and services are classes that use *decorators*. These decorators mark their type and provide metadata that tells Angular how to use them.
* The metadata for a component class associates it with a *template* that defines a view. A template combines ordinary HTML with Angular *directives* and *binding markup* that allow Angular to modify the HTML before rendering it for display.

View File

@ -0,0 +1,303 @@
# Attribute, class, and style bindings
The template syntax provides specialized one-way bindings for scenarios less well-suited to property binding.
<div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide.
</div>
## Attribute binding
Set the value of an attribute directly with an **attribute binding**. This is the only exception to the rule that a binding sets a target property and the only binding that creates and sets an attribute.
Usually, setting an element property with a [property binding](guide/property-binding)
is preferable to setting the attribute with a string. However, sometimes
there is no element property to bind, so attribute binding is the solution.
Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). They are purely attributes, don't correspond to element properties, and don't set element properties. In these cases, there are no property targets to bind to.
Attribute binding syntax resembles property binding, but
instead of an element property between brackets, start with the prefix `attr`,
followed by a dot (`.`), and the name of the attribute.
You then set the attribute value, using an expression that resolves to a string,
or remove the attribute when the expression resolves to `null`.
One of the primary use cases for attribute binding
is to set ARIA attributes, as in this example:
<code-example path="attribute-binding/src/app/app.component.html" region="attrib-binding-aria" header="src/app/app.component.html"></code-example>
{@a colspan}
<div class="alert is-helpful">
#### `colspan` and `colSpan`
Notice the difference between the `colspan` attribute and the `colSpan` property.
If you wrote something like this:
<code-example language="html">
&lt;tr&gt;&lt;td colspan="{{1 + 1}}"&gt;Three-Four&lt;/td&gt;&lt;/tr&gt;
</code-example>
You'd get this error:
<code-example language="bash">
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
</code-example>
As the message says, the `<td>` element does not have a `colspan` property. This is true
because `colspan` is an attribute&mdash;`colSpan`, with a capital `S`, is the
corresponding property. Interpolation and property binding can set only *properties*, not attributes.
Instead, you'd use property binding and write it like this:
<code-example path="attribute-binding/src/app/app.component.html" region="colSpan" header="src/app/app.component.html"></code-example>
</div>
<hr/>
{@a class-binding}
## Class binding
Here's how to set the `class` attribute without a binding in plain HTML:
```html
<!-- standard class attribute setting -->
<div class="foo bar">Some text</div>
```
You can also add and remove CSS class names from an element's `class` attribute with a **class binding**.
To create a single class binding, start with the prefix `class` followed by a dot (`.`) and the name of the CSS class (for example, `[class.foo]="hasFoo"`).
Angular adds the class when the bound expression is truthy, and it removes the class when the expression is falsy (with the exception of `undefined`, see [styling delegation](#styling-delegation)).
To create a binding to multiple classes, use a generic `[class]` binding without the dot (for example, `[class]="classExpr"`).
The expression can be a space-delimited string of class names, or you can format it as an object with class names as the keys and truthy/falsy expressions as the values.
With object format, Angular will add a class only if its associated value is truthy.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
If there are multiple bindings to the same class name, conflicts are resolved using [styling precedence](#styling-precedence).
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="15%">
</col>
<col width="20%">
</col>
<col width="35%">
</col>
<col width="30%">
</col>
<tr>
<th>
Binding Type
</th>
<th>
Syntax
</th>
<th>
Input Type
</th>
<th>
Example Input Values
</th>
</tr>
<tr>
<td>Single class binding</td>
<td><code>[class.foo]="hasFoo"</code></td>
<td><code>boolean | undefined | null</code></td>
<td><code>true</code>, <code>false</code></td>
</tr>
<tr>
<td rowspan=3>Multi-class binding</td>
<td rowspan=3><code>[class]="classExpr"</code></td>
<td><code>string</code></td>
<td><code>"my-class-1 my-class-2 my-class-3"</code></td>
</tr>
<tr>
<td><code>{[key: string]: boolean | undefined | null}</code></td>
<td><code>{foo: true, bar: false}</code></td>
</tr>
<tr>
<td><code>Array</code><<code>string</code>></td>
<td><code>['foo', 'bar']</code></td>
</tr>
</table>
The [NgClass](guide/built-in-directives/#ngclass) directive can be used as an alternative to direct `[class]` bindings.
However, using the above class binding syntax without `NgClass` is preferred because due to improvements in class binding in Angular, `NgClass` no longer provides significant value, and might eventually be removed in the future.
<hr/>
## Style binding
Here's how to set the `style` attribute without a binding in plain HTML:
```html
<!-- standard style attribute setting -->
<div style="color: blue">Some text</div>
```
You can also set styles dynamically with a **style binding**.
To create a single style binding, start with the prefix `style` followed by a dot (`.`) and the name of the CSS style property (for example, `[style.width]="width"`).
The property will be set to the value of the bound expression, which is normally a string.
Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
<div class="alert is-helpful">
Note that a _style property_ name can be written in either
[dash-case](guide/glossary#dash-case), as shown above, or
[camelCase](guide/glossary#camelcase), such as `fontSize`.
</div>
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly without the dot (for example, `[style]="styleExpr"`).
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`.
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
If there are multiple bindings to the same style property, conflicts are resolved using [styling precedence rules](#styling-precedence).
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="15%">
</col>
<col width="20%">
</col>
<col width="35%">
</col>
<col width="30%">
</col>
<tr>
<th>
Binding Type
</th>
<th>
Syntax
</th>
<th>
Input Type
</th>
<th>
Example Input Values
</th>
</tr>
<tr>
<td>Single style binding</td>
<td><code>[style.width]="width"</code></td>
<td><code>string | undefined | null</code></td>
<td><code>"100px"</code></td>
</tr>
<tr>
<tr>
<td>Single style binding with units</td>
<td><code>[style.width.px]="width"</code></td>
<td><code>number | undefined | null</code></td>
<td><code>100</code></td>
</tr>
<tr>
<td rowspan=3>Multi-style binding</td>
<td rowspan=3><code>[style]="styleExpr"</code></td>
<td><code>string</code></td>
<td><code>"width: 100px; height: 100px"</code></td>
</tr>
<tr>
<td><code>{[key: string]: string | undefined | null}</code></td>
<td><code>{width: '100px', height: '100px'}</code></td>
</tr>
<tr>
<td><code>Array</code><<code>string</code>></td>
<td><code>['width', '100px']</code></td>
</tr>
</table>
The [NgStyle](guide/built-in-directives/#ngstyle) directive can be used as an alternative to direct `[style]` bindings.
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
<hr/>
{@a styling-precedence}
## Styling Precedence
A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives).
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element.
<div class="alert is-helpful">
<h4>Styling precedence (highest to lowest)</h4>
1. Template bindings
1. Property binding (for example, `<div [class.foo]="hasFoo">` or `<div [style.color]="color">`)
1. Map binding (for example, `<div [class]="classExpr">` or `<div [style]="styleExpr">`)
1. Static value (for example, `<div class="foo">` or `<div style="color: blue">`)
1. Directive host bindings
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
1. Component host bindings
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
</div>
The more specific a class or style binding is, the higher its precedence.
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding.
<code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
Specificity rules also apply when it comes to bindings that originate from different sources.
It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components.
Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings.
Directives often augment component behavior, so host bindings from components have the lowest precedence.
<code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
In addition, bindings take precedence over static attributes.
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic.
<code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
{@a styling-delegation}
### Delegating to styles with lower precedence
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values.
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style.
For example, consider the following template:
<code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding.
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.

View File

@ -18,12 +18,12 @@ There are three kinds of directives in Angular:
You saw a component for the first time in the [Getting Started](start "Getting Started with Angular") tutorial.
*Structural Directives* change the structure of the view.
Two examples are [NgFor](guide/template-syntax#ngFor) and [NgIf](guide/template-syntax#ngIf).
Two examples are [NgFor](guide/built-in-directives#ngFor) and [NgIf](guide/built-in-directives#ngIf).
Learn about them in the [Structural Directives](guide/structural-directives) guide.
*Attribute directives* are used as attributes of elements.
The built-in [NgStyle](guide/template-syntax#ngStyle) directive in the
[Template Syntax](guide/template-syntax) guide, for example,
The built-in [NgStyle](guide/built-in-directives#ngStyle) directive in the
[Built-in directives](guide/built-in-directives) guide, for example,
can change several element styles at the same time.
## Build a simple attribute directive

View File

@ -1,122 +0,0 @@
# Building with Bazel
This guide explains how to build and test Angular apps with Bazel.
<div class="alert is-helpful">
This guide assumes you are already familiar with developing and building Angular applications using the [CLI](cli).
It describes features which are part of Angular Labs, and are not considered a stable, supported API.
</div>
## Using Bazel with the Angular CLI
The `@angular/bazel` package provides a builder that allows Angular CLI to use Bazel as the build tool.
To opt-in an existing application, run
```sh
ng add @angular/bazel
```
To use Bazel in a new application, first install `@angular/bazel` globally
```sh
npm install -g @angular/bazel
```
then create the new application with
```sh
ng new --collection=@angular/bazel
```
Now when you use Angular CLI build commands such as `ng build` and `ng serve`,
Bazel is used behind the scenes.
Outputs from Bazel appear in the `dist/bin` folder.
> The command-line output includes extra logging from Bazel.
> We plan to reduce this in the future.
### Removing Bazel
If you need to opt-out from using Bazel, you can restore the backup files:
- `/angular.json.bak` replaces `/angular.json`
## Advanced configuration
<div class="alert is-helpful">
Editing the Bazel configuration may prevent you opting out of Bazel.
Custom behaviors driven by Bazel won't be available in other Builders.
This section assumes you are familiar with [Bazel](https://docs.bazel.build).
</div>
You can manually adjust the Bazel configuration to:
* customize the build steps
* parallellize the build for scale and incrementality
Create the initial Bazel configuration files by running the following command:
```sh
ng build --leaveBazelFilesOnDisk
```
Now you'll find new files in the Angular workspace:
* `/WORKSPACE` tells Bazel how to download external dependencies.
* `/BUILD.bazel` and `/src/BUILD.bazel` tell Bazel about your source code.
You can find a full-featured example with custom Bazel configurations at https://github.com/bazelbuild/rules_nodejs/tree/master/examples/angular.
Documentation for using Bazel for frontend projects is linked from https://docs.bazel.build/versions/master/bazel-and-javascript.html.
## Running Bazel directly
In some cases you'll want to bypass the Angular CLI builder, and run the Bazel CLI directly.
The Bazel tool is managed by the `@bazel/bazelisk` package (similar to how Node.js can be managed by `nvm`).
You can install it globally to get the `bazelisk` command in your path, or use `$(npm bin)/bazelisk` in place of bazelisk below.
The common commands in Bazel are:
* `bazelisk build [targets]`: Compile the default output artifacts of the given targets.
* `bazelisk test [targets]`: For whichever `*_test` targets are found in the patterns, run the tests.
* `bazelisk run [target]`: Compile the program represented by target, and then run it.
To repeat the command any time the inputs change (watch mode), replace `bazelisk` with `ibazel` in these commands.
The output locations are printed in the output.
Full documentation for the Bazel CLI is at https://docs.bazel.build/versions/master/command-line-reference.html.
## Querying the build graph
Because Bazel constructs a graph out of your targets, you can find lots of useful information.
Using the graphviz optional dependency, you'll have a program `dot`, which you can use with `bazel query`:
```bash
$ bazel query --output=graph ... | dot -Tpng > graph.png
```
See https://docs.bazel.build/versions/master/query-how-to.html for more details on `bazel query`.
## Customizing `BUILD.bazel` files
"Rules" are like plugins for Bazel. Many rule sets are available. This guide documents the ones maintained by the Angular team at Google.
Rules are used in `BUILD.bazel` files, which are markers for the packages in your workspace. Each `BUILD.bazel` file declares a separate package to Bazel, though you can have more coarse-grained distributions so that the packages you publish (for example, to `npm`) can be made up of many Bazel packages.
In the `BUILD.bazel` file, each rule must first be imported, using the `load` statement. Then the rule is called with some attributes, and the result of calling the rule is that you've declared to Bazel how it can derive some outputs given some inputs and dependencies. Then later, when you run a `bazel` command line, Bazel loads all the rules you've declared to determine an absolute ordering of what needs to be run. Note that only the rules needed to produce the requested output will actually be executed.
A list of common rules for frontend development is documented in the README at https://github.com/bazelbuild/rules_nodejs/.

View File

@ -0,0 +1,318 @@
# Binding syntax: an overview
Data-binding is a mechanism for coordinating what users see, specifically
with application data values.
While you could push values to and pull values from HTML,
the application is easier to write, read, and maintain if you turn these tasks over to a binding framework.
You simply declare bindings between binding sources, target HTML elements, and let the framework do the rest.
<div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide.
</div>
Angular provides many kinds of data-binding. Binding types can be grouped into three categories distinguished by the direction of data flow:
* From the _source-to-view_
* From _view-to-source_
* Two-way sequence: _view-to-source-to-view_
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="30%">
</col>
<col width="50%">
</col>
<col width="20%">
</col>
<tr>
<th>
Type
</th>
<th>
Syntax
</th>
<th>
Category
</th>
</tr>
<tr>
<td>
Interpolation<br>
Property<br>
Attribute<br>
Class<br>
Style
</td>
<td>
<code-example>
{{expression}}
[target]="expression"
bind-target="expression"
</code-example>
</td>
<td>
One-way<br>from data source<br>to view target
</td>
<tr>
<td>
Event
</td>
<td>
<code-example>
(target)="statement"
on-target="statement"
</code-example>
</td>
<td>
One-way<br>from view target<br>to data source
</td>
</tr>
<tr>
<td>
Two-way
</td>
<td>
<code-example>
[(target)]="expression"
bindon-target="expression"
</code-example>
</td>
<td>
Two-way
</td>
</tr>
</tr>
</table>
Binding types other than interpolation have a **target name** to the left of the equal sign, either surrounded by punctuation, `[]` or `()`,
or preceded by a prefix: `bind-`, `on-`, `bindon-`.
The *target* of a binding is the property or event inside the binding punctuation: `[]`, `()` or `[()]`.
Every public member of a **source** directive is automatically available for binding.
You don't have to do anything special to access a directive member in a template expression or statement.
### Data-binding and HTML
In the normal course of HTML development, you create a visual structure with HTML elements, and
you modify those elements by setting element attributes with string constants.
```html
<div class="special">Plain old HTML</div>
<img src="images/item.png">
<button disabled>Save</button>
```
With data-binding, you can control things like the state of a button:
<code-example path="binding-syntax/src/app/app.component.html" region="disabled-button" header="src/app/app.component.html"></code-example>
Notice that the binding is to the `disabled` property of the button's DOM element,
**not** the attribute. This applies to data-binding in general. Data-binding works with *properties* of DOM elements, components, and directives, not HTML *attributes*.
{@a html-attribute-vs-dom-property}
### HTML attribute vs. DOM property
The distinction between an HTML attribute and a DOM property is key to understanding
how Angular binding works. **Attributes are defined by HTML. Properties are accessed from DOM (Document Object Model) nodes.**
* A few HTML attributes have 1:1 mapping to properties; for example, `id`.
* Some HTML attributes don't have corresponding properties; for example, `aria-*`.
* Some DOM properties don't have corresponding attributes; for example, `textContent`.
It is important to remember that *HTML attribute* and the *DOM property* are different things, even when they have the same name.
In Angular, the only role of HTML attributes is to initialize element and directive state.
**Template binding works with *properties* and *events*, not *attributes*.**
When you write a data-binding, you're dealing exclusively with the *DOM properties* and *events* of the target object.
<div class="alert is-helpful">
This general rule can help you build a mental model of attributes and DOM properties:
**Attributes initialize DOM properties and then they are done.
Property values can change; attribute values can't.**
There is one exception to this rule.
Attributes can be changed by `setAttribute()`, which re-initializes corresponding DOM properties.
</div>
For more information, see the [MDN Interfaces documentation](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces) which has API docs for all the standard DOM elements and their properties.
Comparing the [`<td>` attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) attributes to the [`<td>` properties](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) provides a helpful example for differentiation.
In particular, you can navigate from the attributes page to the properties via "DOM interface" link, and navigate the inheritance hierarchy up to `HTMLTableCellElement`.
#### Example 1: an `<input>`
When the browser renders `<input type="text" value="Sarah">`, it creates a
corresponding DOM node with a `value` property initialized to "Sarah".
```html
<input type="text" value="Sarah">
```
When the user enters "Sally" into the `<input>`, the DOM element `value` *property* becomes "Sally".
However, if you look at the HTML attribute `value` using `input.getAttribute('value')`, you can see that the *attribute* remains unchanged&mdash;it returns "Sarah".
The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value.
To see attributes versus DOM properties in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax.
#### Example 2: a disabled button
The `disabled` attribute is another example. A button's `disabled`
*property* is `false` by default so the button is enabled.
When you add the `disabled` *attribute*, its presence alone
initializes the button's `disabled` *property* to `true`
so the button is disabled.
```html
<button disabled>Test Button</button>
```
Adding and removing the `disabled` *attribute* disables and enables the button.
However, the value of the *attribute* is irrelevant,
which is why you cannot enable a button by writing `<button disabled="false">Still Disabled</button>`.
To control the state of the button, set the `disabled` *property*,
<div class="alert is-helpful">
Though you could technically set the `[attr.disabled]` attribute binding, the values are different in that the property binding requires to a boolean value, while its corresponding attribute binding relies on whether the value is `null` or not. Consider the following:
```html
<input [disabled]="condition ? true : false">
<input [attr.disabled]="condition ? 'disabled' : null">
```
Generally, use property binding over attribute binding as it is more intuitive (being a boolean value), has a shorter syntax, and is more performant.
</div>
To see the `disabled` button example in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax. This example shows you how to toggle the disabled property from the component.
## Binding types and targets
The **target of a data-binding** is something in the DOM.
Depending on the binding type, the target can be a property (element, component, or directive),
an event (element, component, or directive), or sometimes an attribute name.
The following table summarizes the targets for the different binding types.
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="10%">
</col>
<col width="15%">
</col>
<col width="75%">
</col>
<tr>
<th>
Type
</th>
<th>
Target
</th>
<th>
Examples
</th>
</tr>
<tr>
<td>
Property
</td>
<td>
Element&nbsp;property<br>
Component&nbsp;property<br>
Directive&nbsp;property
</td>
<td>
<code>src</code>, <code>hero</code>, and <code>ngClass</code> in the following:
<code-example path="template-syntax/src/app/app.component.html" region="property-binding-syntax-1"></code-example>
<!-- For more information, see [Property Binding](guide/property-binding). -->
</td>
</tr>
<tr>
<td>
Event
</td>
<td>
Element&nbsp;event<br>
Component&nbsp;event<br>
Directive&nbsp;event
</td>
<td>
<code>click</code>, <code>deleteRequest</code>, and <code>myClick</code> in the following:
<code-example path="template-syntax/src/app/app.component.html" region="event-binding-syntax-1"></code-example>
<!-- KW--Why don't these links work in the table? -->
<!-- <div>For more information, see [Event Binding](guide/event-binding).</div> -->
</td>
</tr>
<tr>
<td>
Two-way
</td>
<td>
Event and property
</td>
<td>
<code-example path="template-syntax/src/app/app.component.html" region="2-way-binding-syntax-1"></code-example>
</td>
</tr>
<tr>
<td>
Attribute
</td>
<td>
Attribute
(the&nbsp;exception)
</td>
<td>
<code-example path="template-syntax/src/app/app.component.html" region="attribute-binding-syntax-1"></code-example>
</td>
</tr>
<tr>
<td>
Class
</td>
<td>
<code>class</code> property
</td>
<td>
<code-example path="template-syntax/src/app/app.component.html" region="class-binding-syntax-1"></code-example>
</td>
</tr>
<tr>
<td>
Style
</td>
<td>
<code>style</code> property
</td>
<td>
<code-example path="template-syntax/src/app/app.component.html" region="style-binding-syntax-1"></code-example>
</td>
</tr>
</table>

View File

@ -54,16 +54,17 @@ Angular supports most recent browsers. This includes the following specific vers
</td>
<td>
<div> 11, 10*, 9* ("compatibility view" mode not supported) </div>
<div>*deprecated in v10, see the <a href="/guide/deprecations#ie-9-10">deprecations guide</a>.</div>
<div>*deprecated in v10, see the {@link guide/deprecations#ie-9-10-and-mobile deprecations guide}.</div>
</td>
</tr>
<tr>
<tr>
<td>
IE Mobile
IE Mobile*
</td>
<td>
11
<div>*deprecated in v10, see the {@link guide/deprecations#ie-9-10-and-mobile deprecations guide}.</div>
</td>
</tr>
<tr>
@ -525,7 +526,7 @@ For example:
// __Zone_enable_cross_context_check = true;
&lt;/script>
&lt;!-- zone.js required by Angular -->
&lt;script src="node_modules/zone.js/dist/zone.js">&lt;/script>
&lt;script src="node_modules/zone.js/bundles/zone.umd.js">&lt;/script>
&lt;!-- application polyfills -->
</code-example>

View File

@ -262,6 +262,33 @@ Each budget entry is a JSON object with the following properties:
</table>
{@a commonjs }
## Configuring CommonJS dependencies
<div class="alert is-important">
It is recommended that you avoid depending on CommonJS modules in your Angular applications.
Depending on CommonJS modules can prevent bundlers and minifiers from optimizing your application, which results in larger bundle sizes.
Instead, it is recommended that you use [ECMAScript modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) in your entire application.
For more information, see [How CommonJS is making your bundles larger](https://web.dev/commonjs-larger-bundles/).
</div>
The Angular CLI outputs warnings if it detects that your browser application depends on CommonJS modules.
To disable these warnings, you can add the CommonJS module name to `allowedCommonJsDependencies` option in the `build` options located in `angular.json` file.
<code-example lang="json">
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"allowedCommonJsDependencies": [
"lodash"
]
...
}
...
},
</code-example>
{@a browser-compat}

View File

@ -0,0 +1,435 @@
# Built-in directives
Angular offers two kinds of built-in directives: [_attribute_ directives](guide/attribute-directives) and [_structural_ directives](guide/structural-directives).
<div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide.
</div>
For more detail, including how to build your own custom directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives).
<hr/>
{@a attribute-directives}
## Built-in attribute directives
Attribute directives listen to and modify the behavior of
other HTML elements, attributes, properties, and components.
You usually apply them to elements as if they were HTML attributes, hence the name.
Many NgModules such as the [`RouterModule`](guide/router "Routing and Navigation")
and the [`FormsModule`](guide/forms "Forms") define their own attribute directives.
The most common attribute directives are as follows:
* [`NgClass`](guide/built-in-directives#ngClass)&mdash;adds and removes a set of CSS classes.
* [`NgStyle`](guide/built-in-directives#ngStyle)&mdash;adds and removes a set of HTML styles.
* [`NgModel`](guide/built-in-directives#ngModel)&mdash;adds two-way data binding to an HTML form element.
<hr/>
{@a ngClass}
## `NgClass`
Add or remove several CSS classes simultaneously with `ngClass`.
<code-example path="built-in-directives/src/app/app.component.html" region="special-div" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
To add or remove a *single* class, use [class binding](guide/attribute-binding#class-binding) rather than `NgClass`.
</div>
Consider a `setCurrentClasses()` component method that sets a component property,
`currentClasses`, with an object that adds or removes three classes based on the
`true`/`false` state of three other component properties. Each key of the object is a CSS class name; its value is `true` if the class should be added,
`false` if it should be removed.
<code-example path="built-in-directives/src/app/app.component.ts" region="setClasses" header="src/app/app.component.ts"></code-example>
Adding an `ngClass` property binding to `currentClasses` sets the element's classes accordingly:
<code-example path="built-in-directives/src/app/app.component.html" region="NgClass-1" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
Remember that in this situation you'd call `setCurrentClasses()`,
both initially and when the dependent properties change.
</div>
<hr/>
{@a ngStyle}
## `NgStyle`
Use `NgStyle` to set many inline styles simultaneously and dynamically, based on the state of the component.
### Without `NgStyle`
For context, consider setting a *single* style value with [style binding](guide/attribute-binding#style-binding), without `NgStyle`.
<code-example path="built-in-directives/src/app/app.component.html" region="without-ng-style" header="src/app/app.component.html"></code-example>
However, to set *many* inline styles at the same time, use the `NgStyle` directive.
The following is a `setCurrentStyles()` method that sets a component
property, `currentStyles`, with an object that defines three styles,
based on the state of three other component properties:
<code-example path="built-in-directives/src/app/app.component.ts" region="setStyles" header="src/app/app.component.ts"></code-example>
Adding an `ngStyle` property binding to `currentStyles` sets the element's styles accordingly:
<code-example path="built-in-directives/src/app/app.component.html" region="NgStyle-2" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
Remember to call `setCurrentStyles()`, both initially and when the dependent properties change.
</div>
<hr/>
{@a ngModel}
## `[(ngModel)]`: Two-way binding
The `NgModel` directive allows you to display a data property and
update that property when the user makes changes. Here's an example:
<code-example path="built-in-directives/src/app/app.component.html" header="src/app/app.component.html (NgModel example)" region="NgModel-1"></code-example>
### Import `FormsModule` to use `ngModel`
Before using the `ngModel` directive in a two-way data binding,
you must import the `FormsModule` and add it to the NgModule's `imports` list.
Learn more about the `FormsModule` and `ngModel` in [Forms](guide/forms#ngModel).
Remember to import the `FormsModule` to make `[(ngModel)]` available as follows:
<code-example path="built-in-directives/src/app/app.module.ts" header="src/app/app.module.ts (FormsModule import)" region="import-forms-module"></code-example>
You could achieve the same result with separate bindings to
the `<input>` element's `value` property and `input` event:
<code-example path="built-in-directives/src/app/app.component.html" region="without-NgModel" header="src/app/app.component.html"></code-example>
To streamline the syntax, the `ngModel` directive hides the details behind its own `ngModel` input and `ngModelChange` output properties:
<code-example path="built-in-directives/src/app/app.component.html" region="NgModelChange" header="src/app/app.component.html"></code-example>
The `ngModel` data property sets the element's value property and the `ngModelChange` event property
listens for changes to the element's value.
### `NgModel` and value accessors
The details are specific to each kind of element and therefore the `NgModel` directive only works for an element
supported by a [ControlValueAccessor](api/forms/ControlValueAccessor)
that adapts an element to this protocol.
Angular provides *value accessors* for all of the basic HTML form elements and the
[Forms](guide/forms) guide shows how to bind to them.
You can't apply `[(ngModel)]` to a non-form native element or a
third-party custom component until you write a suitable value accessor. For more information, see
the API documentation on [DefaultValueAccessor](https://angular.io/api/forms/DefaultValueAccessor).
You don't need a value accessor for an Angular component that
you write because you can name the value and event properties
to suit Angular's basic [two-way binding syntax](guide/two-way-binding)
and skip `NgModel` altogether.
The `sizer` in the
[Two-way Binding](guide/two-way-binding) section is an example of this technique.
Separate `ngModel` bindings are an improvement over binding to the
element's native properties, but you can streamline the binding with a
single declaration using the `[(ngModel)]` syntax:
<code-example path="built-in-directives/src/app/app.component.html" region="NgModel-1" header="src/app/app.component.html"></code-example>
This `[(ngModel)]` syntax can only _set_ a data-bound property.
If you need to do something more, you can write the expanded form;
for example, the following changes the `<input>` value to uppercase:
<code-example path="built-in-directives/src/app/app.component.html" region="uppercase" header="src/app/app.component.html"></code-example>
Here are all variations in action, including the uppercase version:
<div class="lightbox">
<img src='generated/images/guide/built-in-directives/ng-model-anim.gif' alt="NgModel variations">
</div>
<hr/>
{@a structural-directives}
## Built-in _structural_ directives
Structural directives are responsible for HTML layout.
They shape or reshape the DOM's structure, typically by adding, removing, and manipulating
the host elements to which they are attached.
This section is an introduction to the common built-in structural directives:
* [`NgIf`](guide/built-in-directives#ngIf)&mdash;conditionally creates or destroys subviews from the template.
* [`NgFor`](guide/built-in-directives#ngFor)&mdash;repeat a node for each item in a list.
* [`NgSwitch`](guide/built-in-directives#ngSwitch)&mdash;a set of directives that switch among alternative views.
<div class="alert is-helpful">
The deep details of structural directives are covered in the
[Structural Directives](guide/structural-directives) guide,
which explains the following:
* Why you
[prefix the directive name with an asterisk (\*)](guide/structural-directives#the-asterisk--prefix).
* Using [`<ng-container>`](guide/structural-directives#ngcontainer "<ng-container>")
to group elements when there is no suitable host element for the directive.
* How to write your own structural directive.
* That you can only apply [one structural directive](guide/structural-directives#one-per-element "one per host element") to an element.
</div>
<hr/>
{@a ngIf}
## NgIf
You can add or remove an element from the DOM by applying an `NgIf` directive to
a host element.
Bind the directive to a condition expression like `isActive` in this example.
<code-example path="built-in-directives/src/app/app.component.html" region="NgIf-1" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
Don't forget the asterisk (`*`) in front of `ngIf`. For more information
on the asterisk, see the [asterisk (*) prefix](guide/structural-directives#the-asterisk--prefix) section of
[Structural Directives](guide/structural-directives).
</div>
When the `isActive` expression returns a truthy value, `NgIf` adds the
`ItemDetailComponent` to the DOM.
When the expression is falsy, `NgIf` removes the `ItemDetailComponent`
from the DOM, destroying that component and all of its sub-components.
### Show/hide vs. `NgIf`
Hiding an element is different from removing it with `NgIf`.
For comparison, the following example shows how to control
the visibility of an element with a
[class](guide/attribute-binding#class-binding) or [style](guide/attribute-binding#style-binding) binding.
<code-example path="built-in-directives/src/app/app.component.html" region="NgIf-3" header="src/app/app.component.html"></code-example>
When you hide an element, that element and all of its descendants remain in the DOM.
All components for those elements stay in memory and
Angular may continue to check for changes.
You could be holding onto considerable computing resources and degrading performance
unnecessarily.
`NgIf` works differently. When `NgIf` is `false`, Angular removes the element and its descendants from the DOM.
It destroys their components, freeing up resources, which
results in a better user experience.
If you are hiding large component trees, consider `NgIf` as a more
efficient alternative to showing/hiding.
<div class="alert is-helpful">
For more information on `NgIf` and `ngIfElse`, see the [API documentation about NgIf](api/common/NgIf).
</div>
### Guard against null
Another advantage of `ngIf` is that you can use it to guard against null. Show/hide
is best suited for very simple use cases, so when you need a guard, opt instead for `ngIf`. Angular will throw an error if a nested expression tries to access a property of `null`.
The following shows `NgIf` guarding two `<div>`s.
The `currentCustomer` name appears only when there is a `currentCustomer`.
The `nullCustomer` will not be displayed as long as it is `null`.
<code-example path="built-in-directives/src/app/app.component.html" region="NgIf-2" header="src/app/app.component.html"></code-example>
<code-example path="built-in-directives/src/app/app.component.html" region="NgIf-2b" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
See also the
[safe navigation operator](guide/template-expression-operators#safe-navigation-operator "Safe navigation operator (?.)") below.
</div>
<hr/>
{@a ngFor}
## `NgFor`
`NgFor` is a repeater directive&mdash;a way to present a list of items.
You define a block of HTML that defines how a single item should be displayed
and then you tell Angular to use that block as a template for rendering each item in the list.
The text assigned to `*ngFor` is the instruction that guides the repeater process.
The following example shows `NgFor` applied to a simple `<div>`. (Don't forget the asterisk (`*`) in front of `ngFor`.)
<code-example path="built-in-directives/src/app/app.component.html" region="NgFor-1" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
Don't forget the asterisk (`*`) in front of `ngFor`. For more information
on the asterisk, see the [asterisk (*) prefix](guide/structural-directives#the-asterisk--prefix) section of
[Structural Directives](guide/structural-directives).
</div>
You can also apply an `NgFor` to a component element, as in the following example.
<code-example path="built-in-directives/src/app/app.component.html" region="NgFor-2" header="src/app/app.component.html"></code-example>
{@a microsyntax}
<div class="callout is-critical">
<header>*ngFor microsyntax</header>
The string assigned to `*ngFor` is not a [template expression](guide/interpolation). Rather,
it's a *microsyntax*&mdash;a little language of its own that Angular interprets.
The string `"let item of items"` means:
> *Take each item in the `items` array, store it in the local `item` looping variable, and
make it available to the templated HTML for each iteration.*
Angular translates this instruction into an `<ng-template>` around the host element,
then uses this template repeatedly to create a new set of elements and bindings for each `item`
in the list.
For more information about microsyntax, see the [Structural Directives](guide/structural-directives#microsyntax) guide.
</div>
{@a template-input-variable}
{@a template-input-variables}
### Template input variables
The `let` keyword before `item` creates a template input variable called `item`.
The `ngFor` directive iterates over the `items` array returned by the parent component's `items` property
and sets `item` to the current item from the array during each iteration.
Reference `item` within the `ngFor` host element
as well as within its descendants to access the item's properties.
The following example references `item` first in an interpolation
and then passes in a binding to the `item` property of the `<app-item-detail>` component.
<code-example path="built-in-directives/src/app/app.component.html" region="NgFor-1-2" header="src/app/app.component.html"></code-example>
For more information about template input variables, see
[Structural Directives](guide/structural-directives#template-input-variable).
### `*ngFor` with `index`
The `index` property of the `NgFor` directive context
returns the zero-based index of the item in each iteration.
You can capture the `index` in a template input variable and use it in the template.
The next example captures the `index` in a variable named `i` and displays it with the item name.
<code-example path="built-in-directives/src/app/app.component.html" region="NgFor-3" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
`NgFor` is implemented by the `NgForOf` directive. Read more about the other `NgForOf` context values such as `last`, `even`,
and `odd` in the [NgForOf API reference](api/common/NgForOf).
</div>
{@a trackBy}
### *ngFor with `trackBy`
If you use `NgFor` with large lists, a small change to one item, such as removing or adding an item, can trigger a cascade of DOM manipulations. For example, re-querying the server could reset a list with all new item objects, even when those items were previously displayed. In this case, Angular sees only a fresh list of new object references and has no choice but to replace the old DOM elements with all new DOM elements.
You can make this more efficient with `trackBy`.
Add a method to the component that returns the value `NgFor` should track.
In this case, that value is the hero's `id`. If the `id` has already been rendered,
Angular keeps track of it and doesn't re-query the server for the same `id`.
<code-example path="built-in-directives/src/app/app.component.ts" region="trackByItems" header="src/app/app.component.ts"></code-example>
In the microsyntax expression, set `trackBy` to the `trackByItems()` method.
<code-example path="built-in-directives/src/app/app.component.html" region="trackBy" header="src/app/app.component.html"></code-example>
Here is an illustration of the `trackBy` effect.
"Reset items" creates new items with the same `item.id`s.
"Change ids" creates new items with new `item.id`s.
* With no `trackBy`, both buttons trigger complete DOM element replacement.
* With `trackBy`, only changing the `id` triggers element replacement.
<div class="lightbox">
<img src="generated/images/guide/built-in-directives/ngfor-trackby.gif" alt="Animation of trackBy">
</div>
<div class="alert is-helpful">
Built-in directives use only public APIs; that is,
they do not have special access to any private APIs that other directives can't access.
</div>
<hr/>
{@a ngSwitch}
## The `NgSwitch` directives
NgSwitch is like the JavaScript `switch` statement.
It displays one element from among several possible elements, based on a switch condition.
Angular puts only the selected element into the DOM.
<!-- API Flagged -->
`NgSwitch` is actually a set of three, cooperating directives:
`NgSwitch`, `NgSwitchCase`, and `NgSwitchDefault` as in the following example.
<code-example path="built-in-directives/src/app/app.component.html" region="NgSwitch" header="src/app/app.component.html"></code-example>
<div class="lightbox">
<img src="generated/images/guide/built-in-directives/ngswitch.gif" alt="Animation of NgSwitch">
</div>
`NgSwitch` is the controller directive. Bind it to an expression that returns
the *switch value*, such as `feature`. Though the `feature` value in this
example is a string, the switch value can be of any type.
**Bind to `[ngSwitch]`**. You'll get an error if you try to set `*ngSwitch` because
`NgSwitch` is an *attribute* directive, not a *structural* directive.
Rather than touching the DOM directly, it changes the behavior of its companion directives.
**Bind to `*ngSwitchCase` and `*ngSwitchDefault`**.
The `NgSwitchCase` and `NgSwitchDefault` directives are _structural_ directives
because they add or remove elements from the DOM.
* `NgSwitchCase` adds its element to the DOM when its bound value equals the switch value and removes
its bound value when it doesn't equal the switch value.
* `NgSwitchDefault` adds its element to the DOM when there is no selected `NgSwitchCase`.
The switch directives are particularly useful for adding and removing *component elements*.
This example switches among four `item` components defined in the `item-switch.components.ts` file.
Each component has an `item` [input property](guide/inputs-outputs#input "Input property")
which is bound to the `currentItem` of the parent component.
Switch directives work as well with native elements and web components too.
For example, you could replace the `<app-best-item>` switch case with the following.
<code-example path="built-in-directives/src/app/app.component.html" region="NgSwitch-div" header="src/app/app.component.html"></code-example>

View File

@ -10,7 +10,7 @@
</tr>
<tr>
<td><code><b>platformBrowserDynamic().bootstrapModule</b>(AppModule);</code></td>
<td><p>Bootstraps the app, using the root component from the specified <code>NgModule</code>. </p>
<td><p>Carga la app, usando el componente raíz del <code>NgModule</code> especificado.</p>
</td>
</tr>
</tbody></table>
@ -24,370 +24,372 @@
</tr>
<tr>
<td><code>@<b>NgModule</b>({ declarations: ..., imports: ...,<br> exports: ..., providers: ..., bootstrap: ...})<br>class MyModule {}</code></td>
<td><p>Defines a module that contains components, directives, pipes, and providers.</p>
<td><p>Define un módulo que contiene componentes, directivas, pipes y proveedores.</p>
</td>
</tr><tr>
<td><code><b>declarations:</b> [MyRedComponent, MyBlueComponent, MyDatePipe]</code></td>
<td><p>List of components, directives, and pipes that belong to this module.</p>
<td><p>Lista de componentes, directivas y pipes que pertenecen a este módulo.</p>
</td>
</tr><tr>
<td><code><b>imports:</b> [BrowserModule, SomeOtherModule]</code></td>
<td><p>List of modules to import into this module. Everything from the imported modules
is available to <code>declarations</code> of this module.</p>
<td><p>Lista de módulos para importar en este módulo. Todo, desde los módulos importados,
está disponible para las declaraciones (<code>declarations</code>) de este módulo.
</td>
</tr><tr>
<td><code><b>exports:</b> [MyRedComponent, MyDatePipe]</code></td>
<td><p>List of components, directives, and pipes visible to modules that import this module.</p>
<td><p>Lista de componentes, directivas y pipes visibles a los módulos que importan este módulo.</p>
</td>
</tr><tr>
<td><code><b>providers:</b> [MyService, { provide: ... }]</code></td>
<td><p>List of dependency injection providers visible both to the contents of this module and to importers of this module.</p>
<td><p>Lista de proveedores de inyección de dependencias visibles tanto para los contenidos de este módulo como para los importadores de este módulo.</p>
</td>
</tr><tr>
<td><code><b>entryComponents:</b> [SomeComponent, OtherComponent]</code></td>
<td><p>List of components not referenced in any reachable template, for example dynamically created from code.</p></td>
<td><p>Lista de componentes no referenciados en cualquier plantilla accesible, por ejemplo, creada dinámicamente a partir de código.</p></td>
</tr><tr>
<td><code><b>bootstrap:</b> [MyAppComponent]</code></td>
<td><p>List of components to bootstrap when this module is bootstrapped.</p>
<td><p>Lista de componentes a empaquetar cuando este módulo se inicia.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Template syntax</th>
<th>Sintaxis de plantilla</th>
<th></th>
</tr>
<tr>
<td><code>&lt;input <b>[value]</b>="firstName"&gt;</code></td>
<td><p>Binds property <code>value</code> to the result of expression <code>firstName</code>.</p>
<td><p>Vincula la propiedad <code>value</code> al resultado de la expresn <code>firstName</code>.</p>
</td>
</tr><tr>
<td><code>&lt;div <b>[attr.role]</b>="myAriaRole"&gt;</code></td>
<td><p>Binds attribute <code>role</code> to the result of expression <code>myAriaRole</code>.</p>
<td><p>Vincula el atributo <code>role</code> al resultado de la expresn <code>myAriaRole</code>.</p>
</td>
</tr><tr>
<td><code>&lt;div <b>[class.extra-sparkle]</b>="isDelightful"&gt;</code></td>
<td><p>Binds the presence of the CSS class <code>extra-sparkle</code> on the element to the truthiness of the expression <code>isDelightful</code>.</p>
<td><p>Vincula la presencia de la clase CSS <code>extra-sparkle</code> sobre el elemento a la veracidad de la expresn <code>isDelightful</code>.</p>
</td>
</tr><tr>
<td><code>&lt;div <b>[style.width.px]</b>="mySize"&gt;</code></td>
<td><p>Binds style property <code>width</code> to the result of expression <code>mySize</code> in pixels. Units are optional.</p>
<td><p>Vincula la propiedad de estilo <code>width</code> al resultado de la expresn <code>mySize</code> en píxeles. La unidad de medida es opcional.</p>
</td>
</tr><tr>
<td><code>&lt;button <b>(click)</b>="readRainbow($event)"&gt;</code></td>
<td><p>Calls method <code>readRainbow</code> when a click event is triggered on this button element (or its children) and passes in the event object.</p>
<td><p>Llama al método <code>readRainbow</code> cuando se lanza un evento click en este elemento botón (o sus hijos) y pasa por argumento el objeto evento.</p>
</td>
</tr><tr>
<td><code>&lt;div title="Hello <b>{{ponyName}}</b>"&gt;</code></td>
<td><code>&lt;div title="Hola <b>{{ponyName}}</b>"&gt;</code></td>
<td><p>Vincula una propiedad a una cadena interpolada, por ejemplo, "Hola Seabiscuit". Equivalente a:
<td><p>Binds a property to an interpolated string, for example, "Hello Seabiscuit". Equivalent to:
<code>&lt;div [title]="'Hello ' + ponyName"&gt;</code></p>
<code>&lt;div [title]="'Hola ' + ponyName"&gt;</code></p>
</td>
</tr><tr>
<td><code>&lt;p&gt;Hello <b>{{ponyName}}</b>&lt;/p&gt;</code></td>
<td><p>Binds text content to an interpolated string, for example, "Hello Seabiscuit".</p>
<td><code>&lt;p&gt;Hola <b>{{ponyName}}</b>&lt;/p&gt;</code></td>
<td><p>Vincula el contenido de texto a una cadena interpolada, por ejemplo, "Hola Seabiscuit".</p>
</td>
</tr><tr>
<td><code>&lt;my-cmp <b>[(title)]</b>="name"&gt;</code></td>
<td><p>Sets up two-way data binding. Equivalent to: <code>&lt;my-cmp [title]="name" (titleChange)="name=$event"&gt;</code></p>
<td><p>Establece el two-way data binding. Equivalente a: <code>&lt;my-cmp [title]="name" (titleChange)="name=$event"&gt;</code></p>
</td>
</tr><tr>
<td><code>&lt;video <b>#movieplayer</b> ...&gt;<br> &lt;button <b>(click)</b>="movieplayer.play()"&gt;<br>&lt;/video&gt;</code></td>
<td><p>Creates a local variable <code>movieplayer</code> that provides access to the <code>video</code> element instance in data-binding and event-binding expressions in the current template.</p>
<td><p>Crea una variable local <code>movieplayer</code> que provee acceso a la instancia del elemento <code>video</code> en las expresiones de data-binding y event-binding de la actual plantilla.</p>
</td>
</tr><tr>
<td><code>&lt;p <b>*myUnless</b>="myExpression"&gt;...&lt;/p&gt;</code></td>
<td><p>The <code>*</code> symbol turns the current element into an embedded template. Equivalent to:
<td><p>El símbolo <code>*</code> convierte el elemento actual en una plantilla incrustada. Equivalente a:
<code>&lt;ng-template [myUnless]="myExpression"&gt;&lt;p&gt;...&lt;/p&gt;&lt;/ng-template&gt;</code></p>
</td>
</tr><tr>
<td><code>&lt;p&gt;Card No.: <b>{{cardNumber | myCardNumberFormatter}}</b>&lt;/p&gt;</code></td>
<td><p>Transforms the current value of expression <code>cardNumber</code> via the pipe called <code>myCardNumberFormatter</code>.</p>
<td><p>Transforma el valor actual de la expresn <code>cardNumber</code> a través de la pipe <code>myCardNumberFormatter</code>.</p>
</td>
</tr><tr>
<td><code>&lt;p&gt;Employer: <b>{{employer?.companyName}}</b>&lt;/p&gt;</code></td>
<td><p>The safe navigation operator (<code>?</code>) means that the <code>employer</code> field is optional and if <code>undefined</code>, the rest of the expression should be ignored.</p>
<td><p>El operador de navegación seguro (<code>?</code>) significa que el campo <code>employer</code> es opcional y que si es <code>undefined</code>, el resto de la expresión debería ser ignorado.</p>
</td>
</tr><tr>
<td><code>&lt;<b>svg:</b>rect x="0" y="0" width="100" height="100"/&gt;</code></td>
<td><p>An SVG snippet template needs an <code>svg:</code> prefix on its root element to disambiguate the SVG element from an HTML component.</p>
<td><p>Una plantilla de fragmento SVG necesita un prefijo <code>svg:</code> en su elemento raíz para distinguir el elemento SVG de un componente HTML.</p>
</td>
</tr><tr>
<td><code>&lt;<b>svg</b>&gt;<br> &lt;rect x="0" y="0" width="100" height="100"/&gt;<br>&lt;/<b>svg</b>&gt;</code></td>
<td><p>An <code>&lt;svg&gt;</code> root element is detected as an SVG element automatically, without the prefix.</p>
<td><p>Un elemento raíz <code>&lt;svg&gt;</code> es detectado como un elemento SVG automáticamente, sin el prefijo.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Built-in directives</th>
<th>Directivas incorporadas</th>
<th><p><code>import { CommonModule } from '@angular/common';</code>
</p>
</th>
</tr>
<tr>
<td><code>&lt;section <b>*ngIf</b>="showSection"&gt;</code></td>
<td><p>Removes or recreates a portion of the DOM tree based on the <code>showSection</code> expression.</p>
<td><p>Elimina o recrea una parte del árbol DOM basado en la expresión <code>showSection</code>.</p>
</td>
</tr><tr>
<td><code>&lt;li <b>*ngFor</b>="let item of list"&gt;</code></td>
<td><p>Turns the li element and its contents into a template, and uses that to instantiate a view for each item in list.</p>
<td><p>Convierte el elemento li y su contenido en una plantilla, y lo utiliza para crear una vista por cada elemento de la lista.</p>
</td>
</tr><tr>
<td><code>&lt;div <b>[ngSwitch]</b>="conditionExpression"&gt;<br> &lt;ng-template <b>[<b>ngSwitchCase</b>]</b>="case1Exp"&gt;...&lt;/ng-template&gt;<br> &lt;ng-template <b>ngSwitchCase</b>="case2LiteralString"&gt;...&lt;/ng-template&gt;<br> &lt;ng-template <b>ngSwitchDefault</b>&gt;...&lt;/ng-template&gt;<br>&lt;/div&gt;</code></td>
<td><p>Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of <code>conditionExpression</code>.</p>
<td><p>Intercambia condicionalmente el contenido del div seleccionando una de las plantillas incrustadas en función del valor actual de <code>conditionExpression</code>.</p>
</td>
</tr><tr>
<td><code>&lt;div <b>[ngClass]</b>="{'active': isActive, 'disabled': isDisabled}"&gt;</code></td>
<td><p>Binds the presence of CSS classes on the element to the truthiness of the associated map values. The right-hand expression should return {class-name: true/false} map.</p>
<td><p>Vincula la presencia de clases CSS en el elemento a la veracidad de los valores de mapa asociados. La expresión de la derecha debería devolver el mapa {class-name: true/false}.</p>
</td>
</tr>
<tr>
<td><code>&lt;div <b>[ngStyle]</b>="{'property': 'value'}"&gt;</code><br><code>&lt;div <b>[ngStyle]</b>="dynamicStyles()"&gt;</code></td>
<td><p>Allows you to assign styles to an HTML element using CSS. You can use CSS directly, as in the first example, or you can call a method from the component.</p>
<p>Te permite asignar estilos a un elemento HTML usando CSS. Puedes usar CSS directamente, como en el primer ejemplo, o puedes llamar a un método desde el componente.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Forms</th>
<th>Formularios</th>
<th><p><code>import { FormsModule } from '@angular/forms';</code>
</p>
</th>
</tr>
<tr>
<td><code>&lt;input <b>[(ngModel)]</b>="userName"&gt;</code></td>
<td><p>Provides two-way data-binding, parsing, and validation for form controls.</p>
<td><p>Provee two-way data-binding, conversión y validación para controles de formulario.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Class decorators</th>
<th>Decoradores de clases</th>
<th><p><code>import { Directive, ... } from '@angular/core';</code>
</p>
</th>
</tr>
<tr>
<td><code><b>@Component({...})</b><br>class MyComponent() {}</code></td>
<td><p>Declares that a class is a component and provides metadata about the component.</p>
<td><p>Declara que una clase es un componente y proporciona metadatos sobre el componente.</p>
</td>
</tr><tr>
<td><code><b>@Directive({...})</b><br>class MyDirective() {}</code></td>
<td><p>Declares that a class is a directive and provides metadata about the directive.</p>
<td><p>Declara que una clase es una directiva y proporciona metadatos sobre la directiva.</p>
</td>
</tr><tr>
<td><code><b>@Pipe({...})</b><br>class MyPipe() {}</code></td>
<td><p>Declares that a class is a pipe and provides metadata about the pipe.</p>
<td><p>Declara que una clase es una pipe y proporciona metadatos sobre la pipe.</p>
</td>
</tr><tr>
<td><code><b>@Injectable()</b><br>class MyService() {}</code></td>
<td><p>Declares that a class can be provided and injected by other classes. Without this decorator, the compiler won't generate enough metadata to allow the class to be created properly when it's injected somewhere.</p>
<td><p>Declara que una clase puede ser proporcionada e inyectada por otras clases. Sin este decorador, el compilador no generará suficientes metadatos para permitir que la clase se cree correctamente cuando se inyecta en alguna parte.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Directive configuration</th>
<th>Configuración de Directiva</th>
<th><p><code>@Directive({ property1: value1, ... })</code>
</p>
</th>
</tr>
<tr>
<td><code><b>selector:</b> '.cool-button:not(a)'</code></td>
<td><p>Specifies a CSS selector that identifies this directive within a template. Supported selectors include <code>element</code>,
<td><p>Especifica un selector CSS que identifica esta directiva dentro de una plantilla. Los selectores compatibles incluyen <code>element</code>,
<code>[attribute]</code>, <code>.class</code>, and <code>:not()</code>.</p>
<p>Does not support parent-child relationship selectors.</p>
<p>No soporta selectores de relación padre-hijo.</p>
</td>
</tr><tr>
<td><code><b>providers:</b> [MyService, { provide: ... }]</code></td>
<td><p>List of dependency injection providers for this directive and its children.</p>
<td><p>Lista de proveedores de inyección de dependencia para esta directiva y sus hijos.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Component configuration</th>
<th>Configuración de Componente</th>
<th><p>
<code>@Component</code> extends <code>@Directive</code>,
so the <code>@Directive</code> configuration applies to components as well</p>
<code>@Component</code> extiende <code>@Directive</code>,
entonces la configuración de <code>@Directive</code> se aplica también a los componentes</p>
</th>
</tr>
<tr>
<td><code><b>moduleId:</b> module.id</code></td>
<td><p>If set, the <code>templateUrl</code> and <code>styleUrl</code> are resolved relative to the component.</p>
<td><p>Si está presente, el <code>templateUrl</code> y <code>styleUrl</code> se resuelven en relación con el componente.</p>
</td>
</tr><tr>
<td><code><b>viewProviders:</b> [MyService, { provide: ... }]</code></td>
<td><p>List of dependency injection providers scoped to this component's view.</p>
<td><p>Lista de proveedores de inyección de dependencias en la vista de este componente.</p>
</td>
</tr><tr>
<td><code><b>template:</b> 'Hello {{name}}'<br><b>templateUrl:</b> 'my-component.html'</code></td>
<td><p>Inline template or external template URL of the component's view.</p>
<td><code><b>template:</b> 'Hola {{name}}'<br><b>templateUrl:</b> 'my-component.html'</code></td>
<td><p>Plantilla en línea o URL de plantilla externa de la vista del componente.</p>
</td>
</tr><tr>
<td><code><b>styles:</b> ['.primary {color: red}']<br><b>styleUrls:</b> ['my-component.css']</code></td>
<td><p>List of inline CSS styles or external stylesheet URLs for styling the components view.</p>
<td><p>Lista de estilos CSS en línea o URL de hojas de estilo externas para estilar la vista del componente.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Class field decorators for directives and components</th>
<th>Decoradores para los campos de la clase para directivas y componentes.</th>
<th><p><code>import { Input, ... } from '@angular/core';</code>
</p>
</th>
</tr>
<tr>
<td><code><b>@Input()</b> myProperty;</code></td>
<td><p>Declares an input property that you can update via property binding (example:
<td><p>Declara una propiedad de entrada (input) que puede actualizar mediante el enlace de propiedad (property binding) (ejemplo:
<code>&lt;my-cmp [myProperty]="someExpression"&gt;</code>).</p>
</td>
</tr><tr>
<td><code><b>@Output()</b> myEvent = new EventEmitter();</code></td>
<td><p>Declares an output property that fires events that you can subscribe to with an event binding (example: <code>&lt;my-cmp (myEvent)="doSomething()"&gt;</code>).</p>
<td><p>Declara una propiedad de salida (output) que dispara eventos a los que puedes suscribirse con un enlace de evento (event binding) (ejemplo: <code>&lt;my-cmp (myEvent)="doSomething()"&gt;</code>).</p>
</td>
</tr><tr>
<td><code><b>@HostBinding('class.valid')</b> isValid;</code></td>
<td><p>Binds a host element property (here, the CSS class <code>valid</code>) to a directive/component property (<code>isValid</code>).</p>
<td><p>Vincula una propiedad del elemento anfitrión (aquí, la clase CSS <code>valid</code>) a una propiedad de directiva/componente (<code>isValid</code>).</p>
</td>
</tr><tr>
<td><code><b>@HostListener('click', ['$event'])</b> onClick(e) {...}</code></td>
<td><p>Subscribes to a host element event (<code>click</code>) with a directive/component method (<code>onClick</code>), optionally passing an argument (<code>$event</code>).</p>
<td><p>Se suscribe a un evento del elemento anfitrión (<code>click</code>) con un método de directiva/componente (<code>onClick</code>), opcionalmente, pasando un argumento (<code>$event</code>).</p>
</td>
</tr><tr>
<td><code><b>@ContentChild(myPredicate)</b> myChildComponent;</code></td>
<td><p>Binds the first result of the component content query (<code>myPredicate</code>) to a property (<code>myChildComponent</code>) of the class.</p>
<td><p>Vincula el primer resultado de la consulta de contenido del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponent</code>) de la clase.</p>
</td>
</tr><tr>
<td><code><b>@ContentChildren(myPredicate)</b> myChildComponents;</code></td>
<td><p>Binds the results of the component content query (<code>myPredicate</code>) to a property (<code>myChildComponents</code>) of the class.</p>
<td><p>Vincula los resultados de la consulta de contenido del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponents</code>) de la clase.</p>
</td>
</tr><tr>
<td><code><b>@ViewChild(myPredicate)</b> myChildComponent;</code></td>
<td><p>Binds the first result of the component view query (<code>myPredicate</code>) to a property (<code>myChildComponent</code>) of the class. Not available for directives.</p>
<td><p>Vincula el primer resultado de la consulta de vista del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponent</code>) de la clase. No disponible para directivas.</p>
</td>
</tr><tr>
<td><code><b>@ViewChildren(myPredicate)</b> myChildComponents;</code></td>
<td><p>Binds the results of the component view query (<code>myPredicate</code>) to a property (<code>myChildComponents</code>) of the class. Not available for directives.</p>
<td><p>Vincula los resultados de la consulta de vista del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponents</code>) de la clase. No disponible para directivas.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Directive and component change detection and lifecycle hooks</th>
<th><p>(implemented as class methods)
<th>Detección de cambios (change detection) y ciclos de vida (lifecycle hooks) en directivas y componentes</th>
<th><p>(implementado como métodos de clase)
</p>
</th>
</tr>
<tr>
<td><code><b>constructor(myService: MyService, ...)</b> { ... }</code></td>
<td><p>Called before any other lifecycle hook. Use it to inject dependencies, but avoid any serious work here.</p>
<td><p>Se llama antes que cualquier ciclo de vida. Úselo para inyectar dependencias, pero evite cualquier trabajo serio aquí.</p>
</td>
</tr><tr>
<td><code><b>ngOnChanges(changeRecord)</b> { ... }</code></td>
<td><p>Called after every change to input properties and before processing content or child views.</p>
<td><p>Se llama después de cada cambio en las propiedades de entrada (input) y antes de procesar contenido o vistas de hijos.</p>
</td>
</tr><tr>
<td><code><b>ngOnInit()</b> { ... }</code></td>
<td><p>Called after the constructor, initializing input properties, and the first call to <code>ngOnChanges</code>.</p>
<td><p>Se llama después del constructor, inicializando propiedades de entrada (input), y la primera llamada a <code>ngOnChanges</code>.</p>
</td>
</tr><tr>
<td><code><b>ngDoCheck()</b> { ... }</code></td>
<td><p>Called every time that the input properties of a component or a directive are checked. Use it to extend change detection by performing a custom check.</p>
<td><p>Se llama cada vez que se verifican las propiedades de entrada (input) de un componente o una directiva. Úselo para extender la detección de cambios (change detection) realizando una verificación personalizada.</p>
</td>
</tr><tr>
<td><code><b>ngAfterContentInit()</b> { ... }</code></td>
<td><p>Called after <code>ngOnInit</code> when the component's or directive's content has been initialized.</p>
<td><p>Se llama después de <code>ngOnInit</code> cuando el contenido del componente o directiva ha sido inicializado.</p>
</td>
</tr><tr>
<td><code><b>ngAfterContentChecked()</b> { ... }</code></td>
<td><p>Called after every check of the component's or directive's content.</p>
<td><p>Se llama después de cada verificación del contenido del componente o directiva.</p>
</td>
</tr><tr>
<td><code><b>ngAfterViewInit()</b> { ... }</code></td>
<td><p>Called after <code>ngAfterContentInit</code> when the component's views and child views / the view that a directive is in has been initialized.</p>
<td><p>Se llama después de <code>ngAfterContentInit</code> cuando las vistas del componente y las vistas hijas / la vista en la que se encuentra una directiva ha sido inicializado.</p>
</td>
</tr><tr>
<td><code><b>ngAfterViewChecked()</b> { ... }</code></td>
<td><p>Called after every check of the component's views and child views / the view that a directive is in.</p>
<td><p>Se llama después de cada verificación de las vistas del componentes y las vistas hijas / la vista en la que se encuentra una directiva.</p>
</td>
</tr><tr>
<td><code><b>ngOnDestroy()</b> { ... }</code></td>
<td><p>Called once, before the instance is destroyed.</p>
<td><p>Se llama una vez, antes de que la instancia se destruya.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Dependency injection configuration</th>
<th>Configuración de inyección de dependencia</th>
<th></th>
</tr>
<tr>
<td><code>{ <b>provide</b>: MyService, <b>useClass</b>: MyMockService }</code></td>
<td><p>Sets or overrides the provider for <code>MyService</code> to the <code>MyMockService</code> class.</p>
<td><p>Establece o sobre-escribe el proveedor para <code>MyService</code> en la clase <code>MyMockService</code>.</p>
</td>
</tr><tr>
<td><code>{ <b>provide</b>: MyService, <b>useFactory</b>: myFactory }</code></td>
<td><p>Sets or overrides the provider for <code>MyService</code> to the <code>myFactory</code> factory function.</p>
<td><p>Establece o sobre-escribe el proveedor para <code>MyService</code> en la factoría de función <code>myFactory</code>.</p>
</td>
</tr><tr>
<td><code>{ <b>provide</b>: MyValue, <b>useValue</b>: 41 }</code></td>
<td><p>Sets or overrides the provider for <code>MyValue</code> to the value <code>41</code>.</p>
<td><p>Establece o sobre-escribe el proveedor para <code>MyValue</code> al valor <code>41</code>.</p>
</td>
</tr>
</tbody></table>
<table class="is-full-width is-fixed-layout">
<tbody><tr>
<th>Routing and navigation</th>
<th>Enrutamiento y navegación</th>
<th><p><code>import { Routes, RouterModule, ... } from '@angular/router';</code>
</p>
</th>
</tr>
<tr>
<td><code>const routes: <b>Routes</b> = [<br> { path: '', component: HomeComponent },<br> { path: 'path/:routeParam', component: MyComponent },<br> { path: 'staticPath', component: ... },<br> { path: '**', component: ... },<br> { path: 'oldPath', redirectTo: '/staticPath' },<br> { path: ..., component: ..., data: { message: 'Custom' } }<br>]);<br><br>const routing = RouterModule.forRoot(routes);</code></td>
<td><p>Configures routes for the application. Supports static, parameterized, redirect, and wildcard routes. Also supports custom route data and resolve.</p>
<td><p>Configura rutas para la aplicación. Soporta rutas estáticas, parametrizadas, de redireccionamiento y comodines. También soporta datos de ruta personalizados y los resuelve.</p>
</td>
</tr><tr>
<td><code><br>&lt;<b>router-outlet</b>&gt;&lt;/<b>router-outlet</b>&gt;<br>&lt;<b>router-outlet</b> name="aux"&gt;&lt;/<b>router-outlet</b>&gt;<br></code></td>
<td><p>Marks the location to load the component of the active route.</p>
<td><p>Marca la ubicación para cargar el componente de la ruta activa.</p>
</td>
</tr><tr>
<td><code><br>&lt;a routerLink="/path"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path', routeParam ]"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path', { matrixParam: 'value' } ]"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path' ]" [queryParams]="{ page: 1 }"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path' ]" fragment="anchor"&gt;<br></code></td>
<td><p>Creates a link to a different view based on a route instruction consisting of a route path, required and optional parameters, query parameters, and a fragment. To navigate to a root route, use the <code>/</code> prefix; for a child route, use the <code>./</code>prefix; for a sibling or parent, use the <code>../</code> prefix.</p>
<td><p>Crea un enlace a una vista diferente basada en una instrucción de ruta que consta de un camino de de ruta, parámetros obligatorios y opcionales, parámetros de consulta y un fragmento. Para navegar a un camino de ruta, usa el prefijo <code>/</code>; para una ruta hija, usa el prefijo <code>./</code>; para un padre o hermano, usa el prefijo <code>../</code>.</p>
</td>
</tr><tr>
<td><code>&lt;a [routerLink]="[ '/path' ]" routerLinkActive="active"&gt;</code></td>
<td><p>The provided classes are added to the element when the <code>routerLink</code> becomes the current active route.</p>
<td><p>Las clases proporcionadas se agregan al elemento cuando el <code>routerLink</code> se convierte en la ruta activa actual.</p>
</td>
</tr><tr>
<td><code>class <b>CanActivate</b>Guard implements <b>CanActivate</b> {<br> canActivate(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canActivate: [<b>CanActivate</b>Guard] }</code></td>
<td><p>An interface for defining a class that the router should call first to determine if it should activate this component. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p>
<td><p>Una interfaz para definir una clase que el enrutador debe llamar primero para determinar si debe activar este componente. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelba en un boolean|UrlTree.</p>
</td>
</tr><tr>
<td><code>class <b>CanDeactivate</b>Guard implements <b>CanDeactivate</b>&lt;T&gt; {<br> canDeactivate(<br> component: T,<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canDeactivate: [<b>CanDeactivate</b>Guard] }</code></td>
<td><p>An interface for defining a class that the router should call first to determine if it should deactivate this component after a navigation. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p>
<td><p>Una interfaz para definir una clase que el enrutador debería llamar primero para determinar si debería desactivar este componente después de una navegación. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelva a boolean|UrlTree.</p>
</td>
</tr><tr>
<td><code>class <b>CanActivateChild</b>Guard implements <b>CanActivateChild</b> {<br> canActivateChild(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canActivateChild: [CanActivateGuard],<br> children: ... }</code></td>
<td><p>An interface for defining a class that the router should call first to determine if it should activate the child route. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p>
<td><p>Una interfaz para definir una clase que el enrutador debe llamar primero para determinar si debe activar la ruta hija. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelva en un boolean|UrlTree.</p>
</td>
</tr><tr>
<td><code>class <b>Resolve</b>Guard implements <b>Resolve</b>&lt;T&gt; {<br> resolve(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;any&gt;|Promise&lt;any&gt;|any { ... }<br>}<br><br>{ path: ..., resolve: [<b>Resolve</b>Guard] }</code></td>
<td><p>An interface for defining a class that the router should call first to resolve route data before rendering the route. Should return a value or an Observable/Promise that resolves to a value.</p>
<td><p>Una interfaz para definir una clase que el enrutador debe llamar primero para resolver los datos de la ruta antes de representar la ruta. Debe devolver un valor o un Observable/Promise que se resuelva en un valor.</p>
</td>
</tr><tr>
<td><code>class <b>CanLoad</b>Guard implements <b>CanLoad</b> {<br> canLoad(<br> route: Route<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canLoad: [<b>CanLoad</b>Guard], loadChildren: ... }</code></td>
<td><p>An interface for defining a class that the router should call first to check if the lazy loaded module should be loaded. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p>
<td><p>Una interfaz para definir una clase a la que el enrutador debe llamar primero para verificar si el módulo perezoso cargado (lazy loaded module) debe cargarse. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelva en un boolean|UrlTree.</p>
</td>
</tr>
</tbody></table>

View File

@ -25,7 +25,7 @@ in which two or more components share information.
## Pass data from parent to child with input binding
`HeroChildComponent` has two ***input properties***,
typically adorned with [@Input decorations](guide/template-syntax#inputs-outputs).
typically adorned with [@Input() decorator](guide/inputs-outputs#input).
<code-example path="component-interaction/src/app/hero-child.component.ts" header="component-interaction/src/app/hero-child.component.ts">
@ -180,7 +180,7 @@ The child component exposes an `EventEmitter` property with which it `emits` eve
The parent binds to that event property and reacts to those events.
The child's `EventEmitter` property is an ***output property***,
typically adorned with an [@Output decoration](guide/template-syntax#inputs-outputs)
typically adorned with an [@Output() decorator](guide/inputs-outputs#output)
as seen in this `VoterComponent`:

View File

@ -0,0 +1,247 @@
# Creando librerías
Está pagina provee una vista conceptual de como puedes crear y publicar nuevas librerías para extender las funcionalidades de Angular.
Si necesitas resolver el mismo problema en mas de una aplicación (o quiere compartir tu solución con otros desarrolladores), tienes un candidato para una librería.
Un ejemplo simple puede ser un botón que envía a los usuarios hacia el sitio web de tu empresa, que sería incluido en todas las aplicaciones que tu empresa crea.
## Empezando
Usa el Angular CLI para generar un nuevo esqueleto de librería, en nuevo espacio de trabajo con los siguiente comandos.
<code-example language="bash">
ng new my-workspace --create-application=false
cd my-workspace
ng generate library my-lib
</code-example>
El comando `ng generate` crea la carpeta `projects/my-lib` en el espacio de trabajo, que contiene un componente y un servicio dentro de un NgModule.
<div class="alert is-helpful">
Para más detalles sobre como una librería es estructurada, refiérase a los [Archivos de Librería](guide/file-structure#library-project-files) en la sección de [Guía de estructura de archivos](guide/file-structure).
Puedes usar un modelo de monorepo para usar el mismo espacio de trabajo con multiples proyectos. Véase [Configuración para espacio de trabajo multiproyecto](guide/file-structure#multiple-projects).
</div>
Cuando se genera una nueva librería, el archivo de configuración del espacio de trabajo, `angular.json`, es actualizado con un proyecto de tipo 'library'.
<code-example format="json">
"projects": {
...
"my-lib": {
"root": "projects/my-lib",
"sourceRoot": "projects/my-lib/src",
"projectType": "library",
"prefix": "lib",
"architect": {
"build": {
"builder": "@angular-devkit/build-ng-packagr:build",
...
</code-example>
Puedes crear, probar y comprobar con los comandos de CLI:
<code-example language="bash">
ng build my-lib
ng test my-lib
ng lint my-lib
</code-example>
Puedes notar que el constructor configurado para el proyecto es diferente que el constructor por defecto para proyectos.
El constructor, entre otras cosas, asegura que la librería siempre este construida con el [compilador AOT](guide/aot-compiler), sin la necesidad de especificar la bandera `--prod`.
Para hacer el código de la librería reusable debes definir una API pública para ella. Esta "capa de usuario" define que esta disponible para los consumidores de tu librería. Un usuario de tu librería debería ser capaz de acceder a la funcionalidad publica (como NgModules, servicios, proveedores y en general funciones de utilidad) mediante una sola ruta.
La API pública para tu librería es mantenida en el archivo `public-api.ts` en tu carpeta de librería.
Cualquier cosa exportada desde este archivo se hace publica cuando tu librería es importada dentro de una aplicación.
Usa un NgModule para exponer los servicios y componentes.
Tu libería debería suministrar documentatión (típicamente en el archivo README) para la instalación y mantenimiento.
## Refactorizando partes de una app dentro de un librería
Para hacer tu solución reusable, necesitas ajustarla para que no dependa del código específico de la aplicación.
Aquí algunas cosas para considerar al migrar la funcionalidad de la aplicación a una librería.
* Declaraciones tales como componentes y pipes deberían ser diseñados como 'stateless' (sin estado), lo que significa que no dependen ni alteran variables externas. Si tu dependes del estado, necesitas evaluar cada caso y decidir el estado de la aplicación o el estado que la aplicación administraría.
* Cualquier observable al cual los componentes se suscriban internamente deberían ser limpiados y desechados durante el ciclo de vida de esos componentes.
* Los componentes deberían exponer sus interacciones a través de 'inputs' para proporcionar contexto y 'outputs' para comunicar los eventos hacia otros componentes.
* Verifique todas las dependencias internas.
* Para clases personalizadas o interfaces usadas en componentes o servicios, verifique si dependen en clases adicionales o interfaces que también necesiten ser migradas.
* Del mismo modo, si tu código de librería depende de un servicio, este servicio necesita ser migrado.
* Si tu código de librería o sus plantillas dependen de otras librerías (como Angular Material), debes configurar tu librería con esas dependencias.
* Considere como proporcionar servicios a las aplicaciones cliente.
* Los servicios deberían declarar sus propios proveedores (en lugar de declarar los proveedores en el NgModule o en un componente). Esto le permite al compilador dejar los servicios fuera del 'bundle' si este nunca fue inyectado dentro de la aplicación que importa la librería, véase [proveedores Tree-shakable](guide/dependency-injection-providers#tree-shakable-providers)
* Si registras proveedores globales o compartes proveedores a través de múltiples NgModules, usa el [`forRoot()` y `forChild()` como patrones de diseño](guide/singleton-services) proporcionados por el [RouterModule](api/router/RouterModule).
* Si tu librería proporciona servicios opcionales que podrían no ser usados por todos las aplicaciones cliente, soporte apropiadamente el 'tree-shaking' para esos casos usando el [patrón de diseño de token ligero](guide/lightweight-injection-tokens).
{@a integrating-with-the-cli}
## Integración con el CLI usando generación de código con los schematics.
Comúnmente una librería incluye *código reusable* que define componentes, servicios y otros Artefactos de Angular (pipes, directivas y etc.) que tu simplemente importas a un proyecto.
Una librería es empaquetada dentro de un paquete npm para publicar y compartir.
Este paquete también puede incluir [schematics](guide/glossary#schematic) que proporciona instrucciones para generar o transformar código directamente un tu proyecto, de la misma forma que el CLI crea un nuevo componente genérico con `ng generate component`.
Un 'schematic' empaquetado con una librería puede por ejemplo proporcionar al Angular CLI la información que necesita para generar un componente que configura y usa una particular característica o conjunto de características, definido en la librería.
Un ejemplo de esto es el 'schematic' de navegación de Angular Material el cual configura los CDK's `BreakpointObserver` y lo usa con los componentes `MatSideNav` y `MatToolbar` de Angular Material.
Puedes crear e incluir los siguientes tipos de 'schematics'.
* Incluye un 'schematic' de instalación para que con `ng add` puedas agregar tu libería a un proyecto.
* Incluye un 'schematic' de generación en tu librería para que con `ng generate` puedas hacer scaffolding de sus artefactos (componentes, servicios, pruebas y etc) en un proyecto.
* Incluye un 'schematic' de actualización para que con `ng update` puedas actualizar las dependencias de tu librería y proporcionar migraciones para cambios importantes en un nuevo release.
Lo que incluya tu librería depende de tu tarea.
Por ejemplo, podrías definir un 'schematic' para crear un desplegable (dropdown) que esta pre-poblado con datos para mostrar como agregarlo a una aplicación.
Si quieres un desplegable (dropdown) que contendrá valores diferentes cada vez, tu librería podría definir un 'schematic' para crearlo con una configuración dada. Los desarrolladores podrán entonces usar `ng generate` para configurar una instancia para sus propias aplicaciones.
Supón que quieres leer un archivo de configuración y entonces generar una formulario con base a la configuración.
Si este formulario necesita personalización adicional por parte del desarrollador que esta usando tu librería, esto podría trabajar mejor como un 'schematic'.
Sin embargo, si el formulario siempre será el mismo y no necesita de mucha personalización por parte de los desarrolladores, entonces podría crear un componente dinámico que tome la configuración y genere el formulario.
En general, entre más compleja sea personalización, la más util será en enfoque de un 'schematic'.
Para aprender más, véase [Vista general de Schematics](guide/schematics)
## Publicando tu librería
Usa el Angular CLI y el gestor de paquetes npm para construir y publicar tu librería como un paquete npm.
Antes de publicar una librería a NPM, constrúyela usando la bandera `--prod` la cúal usará el compilador y tiempo de ejecución (runtime) más antiguos como 'View Engine' en vez de 'Ivy'.
<code-example language="bash">
ng build my-lib --prod
cd dist/my-lib
npm publish
</code-example>
Si nunca has publicado un paquete en npm antes, tu debes crear un cuenta. Lee más en [Publicando paquetes npm](https://docs.npmjs.com/getting-started/publishing-npm-packages).
<div class="alert is-important">
Por ahora, no es recomendando publicar librerías con Ivy hacia NPM por que Ivy genera código que no es retrocompatible con 'View Engine', entonces las aplicaciones usando 'View Engine' no podrán consumirlas. Además, las instrucciones internas de IVY no son estables aun, lo cual puede romper potencialmente a los consumidores que usan una diferente versión de Angular a la que uso para construir la libería.
Cuando una librería publicada es usada en una aplicación con Ivy, el Angular CLI automáticamente la convertirá a Ivy usando una herramienta conocida como el compilador de compatibilidad Angular (`ngcc`). Por lo tanto, publicar tus librerías usado el compilador 'View Engine' garantiza que ellas puede ser consumidas de forma transparente por ambos motores 'View Engine' y 'Ivy'.
</div>
{@a lib-assets}
## Gestionando activos (assets) en una librería.
Desde la versión 9.x de la herramienta [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md), puedes configurar la herramienta para que automáticamente copie los activos (assets) dentro de el paquete de librería como parte del proceso de construcción.
Puedes usar esta característica cuando tu librería necesite publicar archivos de temas opcionales, funciones de Sass o documentación (como un registro de cambios 'changelog').
* Aprende como [copiar activos (assets) dentro de tu librería como parte de la construcción](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md).
* Aprende más acerca de como usar la herramienta para [incrustar activos (assets) de CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
## Vinculando librerías
Mientras trabajas en un librería publicada, puedes usar [npm link](https://docs.npmjs.com/cli/link) para evitar re instalar la librería en cada construcción.
La librería debe ser reconstruida en cada cambio.
Cuando vinculas una librería, asegurate que el paso de construir corra en modo vigía (watch mode) y que el `package.json` de la librería configure los puntos de entrada correctos.
Por ejemplo, `main` debería apuntar a un archivo JavaScript, no a un archivo TypeScript.
## Utiliza el mapeo de rutas de TypeScript por las dependencias de pares.
Las librerías de Angular deben enumerar todas las dependencias `@angular/*` como dependencias de pares.
Esto garantiza que cuando los módulos solicitan Angular, todos ellos obtienen exactamente el mismo módulo.
Si tu librería lista `@angular/core` en `dependencies` en vez de en `peerDependencies`, podría obtener un módulo Angular diferente, lo qué haría que tu aplicación se rompiera.
Cuando desarrollas una librería, tu debes instalar todas las dependencias de pares mediante `devDependencies` para garantizar que la librería compile apropiadamente.
Una librería vinculada tendrá su propio conjunto de librerías Angular que usa para construir, ubicados en su carpeta `node_modules`.
Sin embargo, esto puede causar problemas mientras construyes o corres tu aplicación.
Para evitar este problema tu puedes usar el mapeo de rutas de TypeScript para indicarle a TypeScript que este debería cargar algunos módulos desde una ubicación especifica.
Enumera todas las dependencias de pares que tu librería usa en el archivo de configuración `./tsconfig.json` del espacio de trabajo de TypeScript, y apúntalos a la copia local en la carpeta `node_modules` de la aplicación.
```
{
"compilerOptions": {
// ...
// paths are relative to `baseUrl` path.
"paths": {
"@angular/*": [
"./node_modules/@angular/*"
]
}
}
}
```
Este mapeador garantiza que tu librería siempre cargue las copias locales del módulo que necesita.
## Usando tu propia librería en aplicaciones.
No tienes que publicar tu librería hacia el gestor de paquetes npm para usarla en tus propias aplicaciones, pero tienes que construirla primero.
Para usar tu propia librería en tu aplicación:
* Construye la librería. No puedes usar una librería antes que se construya.
<code-example language="bash">
ng build my-lib
</code-example>
* En tus aplicaciones, importa la librería por el nombre:
```
import { myExport } from 'my-lib';
```
### Construyendo y re construyendo tu librería.
El paso de construir es importante si no tienes publicada tu librería como un paquete npm y luego ha instalado el paquete de nuevo dentro tu aplicación desde npm.
Por ejemplo, si clonas tu repositorio git y corres `npm install`, tu editor mostrará la importación de `my-lib` como perdida si no tienes aun construida tu librería.
<div class="alert is-helpful">
Cuando importas algo desde una librería en una aplicación Angular, Angular busca un mapeo entre el nombre de librería y una ubicación en disco.
Cuando instalas un paquete de librería, el mapeo esta en la carpeta `node_modules`. Cuando construyes tu propia librería, tiene que encontrar el mapeo en tus rutas de `tsconfig`.
Generando una librería con el Angular CLI automáticamente agrega su ruta en el archivo `tsconfig`.
El Angular CLI usa las rutas `tsconfig` para indicarle al sistema construido donde encontrar la librería.
</div>
Si descubres que los cambios en tu librería no son reflejados en tu aplicación, tu aplicación probablemente esta usando una construcción antigua de la librería.
Puedes re construir tu librería cada vez que hagas cambios en esta, pero este paso extra toma tiempo.
Las *construcciones incrementales* funcionalmente mejoran la experiencia de desarrollo de librerías.
Cada vez que un archivo es cambiando una construcción parcial es realizada y esta emite los archivos modificados.
Las *Construcciones incrementales* puede ser ejecutadas como un proceso en segundo plano en tu entorno de desarrollo. Para aprovechar esta característica agrega la bandera `--watch` al comando de construcción:
<code-example language="bash">
ng build my-lib --watch
</code-example>
<div class="alert is-important">
El comando `build` del CLI utiliza un constructor diferente e invoca una herramienta de construcción diferente para las librerías que para las aplicaciones.
* El sistema de construcción para aplicaciones, `@angular-devkit/build-angular`, esta basado en `webpack`, y esta incluida en todos los nuevos proyectos de Angular CLI.
* El sistema de construcción esta basado en `ng-packagr`. Este es solo agregado en tus dependencias cuando agregas una librería usando `ng generate library my-lib`.
Los dos sistemas de construcción soportan diferentes cosas e incluso si ellos soportan las mismas cosas, ellos hacen esas cosas de forma diferente.
Esto quiere decir que la fuente de TypeScript puede generar en código JavaScript diferente en una librería construida que en una aplicación construida.
Por esta razón, una aplicación que depende de una librería debería solo usar el mapeo de rutas de TypeScript que apunte a la *librería construida*.
El mapeo de rutas de TypeScript no debería apuntar hacia los archivos `.ts` fuente de la librería.
</div>

View File

@ -1,16 +1,13 @@
# Creating libraries
You can create and publish new libraries to extend Angular functionality. If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
This page provides a conceptual overview of how you can create and publish new libraries to extend Angular functionality.
If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
A simple example might be a button that sends users to your company website, that would be included in all apps that your company builds.
<div class="alert is-helpful">
<p>For more details on how a library project is structured you can refer the <a href="guide/file-structure#library-project-files">Library Project Files</a></p>
</div>
## Getting started
Use the Angular CLI to generate a new library skeleton with the following command:
Use the Angular CLI to generate a new library skeleton in a new workspace with the following commands.
<code-example language="bash">
ng new my-workspace --create-application=false
@ -18,12 +15,18 @@ Use the Angular CLI to generate a new library skeleton with the following comman
ng generate library my-lib
</code-example>
The `ng generate` command creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule.
<div class="alert is-helpful">
<p>You can use the monorepo model to use the same workspace for multiple projects. See <a href="guide/file-structure#multiple-projects">Setting up for a multi-project workspace</a>.</p>
For more details on how a library project is structured, refer to the [Library project files](guide/file-structure#library-project-files) section of the [Project File Structure guide](guide/file-structure).
You can use the monorepo model to use the same workspace for multiple projects.
See [Setting up for a multi-project workspace](guide/file-structure#multiple-projects).
</div>
This creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule.
The workspace configuration file, `angular.json`, is updated with a project of type 'library'.
When you generate a new library, the workspace configuration file, `angular.json`, is updated with a project of type 'library'.
<code-example format="json">
"projects": {
@ -69,35 +72,30 @@ Here are some things to consider in migrating application functionality to a lib
* Components should expose their interactions through inputs for providing context, and outputs for communicating events to other components.
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule).
* Check all internal dependencies.
* For custom classes or interfaces used in components or service, check whether they depend on additional classes or interfaces that also need to be migrated.
* Similarly, if your library code depends on a service, that service needs to be migrated.
* If your library code or its templates depend on other libraries (such a Angular Material, for instance), you must configure your library with those dependencies.
* If your library code or its templates depend on other libraries (such as Angular Material, for instance), you must configure your library with those dependencies.
## Reusable code and schematics
* Consider how you provide services to client applications.
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
A library is packaged into an npm package for publishing and sharing, and this package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic skeleton app with `ng generate component`.
A schematic that is combined with a library can, for example, provide the Angular CLI with the information it needs to generate a particular component defined in that library.
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
What you include in your library is determined by the kind of task you are trying to accomplish.
For example, if you want a dropdown with some canned data to show how to add it to your app, your library could define a schematic to create it.
For a component like a dropdown that would contain different passed-in values each time, you could provide it as a component in a shared library.
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` design patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule).
Suppose you want to read a configuration file and then generate a form based on that configuration.
If that form will need additional customization by the user, it might work best as a schematic.
However, if the forms will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
In general, the more complex the customization, the more useful the schematic approach.
* If your library provides optional services that might not be used by all client applications, support proper tree-shaking for that case by using the [lightweight token design pattern](guide/lightweight-injection-tokens).
{@a integrating-with-the-cli}
## Integrating with the CLI
## Integrating with the CLI using code-generation schematics
A library can include [schematics](guide/glossary#schematic) that allow it to integrate with the Angular CLI.
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
A library is packaged into an npm package for publishing and sharing.
This package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic new component with `ng generate component`.
A schematic that is packaged with a library can, for example, provide the Angular CLI with the information it needs to generate a component that configures and uses a particular feature, or set of features, defined in that library.
One example of this is Angular Material's navigation schematic which configures the CDK's `BreakpointObserver` and uses it with Material's `MatSideNav` and `MatToolbar` components.
You can create and include the following kinds of schematics.
* Include an installation schematic so that `ng add` can add your library to a project.
@ -105,11 +103,22 @@ A library can include [schematics](guide/glossary#schematic) that allow it to in
* Include an update schematic so that `ng update` can update your librarys dependencies and provide migrations for breaking changes in new releases.
What you include in your library depends on your task.
For example, you could define a schematic to create a dropdown that is pre-populated with canned data to show how to add it to an app.
If you want a dropdown that would contain different passed-in values each time, your library could define a schematic to create it with a given configuration. Developers could then use `ng generate` to configure an instance for their own app.
Suppose you want to read a configuration file and then generate a form based on that configuration.
If that form will need additional customization by the developer who is using your library, it might work best as a schematic.
However, if the forms will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
In general, the more complex the customization, the more useful the schematic approach.
To learn more, see [Schematics Overview](guide/schematics) and [Schematicsfor Libraries](guide/schematics-for-libraries).
## Publishing your library
Use the Angular CLI and the npm package manager to build and publish your library as an npm package. It is not recommended to publish Ivy libraries to NPM repositories. Before publishing a library to NPM, build it using the `--prod` flag which will use the older compiler and runtime known as View Engine instead of Ivy.
Use the Angular CLI and the npm package manager to build and publish your library as an npm package.
Before publishing a library to NPM, build it using the `--prod` flag which will use the older compiler and runtime known as View Engine instead of Ivy.
<code-example language="bash">
ng build my-lib --prod
@ -119,6 +128,14 @@ npm publish
If you've never published a package in npm before, you must create a user account. Read more in [Publishing npm Packages](https://docs.npmjs.com/getting-started/publishing-npm-packages).
<div class="alert is-important">
For now, it is not recommended to publish Ivy libraries to NPM because Ivy generated code is not backward compatible with View Engine, so apps using View Engine will not be able to consume them. Furthermore, the internal Ivy instructions are not yet stable, which can potentially break consumers using a different Angular version from the one used to build the library.
When a published library is used in an Ivy app, the Angular CLI will automatically convert it to Ivy using a tool known as the Angular compatibility compiler (`ngcc`). Thus, publishing your libraries using the View Engine compiler ensures that they can be transparently consumed by both View Engine and Ivy apps.
</div>
{@a lib-assets}
## Managing assets in a library

View File

@ -197,11 +197,11 @@ Like `EvenBetterLogger`, `HeroService` needs to know if the user is authorized
That authorization can change during the course of a single application session,
as when you log in a different user.
Let's say you don't want to inject `UserService` directly into `HeroService`, because you don't want to complicate that service with security-sensitive information.
Imagine that you don't want to inject `UserService` directly into `HeroService`, because you don't want to complicate that service with security-sensitive information.
`HeroService` won't have direct access to the user information to decide
who is authorized and who isn't.
To resolve this, we give the `HeroService` constructor a boolean flag to control display of secret heroes.
To resolve this, give the `HeroService` constructor a boolean flag to control display of secret heroes.
<code-example path="dependency-injection/src/app/heroes/hero.service.ts" region="internals" header="src/app/heroes/hero.service.ts (excerpt)"></code-example>
@ -262,7 +262,7 @@ For example, when bootstrapping an application, you can register many initialize
```
export const APP_TOKENS = [
{ provide: PLATFORM_INITIALIZER, useFactory: platformInitialized, multi: true },
{ provide: PLATFORM_INITIALIZER, useFactory: platformInitialized, multi: true },
{ provide: APP_INITIALIZER, useFactory: delayBootstrapping, multi: true },
{ provide: APP_BOOTSTRAP_LISTENER, useFactory: appBootstrapped, multi: true },
];
@ -284,6 +284,23 @@ Search for [Constants in API documentation](api?type=const) to find more built-i
</div>
<div class="alert is-helpful">
Note that the reference to the array returned for a `multi` provider is shared between all the
places where the token is injected. We recommend avoiding mutations of the array (especially for
predefined tokens) as it may lead to unexpected behavior in other parts of the app that inject
the same token. You can prevent the value from being mutated by setting its type to `ReadonlyArray`.
</div>
You can use `ReadonlyArray` to type your `multi` provider, so TypeScript triggers an error in case
of unwanted array mutations:
```
constructor(@Inject(MULTI_PROVIDER) multiProvider: ReadonlyArray<MultiProvider>) {
}
```
{@a tree-shakable-provider}
{@a tree-shakable-providers}

View File

@ -320,7 +320,7 @@ You can dramatically reduce launch time by only loading the application modules
absolutely must be present when the app starts.
Configure the Angular Router to defer loading of all other modules (and their associated code), either by
[waiting until the app has launched](guide/router#preloading "Preloading")
[waiting until the app has launched](guide/router-tutorial-toh#preloading "Preloading")
or by [_lazy loading_](guide/router#lazy-loading "Lazy loading")
them on demand.
@ -328,7 +328,7 @@ them on demand.
<header>Don't eagerly import something from a lazy-loaded module</header>
If you mean to lazy-load a module, be careful not import it
If you mean to lazy-load a module, be careful not to import it
in a file that's eagerly loaded when the app starts (such as the root `AppModule`).
If you do that, the module will be loaded immediately.
@ -448,13 +448,13 @@ When targeting older browsers, [polyfills](guide/browser-support#polyfills) can
To maximize compatibility, you could ship a single bundle that includes all your compiled code, plus any polyfills that may be needed.
Users with modern browsers, however, shouldn't have to pay the price of increased bundle size that comes with polyfills they don't need.
Differential loading, which is supported by default in Angular CLI version 8 and higher, solves this problem.
Differential loading, which is supported in Angular CLI version 8 and higher, can help solve this problem.
Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled (which is the default) the CLI builds two separate bundles as part of your deployed application.
Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled the CLI builds two separate bundles as part of your deployed application.
* The first bundle contains modern ES2015 syntax, takes advantage of built-in support in modern browsers, ships fewer polyfills, and results in a smaller bundle size.
* The first bundle contains modern ES2015 syntax. This bundle takes advantage of built-in support in modern browsers, ships fewer polyfills, and results in a smaller bundle size.
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This results in a larger bundle size, but supports older browsers.
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This second bundle is larger, but supports older browsers.
### Differential builds
@ -463,13 +463,13 @@ The [`ng build` CLI command](cli/build) queries the browser configuration and th
The following configurations determine your requirements.
* Browsers list
* Browserslist
The `browserslist` configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options.
The Browserslist configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options.
* TypeScript configuration
In the TypeScript configuration file, `tsconfig.json`, the "target" option in the `compilerOptions` section determines the ECMAScript target version that the code is compiled to.
In the TypeScript configuration file, the "target" option in the `compilerOptions` section determines the ECMAScript target version that the code is compiled to.
Modern browsers support ES2015 natively, while ES5 is more commonly used to support legacy browsers.
<div class="alert is-helpful">
@ -509,16 +509,27 @@ Each script tag has a `type="module"` or `nomodule` attribute. Browsers with nat
### Configuring differential loading
Differential loading is supported by default with version 8 and later of the Angular CLI.
For each application project in your workspace, you can configure how builds are produced based on the `browserslist` and `tsconfig.json` configuration files in your application project.
To include differential loading in your application builds, you must configure the Browserslist and TypeScript configuration files in your application project.
For a newly created Angular application, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015.
The following examples show a `browserlistrc` and `tsconfig.json` file for a newly created Angular application. In this configuration, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015.
<code-example language="none" header="browserslist">
> 0.5%
last 2 versions
<code-example language="none" header="browserslistrc">
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major version
last 2 iOS major versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.
</code-example>
@ -549,36 +560,24 @@ not IE 9-11 # For IE 9-11 support, remove 'not'.
</code-example>
The default configuration creates two builds, with differential loading enabled.
<div class="alert is-important">
To see which browsers are supported with the default configuration and determine which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
To see which browsers are supported and determine which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
</div>
The `browserslist` configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced.
The Browserslist configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced.
If your `browserslist` configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading.
If your Browserslist configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading.
{@a configuration-table }
| browserslist | ES target | Build result |
| Browserslist | ES target | Build result |
| -------- | -------- | -------- |
| ES5 support disabled | es2015 | Single build, ES5 not required |
| ES5 support enabled | es5 | Single build w/conditional polyfills for ES5 only |
| ES5 support enabled | es2015 | Differential loading (two builds w/conditional polyfills) |
### Opting out of differential loading
Differential loading can be explicitly disabled if it causes unexpected issues, or if you need to target ES5 specifically for legacy browser support.
To explicitly disable differential loading and create an ES5 build:
- Enable the `dead` or `IE` browsers in the `browserslist` configuration file by removing the `not` keyword in front of them.
- To create a single ES5 build, set the target in the `compilerOptions` to `es5`.
{@a test-and-serve}
## Local development in older browsers

View File

@ -35,6 +35,7 @@ v9 - v12
| Area | API or Feature | May be removed in |
| ----------------------------- | --------------------------------------------------------------------------- | ----------------- |
| `@angular/bazel` | [`Bazel builder and schematics`](#bazelbuilder) | v10 |
| `@angular/common` | [`ReflectiveInjector`](#reflectiveinjector) | <!--v8--> v11 |
| `@angular/common` | [`CurrencyPipe` - `DEFAULT_CURRENCY_CODE`](api/common/CurrencyPipe#currency-code-deprecation) | <!--v9--> v11 |
| `@angular/core` | [`CollectionChangeRecord`](#core) | <!--v7--> v11 |
@ -59,10 +60,9 @@ v9 - v12
| `@angular/core/testing` | [`TestBed.get`](#testing) | <!--v9--> v12 |
| `@angular/router` | [`ActivatedRoute` params and `queryParams` properties](#activatedroute-props) | unspecified |
| template syntax | [`/deep/`, `>>>`, and `::ng-deep`](#deep-component-style-selector) | <!--v7--> unspecified |
| browser support | [`IE 9 and 10`](#ie-9-10) | <!--v10--> v11 |
| browser support | [`IE 9 and 10, IE mobile`](#ie-9-10-and-mobile) | <!--v10--> v11 |
For information about Angular CDK and Angular Material deprecations, see the [changelog](https://github.com/angular/components/blob/master/CHANGELOG.md).
## Deprecated APIs
@ -160,7 +160,11 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i
This section lists all of the currently-deprecated features, which includes template syntax, configuration options, and any other deprecations not listed in the [Deprecated APIs](#deprecated-apis) section above. It also includes deprecated API usage scenarios or API combinations, to augment the information above.
{@a bazelbuilder}
### Bazel builder and schematics
Bazel builder and schematics were introduced in Angular Labs to let users try out Bazel without having to manage Bazel version and BUILD files.
This feature has been deprecated. For more information, please refer to the [migration doc](https://github.com/angular/angular/blob/master/packages/bazel/src/schematics/README.md).
{@a wtf}
### Web Tracing Framework integration
@ -459,17 +463,17 @@ export class MyModule {
```
{@a ie-9-10}
### IE 9 and 10 support
{@a ie-9-10-and-mobile}
### IE 9, 10, and IE mobile support
Support for IE 9 and 10 has been deprecated and will be removed in a future version.
Support for IE 9 and 10 has been deprecated, as well as support for IE Mobile. These will be dropped in a future version.
Supporting outdated browsers like these increases bundle size, code complexity, and test load, and also requires time and effort that could be spent on improvements to the framework.
For example, fixing issues can be more difficult, as a straightforward fix for modern browsers could break old ones that have quirks due to not receiving updates from vendors.
The final decision was made on three key points:
* __Vendor support__: Microsoft dropped support of IE 9 and 10 on 1/12/16, meaning they no longer provide security updates or technical support.
* __Usage statistics__: We looked at usage trends for IE 9 and 10 from various sources and all indicated that usage percentages were extremely small (fractions of 1%).
* __Feedback from partners__: We also reached out to some of our Angular customers and none expressed concern about dropping IE 9 and 10 support.
* __Vendor support__: Microsoft dropped support of IE 9 and 10 on 1/12/16, meaning they no longer provide security updates or technical support. Additionally, Microsoft dropped support for Windows 10 Mobile in December 2019.
* __Usage statistics__: We looked at usage trends for IE 9 and 10 (as well as IE Mobile) from various sources and all indicated that usage percentages were extremely small (fractions of 1%).
* __Feedback from partners__: We also reached out to some of our Angular customers and none expressed concern about dropping IE 9, 10, nor IE Mobile support.
{@a wrapped-value}
@ -485,6 +489,56 @@ If you rely on the behavior that the same object instance should cause change de
- Clone the resulting value so that it has a new identity.
- Explicitly call [`ChangeDetectorRef.detectChanges()`](api/core/ChangeDetectorRef#detectchanges) to force the update.
{@a deprecated-cli-flags}
## Deprecated CLI APIs and Options
This section contains a complete list all of the currently deprecated CLI flags.
### @angular-devkit/build-angular
| API/Option | May be removed in | Notes |
| ------------------------------- | ----------------- |-------------------------------------------------------------------------------- |
| `i18nFile` | <!--v9--> v11 | Specified in the project locale configuration in version 9 and later. |
| `i18nFormat` | <!--v9--> v11 | Format is now automatically detected. |
| `i18nLocale` | <!--v9--> v11 | New [localization option](/guide/i18n#localize-config) in version 9 and later. |
| `lazyModules` | <!--v9--> v11 | Used with deprecated SystemJsNgModuleLoader. |
| `rebaseRootRelativeCssUrls` | <!--v8--> v11 | Intended only to assist with specific migration issues. |
| `scripts[].lazy` | <!--v8--> v11 | Renamed to `scripts[].inject`. |
| `styles[].lazy` | <!--v8--> v11 | Renamed to `styles[].inject`. |
| `i18nFormat` | <!--v9--> v11 | Renamed to `format` to simplify the user experience. |
| `i18nLocale` | <!--v9--> v11 | Redundant with projects source locale. |
| `scripts[].lazy` | <!--v8--> v11 | Renamed to `scripts[].inject`. |
| `styles[].lazy` | <!--v8--> v11 | Renamed to `styles[].inject`. |
| `i18nFile` | <!--v9--> v11 | Specified in the project locale configuration in version 9 and later. |
| `i18nFormat` | <!--v9--> v11 | Format is now automatically detected. |
| `i18nLocale` | <!--v9--> v11 | New [localization option](/guide/i18n#localize-config) in version 9 and later. |
| `lazyModules` | <!--v9--> v11 | Used with deprecated SystemJsNgModuleLoader. |
### @angular-devkit/core
| API/Option | May be removed in | Notes |
| ------------------------------- | ----------------- |-------------------------------------------------------------------------------- |
| `ModuleNotFoundException` | <!--v8--> v10 | Not used within projects. Used with Tooling API only. Not Yarn PnP compatible and not used in the Angular CLI. Use Node.js [require.resolve](https://nodejs.org/api/modules.html#modules_require_resolve_request_options).|
| `resolve` | <!--v8--> v10 | Not used within projects. Used with Tooling API only. Not Yarn PnP compatible and not used in the Angular CLI. Use Node.js [require.resolve](https://nodejs.org/api/modules.html#modules_require_resolve_request_options).|
| `setResolveHook` | <!--v8--> v10 | Not used within projects. Used with Tooling API only. Not Yarn PnP compatible and not used in the Angular CLI. Use Node.js [require.resolve](https://nodejs.org/api/modules.html#modules_require_resolve_request_options).|
| `ResolveOptions` | <!--v8--> v10 | Not used within projects. Used with Tooling API only. Not Yarn PnP compatible and not used in the Angular CLI. Use Node.js [require.resolve](https://nodejs.org/api/modules.html#modules_require_resolve_request_options).|
| `terminal` | <!--v8--> v10 | Unused implementation of terminal codes (color). |
| `isObservable` | <!--v8--> v10 | Not used within projects. Used with Tooling API only. Use `isObservable` function from the `rxjs` package.|
### @ngtools/webpack
| API/Option | May be removed in | Notes |
| ------------------------------- | ----------------- |-------------------------------------------------------------------------------- |
| `discoverLazyRoutes` | <!--v9--> TBD | Used with deprecated SystemJsNgModuleLoader. |
| `additionalLazyModules` | <!--v9--> TBD | Used with deprecated SystemJsNgModuleLoader. |
| `additionalLazyModuleResources` | <!--v9--> TBD | Used with deprecated SystemJsNgModuleLoader. |
### @schematics/angular
| API/Option | May be removed in | Notes |
| ------------------------------- | ----------------- |-------------------------------------------------------------------------------- |
| `entryComponent` | <!--v9--> TBD | No longer needed with Ivy. |
{@a removed}
## Removed APIs

View File

@ -153,14 +153,14 @@ It marks that `<li>` element (and its children) as the "repeater template":
<div class="alert is-important">
Don't forget the leading asterisk (\*) in `*ngFor`. It is an essential part of the syntax.
Read more about `ngFor` and `*` in the [ngFor section](guide/template-syntax#ngfor) of the [Template Syntax](guide/template-syntax) page.
Read more about `ngFor` and `*` in the [ngFor section](guide/built-in-directives#ngfor) of the [Built-in directives](guide/built-in-directives) page.
</div>
Notice the `hero` in the `ngFor` double-quoted instruction;
it is an example of a template input variable. Read
more about template input variables in the [microsyntax](guide/template-syntax#microsyntax) section of
the [Template Syntax](guide/template-syntax) page.
more about template input variables in the [microsyntax](guide/built-in-directives#microsyntax) section of
the [Built-in directives](guide/built-in-directives) page.
Angular duplicates the `<li>` for each item in the list, setting the `hero` variable
to the item (the hero) in the current iteration. Angular uses that variable as the
@ -255,7 +255,7 @@ To see it in action, add the following paragraph at the bottom of the template:
<div class="alert is-important">
Don't forget the leading asterisk (\*) in `*ngIf`. It is an essential part of the syntax.
Read more about `ngIf` and `*` in the [ngIf section](guide/template-syntax#ngIf) of the [Template Syntax](guide/template-syntax) page.
Read more about `ngIf` and `*` in the [ngIf section](guide/built-in-directives#ngIf) of the [Built-in directives](guide/built-in-directives) page.
</div>
@ -266,7 +266,7 @@ When the component's list of heroes has more than three items, Angular adds the
to the DOM and the message appears.
If there are three or fewer items, Angular omits the paragraph, so no message appears.
For more information, see [template expressions](guide/template-syntax#template-expressions).
For more information, see [template expression operators](guide/interpolation#template-expressions).
<div class="alert is-helpful">

View File

@ -931,7 +931,7 @@ If you do, be sure to set the `id` attribute - not the `name` attribute! The doc
</div>
## Alerts and Calllouts
## Alerts and Callouts
Alerts and callouts present warnings, extra detail or references to other pages. They can also be used to provide commentary that _enriches_ the reader's understanding of the content being presented.

View File

@ -117,9 +117,9 @@ The recently-developed [custom elements](https://developer.mozilla.org/en-US/doc
</tr>
</table>
In browsers that support Custom Elements natively, the specification requires developers use ES2015 classes to define Custom Elements - developers can opt-in to this by setting the `target: "es2015"` property in their project's `tsconfig.json`. As Custom Element and ES2015 support may not be available in all browsers, developers can instead choose to use a polyfill to support older browsers and ES5 code.
In browsers that support Custom Elements natively, the specification requires developers use ES2015 classes to define Custom Elements - developers can opt-in to this by setting the `target: "es2015"` property in their project's [TypeScript configuration file](/guide/typescript-configuration). As Custom Element and ES2015 support may not be available in all browsers, developers can instead choose to use a polyfill to support older browsers and ES5 code.
Use the [Angular CLI](cli) to automatically set up your project with the correct polyfill: `ng add @angular/elements --name=*your_project_name*`.
Use the [Angular CLI](cli) to automatically set up your project with the correct polyfill: `ng add @angular/elements --project=*your_project_name*`.
- For more information about polyfills, see [polyfill documentation](https://www.webcomponents.org/polyfills).
- For more information about Angular browser support, see [Browser Support](guide/browser-support).
@ -186,7 +186,7 @@ aDialog.content = 123; // <-- ERROR: TypeScript knows this should be a string.
aDialog.body = 'News'; // <-- ERROR: TypeScript knows there is no `body` property on `aDialog`.
```
This is a good way to quickly get TypeScript features, such as type checking and autocomplete support, for you custom element. But it can get cumbersome if you need it in several places, because you have to cast the return type on every occurrence.
This is a good way to quickly get TypeScript features, such as type checking and autocomplete support, for your custom element. But it can get cumbersome if you need it in several places, because you have to cast the return type on every occurrence.
An alternative way, that only requires defining each custom element's type once, is augmenting the `HTMLElementTagNameMap`, which TypeScript uses to infer the type of a returned element based on its tag name (for DOM methods such as `document.createElement()`, `document.querySelector()`, etc.):

View File

@ -0,0 +1,108 @@
# Event binding `(event)`
Event binding allows you to listen for certain events such as
keystrokes, mouse movements, clicks, and touches.
<div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide.
</div>
Angular event binding syntax consists of a **target event** name
within parentheses on the left of an equal sign, and a quoted
template statement on the right.
The following event binding listens for the button's click events, calling
the component's `onSave()` method whenever a click occurs:
<div class="lightbox">
<img src='generated/images/guide/template-syntax/syntax-diagram.svg' alt="Syntax diagram">
</div>
## Target event
As above, the target is the button's click event.
<code-example path="event-binding/src/app/app.component.html" region="event-binding-1" header="src/app/app.component.html"></code-example>
Alternatively, use the `on-` prefix, known as the canonical form:
<code-example path="event-binding/src/app/app.component.html" region="event-binding-2" header="src/app/app.component.html"></code-example>
Element events may be the more common targets, but Angular looks first to see if the name matches an event property
of a known directive, as it does in the following example:
<code-example path="event-binding/src/app/app.component.html" region="custom-directive" header="src/app/app.component.html"></code-example>
If the name fails to match an element event or an output property of a known directive,
Angular reports an “unknown directive” error.
## *$event* and event handling statements
In an event binding, Angular sets up an event handler for the target event.
When the event is raised, the handler executes the template statement.
The template statement typically involves a receiver, which performs an action
in response to the event, such as storing a value from the HTML control
into a model.
The binding conveys information about the event. This information can include data values such as an event object, string, or number named `$event`.
The target event determines the shape of the `$event` object.
If the target event is a native DOM element event, then `$event` is a
[DOM event object](https://developer.mozilla.org/en-US/docs/Web/Events),
with properties such as `target` and `target.value`.
Consider this example:
<code-example path="event-binding/src/app/app.component.html" region="event-binding-3" header="src/app/app.component.html"></code-example>
This code sets the `<input>` `value` property by binding to the `name` property.
To listen for changes to the value, the code binds to the `input`
event of the `<input>` element.
When the user makes changes, the `input` event is raised, and the binding executes
the statement within a context that includes the DOM event object, `$event`.
To update the `name` property, the changed text is retrieved by following the path `$event.target.value`.
If the event belongs to a directive&mdash;recall that components
are directives&mdash;`$event` has whatever shape the directive produces.
## Custom events with `EventEmitter`
Directives typically raise custom events with an Angular [EventEmitter](api/core/EventEmitter).
The directive creates an `EventEmitter` and exposes it as a property.
The directive calls `EventEmitter.emit(payload)` to fire an event, passing in a message payload, which can be anything.
Parent directives listen for the event by binding to this property and accessing the payload through the `$event` object.
Consider an `ItemDetailComponent` that presents item information and responds to user actions.
Although the `ItemDetailComponent` has a delete button, it doesn't know how to delete the hero. It can only raise an event reporting the user's delete request.
Here are the pertinent excerpts from that `ItemDetailComponent`:
<code-example path="event-binding/src/app/item-detail/item-detail.component.html" header="src/app/item-detail/item-detail.component.html (template)" region="line-through"></code-example>
<code-example path="event-binding/src/app/item-detail/item-detail.component.ts" header="src/app/item-detail/item-detail.component.ts (deleteRequest)" region="deleteRequest"></code-example>
The component defines a `deleteRequest` property that returns an `EventEmitter`.
When the user clicks *delete*, the component invokes the `delete()` method,
telling the `EventEmitter` to emit an `Item` object.
Now imagine a hosting parent component that binds to the `deleteRequest` event
of the `ItemDetailComponent`.
<code-example path="event-binding/src/app/app.component.html" header="src/app/app.component.html (event-binding-to-component)" region="event-binding-to-component"></code-example>
When the `deleteRequest` event fires, Angular calls the parent component's
`deleteItem()` method, passing the *item-to-delete* (emitted by `ItemDetail`)
in the `$event` variable.
## Template statements have side effects
Though [template expressions](guide/interpolation#template-expressions) shouldn't have [side effects](guide/property-binding#avoid-side-effects), template
statements usually do. The `deleteItem()` method does have
a side effect: it deletes an item.
Deleting an item updates the model, and depending on your code, triggers
other changes including queries and saving to a remote server.
These changes propagate through the system and ultimately display in this and other views.

View File

@ -40,7 +40,8 @@ The top level of the workspace contains workspace-wide configuration files, conf
| `package-lock.json` | Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. |
| `src/` | Source files for the root-level application project. |
| `node_modules/` | Provides [npm packages](guide/npm-packages) to the entire workspace. Workspace-wide `node_modules` dependencies are visible to all projects. |
| `tsconfig.json` | Default [TypeScript](https://www.typescriptlang.org/) configuration for projects in the workspace. |
| `tsconfig.json` | The `tsconfig.json` file is a ["Solution Style"](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#support-for-solution-style-tsconfigjson-files) TypeScript configuration file. Code editors and TypeScripts language server use this file to improve development experience. Compilers do not use this file. |
| `tsconfig.base.json` | The base [TypeScript](https://www.typescriptlang.org/) configuration for projects in the workspace. All other configuration files inherit from this base file. For more information, see the [Configuration inheritance with extends](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#configuration-inheritance-with-extends) section of the TypeScript documentation.|
| `tslint.json` | Default [TSLint](https://palantir.github.io/tslint/) configuration for projects in the workspace. |
@ -54,7 +55,7 @@ This initial root-level application is the *default app* for CLI commands (unles
<div class="alert is-helpful">
Besides using the CLI on the command line, you can also use an interactive development environment like [Angular Console](https://angularconsole.com/), or manipulate files directly in the app's source folder and configuration files.
Besides using the CLI on the command line, you can also manipulate files directly in the app's source folder and configuration files.
</div>
@ -77,6 +78,12 @@ Files at the top level of `src/` support testing and running your application. S
| `styles.sass` | Lists CSS files that supply styles for a project. The extension reflects the style preprocessor you have configured for the project. |
| `test.ts` | The main entry point for your unit tests, with some Angular-specific configuration. You don't typically need to edit this file. |
<div class="alert is-helpful">
If you create an application using Angular's strict mode, you will also have an additional `package.json` file in the `src/app` directory. For more information, see [Strict mode](/guide/strict-mode).
</div>
{@a app-src}
Inside the `src/` folder, the `app/` folder contains your project's logic and data.
@ -89,13 +96,14 @@ Angular components, templates, and styles go here.
| `app/app.component.css` | Defines the base CSS stylesheet for the root `AppComponent`. |
| `app/app.component.spec.ts` | Defines a unit test for the root `AppComponent`. |
| `app/app.module.ts` | Defines the root module, named `AppModule`, that tells Angular how to assemble the application. Initially declares only the `AppComponent`. As you add more components to the app, they must be declared here. |
| `app/package.json` | This file is generated only in applications created using `--strict` mode. This file is not used by package managers. It is used to tell the tools and bundlers whether the code under this directory is free of non-local [side-effects](guide/strict-mode#side-effect). |
### Application configuration files
The application-specific configuration files for the root application reside at the workspace root level.
For a multi-project workspace, project-specific configuration files are in the project root, under `projects/project-name/`.
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.json`, and project-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.base.json`, and project-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
| APPLICATION-SPECIFIC CONFIG FILES | PURPOSE |
| :--------------------- | :------------------------------------------|

View File

@ -4,22 +4,27 @@ Handling user input with forms is the cornerstone of many common applications. A
Angular provides two different approaches to handling user input through forms: reactive and template-driven. Both capture user input events from the view, validate the user input, create a form model and data model to update, and provide a way to track changes.
Reactive and template-driven forms process and manage form data differently. Each offers different advantages.
**In general:**
* **Reactive forms** are more robust: they're more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms.
* **Template-driven forms** are useful for adding a simple form to an app, such as an email list signup form. They're easy to add to an app, but they don't scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, use template-driven forms.
This guide provides information to help you decide which type of form works best for your situation. It introduces the common building blocks used by both approaches. It also summarizes the key differences between the two approaches, and demonstrates those differences in the context of setup, data flow, and testing.
<div class="alert is-helpful">
## Prerequisites
**Note:** For complete information about each kind of form, see [Reactive Forms](guide/reactive-forms) and [Template-driven Forms](guide/forms).
This guide assumes that you have a basic understanding of the following.
</div>
* [TypeScript](https://www.typescriptlang.org/docs/home.html "The TypeScript language") and HTML5 programming.
## Key differences
* Angular app-design fundamentals, as described in [Angular Concepts](guide/architecture "Introduction to Angular concepts.").
* The basics of [Angular template syntax](guide/architecture-components#template-syntax "Template syntax intro").
## Choosing an approach
Reactive forms and template-driven forms process and manage form data differently. Each approach offers different advantages.
* **Reactive forms** provide direct, explicit access to the underlying forms object model. Compared to template-driven forms, they are more robust: they're more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms.
* **Template-driven forms** rely on directives in the template to create and manipulate the underlying object model. They are useful for adding a simple form to an app, such as an email list signup form. They're easy to add to an app, but they don't scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, template-driven forms could be a good fit.
### Key differences
The table below summarizes the key differences between reactive and template-driven forms.
@ -30,17 +35,33 @@ The table below summarizes the key differences between reactive and template-dri
||Reactive|Template-driven|
|--- |--- |--- |
|Setup (form model)|More explicit, created in component class|Less explicit, created by directives|
|Data model|Structured|Unstructured|
|Predictability|Synchronous|Asynchronous|
|Form validation|Functions|Directives|
|Mutability|Immutable|Mutable|
|Scalability|Low-level API access|Abstraction on top of APIs|
|[Setup of form model](#setup) | Explicit, created in component class | Implicit, created by directives |
|[Data model](#data-flow-in-forms) | Structured and immutable | Unstructured and mutable |
|Predictability | Synchronous | Asynchronous |
|[Form validation](#validation) | Functions | Directives |
## Common foundation
### Scalability
Both reactive and template-driven forms share underlying building blocks.
If forms are a central part of your application, scalability is very important. Being able to reuse form models across components is critical.
Reactive forms are more scalable than template-driven forms. They provide direct access to the underlying form API, and synchronous access to the form data model, making creating large-scale forms easier.
Reactive forms require less setup for testing, and testing does not require deep understanding of change detection to properly test form updates and validation.
Template-driven forms focus on simple scenarios and are not as reusable.
They abstract away the underlying form API, and provide only asynchronous access to the form data model.
The abstraction of template-driven forms also affects testing.
Tests are deeply reliant on manual change detection execution to run properly, and require more setup.
{@a setup}
## Setting up the form model
Both reactive and template-driven forms track value changes between the form input elements that users interact with and the form data in your component model.
The two approaches share underlying building blocks, but differ in how you create and manage the common form-control instances.
### Common form foundation classes
Both reactive and template-driven forms are built on the following base classes.
* `FormControl` tracks the value and validation status of an individual form control.
@ -50,59 +71,59 @@ Both reactive and template-driven forms share underlying building blocks.
* `ControlValueAccessor` creates a bridge between Angular `FormControl` instances and native DOM elements.
See the [Form model setup](#setup-the-form-model) section below for an introduction to how these control instances are created and managed with reactive and template-driven forms. Further details are provided in the [data flow section](#data-flow-in-forms) of this guide.
{@a setup-the-form-model}
## Form model setup
Reactive and template-driven forms both use a form model to track value changes between Angular forms and form input elements. The examples below show how the form model is defined and created.
### Setup in reactive forms
Here's a component with an input field for a single control implemented using reactive forms.
With reactive forms, you define the form model directly in the component class.
The `[formControl]` directive links the explicitly created `FormControl` instance to a specific form element in the view, using an internal value accessor.
The following component implements an input field for a single control, using reactive forms. In this example, the form model is the `FormControl` instance.
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.ts">
</code-example>
The source of truth provides the value and status of the form element at a given point in time. In reactive forms, the form model is the source of truth. In the example above, the form model is the `FormControl` instance.
Figure 1 shows how, in reactive forms, the form model is the source of truth; it provides the value and status of the form element at any given point in time, through the `[formControl]` directive on the input element.
**Figure 1.** *Direct access to forms model in a reactive form.*
<div class="lightbox">
<img src="generated/images/guide/forms-overview/key-diff-reactive-forms.png" alt="Reactive forms key differences">
</div>
With reactive forms, the form model is explicitly defined in the component class. The reactive form directive (in this case, `FormControlDirective`) then links the existing `FormControl` instance to a specific form element in the view using a value accessor (`ControlValueAccessor` instance).
### Setup in template-driven forms
Here's the same component with an input field for a single control implemented using template-driven forms.
In template-driven forms, the form model is implicit, rather than explicit. The directive `NgModel` creates and manages a `FormControl` instance for a given form element.
The following component implements the same input field for a single control, using template-driven forms.
<code-example path="forms-overview/src/app/template/favorite-color/favorite-color.component.ts">
</code-example>
In template-driven forms, the source of truth is the template.
In a template-driven form the source of truth is the template. You do not have direct programmatic access to the `FormControl` instance, as shown in Figure 2.
**Figure 2.** *Indirect access to forms model in a template-driven form.*
<div class="lightbox">
<img src="generated/images/guide/forms-overview/key-diff-td-forms.png" alt="Template-driven forms key differences">
</div>
The abstraction of the form model promotes simplicity over structure. The template-driven form directive `NgModel` is responsible for creating and managing the `FormControl` instance for a given form element. It's less explicit, but you no longer have direct control over the form model.
{@a data-flow-in-forms}
## Data flow in forms
When building forms in Angular, it's important to understand how the framework handles data flowing from the user or from programmatic changes. Reactive and template-driven forms follow two different strategies when handling form input. The data flow examples below begin with the favorite color input field example from above, and then show how changes to favorite color are handled in reactive forms compared to template-driven forms.
When an application contains a form, Angular must keep the view in sync with the component model and the component model in sync with the view.
As users change values and make selections through the view, the new values must be reflected in the data model.
Similarly, when the program logic changes values in the data model, those values must be reflected in the view.
Reactive and template-driven forms differ in how they handle data flowing from the user or from programmatic changes.
The following diagrams illustrate both kinds of data flow for each type of form, using the favorite-color input field defined above.
### Data flow in reactive forms
As described above, in reactive forms each form element in the view is directly linked to a form model (`FormControl` instance). Updates from the view to the model and from the model to the view are synchronous and aren't dependent on the UI rendered. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
In reactive forms each form element in the view is directly linked to the form model (a `FormControl` instance). Updates from the view to the model and from the model to the view are synchronous and do not depend on how the UI is rendered.
<div class="lightbox">
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-vtm.png" alt="Reactive forms data flow - view to model" width="100%">
</div>
The steps below outline the data flow from view to model.
The view-to-model diagram shows how data flows when an input field's value is changed from the view through the following steps.
1. The user types a value into the input element, in this case the favorite color *Blue*.
1. The form input element emits an "input" event with the latest value.
@ -111,25 +132,25 @@ The steps below outline the data flow from view to model.
1. Any subscribers to the `valueChanges` observable receive the new value.
<div class="lightbox">
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-mtv.png" alt="Reactive forms data flow - model to view" width="100%">
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-vtm.png" alt="Reactive forms data flow - view to model">
</div>
The steps below outline the data flow from model to view.
The model-to-view diagram shows how a programmatic change to the model is propagated to the view through the following steps.
1. The user calls the `favoriteColorControl.setValue()` method, which updates the `FormControl` value.
1. The `FormControl` instance emits the new value through the `valueChanges` observable.
1. Any subscribers to the `valueChanges` observable receive the new value.
1. The control value accessor on the form input element updates the element with the new value.
### Data flow in template-driven forms
In template-driven forms, each form element is linked to a directive that manages the form model internally. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
<div class="lightbox">
<img src="generated/images/guide/forms-overview/dataflow-td-forms-vtm.png" alt="Template-driven forms data flow - view to model" width="100%">
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-mtv.png" alt="Reactive forms data flow - model to view">
</div>
The steps below outline the data flow from view to model when the input value changes from *Red* to *Blue*.
### Data flow in template-driven forms
In template-driven forms, each form element is linked to a directive that manages the form model internally.
The view-to-model diagram shows how data flows when an input field's value is changed from the view through the following steps.
1. The user types *Blue* into the input element.
1. The input element emits an "input" event with the value *Blue*.
@ -141,10 +162,10 @@ The steps below outline the data flow from view to model when the input value ch
is updated to the value emitted by the `ngModelChange` event (*Blue*).
<div class="lightbox">
<img src="generated/images/guide/forms-overview/dataflow-td-forms-mtv.png" alt="Template-driven forms data flow - model to view" width="100%">
<img src="generated/images/guide/forms-overview/dataflow-td-forms-vtm.png" alt="Template-driven forms data flow - view to model" width="100%">
</div>
The steps below outline the data flow from model to view when the `favoriteColor` changes from *Blue* to *Red*.
The model-to-view diagram shows how data flows from model to view when the `favoriteColor` changes from *Blue* to *Red*, through the following steps
1. The `favoriteColor` value is updated in the component.
1. Change detection begins.
@ -156,6 +177,30 @@ The steps below outline the data flow from model to view when the `favoriteColor
1. Any subscribers to the `valueChanges` observable receive the new value.
1. The control value accessor updates the form input element in the view with the latest `favoriteColor` value.
<div class="lightbox">
<img src="generated/images/guide/forms-overview/dataflow-td-forms-mtv.png" alt="Template-driven forms data flow - model to view" width="100%">
</div>
### Mutability of the data model
The change-tracking method plays a role in the efficiency of your application.
* **Reactive forms** keep the data model pure by providing it as an immutable data structure.
Each time a change is triggered on the data model, the `FormControl` instance returns a new data model rather than updating the existing data model.
This gives you the ability to track unique changes to the data model through the control's observable.
Change detection is more efficient because it only needs to update on unique changes.
Because data updates follow reactive patterns, you can integrate with observable operators to transform data.
* **Template-driven** forms rely on mutability with two-way data binding to update the data model in the component as changes are made in the template.
Because there are no unique changes to track on the data model when using two-way data binding, change detection is less efficient at determining when updates are required.
The difference is demonstrated in the previous examples that use the favorite-color input element.
* With reactive forms, the **`FormControl` instance** always returns a new value when the control's value is updated.
* With template-driven forms, the **favorite color property** is always modified to its new value.
{@a validation}
## Form validation
Validation is an integral part of managing any set of forms. Whether you're checking for required fields or querying an external API for an existing username, Angular provides a set of built-in validators as well as the ability to create custom validators.
@ -167,36 +212,37 @@ For more information, see [Form Validation](guide/form-validation).
## Testing
Testing plays a large part in complex applications and a simpler testing strategy is useful when validating that your forms function correctly. Reactive forms and template-driven forms have different levels of reliance on rendering the UI to perform assertions based on form control and form field changes. The following examples demonstrate the process of testing forms with reactive and template-driven forms.
Testing plays a large part in complex applications. A simpler testing strategy is useful when validating that your forms function correctly.
Reactive forms and template-driven forms have different levels of reliance on rendering the UI to perform assertions based on form control and form field changes.
The following examples demonstrate the process of testing forms with reactive and template-driven forms.
### Testing reactive forms
Reactive forms provide a relatively easy testing strategy because they provide synchronous access to the form and data models, and they can be tested without rendering the UI. In these tests, status and data are queried and manipulated through the control without interacting with the change detection cycle.
Reactive forms provide a relatively easy testing strategy because they provide synchronous access to the form and data models, and they can be tested without rendering the UI.
In these tests, status and data are queried and manipulated through the control without interacting with the change detection cycle.
The following tests use the favorite color components mentioned earlier to verify the data flows from view to model and model to view for a reactive form.
The following tests use the favorite-color components from previous examples to verify the view-to-model and model-to-view data flows for a reactive form.
The following test verifies the data flow from view to model.
**Verifying view-to-model data flow**
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="view-to-model" header="Favorite color test - view to model">
</code-example>
Here are the steps performed in the view to model test.
The first example performs the following steps to verify the view-to-model data flow.
1. Query the view for the form input element, and create a custom "input" event for the test.
1. Set the new value for the input to *Red*, and dispatch the "input" event on the form input element.
1. Assert that the component's `favoriteColorControl` value matches the value from the input.
The following test verifies the data flow from model to view.
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="model-to-view" header="Favorite color test - model to view">
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="view-to-model" header="Favorite color test - view to model">
</code-example>
Here are the steps performed in the model to view test.
The next example performs the following steps to verify the model-to-view data flow.
1. Use the `favoriteColorControl`, a `FormControl` instance, to set the new value.
1. Query the view for the form input element.
1. Assert that the new value set on the control matches the value in the input.
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="model-to-view" header="Favorite color test - model to view">
</code-example>
### Testing template-driven forms
Writing tests with template-driven forms requires a detailed knowledge of the change detection process and an understanding of how directives run on each cycle to ensure that elements are queried, tested, or changed at the correct time.
@ -228,46 +274,17 @@ Here are the steps performed in the model to view test.
1. Query the view for the form input element.
1. Assert that the input value matches the value of the `favoriteColor` property in the component instance.
## Mutability
The change tracking method plays a role in the efficiency of your application.
* **Reactive forms** keep the data model pure by providing it as an immutable data structure. Each time a change is triggered on the data model, the `FormControl` instance returns a new data model rather than updating the existing data model. This gives you the ability to track unique changes to the data model through the control's observable. This provides one way for change detection to be more efficient because it only needs to update on unique changes. It also follows reactive patterns that integrate with observable operators to transform data.
* **Template-driven** forms rely on mutability with two-way data binding to update the data model in the component as changes are made in the template. Because there are no unique changes to track on the data model when using two-way data binding, change detection is less efficient at determining when updates are required.
The difference is demonstrated in the examples above using the **favorite color** input element.
* With reactive forms, the **`FormControl` instance** always returns a new value when the control's value is updated.
* With template-driven forms, the **favorite color property** is always modified to its new value.
## Scalability
If forms are a central part of your application, scalability is very important. Being able to reuse form models across components is critical.
* **Reactive forms** provide access to low-level APIs and synchronous access to the form model, making creating large-scale forms easier.
* **Template-driven** forms focus on simple scenarios, are not as reusable, abstract away the low-level APIs, and provide asynchronous access to the form model. The abstraction with template-driven forms also surfaces in testing, where testing reactive forms requires less setup and no dependence on the change detection cycle when updating and validating the form and data models during testing.
## Final thoughts
Choosing a strategy begins with understanding the strengths and weaknesses of the options presented. Low-level API and form model access, predictability, mutability, straightforward validation and testing strategies, and scalability are all important considerations in choosing the infrastructure you use to build your forms in Angular. Template-driven forms are similar to patterns in AngularJS, but they have limitations given the criteria of many modern, large-scale Angular apps. Reactive forms minimize these limitations. Reactive forms integrate with reactive patterns already present in other areas of the Angular architecture, and complement those requirements well.
## Next steps
To learn more about reactive forms, see the following guides:
* [Reactive Forms](guide/reactive-forms)
* [Form Validation](guide/form-validation#reactive-form-validation)
* [Dynamic Forms](guide/dynamic-form)
* [Reactive forms](guide/reactive-forms)
* [Form validation](guide/form-validation#reactive-form-validation)
* [Dynamic forms](guide/dynamic-form)
To learn more about template-driven forms, see the following guides:
* [Template-driven Forms](guide/forms#template-driven-forms)
* [Form Validation](guide/form-validation#template-driven-validation)
* [Building a template-driven form](guide/forms) tutorial
* [Form validation](guide/form-validation#template-driven-validation)
* `NgForm` directive API reference

View File

@ -1,389 +1,234 @@
# Template-driven forms
Forms are the mainstay of business applications.
You use forms to log in, submit a help request, place an order, book a flight,
schedule a meeting, and perform countless other data-entry tasks.
In developing a form, it's important to create a data-entry experience that guides the
user efficiently and effectively through the workflow.
<div class="alert is-helpful">
For the sample app that this page describes, see the <live-example></live-example>.
</div>
## Introduction to Template-driven forms
Developing forms requires design skills (which are out of scope for this page), as well as framework support for
*two-way data binding, change tracking, validation, and error handling*,
which you'll learn about on this page.
This page shows you how to build a simple form from scratch. Along the way you'll learn how to:
* Build an Angular form with a component and template.
* Use `ngModel` to create two-way data bindings for reading and writing input-control values.
* Track state changes and the validity of form controls.
* Provide visual feedback using special CSS classes that track the state of the controls.
* Display validation errors to users and enable/disable form controls.
* Share information across HTML elements using template reference variables.
# Building a template-driven form
{@a template-driven}
You can build forms by writing templates in the Angular [template syntax](guide/template-syntax) with
the form-specific directives and techniques described in this page.
This tutorial shows you how to create a template-driven form whose control elements are bound to data properties, with input validation to maintain data integrity and styling to improve the user experience.
Template-driven forms use [two-way data binding](guide/architecture-components#data-binding "Intro to 2-way data binding") to update the data model in the component as changes are made in the template and vice versa.
<div class="alert is-helpful">
You can also use a reactive (or model-driven) approach to build forms.
However, this page focuses on template-driven forms.
Angular supports two design approaches for interactive forms. You can build forms by writing templates using Angular [template syntax and directives](guide/glossary#template "Definition of template terms") with the form-specific directives and techniques described in this tutorial, or you can use a reactive (or model-driven) approach to build forms.
Template-driven forms are suitable for small or simple forms, while reactive forms are more scalable and suitable for complex forms.
For a comparison of the two approaches, see [Introduction to Forms](guide/forms-overview "Overview of Angular forms.")
</div>
You can build almost any form with an Angular template&mdash;login forms, contact forms, and pretty much any business form.
You can lay out the controls creatively, bind them to data, specify validation rules and display validation errors,
You can build almost any kind of form with an Angular template&mdash;login forms, contact forms, and pretty much any business form.
You can lay out the controls creatively and bind them to the data in your object model.
You can specify validation rules and display validation errors,
conditionally enable or disable specific controls, trigger built-in visual feedback, and much more.
Angular makes the process easy by handling many of the repetitive, boilerplate tasks you'd
otherwise wrestle with yourself.
This tutorial shows you how to build a form from scratch, using a simplified sample form like the one from the [Tour of Heroes tutorial](tutorial "Tour of Heroes") to illustrate the techniques.
You'll learn to build a template-driven form that looks like this:
<div class="alert is-helpful">
Run or download the example app: <live-example></live-example>.
</div>
## Objectives
This tutorial teaches you how to do the following:
* Build an Angular form with a component and template.
* Use `ngModel` to create two-way data bindings for reading and writing input-control values.
* Provide visual feedback using special CSS classes that track the state of the controls.
* Display validation errors to users and enable or disable form controls based on the form status.
* Share information across HTML elements using [template reference variables](guide/template-reference-variables).
## Prerequisites
Before going further into template-driven forms, you should have a basic understanding of the following.
* TypeScript and HTML5 programming.
* Angular app-design fundamentals, as described in [Angular Concepts](guide/architecture "Introduction to Angular concepts.").
* The basics of [Angular template syntax](guide/template-syntax "Template syntax guide").
* The form-design concepts that are presented in [Introduction to Forms](guide/forms-overview "Overview of Angular forms.").
{@a intro}
## Build a template-driven form
Template-driven forms rely on directives defined in the `FormsModule`.
* The `NgModel` directive reconciles value changes in the attached form element with changes in the data model, allowing you to respond to user input with input validation and error handling.
* The `NgForm` directive creates a top-level `FormGroup` instance and binds it to a `<form>` element to track aggregated form value and validation status.
As soon as you import `FormsModule`, this directive becomes active by default on all `<form>` tags. You don't need to add a special selector.
* The `NgModelGroup` directive creates and binds a `FormGroup` instance to a DOM element.
### The sample application
The sample form in this guide is used by the *Hero Employment Agency* to maintain personal information about heroes.
Every hero needs a job. This form helps the agency match the right hero with the right crisis.
<div class="lightbox">
<img src="generated/images/guide/forms/hero-form-1.png" alt="Clean Form">
</div>
The *Hero Employment Agency* uses this form to maintain personal information about heroes.
Every hero needs a job. It's the company mission to match the right hero with the right crisis.
The form highlights some design features that make it easier to use. For instance, the two required fields have a green bar on the left to make them easy to spot. These fields have initial values, so the form is valid and the **Submit** button is enabled.
Two of the three fields on this form are required. Required fields have a green bar on the left to make them easy to spot.
If you delete the hero name, the form displays a validation error in an attention-grabbing style:
As you work with this form, you will learn how to include validation logic, how to customize the presentation with standard CSS, and how to handle error conditions to ensure valid input.
If the user deletes the hero name, for example, the form becomes invalid. The app detects the changed status, and displays a validation error in an attention-grabbing style.
In addition, the **Submit** button is disabled, and the "required" bar to the left of the input control changes from green to red.
<div class="lightbox">
<img src="generated/images/guide/forms/hero-form-2.png" alt="Invalid, Name Required">
</div>
Note that the *Submit* button is disabled, and the "required" bar to the left of the input control changes from green to red.
### Step overview
<div class="alert is-helpful">
In the course of this tutorial, you bind a sample form to data and handle user input using the following steps.
You can customize the colors and location of the "required" bar with standard CSS.
1. Build the basic form.
* Define a sample data model.
* Include required infrastructure such as the `FormsModule`.
2. Bind form controls to data properties using the `ngModel` directive and two-way data-binding syntax.
* Examine how `ngModel` reports control states using CSS classes.
* Name controls to make them accessible to `ngModel`.
3. Track input validity and control status using `ngModel`.
* Add custom CSS to provide visual feedback on the status.
* Show and hide validation-error messages.
4. Respond to a native HTML button-click event by adding to the model data.
5. Handle form submission using the [`ngSubmit`](api/forms/NgForm#properties) output property of the form.
* Disable the **Submit** button until the form is valid.
* After submit, swap out the finished form for different content on the page.
</div>
{@a step1}
You'll build this form in small steps:
## Build the form
1. Create the `Hero` model class.
1. Create the component that controls the form.
1. Create a template with the initial form layout.
1. Bind data properties to each form control using the `ngModel` two-way data-binding syntax.
1. Add a `name` attribute to each form-input control.
1. Add custom CSS to provide visual feedback.
1. Show and hide validation-error messages.
1. Handle form submission with *ngSubmit*.
1. Disable the forms *Submit* button until the form is valid.
You can recreate the sample application from the code provided here, or you can examine or download the <live-example></live-example>.
## Setup
1. The provided sample application creates the `Hero` class which defines the data model reflected in the form.
Create a new project named <code>angular-forms</code>:
<code-example path="forms/src/app/hero.ts" header="src/app/hero.ts"></code-example>
<code-example language="sh" class="code-shell">
2. The form layout and details are defined in the `HeroFormComponent` class.
ng new angular-forms
<code-example path="forms/src/app/hero-form/hero-form.component.ts" header="src/app/hero-form/hero-form.component.ts (v1)" region="v1"></code-example>
</code-example>
The component's `selector` value of "app-hero-form" means you can drop this form in a parent
template using the `<app-hero-form>` tag.
## Create the Hero model class
3. The following code creates a new hero instance, so that the initial form can show an example hero.
As users enter form data, you'll capture their changes and update an instance of a model.
You can't lay out the form until you know what the model looks like.
<code-example path="forms/src/app/hero-form/hero-form.component.ts" region="SkyDog"></code-example>
A model can be as simple as a "property bag" that holds facts about a thing of application importance.
That describes well the `Hero` class with its three required fields (`id`, `name`, `power`)
and one optional field (`alterEgo`).
This demo uses dummy data for `model` and `powers`. In a real app, you would inject a data service to get and save real data, or expose these properties as inputs and outputs.
Using the Angular CLI command [`ng generate class`](cli/generate), generate a new class named `Hero`:
4. The application enables the Forms feature and registers the created form component.
<code-example language="sh" class="code-shell">
<code-example path="forms/src/app/app.module.ts" header="src/app/app.module.ts"></code-example>
ng generate class Hero
5. The form is displayed in the application layout defined by the root component's template.
</code-example>
<code-example path="forms/src/app/app.component.html" header="src/app/app.component.html"></code-example>
With this content:
The initial template defines the layout for a form with two form groups and a submit button.
The form groups correspond to two properties of the Hero data model, name and alterEgo. Each group has a label and a box for user input.
<code-example path="forms/src/app/hero.ts" header="src/app/hero.ts"></code-example>
* The **Name** `<input>` control element has the HTML5 `required` attribute.
* The **Alter Ego** `<input>` control element does not because `alterEgo` is optional.
It's an anemic model with few requirements and no behavior. Perfect for the demo.
The **Submit** button has some classes on it for styling.
At this point, the form layout is all plain HTML5, with no bindings or directives.
The TypeScript compiler generates a public field for each `public` constructor parameter and
automatically assigns the parameters value to that field when you create heroes.
6. The sample form uses some style classes from [Twitter Bootstrap](http://getbootstrap.com/css/): `container`, `form-group`, `form-control`, and `btn`.
To use these styles, the app's style sheet imports the library.
The `alterEgo` is optional, so the constructor lets you omit it; note the question mark (?) in `alterEgo?`.
<code-example path="forms/src/styles.1.css" header="src/styles.css"></code-example>
You can create a new hero like this:
7. The form makes the hero applicant choose one superpower from a fixed list of agency-approved powers.
The predefined list of `powers` is part of the data model, maintained internally in `HeroFormComponent`.
The Angular [NgForOf directive](api/common/NgForOf "API reference") iterates over the data values to populate the `<select>` element.
<code-example path="forms/src/app/hero-form/hero-form.component.ts" region="SkyDog"></code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (powers)" region="powers"></code-example>
## Create a form component
An Angular form has two parts: an HTML-based _template_ and a component _class_
to handle data and user interactions programmatically.
Begin with the class because it states, in brief, what the hero editor can do.
Using the Angular CLI command [`ng generate component`](cli/generate), generate a new component named `HeroForm`:
<code-example language="sh" class="code-shell">
ng generate component HeroForm
</code-example>
With this content:
<code-example path="forms/src/app/hero-form/hero-form.component.ts" header="src/app/hero-form/hero-form.component.ts (v1)" region="v1"></code-example>
Theres nothing special about this component, nothing form-specific,
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 "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.
Down the road, you can inject a data service to get and save real data
or perhaps expose these properties as inputs and outputs
(see [Input and output properties](guide/template-syntax#inputs-outputs) on the
[Template Syntax](guide/template-syntax) page) for binding to a
parent component. This is not a concern now and these future changes won't affect the form.
* You added a `diagnostic` property to return a JSON representation of the model.
It'll help you see what you're doing during development; you've left yourself a cleanup note to discard it later.
## Revise *app.module.ts*
`app.module.ts` defines the application's root module. In it you identify the external modules you'll use in the application
and declare the components that belong to this module, such as the `HeroFormComponent`.
Because template-driven forms are in their own module, you need to add the `FormsModule` to the array of
`imports` for the application module before you can use forms.
Update it with the following:
<code-example path="forms/src/app/app.module.ts" header="src/app/app.module.ts"></code-example>
<div class="alert is-helpful">
There are two changes:
1. You import `FormsModule`.
1. You add the `FormsModule` to the list of `imports` defined in the `@NgModule` decorator. This gives the application
access to all of the template-driven forms features, including `ngModel`.
</div>
<div class="alert is-important">
If a component, directive, or pipe belongs to a module in the `imports` array, _don't_ re-declare it in the `declarations` array.
If you wrote it and it should belong to this module, _do_ declare it in the `declarations` array.
</div>
## Revise *app.component.html*
`AppComponent` is the application's root component. It will host the new `HeroFormComponent`.
Replace the contents of its template with the following:
<code-example path="forms/src/app/app.component.html" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
There are only two changes.
The `template` is simply the new element tag identified by the component's `selector` property.
This displays the hero form when the application component is loaded.
Don't forget to remove the `name` field from the class body as well.
</div>
## Create an initial HTML form template
Update the template file with the following contents:
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="start" header="src/app/hero-form/hero-form.component.html"></code-example>
The language is simply HTML5. You're presenting two of the `Hero` fields, `name` and `alterEgo`, and
opening them up for user input in input boxes.
The *Name* `<input>` control has the HTML5 `required` attribute;
the *Alter Ego* `<input>` control does not because `alterEgo` is optional.
You added a *Submit* button at the bottom with some classes on it for styling.
*You're not using Angular yet*. There are no bindings or extra directives, just layout.
<div class="alert is-helpful">
In template driven forms, if you've imported `FormsModule`, you don't have to do anything
to the `<form>` tag in order to make use of `FormsModule`. Continue on to see how this works.
</div>
The `container`, `form-group`, `form-control`, and `btn` classes
come from [Twitter Bootstrap](http://getbootstrap.com/css/). These classes are purely cosmetic.
Bootstrap gives the form a little style.
<div class="callout is-important">
<header>
Angular forms don't require a style library
</header>
Angular makes no use of the `container`, `form-group`, `form-control`, and `btn` classes or
the styles of any external library. Angular apps can use any CSS library or none at all.
</div>
To add the stylesheet, open `styles.css` and add the following import line at the top:
<code-example path="forms/src/styles.1.css" header="src/styles.css"></code-example>
## Add powers with _*ngFor_
The hero must choose one superpower from a fixed list of agency-approved powers.
You maintain that list internally (in `HeroFormComponent`).
You'll add a `select` to the
form and bind the options to the `powers` list using `ngFor`,
a technique seen previously in the [Displaying Data](guide/displaying-data) page.
Add the following HTML *immediately below* the *Alter Ego* group:
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (powers)" region="powers"></code-example>
This code repeats the `<option>` tag for each power in the list of powers.
The `pow` template input variable is a different power in each iteration;
you display its name using the interpolation syntax.
{@a ngModel}
## Two-way data binding with _ngModel_
Running the app right now would be disappointing.
If you run the app right now, you see the list of powers in the selection control. The input elements are not yet bound to data values or events, so they are still blank and have no behavior.
<div class="lightbox">
<img src="generated/images/guide/forms/hero-form-3.png" alt="Early form with no binding">
</div>
{@a ngModel}
You don't see hero data because you're not binding to the `Hero` yet.
You know how to do that from earlier pages.
[Displaying Data](guide/displaying-data) teaches property binding.
[User Input](guide/user-input) shows how to listen for DOM events with an
event binding and how to update a component property with the displayed value.
## Bind input controls to data properties
Now you need to display, listen, and extract at the same time.
The next step is to bind the input controls to the corresponding `Hero` properties with two-way data binding, so that they respond to user input by updating the data model, and also respond to programmatic changes in the data by updating the display.
You could use the techniques you already know, but
instead you'll use the new `[(ngModel)]` syntax, which
makes binding the form to the model easy.
The `ngModel` directive declared in the `FormsModule` lets you bind controls in your template-driven form to properties in your data model.
When you include the directive using the syntax for two-way data binding, `[(ngModel)]`, Angular can track the value and user interaction of the control and keep the view synced with the model.
Find the `<input>` tag for *Name* and update it like this:
1. Edit the template file `hero-form.component.html`.
2. Find the `<input>` tag next to the **Name** label.
3. Add the `ngModel` directive, using two-way data binding syntax `[(ngModel)]="..."`.
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-1"></code-example>
<div class="alert is-helpful">
You added a diagnostic interpolation after the input tag
so you can see what you're doing.
You left yourself a note to throw it away when you're done.
This example has a temporary diagnostic interpolation after each input tag, `{{model.name}}`, to show the current data value of the corresponding property.
The note reminds you to remove the diagnostic lines when you have finished observing the two-way data binding at work.
</div>
Focus on the binding syntax: `[(ngModel)]="..."`.
{@a ngForm}
You need one more addition to display the data. Declare
a template variable for the form. Update the `<form>` tag with
`#heroForm="ngForm"` as follows:
### Access the overall form status
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="template-variable"></code-example>
When you imported the `FormsModule` in your component, Angular automatically created and attached an [NgForm](api/forms/NgForm "API reference for NgForm") directive to the `<form>` tag in the template (because `NgForm` has the selector `form` that matches `<form>` elements).
The variable `heroForm` is now a reference to the `NgForm` directive that governs the form as a whole.
To get access to the `NgForm` and the overall form status, declare a [template reference variable](guide/template-reference-variables).
<div class="alert is-helpful">
1. Edit the template file `hero-form.component.html`.
{@a ngForm}
2. Update the `<form>` tag with a template reference variable, `#heroForm`, and set its value as follows.
### The _NgForm_ directive
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="template-variable"></code-example>
What `NgForm` directive?
You didn't add an [NgForm](api/forms/NgForm) directive.
The `heroForm` template variable is now a reference to the `NgForm` directive instance that governs the form as a whole.
Angular did. Angular automatically creates and attaches an `NgForm` directive to the `<form>` tag.
3. Run the app.
The `NgForm` directive supplements the `form` element with additional features.
It holds the controls you created for the elements with an `ngModel` directive
and `name` attribute, and monitors their properties, including their validity.
It also has its own `valid` property which is true only *if every contained
control* is valid.
4. Start typing in the **Name** input box.
</div>
As you add and delete characters, you can see them appear and disappear from the data model.
For example:
If you ran the app now and started typing in the *Name* input box,
adding and deleting characters, you'd see them appear and disappear
from the interpolated text.
At some point it might look like this:
<div class="lightbox">
<img src="generated/images/guide/forms/ng-model-in-action.png" alt="ngModel in action">
</div>
<div class="lightbox">
<img src="generated/images/guide/forms/ng-model-in-action.png" alt="ngModel in action">
</div>
The diagnostic line that shows interpolated values demonstrates that values are really flowing from the input box to the model and back again.
The diagnostic is evidence that values really are flowing from the input box to the model and
back again.
### Naming control elements
<div class="alert is-helpful">
When you use `[(ngModel)]` on an element, you must define a `name` attribute for that element.
Angular uses the assigned name to register the element with the `NgForm` directive attached to the parent `<form>` element.
That's *two-way data binding*.
For more information, see
[Two-way binding with NgModel](guide/template-syntax#ngModel) on the
the [Template Syntax](guide/template-syntax) page.
The example added a `name` attribute to the `<input>` element and set it to "name",
which makes sense for the hero's name.
Any unique value will do, but using a descriptive name is helpful.
</div>
1. Add similar `[(ngModel)]` bindings and `name` attributes to **Alter Ego** and **Hero Power**.
Notice that you also added a `name` attribute to the `<input>` tag and set it to "name",
which makes sense for the hero's name. Any unique value will do, but using a descriptive name is helpful.
Defining a `name` attribute is a requirement when using `[(ngModel)]` in combination with a form.
2. You can now remove the diagnostic messages that show interpolated values.
<div class="alert is-helpful">
3. To confirm that two-way data binding works for the entire hero model, add a new binding at the top to the component's `diagnostic` property.
Internally, Angular creates `FormControl` instances and
registers them with an `NgForm` directive that Angular attached to the `<form>` tag.
Each `FormControl` is registered under the name you assigned to the `name` attribute.
Read more in the previous section, [The NgForm directive](guide/forms#ngForm).
</div>
Add similar `[(ngModel)]` bindings and `name` attributes to *Alter Ego* and *Hero Power*.
You'll ditch the input box binding message
and add a new binding (at the top) to the component's `diagnostic` property.
Then you can confirm that two-way data binding works *for the entire hero model*.
After revision, the core of the form should look like this:
After these revisions, the form template should look like the following:
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModel-2"></code-example>
<div class="alert is-helpful">
* Notice that each `<input>` element has an `id` property. This is used by the `<label>` element's `for` attribute to match the label to its input control. This is a [standard HTML feature](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label).
* Each input element has an `id` property that is used by the `label` element's `for` attribute
to match the label to its input control.
* Each input element has a `name` property that is required by Angular forms to register the control with the form.
</div>
* Each `<input>` element also has the required `name` property that Angular uses to register the control with the form.
If you run the app now and change every hero model property, the form might display like this:
@ -391,18 +236,15 @@ If you run the app now and change every hero model property, the form might disp
<img src="generated/images/guide/forms/ng-model-in-action-2.png" alt="ngModel in action">
</div>
The diagnostic near the top of the form
confirms that all of your changes are reflected in the model.
The diagnostic near the top of the form confirms that all of your changes are reflected in the model.
*Delete* the `{{diagnostic}}` binding at the top as it has served its purpose.
4. When you have observed the effects, you can delete the `{{diagnostic}}` binding.
## Track control state and validity with _ngModel_
## Track control states
Using `ngModel` in a form gives you more than just two-way data binding. It also tells
you if the user touched the control, if the value changed, or if the value became invalid.
The *NgModel* directive doesn't just track state; it updates the control with special Angular CSS classes that reflect the state.
You can leverage those class names to change the appearance of the control.
The `NgModel` directive on a control tracks the state of that control.
It tells you if the user touched the control, if the value changed, or if the value became invalid.
Angular sets special CSS classes on the control element to reflect the state, as shown in the following table.
<table>
@ -472,38 +314,32 @@ You can leverage those class names to change the appearance of the control.
</table>
Temporarily add a [template reference variable](guide/template-syntax#ref-vars) named `spy`
to the _Name_ `<input>` tag and use it to display the input's CSS classes.
You use these CSS classes to define the styles for your control based on its status.
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-2"></code-example>
### Observe control states
Now run the app and look at the _Name_ input box.
Follow these steps *precisely*:
To see how the classes are added and removed by the framework, open the browser's developer tools and inspect the `<input>` element that represents the hero name.
1. Look but don't touch.
1. Click inside the name box, then click outside it.
1. Add slashes to the end of the name.
1. Erase the name.
1. Using your browser's developer tools, find the `<input>` element that corresponds to the **Name** input box.
You can see that the element has multiple CSS classes in addition to "form-control".
The actions and effects are as follows:
2. When you first bring it up, the classes indicate that it has a valid value, that the value has not been changed since initialization or reset, and that the control has not been visited since initialization or reset.
<div class="lightbox">
<img src="generated/images/guide/forms/control-state-transitions-anim.gif" alt="Control State Transition">
</div>
```
<input ... class="form-control ng-untouched ng-pristine ng-valid" ...>
```
You should see the following transitions and class names:
3. Take the following actions on the **Name** `<input>` box, and observe which classes appear.
* Look but don't touch. The classes indicate that it is untouched, pristine, and valid.
* Click inside the name box, then click outside it. The control has now been visited, and the element has the `ng-touched` class instead of the `ng-untouched` class.
* Add slashes to the end of the name. It is now touched and dirty.
* Erase the name. This makes the value invalid, so the `ng-invalid` class replaces the `ng-valid` class.
<div class="lightbox">
<img src="generated/images/guide/forms/ng-control-class-changes.png" alt="Control state transitions">
</div>
### Create visual feedback for states
The `ng-valid`/`ng-invalid` pair is the most interesting, because you want to send a
strong visual signal when the values are invalid. You also want to mark required fields.
To create such visual feedback, add definitions for the `ng-*` CSS classes.
*Delete* the `#spy` template reference variable and the `TODO` as they have served their purpose.
## Add custom CSS for visual feedback
The `ng-valid`/`ng-invalid` pair is particularly interesting, because you want to send a
strong visual signal when the values are invalid.
You also want to mark required fields.
You can mark required fields and invalid data at the same time with a colored bar
on the left of the input box:
@ -512,20 +348,25 @@ on the left of the input box:
<img src="generated/images/guide/forms/validity-required-indicator.png" alt="Invalid Form">
</div>
You achieve this effect by adding these class definitions to a new `forms.css` file
that you add to the project as a sibling to `index.html`:
To change the appearance in this way, take the following steps.
<code-example path="forms/src/assets/forms.css" header="src/assets/forms.css"></code-example>
1. Add definitions for the `ng-*` CSS classes.
Update the `<head>` of `index.html` to include this style sheet:
2. Add these class definitions to a new `forms.css` file.
<code-example path="forms/src/index.html" header="src/index.html (styles)" region="styles"></code-example>
3. Add the new file to the project as a sibling to `index.html`:
## Show and hide validation error messages
<code-example path="forms/src/assets/forms.css" header="src/assets/forms.css"></code-example>
You can improve the form. The _Name_ input box is required and clearing it turns the bar red.
That says something is wrong but the user doesn't know *what* is wrong or what to do about it.
Leverage the control's state to reveal a helpful message.
4. In the `index.html` file, update the `<head>` tag to include the new style sheet.
<code-example path="forms/src/index.html" header="src/index.html (styles)" region="styles"></code-example>
### Show and hide validation error messages
The **Name** input box is required and clearing it turns the bar red.
That indicates that something is wrong, but the user doesn't know what is wrong or what to do about it.
You can provide a helpful message by checking for and responding to the control's state.
When the user deletes the name, the form should look like this:
@ -533,166 +374,135 @@ When the user deletes the name, the form should look like this:
<img src="generated/images/guide/forms/name-required-error.png" alt="Name required">
</div>
To achieve this effect, extend the `<input>` tag with the following:
The **Hero Power** select box is also required, but it doesn't need this kind of error handling because the selection box already constrains the selection to valid values.
* A [template reference variable](guide/template-syntax#ref-vars).
* The "*is required*" message in a nearby `<div>`, which you'll display only if the control is invalid.
To define and show an error message when appropriate, take the following steps.
Here's an example of an error message added to the _name_ input box:
1. Extend the `<input>` tag with a template reference variable that you can use to access the input box's Angular control from within the template. In the example, the variable is `#name="ngModel"`.
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="name-with-error-msg"></code-example>
<div class="alert is-helpful">
You need a template reference variable to access the input box's Angular control from within the template.
Here you created a variable called `name` and gave it the value "ngModel".
The template reference variable (`#name`) is set to `"ngModel"` because that is the value of the [`NgModel.exportAs`](api/core/Directive#exportAs) property. This property tells Angular how to link a reference variable to a directive.
<div class="alert is-helpful">
</div>
Why "ngModel"?
A directive's [exportAs](api/core/Directive) property
tells Angular how to link the reference variable to the directive.
You set `name` to `ngModel` because the `ngModel` directive's `exportAs` property happens to be "ngModel".
</div>
You control visibility of the name error message by binding properties of the `name`
2. Add a `<div>` that contains a suitable error message.
3. Show or hide the error message by binding properties of the `name`
control to the message `<div>` element's `hidden` property.
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (hidden-error-msg)" region="hidden-error-msg"></code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (hidden-error-msg)" region="hidden-error-msg"></code-example>
In this example, you hide the message when the control is valid or pristine;
"pristine" means the user hasn't changed the value since it was displayed in this form.
4. Add a conditional error message to the _name_ input box, as in the following example.
This user experience is the developer's choice. Some developers want the message to display at all times.
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="name-with-error-msg"></code-example>
<div class="callout is-helpful">
<header>Illustrating the "pristine" state</header>
In this example, you hide the message when the control is either valid or *pristine*.
Pristine means the user hasn't changed the value since it was displayed in this form.
If you ignore the `pristine` state, you would hide the message only when the value is valid.
If you arrive in this component with a new (blank) hero or an invalid hero,
you'll see the error message immediately, before you've done anything.
Some developers want the message to display only when the user makes an invalid change.
Hiding the message while the control is "pristine" achieves that goal.
You'll see the significance of this choice when you add a new hero to the form.
You might want the message to display only when the user makes an invalid change.
Hiding the message while the control is in the `pristine` state achieves that goal.
You'll see the significance of this choice when you add a new hero to the form in the next step.
The hero *Alter Ego* is optional so you can leave that be.
</div>
Hero *Power* selection is required.
You can add the same kind of error handling to the `<select>` if you want,
but it's not imperative because the selection box already constrains the
power to valid values.
## Add a new hero
Now you'll add a new hero in this form.
Place a *New Hero* button at the bottom of the form and bind its click event to a `newHero` component method.
This exercise shows how you can respond to a native HTML button-click event by adding to the model data.
To let form users add a new hero, you will add a **New Hero** button that responds to a click event.
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-no-reset" header="src/app/hero-form/hero-form.component.html (New Hero button)"></code-example>
1. In the template, place a "New Hero" `<button>` element at the bottom of the form.
2. In the component file, add the hero-creation method to the hero data model.
<code-example path="forms/src/app/hero-form/hero-form.component.ts" region="new-hero" header="src/app/hero-form/hero-form.component.ts (New Hero method)"></code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.ts" region="new-hero" header="src/app/hero-form/hero-form.component.ts (New Hero method)"></code-example>
Run the application again, click the *New Hero* button, and the form clears.
The *required* bars to the left of the input box are red, indicating invalid `name` and `power` properties.
That's understandable as these are required fields.
The error messages are hidden because the form is pristine; you haven't changed anything yet.
3. Bind the button's click event to a hero-creation method, `newHero()`.
Enter a name and click *New Hero* again.
The app displays a _Name is required_ error message.
You don't want error messages when you create a new (empty) hero.
Why are you getting one now?
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-no-reset" header="src/app/hero-form/hero-form.component.html (New Hero button)"></code-example>
Inspecting the element in the browser tools reveals that the *name* input box is _no longer pristine_.
The form remembers that you entered a name before clicking *New Hero*.
Replacing the hero object *did not restore the pristine state* of the form controls.
4. Run the application again and click the **New Hero** button.
You have to clear all of the flags imperatively, which you can do
by calling the form's `reset()` method after calling the `newHero()` method.
The form clears, and the *required* bars to the left of the input box are red, indicating invalid `name` and `power` properties.
Notice that the error messages are hidden. This is because the form is pristine; you haven't changed anything yet.
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-form-reset" header="src/app/hero-form/hero-form.component.html (Reset the form)"></code-example>
5. Enter a name and click **New Hero** again.
Now clicking "New Hero" resets both the form and its control flags.
Now the app displays a _Name is required_ error message, because the input box is no longer pristine.
The form remembers that you entered a name before clicking **New Hero**.
6. To restore the pristine state of the form controls, clear all of the flags imperatively by calling the form's `reset()` method after calling the `newHero()` method.
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-form-reset" header="src/app/hero-form/hero-form.component.html (Reset the form)"></code-example>
Now clicking **New Hero** resets both the form and its control flags.
<div class="alert is-helpful">
See the [User Input](guide/user-input) guide for more information about listening for DOM events with an event binding and updating a corresponding component property.
</div>
## Submit the form with _ngSubmit_
The user should be able to submit this form after filling it in.
The *Submit* button at the bottom of the form
does nothing on its own, but it will
trigger a form submit because of its type (`type="submit"`).
The **Submit** button at the bottom of the form does nothing on its own, but it does
trigger a form-submit event because of its type (`type="submit"`).
To respond to this event, take the following steps.
A "form submit" is useless at the moment.
To make it useful, bind the form's `ngSubmit` event property
to the hero form component's `onSubmit()` method:
1. Bind the form's [`ngSubmit`](api/forms/NgForm#properties) event property to the hero-form component's `onSubmit()` method.
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (ngSubmit)" region="ngSubmit"></code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (ngSubmit)" region="ngSubmit"></code-example>
You'd already defined a template reference variable,
`#heroForm`, and initialized it with the value "ngForm".
Now, use that variable to access the form with the Submit button.
2. Use the template reference variable, `#heroForm` to access the form that contains the **Submit** button and create an event binding.
You will bind the form property that indicates its overall validity to the **Submit** button's `disabled` property.
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (submit-button)" region="submit-button"></code-example>
You'll bind the form's overall validity via
the `heroForm` variable to the button's `disabled` property
using an event binding. Here's the code:
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (submit-button)" region="submit-button"></code-example>
If you run the application now, you find that the button is enabled&mdash;although
3. Run the application now. Notice that the button is enabled&mdash;although
it doesn't do anything useful yet.
Now if you delete the Name, you violate the "required" rule, which
is duly noted in the error message.
The *Submit* button is also disabled.
4. Delete the **Name** value. This violates the "required" rule, so it displays the error message&mdash;and notice that it also disables the **Submit** button.
Not impressed? Think about it for a moment. What would you have to do to
wire the button's enable/disabled state to the form's validity without Angular's help?
For you, it was as simple as this:
You didn't have to explicitly wire the button's enabled state to the form's validity.
The `FormsModule` did this automatically when you defined a template reference variable on the enhanced form element, then referred to that variable in the button control.
1. Define a template reference variable on the (enhanced) form element.
2. Refer to that variable in a button many lines away.
### Respond to form submission
## Toggle two form regions (extra credit)
To show a response to form submission, you can hide the data entry area and display something else in its place.
Submitting the form isn't terribly dramatic at the moment.
<div class="alert is-helpful">
An unsurprising observation for a demo. To be honest,
jazzing it up won't teach you anything new about forms.
But this is an opportunity to exercise some of your newly won
binding skills.
If you aren't interested, skip to this page's conclusion.
</div>
For a more strikingly visual effect,
hide the data entry area and display something else.
Wrap the form in a `<div>` and bind
1. Wrap the entire form in a `<div>` and bind
its `hidden` property to the `HeroFormComponent.submitted` property.
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="edit-div"></code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="edit-div"></code-example>
The main form is visible from the start because the
`submitted` property is false until you submit the form,
as this fragment from the `HeroFormComponent` shows:
* The main form is visible from the start because the `submitted` property is false until you submit the form, as this fragment from the `HeroFormComponent` shows:
<code-example path="forms/src/app/hero-form/hero-form.component.ts" header="src/app/hero-form/hero-form.component.ts (submitted)" region="submitted"></code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.ts" header="src/app/hero-form/hero-form.component.ts (submitted)" region="submitted"></code-example>
When you click the *Submit* button, the `submitted` flag becomes true and the form disappears
as planned.
* When you click the **Submit** button, the `submitted` flag becomes true and the form disappears.
Now the app needs to show something else while the form is in the submitted state.
Add the following HTML below the `<div>` wrapper you just wrote:
2. To show something else while the form is in the submitted state, add the following HTML below the new `<div>` wrapper.
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="submitted"></code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="submitted"></code-example>
There's the hero again, displayed read-only with interpolation bindings.
This `<div>` appears only while the component is in the submitted state.
This `<div>`, which shows a read-only hero with interpolation bindings, appears only while the component is in the submitted state.
The HTML includes an *Edit* button whose click event is bound to an expression
The alternative display includes an *Edit* button whose click event is bound to an expression
that clears the `submitted` flag.
When you click the *Edit* button, this block disappears and the editable form reappears.
3. Click the *Edit* button to switch the display back to the editable form.
## Summary
The Angular form discussed in this page takes advantage of the following
framework features to provide support for data modification, validation, and more:
framework features to provide support for data modification, validation, and more.
* An Angular HTML form template.
* A form component class with a `@Component` decorator.
@ -700,8 +510,8 @@ framework features to provide support for data modification, validation, and mor
* Template-reference variables such as `#heroForm` and `#name`.
* `[(ngModel)]` syntax for two-way data binding.
* The use of `name` attributes for validation and form-element change tracking.
* The reference variables `valid` property on input controls to check if a control is valid and show/hide error messages.
* Controlling the *Submit* button's enabled state by binding to `NgForm` validity.
* The reference variables `valid` property on input controls to check if a control is valid and show or hide error messages.
* Controlling the **Submit** button's enabled state by binding to `NgForm` validity.
* Custom CSS classes that provide visual feedback to users about invalid controls.
Heres the code for the final version of the application:
@ -741,4 +551,3 @@ Heres the code for the final version of the application:
</code-pane>
</code-tabs>

View File

@ -210,6 +210,7 @@ An Angular component class is responsible for exposing data and handling most of
Read more about component classes, templates, and views in [Introduction to Angular concepts](guide/architecture).
## configuration
See [workspace configuration](#cli-config)
@ -252,15 +253,15 @@ Data binding is an alternative to manually pushing application data values into
event listeners, pulling changed values from the screen, and
updating application data values.
Read about the following forms of binding in [Template Syntax](guide/template-syntax):
Read about the following forms of binding in Angular's [Template Syntax](guide/template-syntax):
* [Interpolation](guide/template-syntax#interpolation)
* [Property binding](guide/template-syntax#property-binding)
* [Event binding](guide/template-syntax#event-binding)
* [Attribute binding](guide/template-syntax#attribute-binding)
* [Class binding](guide/template-syntax#class-binding)
* [Style binding](guide/template-syntax#style-binding)
* [Two-way data binding with ngModel](guide/template-syntax#ngModel)
* [Interpolation](guide/interpolation)
* [Property binding](guide/property-binding)
* [Event binding](guide/event-binding)
* [Attribute binding](guide/attribute-binding)
* [Class binding](guide/attribute-binding#class-binding)
* [Style binding](guide/attribute-binding#style-binding)
* [Two-way data binding with ngModel](guide/built-in-directives#ngModel)
{@a declarable}
@ -472,11 +473,11 @@ Learn more about the injector hierarchy in [Hierarchical Dependency Injectors](g
## input
When defining a [directive](#directive), the `@Input()` decorator on a directive property
makes that property available as a *target* of a [property binding](guide/template-syntax#property-binding).
makes that property available as a *target* of a [property binding](guide/property-binding).
Data values flow into an input property from the data source identified
in the [template expression](#template-expression) to the right of the equal sign.
To learn more, see [input and output properties](guide/template-syntax#inputs-outputs).
To learn more, see [input and output properties](guide/inputs-outputs).
{@a interpolation}
@ -491,7 +492,7 @@ or displayed between element tags, as in this example.
```
Read more about [interpolation](guide/template-syntax#interpolation) in [Template Syntax](guide/template-syntax).
Read more in the [Interpolation](guide/interpolation) guide.
{@a ivy}
@ -578,7 +579,6 @@ Angular calls these hook methods in the following order:
To learn more, see [Lifecycle Hooks](guide/lifecycle-hooks).
{@a M}
{@a module}
@ -653,11 +653,11 @@ An object passed to the `subscribe()` method for an [observable](#observable). T
## output
When defining a [directive](#directive), the `@Output{}` decorator on a directive property
makes that property available as a *target* of [event binding](guide/template-syntax#event-binding).
makes that property available as a *target* of [event binding](guide/event-binding).
Events stream *out* of this property to the receiver identified
in the [template expression](#template-expression) to the right of the equal sign.
To learn more, see [Input and Output Properties](guide/template-syntax#inputs-outputs).
To learn more, see [Input and Output Properties](guide/inputs-outputs).
{@a P}
@ -732,13 +732,33 @@ The alternative is a [template-driven form](#template-driven-forms).
When using reactive forms:
* The "source of truth", the form model, is defined in the component class.
* Validation is set up through validation functions rather than valdation directives.
* Validation is set up through validation functions rather than validation directives.
* Each control is explicitly created in the component class by creating a `FormControl` instance manually or with `FormBuilder`.
* The template input elements do *not* use `ngModel`.
* The associated Angular directives are prefixed with `form`, such as `formControl`, `formGroup`, and `formControlName`.
The alternative is a template-driven form. For an introduction and comparison of both forms approaches, see [Introduction to Angular Forms](guide/forms-overview).
{@a resolver}
## resolver
A class that implements the [Resolve](api/router/Resolve "API reference") interface (or a function with the same signature as the [resolve() method](api/router/Resolve#resolve "API reference")) that you use to produce or retrieve data that is needed before navigation to a requested route can be completed.
Resolvers run after all [route guards](#route-guard "Definition") for a route tree have been executed and have succeeded.
See an example of using a [resolve guard](guide/router-tutorial-toh#resolve-guard "Routing techniques tutorial") to retrieve dynamic data.
{@a route-guard}
## route guard
A method that controls navigation to a requested route in a routing application.
Guards determine whether a route can be activated or deactivated, and whether a lazy-loaded module can be loaded.
Learn more in the [Routing and Navigation](guide/router#preventing-unauthorized-access "Examples") guide.
{@a router}
{@a router-module}
@ -917,7 +937,7 @@ The alternative is a reactive form. For an introduction and comparison of both f
A TypeScript-like syntax that Angular evaluates within a [data binding](#data-binding).
Read about how to write template expressions in [Template expressions](guide/template-syntax#template-expressions).
Read about how to write template expressions in the [template expressions](guide/interpolation#template-expressions) section of the [Interpolation](guide/interpolation) guide.
{@a token}
@ -950,6 +970,10 @@ Many code editors and IDEs support TypeScript either natively or with plug-ins.
TypeScript is the preferred language for Angular development.
Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).
## TypeScript configuration file
A file specifies the root files and the compiler options required to compile a TypeScript project. For more information, see [TypeScript configuration](/guide/typescript-configuration).
{@a U}

View File

@ -1,6 +1,6 @@
# Communicating with backend services using HTTP
Most front-end applications need to communicate with a server over the HTTP protocol, in order to download or upload data and accesss other back-end services.
Most front-end applications need to communicate with a server over the HTTP protocol, in order to download or upload data and access other back-end services.
Angular provides a simplified client HTTP API for Angular applications, the `HttpClient` service class in `@angular/common/http`.
The HTTP client service offers the following major features.
@ -63,7 +63,7 @@ Look at the `AppModule` _imports_ to see how it is configured.
## Requesting data from a server
Use the [`HTTPClient.get()`](api/common/http/HttpClient#get) method to fetch data from a server.
The aynchronous method sends an HTTP request, and returns an Observable that emits the requested data when the response is received.
The asynchronous method sends an HTTP request, and returns an Observable that emits the requested data when the response is received.
The return type varies based on the `observe` and `responseType` values that you pass to the call.
The `get()` method takes two arguments; the endpoint URL from which to fetch, and an *options* object that you can use to configure the request.
@ -277,7 +277,7 @@ searchHeroes(term: string): Observable {
return this.http.jsonp(heroesUrl, 'callback').pipe(
catchError(this.handleError('searchHeroes', [])) // then handle the error
);
};
}
```
This request passes the `heroesURL` as the first parameter and the callback function name as the second parameter.
@ -805,16 +805,16 @@ The `CachingInterceptor` in the following example demonstrates this approach.
header="app/http-interceptors/caching-interceptor.ts)">
</code-example>
* The `isCachable()` function determines if the request is cachable.
In this sample, only GET requests to the npm package search api are cachable.
* The `isCacheable()` function determines if the request is cacheable.
In this sample, only GET requests to the npm package search api are cacheable.
* If the request is not cachable, the interceptor simply forwards the request
* If the request is not cacheable, the interceptor simply forwards the request
to the next handler in the chain.
* If a cachable request is found in the cache, the interceptor returns an `of()` _observable_ with
* If a cacheable request is found in the cache, the interceptor returns an `of()` _observable_ with
the cached response, by-passing the `next` handler (and all other interceptors downstream).
* If a cachable request is not in cache, the code calls `sendRequest()`.
* If a cacheable request is not in cache, the code calls `sendRequest()`.
This function creates a [request clone](#immutability) without headers, because the npm API forbids them.
The function then forwards the clone of the request to `next.handle()` which ultimately calls the server and returns the server's response.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,342 @@
# `@Input()` and `@Output()` properties
`@Input()` and `@Output()` allow Angular to share data between the parent context
and child directives or components. An `@Input()` property is writable
while an `@Output()` property is observable.
<div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide.
</div>
Consider this example of a child/parent relationship:
```html
<parent-component>
<child-component></child-component>
</parent-component>
```
Here, the `<child-component>` selector, or child directive, is embedded
within a `<parent-component>`, which serves as the child's context.
`@Input()` and `@Output()` act as
the API, or application programming interface, of the child
component in that they allow the child to
communicate with the parent. Think of `@Input()` and `@Output()` like ports
or doorways&mdash;`@Input()` is the doorway into the component allowing data
to flow in while `@Output()` is the doorway out of the component, allowing the
child component to send data out.
<div class="alert is-helpful">
#### `@Input()` and `@Output()` are independent
Though `@Input()` and `@Output()` often appear together in apps, you can use
them separately. If the nested
component is such that it only needs to send data to its parent, you wouldn't
need an `@Input()`, only an `@Output()`. The reverse is also true in that if the
child only needs to receive data from the parent, you'd only need `@Input()`.
</div>
{@a input}
## How to use `@Input()`
Use the `@Input()` decorator in a child component or directive to let Angular know
that a property in that component can receive its value from its parent component.
It helps to remember that the data flow is from the perspective of the
child component. So an `@Input()` allows data to be input _into_ the
child component from the parent component.
<div class="lightbox">
<img src="generated/images/guide/inputs-outputs/input.svg" alt="Input data flow diagram">
</div>
To illustrate the use of `@Input()`, edit these parts of your app:
* The child component class and template
* The parent component class and template
### In the child
To use the `@Input()` decorator in a child component class, first import
`Input` and then decorate the property with `@Input()`:
<code-example path="inputs-outputs/src/app/item-detail/item-detail.component.ts" region="use-input" header="src/app/item-detail/item-detail.component.ts"></code-example>
In this case, `@Input()` decorates the property <code class="no-auto-link">item</code>, which has
a type of `string`, however, `@Input()` properties can have any type, such as
`number`, `string`, `boolean`, or `object`. The value for `item` will come from the parent component, which the next section covers.
Next, in the child component template, add the following:
<code-example path="inputs-outputs/src/app/item-detail/item-detail.component.html" region="property-in-template" header="src/app/item-detail/item-detail.component.html"></code-example>
### In the parent
The next step is to bind the property in the parent component's template.
In this example, the parent component template is `app.component.html`.
First, use the child's selector, here `<app-item-detail>`, as a directive within the
parent component template. Then, use [property binding](guide/property-binding)
to bind the property in the child to the property of the parent.
<code-example path="inputs-outputs/src/app/app.component.html" region="input-parent" header="src/app/app.component.html"></code-example>
Next, in the parent component class, `app.component.ts`, designate a value for `currentItem`:
<code-example path="inputs-outputs/src/app/app.component.ts" region="parent-property" header="src/app/app.component.ts"></code-example>
With `@Input()`, Angular passes the value for `currentItem` to the child so that `item` renders as `Television`.
The following diagram shows this structure:
<div class="lightbox">
<img src="generated/images/guide/inputs-outputs/input-diagram-target-source.svg" alt="Property binding diagram">
</div>
The target in the square brackets, `[]`, is the property you decorate
with `@Input()` in the child component. The binding source, the part
to the right of the equal sign, is the data that the parent
component passes to the nested component.
The key takeaway is that when binding to a child component's property in a parent component&mdash;that is, what's
in square brackets&mdash;you must
decorate the property with `@Input()` in the child component.
<div class="alert is-helpful">
### `OnChanges` and `@Input()`
To watch for changes on an `@Input()` property, use
`OnChanges`, one of Angular's [lifecycle hooks](guide/lifecycle-hooks#onchanges).
`OnChanges` is specifically designed to work with properties that have the
`@Input()` decorator. See the [`OnChanges`](guide/lifecycle-hooks#onchanges) section of the [Lifecycle Hooks](guide/lifecycle-hooks) guide for more details and examples.
</div>
{@a output}
## How to use `@Output()`
Use the `@Output()` decorator in the child component or directive to allow data to flow from
the child _out_ to the parent.
An `@Output()` property should normally be initialized to an Angular [`EventEmitter`](api/core/EventEmitter) with values flowing out of the component as [events](guide/event-binding).
<div class="lightbox">
<img src="generated/images/guide/inputs-outputs/output.svg" alt="Output diagram">
</div>
Just like with `@Input()`, you can use `@Output()`
on a property of the child component but its type should be
`EventEmitter`.
`@Output()` marks a property in a child component as a doorway
through which data can travel from the child to the parent.
The child component then has to raise an event so the
parent knows something has changed. To raise an event,
`@Output()` works hand in hand with `EventEmitter`,
which is a class in `@angular/core` that you
use to emit custom events.
When you use `@Output()`, edit these parts of your app:
* The child component class and template
* The parent component class and template
The following example shows how to set up an `@Output()` in a child
component that pushes data you enter in an HTML `<input>` to an array in the
parent component.
<div class="alert is-helpful">
The HTML element `<input>` and the Angular decorator `@Input()`
are different. This documentation is about component communication in Angular as it pertains to `@Input()` and `@Output()`. For more information on the HTML element `<input>`, see the [W3C Recommendation](https://www.w3.org/TR/html5/sec-forms.html#the-input-element).
</div>
## In the child
This example features an `<input>` where a user can enter a value and click a `<button>` that raises an event. The `EventEmitter` then relays the data to the parent component.
First, be sure to import `Output` and `EventEmitter`
in the child component class:
```js
import { Output, EventEmitter } from '@angular/core';
```
Next, still in the child, decorate a property with `@Output()` in the component class.
The following example `@Output()` is called `newItemEvent` and its type is
`EventEmitter`, which means it's an event.
<code-example path="inputs-outputs/src/app/item-output/item-output.component.ts" region="item-output" header="src/app/item-output/item-output.component.ts"></code-example>
The different parts of the above declaration are as follows:
* `@Output()`&mdash;a decorator function marking the property as a way for data to go from the child to the parent
* `newItemEvent`&mdash;the name of the `@Output()`
* `EventEmitter<string>`&mdash;the `@Output()`'s type
* `new EventEmitter<string>()`&mdash;tells Angular to create a new event emitter and that the data it emits is of type string. The type could be any type, such as `number`, `boolean`, and so on. For more information on `EventEmitter`, see the [EventEmitter API documentation](api/core/EventEmitter).
Next, create an `addNewItem()` method in the same component class:
<code-example path="inputs-outputs/src/app/item-output/item-output.component.ts" region="item-output-class" header="src/app/item-output/item-output.component.ts"></code-example>
The `addNewItem()` function uses the `@Output()`, `newItemEvent`,
to raise an event in which it emits the value the user
types into the `<input>`. In other words, when
the user clicks the add button in the UI, the child lets the parent know
about the event and gives that data to the parent.
### In the child's template
The child's template has two controls. The first is an HTML `<input>` with a
[template reference variable](guide/template-reference-variables) , `#newItem`,
where the user types in an item name. Whatever the user types
into the `<input>` gets stored in the `#newItem` variable.
<code-example path="inputs-outputs/src/app/item-output/item-output.component.html" region="child-output" header="src/app/item-output/item-output.component.html"></code-example>
The second element is a `<button>`
with an [event binding](guide/event-binding). You know it's
an event binding because the part to the left of the equal
sign is in parentheses, `(click)`.
The `(click)` event is bound to the `addNewItem()` method in the child component class which
takes as its argument whatever the value of `#newItem` is.
Now the child component has an `@Output()`
for sending data to the parent and a method for raising an event.
The next step is in the parent.
## In the parent
In this example, the parent component is `AppComponent`, but you could use
any component in which you could nest the child.
The `AppComponent` in this example features a list of `items`
in an array and a method for adding more items to the array.
<code-example path="inputs-outputs/src/app/app.component.ts" region="add-new-item" header="src/app/app.component.ts"></code-example>
The `addItem()` method takes an argument in the form of a string
and then pushes, or adds, that string to the `items` array.
### In the parent's template
Next, in the parent's template, bind the parent's
method to the child's event. Put the child selector, here `<app-item-output>`,
within the parent component's
template, `app.component.html`.
<code-example path="inputs-outputs/src/app/app.component.html" region="output-parent" header="src/app/app.component.html"></code-example>
The event binding, `(newItemEvent)='addItem($event)'`, tells
Angular to connect the event in the child, `newItemEvent`, to
the method in the parent, `addItem()`, and that the event that the child
is notifying the parent about is to be the argument of `addItem()`.
In other words, this is where the actual hand off of data takes place.
The `$event` contains the data that the user types into the `<input>`
in the child template UI.
Now, in order to see the `@Output()` working, add the following to the parent's template:
```html
<ul>
<li *ngFor="let item of items">{{item}}</li>
</ul>
```
The `*ngFor` iterates over the items in the `items` array. When you enter a value in the child's `<input>` and click the button, the child emits the event and the parent's `addItem()` method pushes the value to the `items` array and it renders in the list.
## `@Input()` and `@Output()` together
You can use `@Input()` and `@Output()` on the same child component as in the following:
<code-example path="inputs-outputs/src/app/app.component.html" region="together" header="src/app/app.component.html"></code-example>
The target, `item`, which is an `@Input()` property in the child component class, receives its value from the parent's property, `currentItem`. When you click delete, the child component raises an event, `deleteRequest`, which is the argument for the parent's `crossOffItem()` method.
The following diagram is of an `@Input()` and an `@Output()` on the same
child component and shows the different parts of each:
<div class="lightbox">
<img src="generated/images/guide/inputs-outputs/input-output-diagram.svg" alt="Input/Output diagram">
</div>
As the diagram shows, use inputs and outputs together in the same manner as using them separately. Here, the child selector is `<app-input-output>` with `item` and `deleteRequest` being `@Input()` and `@Output()`
properties in the child component class. The property `currentItem` and the method `crossOffItem()` are both in the parent component class.
To combine property and event bindings using the banana-in-a-box
syntax, `[()]`, see [Two-way Binding](guide/two-way-binding).
## `@Input()` and `@Output()` declarations
Instead of using the `@Input()` and `@Output()` decorators
to declare inputs and outputs, you can identify
members in the `inputs` and `outputs` arrays
of the directive metadata, as in this example:
<code-example path="inputs-outputs/src/app/in-the-metadata/in-the-metadata.component.ts" region="metadata" header="src/app/in-the-metadata/in-the-metadata.component.ts"></code-example>
While declaring `inputs` and `outputs` in the `@Directive` and `@Component`
metadata is possible, it is a better practice to use the `@Input()` and `@Output()`
class decorators instead, as follows:
<code-example path="inputs-outputs/src/app/input-output/input-output.component.ts" region="input-output" header="src/app/input-output/input-output.component.ts"></code-example>
See the [Decorate input and output properties](guide/styleguide#decorate-input-and-output-properties) section of the
[Style Guide](guide/styleguide) for details.
<div class="alert is-helpful">
If you get a template parse error when trying to use inputs or outputs, but you know that the
properties do indeed exist, double check
that your properties are annotated with `@Input()` / `@Output()` or that you've declared
them in an `inputs`/`outputs` array:
<code-example language="bash">
Uncaught Error: Template parse errors:
Can't bind to 'item' since it isn't a known property of 'app-item-detail'
</code-example>
</div>
{@a aliasing-io}
## Aliasing inputs and outputs
Sometimes the public name of an input/output property should be different from the internal name. While it is a best practice to avoid this situation, Angular does
offer a solution.
### Aliasing in the metadata
Alias inputs and outputs in the metadata using a colon-delimited (`:`) string with
the directive property name on the left and the public alias on the right:
<code-example path="inputs-outputs/src/app/aliasing/aliasing.component.ts" region="alias" header="src/app/aliasing/aliasing.component.ts"></code-example>
### Aliasing with the `@Input()`/`@Output()` decorator
You can specify the alias for the property name by passing the alias name to the `@Input()`/`@Output()` decorator. The internal name remains as usual.
<code-example path="inputs-outputs/src/app/aliasing/aliasing.component.ts" region="alias-input-output" header="src/app/aliasing/aliasing.component.ts"></code-example>

View File

@ -0,0 +1,175 @@
# Interpolation and template expressions
Interpolation allows you to incorporate calculated strings into the text
between HTML element tags and within attribute assignments. Template
expressions are what you use to calculate those strings.
<div class="alert is-helpful">
See the <live-example></live-example> for all of
the syntax and code snippets in this guide.
</div>
## Interpolation `{{...}}`
Interpolation refers to embedding expressions into marked up text.
By default, interpolation uses as its delimiter the double curly braces, `{{` and `}}`.
In the following snippet, `{{ currentCustomer }}` is an example of interpolation.
<code-example path="interpolation/src/app/app.component.html" region="interpolation-example1" header="src/app/app.component.html"></code-example>
The text between the braces is often the name of a component
property. Angular replaces that name with the
string value of the corresponding component property.
<code-example path="interpolation/src/app/app.component.html" region="component-property" header="src/app/app.component.html"></code-example>
In the example above, Angular evaluates the `title` and `itemImageUrl` properties
and fills in the blanks, first displaying some title text and then an image.
More generally, the text between the braces is a **template expression**
that Angular first **evaluates** and then **converts to a string**.
The following interpolation illustrates the point by adding two numbers:
<code-example path="interpolation/src/app/app.component.html" region="convert-string" header="src/app/app.component.html"></code-example>
The expression can invoke methods of the host component such as `getVal()` in
the following example:
<code-example path="interpolation/src/app/app.component.html" region="invoke-method" header="src/app/app.component.html"></code-example>
Angular evaluates all expressions in double curly braces,
converts the expression results to strings, and links them with neighboring literal strings. Finally,
it assigns this composite interpolated result to an **element or directive property**.
You appear to be inserting the result between element tags and assigning it to attributes.
However, interpolation is a special syntax that Angular converts into a *property binding*.
<div class="alert is-helpful">
If you'd like to use something other than `{{` and `}}`, you can
configure the interpolation delimiter via the
[interpolation](api/core/Component#interpolation)
option in the `Component` metadata.
</div>
## Template expressions
A template **expression** produces a value and appears within the double
curly braces, `{{ }}`.
Angular executes the expression and assigns it to a property of a binding target;
the target could be an HTML element, a component, or a directive.
The interpolation braces in `{{1 + 1}}` surround the template expression `1 + 1`.
In the property binding,
a template expression appears in quotes to the right of the&nbsp;`=` symbol as in `[property]="expression"`.
In terms of syntax, template expressions are similar to JavaScript.
Many JavaScript expressions are legal template expressions, with a few exceptions.
You can't use JavaScript expressions that have or promote side effects,
including:
* Assignments (`=`, `+=`, `-=`, `...`)
* Operators such as `new`, `typeof`, `instanceof`, etc.
* Chaining expressions with <code>;</code> or <code>,</code>
* The increment and decrement operators `++` and `--`
* Some of the ES2015+ operators
Other notable differences from JavaScript syntax include:
* No support for the bitwise operators such as `|` and `&`
* New [template expression operators](guide/template-expression-operators), such as `|`, `?.` and `!`
## Expression context
The *expression context* is typically the _component_ instance.
In the following snippets, the `recommended` within double curly braces and the
`itemImageUrl2` in quotes refer to properties of the `AppComponent`.
<code-example path="interpolation/src/app/app.component.html" region="component-context" header="src/app/app.component.html"></code-example>
An expression may also refer to properties of the _template's_ context
such as a template input variable,
<!-- link to built-in-directives#template-input-variables -->
`let customer`, or a template reference variable, `#customerInput`.
<!-- link to guide/template-ref-variables -->
<code-example path="interpolation/src/app/app.component.html" region="template-input-variable" header="src/app/app.component.html (template input variable)"></code-example>
<code-example path="interpolation/src/app/app.component.html" region="template-reference-variable" header="src/app/app.component.html (template reference variable)"></code-example>
The context for terms in an expression is a blend of the _template variables_,
the directive's _context_ object (if it has one), and the component's _members_.
If you reference a name that belongs to more than one of these namespaces,
the template variable name takes precedence, followed by a name in the directive's _context_,
and, lastly, the component's member names.
The previous example presents such a name collision. The component has a `customer`
property and the `*ngFor` defines a `customer` template variable.
<div class="alert is-helpful">
The `customer` in `{{customer.name}}`
refers to the template input variable, not the component's property.
Template expressions cannot refer to anything in
the global namespace, except `undefined`. They can't refer to
`window` or `document`. Additionally, they
can't call `console.log()` or `Math.max()` and they are restricted to referencing
members of the expression context.
</div>
## Expression guidelines
When using template expressions follow these guidelines:
* [Simplicity](guide/interpolation#simplicity)
* [Quick execution](guide/interpolation#quick-execution)
* [No visible side effects](guide/interpolation#no-visible-side-effects)
### Simplicity
Although it's possible to write complex template expressions, it's a better
practice to avoid them.
A property name or method call should be the norm, but an occasional Boolean negation, `!`, is OK.
Otherwise, confine application and business logic to the component,
where it is easier to develop and test.
### Quick execution
Angular executes template expressions after every change detection cycle.
Change detection cycles are triggered by many asynchronous activities such as
promise resolutions, HTTP results, timer events, key presses and mouse moves.
Expressions should finish quickly or the user experience may drag, especially on slower devices.
Consider caching values when their computation is expensive.
### No visible side effects
A template expression should not change any application state other than the value of the
target property.
This rule is essential to Angular's "unidirectional data flow" policy.
You should never worry that reading a component value might change some other displayed value.
The view should be stable throughout a single rendering pass.
An [idempotent](https://en.wikipedia.org/wiki/Idempotence) expression is ideal because
it is free of side effects and improves Angular's change detection performance.
In Angular terms, an idempotent expression always returns
*exactly the same thing* until one of its dependent values changes.
Dependent values should not change during a single turn of the event loop.
If an idempotent expression returns a string or a number, it returns the same string or number when called twice in a row. If the expression returns an object, including an `array`, it returns the same object *reference* when called twice in a row.
<div class="alert is-helpful">
There is one exception to this behavior that applies to `*ngFor`. `*ngFor` has `trackBy` functionality that can deal with referential inequality of objects when iterating over them. See [*ngFor with `trackBy`](guide/built-in-directives #ngfor-with-trackby) for details.
</div>

View File

@ -2,20 +2,20 @@
The Angular team has worked hard to ensure Ivy is as backwards-compatible with the previous rendering engine ("View Engine") as possible.
However, in rare cases, minor changes were necessary to ensure that the Angular's behavior was predictable and consistent, correcting issues in the View Engine implementation.
In order to smooth the transition, we have provided [automated migrations](guide/updating-to-version-9#migrations) wherever possible so your application and library code is migrated automatically by the CLI.
In order to smooth the transition, we have provided [automated migrations](guide/updating-to-version-10#migrations) wherever possible so your application and library code is migrated automatically by the CLI.
That said, some applications will likely need to apply some manual updates.
{@a debugging}
## How to debug errors with Ivy
In version 9, [a few deprecated APIs have been removed](guide/updating-to-version-9#removals) and there are a [few breaking changes](guide/updating-to-version-9#breaking-changes) unrelated to Ivy.
In version 10, [a few deprecated APIs have been removed](guide/updating-to-version-10#removals) and there are a [few breaking changes](guide/updating-to-version-10#breaking-changes) unrelated to Ivy.
If you're seeing errors after updating to version 9, you'll first want to rule those changes out.
To do so, temporarily [turn off Ivy](guide/ivy#opting-out-of-angular-ivy) in your `tsconfig.json` and re-start your app.
To do so, temporarily [turn off Ivy](guide/ivy#opting-out-of-angular-ivy) in your `tsconfig.base.json` and re-start your app.
If you're still seeing the errors, they are not specific to Ivy. In this case, you may want to consult the [general version 9 guide](guide/updating-to-version-9). If you've opted into any of the stricter type-checking settings that are new with v9, you may also want to check out the [template type-checking guide](guide/template-typecheck).
If you're still seeing the errors, they are not specific to Ivy. In this case, you may want to consult the [general version 10 guide](guide/updating-to-version-10). If you've opted into any of the new, stricter type-checking settings, you may also want to check out the [template type-checking guide](guide/template-typecheck).
If the errors are gone, switch back to Ivy by removing the changes to the `tsconfig.json` and review the list of expected changes below.
If the errors are gone, switch back to Ivy by removing the changes to the `tsconfig.base.json` and review the list of expected changes below.
{@a payload-size-debugging}
### Payload size debugging

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