Compare commits

...

229 Commits

Author SHA1 Message Date
Andrew Scott 263bbd43c1 release: cut the v11.2.2 release (#40951) 2021-02-22 13:48:16 -08:00
Andrew Scott 73a3ff11cb perf(language-service): short-circuit LS operations (#40946)
When certain information is requested from the Angular Language Service, we
know that there will be no additional Angular information if the requested
position is not in an inline template, template url, or style url. To avoid
unnecessary compiler compilations, we short circuit and return `undefined`
before asking the compiler for any type of answer which would trigger a
partial compilation, at the very least.

fixes https://github.com/angular/vscode-ng-language-service/issues/1104

PR Close #40946
2021-02-22 13:19:09 -08:00
Dmitry Drobyshev 4a32579a4d fix(http): emit error on XMLHttpRequest abort event (#40786)
Before this change, when Google Chrome cancels a XMLHttpRequest, an Observable of the response
never finishes. This happens, for example, when you put your computer to sleep or just press
Ctrl+S to save the browser page. After this commit, if request is canceled or aborted an
appropriate Observable will be completed with an error.

Fixes #22324

PR Close #40786
2021-02-22 13:01:11 -08:00
Daniel Díaz 8beead1db2 docs: update year (#40925)
PR Close #40925
2021-02-22 12:37:40 -08:00
Jon Jaques 0d5fbea5dc refactor(zone.js): update Object.create params to match web platform (#34287)
This commit updates `Object.create` argument names used in Zone.js to match web platform.

PR Close #34287
2021-02-22 08:47:39 -08:00
Alex Rickabaugh 3a39fef6b6 test(language-service): update compiler_spec to use the new testing env (#40679)
This commit updates compiler_spec.ts in the Ivy LS suite to utilize the new
testing environment which was introduced in the previous commit. Eventually
all specs should be converted, but converting one right now helps ensure
that the new testing env is working properly and able to support real tests.

PR Close #40679
2021-02-22 08:40:41 -08:00
Alex Rickabaugh 48d42e57e4 test(language-service): introduce new, more configurable testing env (#40679)
The Ivy Language Service codebase testing suite contains a few testing
utilities which allow for assertions of Language Service operations against
an in-memory project. However, this existing utility lacks the flexibility
to test more complex scenarios, such as those involving multiple TS projects
with dependencies between them.

This commit introduces a new 'testing' package for the Ivy LS which attempts
to more faithfully represent the possible states of an IDE, and allows for
testing of more advanced scenarios. The new utility borrows from the prior
version and is geared towards more ergonomic testing. Only basic
functionality is present in this initial implementation, but this will grow
over time.

PR Close #40679
2021-02-22 08:40:41 -08:00
Andrew Kushnir ff86f919ab refactor(core): use RuntimeError to throw provider not found error (#40901)
This PR performs a small refactoring to use `RuntimeError` class and corresponding error code (by calling
`throwProviderNotFoundError` which formats the message) to make it more consistent with other places where
similar errors are thrown.

PR Close #40901
2021-02-19 14:38:19 -08:00
Jefiozie 3b884ed1fc fix(http): ignore question mark when params are parsed (#40610)
This commit adds a fix where params will ignore questions marks when
parsed.

Fixes #28722

PR Close #40610
2021-02-19 12:11:39 -08:00
Benjamin Kindle f1c64b3f38 fix(animations): error when setting position before starting animation (#28255)
it is now possible to set the position when the animation has not ever been started.

PR Close #28255
2021-02-19 12:09:02 -08:00
George Kalpakas dcbf600bbc refactor(docs-infra): convert Sass mixin from camelCase to kebab-case to follow Sass conventions (#40881)
This commit converts the last remaining camelCased Sass mixin
(`deployTheme`) to kebab-case (`deploy-theme`) to follow the Sass
conventions.

Discussed in
https://github.com/angular/angular/pull/40881#discussion_r577961617.

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 9aa0ef964e refactor(docs-infra): create mixin for styling marketing pages (#40881)
Previously, in order to apply some styles to marketing (i.e. non-docs)
pages, we listed the various `.page-*` classes that corresponded to docs
pages. This meant that adding/removing a marketing page required updates
in several places, which is error-prone.

This commit avoids this by using a Sass mixin for applying styles to
marketing pages.

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 181037cd21 refactor(docs-infra): remove duplicate or unused CSS styles (#40881)
This commit removes some CSS styles that have no effect (i.e. are
duplicates or overridden by other rules).

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 36f20919b3 fix(docs-infra): fix top margin of "Press kit" page on small screens (#40881)
Previously, the "Press kit" page had a larger top margin on smaller
screens, that seemed unnecessary.

This commit removes the extra top margin.

Before: ![presskit top section margin before][1]
After: ![presskit top section margin after][2]

[1]: https://user-images.githubusercontent.com/8604205/107988545-efb27080-6fd8-11eb-91d6-79651f2dffaf.png
[2]: https://user-images.githubusercontent.com/8604205/107988547-f04b0700-6fd8-11eb-9c4b-d444b39a34fe.png

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas af8c6d39a5 fix(docs-infra): use consistent padding in marketing pages (#40881)
This commit makes the padding of the "Events", "Features" and
"Press kit" pages consistent with that of other marketing pages.

Before: ![presskit padding before][1]
After: ![presskit padding after][2]

[1]: https://user-images.githubusercontent.com/8604205/107986067-f8547800-6fd3-11eb-9164-51793e431d05.png
[2]: https://user-images.githubusercontent.com/8604205/107986064-f7234b00-6fd3-11eb-9050-ed7ec04e7443.png

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 8bbe791c75 fix(docs-infra): make top-nav consistent across all marketing pages (#40881)
Previously, some of the marketing pages had different styles for the
top-nav than others (even if they had the same layout and
blue-background header). More specifically, the top-nav had a box-shadow
and it was absolutely positioned on some marketing pages, while it had
no box-shadow and was statically positioned on others.

This commit makes the appearance of marketing pages wrt the top-nav
consistent across all marketing pages by changing the styles for the
remaining pages:
- Contributors (`/about`)
- Contribute (`/contribute`)
- Press kit (`/presskit`)

Before: ![contribute topnav shadow before][1]
After: ![contribute topnav shadow after][2]

[1]: https://user-images.githubusercontent.com/8604205/107984898-a6aaee00-6fd1-11eb-8bf3-79393c8983ff.png
[2]: https://user-images.githubusercontent.com/8604205/107984900-a7438480-6fd1-11eb-8d9b-a643d69ab692.png

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 01a3bff576 fix(docs-infra): make the "Contributors" page header similar to other marketing pages (#40881)
Before (wide screen): ![contributors (wide screen) before][1]
Before (narrow screen): ![contributors (narrow screen) before][2]
After (wide screen): ![contributors (wide screen) after][3]
After (narrow screen): ![contributors (narrow screen) after][4]

[1]: https://user-images.githubusercontent.com/8604205/107983880-634f8000-6fcf-11eb-8ad9-5a5df65d3d5e.png
[2]: https://user-images.githubusercontent.com/8604205/107983893-6a768e00-6fcf-11eb-9ccd-158ec491404f.png
[3]: https://user-images.githubusercontent.com/8604205/107983903-6f3b4200-6fcf-11eb-94e1-182893b7a715.png
[4]: https://user-images.githubusercontent.com/8604205/107983895-6ba7bb00-6fcf-11eb-9ff5-59d221ba906d.png

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 9d04484b10 fix(docs-infra): add spacing between past and future events sections (#40881)
This commit adds some more spacing between the past and future events
sections on the "Events" page.

Before: ![events spacing before][1]
After: ![events spacing after][2]

[1]: https://user-images.githubusercontent.com/8604205/107989711-82eca580-6fdb-11eb-837e-1255d439d51a.png
[2]: https://user-images.githubusercontent.com/8604205/107989708-81bb7880-6fdb-11eb-8cf4-4653254e1c37.png

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 2c6ec052c7 refactor(docs-infra): create mixin for styling docs pages (#40881)
Previously, in order to apply some styles to docs (i.e. non-marketing)
pages, we listed the various `.folder-*` classes that corresponded to
docs pages. This meant that adding/removing a docs area required updates
in several places, which is error-prone.

This commit avoids this by using a Sass mixin for applying styles to
docs pages.

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas cb1400d28f fix(docs-infra): ensure the main font is applied to inputs (#40881)
It turns out that `<input>` and `<button>` elements do not inherit the
`font-family` style from `<body>` by default, but rather use a
user-agent defined style. This means that their font-family might be
different than the one used in the rest of the page.

This commit fixes it by ensuring `<input>` (and other) elements inherit
their `font-family` style from their parent element.

Before: ![inputs font before][1]
After: ![inputs font after][2]

(The difference in font is subtle, but it's there.)

[1]: https://user-images.githubusercontent.com/8604205/107853245-76bae980-6e1d-11eb-8318-e5f6e13876cc.png
[2]: https://user-images.githubusercontent.com/8604205/107853246-77538000-6e1d-11eb-86f2-e3e7e41158f5.png

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas f926b25e07 refactor(docs-infra): remove unnecessary font-family styles (#40881)
This commit removes some unnecessary styles setting `font-family` to
`$main-font`. These styles are redundant, because the targeted elements
already inherit this style from `<body>`.

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 3464a99f18 refactor(docs-infra): remove unused CSS for the version selector (#40881)
This commit removes some CSS rules targeting `.doc-version select` in
the sidenav. These rules do not match any elements any more, since now
we use a custom `<aio-select>` component (instead of the `<select>`
element).

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 44aa0d71be fix(docs-infra): merge docs with guide and start with tutorial in search-results (#40881)
Previously, the `docs.md` guide was appearing under "OTHER" in search
results and the results for the `/start*` tutorial pages were appearing
under "START".

This commit changes this so that `docs.md` appears under "GUIDES" and
`/start*` appear under "TUTORIALS", since that is where they belong
conceptually.

It also changes the header of the guides search-area from "GUIDE" to
"GUIDES" and that of tutorials from "TUTORIAL" to "TUTORIALS".

Before: ![search-results areas before][1]
After: ![search-results areas after][2]

[1]: https://user-images.githubusercontent.com/8604205/107811568-0ce80480-6d77-11eb-8652-e7a947c36e63.png
[2]: https://user-images.githubusercontent.com/8604205/107811569-0eb1c800-6d77-11eb-9a69-0000a3703c8a.png

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas fff93ae8f3 fix(docs-infra): show the "Errors List" page under "ERRORS" in search results (#40881)
Previously, the "Errors List" page was appearing under the "OTHER"
section in search results.

This commit fixes this to make it appear under the "ERRORS" section.

Before: ![search-results before][1]
After: ![search-results after][2]

[1]: https://user-images.githubusercontent.com/8604205/107691151-c1b8ed80-6cb3-11eb-8079-fcace685f0ec.png
[2]: https://user-images.githubusercontent.com/8604205/107691145-bfef2a00-6cb3-11eb-8523-b2747fa40469.png

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas 54abe9f66c fix(docs-infra): use relative URLs for internal links on error pages (#40881)
Previously, some of the links on the error pages had URLs prefixed with
`https://angular.io/`. This caused them to be treated as external URLs,
which had the following downsides:
- Links would always point to `angular.io` instead of the same version
  as the error page (e.g. `next.angular.io` or `v11.angular.io`).
- Dgeni would not be able to check that the URLs are valid (i.e. point
  to existing pages).
- An external link icon would incorrectly be shown next to the links on
  `angular.io`.

This commit fixes the links to use relative URLs.

PR Close #40881
2021-02-19 09:15:00 -08:00
George Kalpakas fc07b71d13 fix(docs-infra): show external link icons for external links on error pages (#40881)
This commit adds error pages to the list of docs pages that have an
external link icon next to links to external URLs.

PR Close #40881
2021-02-19 09:15:00 -08:00
Kapunahele Wong 0457aa1b6e docs: edit Component lifecycle title (#40894)
PR Close #40894
2021-02-19 09:10:37 -08:00
David Shevitz 3e813a1618 docs: add missing '@usageNotes' tag to documentation (#40909)
PR Close #40909
2021-02-19 09:09:44 -08:00
arturovt f8055f6fb8 fix(platform-browser): ensure that Hammer loader is called only once (#40911)
Currently, the function that is provided through `HAMMER_LOADER` is called the
same number of times as the `HammerGesturesPlugin.addEventListener` method is called
(until the Hammer is loaded).

This commit adds a class property in which the loader call is saved, thereby
preventing multiple calls to the loader function.

PR Close #25995

PR Close #40911
2021-02-19 09:08:35 -08:00
Amadou Sall c8233a74b8 docs: the token should be associated with LibHeaderComponent (#40922)
PR Close #40922
2021-02-19 09:07:01 -08:00
Kapunahele Wong 4e84b2f3ac docs: edit attribute-directives.md, move best practice to styleguide (#39849)
PR Close #39849
2021-02-19 08:14:55 -08:00
Chellappan 170692c18c refactor(compiler): add process title to Angular node binaries (#40648)
Set the process title for @angular/compiler-cli,@angular/localize packages

Resolves #40634

PR Close #40648
2021-02-17 17:06:27 -08:00
DerekRTP 972eddc1ff docs: update attribute-binding.md to correctly describe [attr.binding] rules (#40878)
PR Close #40878
2021-02-17 17:05:17 -08:00
Dmitrij Kuba 808bded9b0 docs: remove mention of unused Intl polyfill (#40883)
Since `Intl` API was dropped to use to improve browser support,
it is no longer needed as a polyfill to test Angular.

PR Close #40883
2021-02-17 17:04:15 -08:00
Dmitrij Kuba 7bf201ebe8 refactor(platform-browser): remove Intl references (#40883)
Since `Intl` API was dropped to use to improve browser support,
would be nice to remove the references of it.

PR Close #40883
2021-02-17 17:04:15 -08:00
Pete Bacon Darwin 501e15eb98 refactor(localize): avoid computing source-maps in extraction unnecessarily (#40891)
Previously we were calling `updateSourceLocations()` as part of
`extractMessages()` for every file that was passed in, regardless of
whether any `$localize` tagged strings were to be found in the file.

This was very wasteful because it is non-trivial to compute the flattened
source-map for files if it is not needed.

PR Close #40891
2021-02-17 17:02:57 -08:00
Joey Perrott 9a887e35c6 build: update dependencies to enable strict_visibility for bazel yarn_install (#40895)
Beginning with rules_nodejs@3.0.0, strict visibility defaults to true.  This means
that we are no longer, in bazel dependencies, able to depend on a package which was
transitively depended on from another dependency we do have in our package.json

PR Close #40895
2021-02-17 17:01:27 -08:00
David Shevitz a970c19f02 docs: fix minor grammar mistakes in What is Angular topic (#40892)
PR Close #40892
2021-02-17 13:23:49 -08:00
arturovt c8a2e3ae1c perf(core): use ngDevMode to tree-shake warning (#40876)
This commit adds `ngDevMode` guard to show the warning only
in dev mode (similar to how things work in other parts of Ivy runtime code).
The `ngDevMode` flag helps to tree-shake the warning from production builds
(in dev mode everything will work as it works right now) to decrease production bundle size.

PR Close #40876
2021-02-17 11:41:28 -08:00
David Shevitz e74365dd35 docs: add what is angular topic (#40811)
PR Close #40811
2021-02-17 11:13:21 -08:00
Joey Perrott 572e3a356c release: cut the v11.2.1 release (#40887) 2021-02-17 11:22:17 -07:00
Daniel 29a99e806e docs: fix grammar in angular-compiler-options file (#40879)
PR Close #40879
2021-02-17 06:56:39 -08:00
Amadou Sall 5f81eae238 docs: remove the extra backtick character (#40873)
PR Close #40873
2021-02-17 06:56:04 -08:00
abarghoud fead4648a2 docs(core): add documentation for HostListener (#40720)
add return value documentations for HostListener callbacks

Closes #40708

PR Close #40720
2021-02-17 06:55:29 -08:00
Pete Bacon Darwin cc99aec703 refactor(compiler-cli): error on cyclic imports in partial compilation (#40782)
Our approach for handling cyclic imports results in code that is
not easy to tree-shake, so it is not suitable for publishing in a
library.

When compiling in partial compilation mode, we are targeting
such library publication, so we now create a fatal diagnostic
error instead of trying to handle the cyclic import situation.

Closes #40678

PR Close #40782
2021-02-17 06:53:38 -08:00
George Kalpakas 44319c4d82 build: upgrade webdriver-manager to v12.1.8 (#40885)
ChromeDriver now supports Apple Silicon ARM processors.
`webdriver-manager` versions 12.1.7 and earlier will, however,
incorrectly download the arm64 ChromeDriver regardless of the
system's architecture. This results in failure to run Protractor tests
on macOS with the error: `spawn Unknown system error -86`

This commit fixes the problem by upgrading `webdriver-manager` to
version 12.1.8, which includes a fix.
See also https://stackoverflow.com/questions/65618558.

PR Close #40885
2021-02-17 06:51:47 -08:00
George Kalpakas 3f6aed69a4 build: use correct path for local dependencies in ivy-i18n integration project (#40885)
Previously, the paths to some local dependencies in the `ivy-i18n`
integration project were pointing to non-generic bazel files that would
normally not exist on a user's machine.

This commit changes these paths to relative paths pointing to build
artifacts that are guaranteed to exist (once the necessary build
commands have been executed).

PR Close #40885
2021-02-17 06:51:47 -08:00
George Kalpakas 4943dba322 build: ensure integration projects use root webdriver-manager (#40885)
Ensure that all integration projects use `webdriver-manager` from the
root `node_modules/`. See acfd0edd38 for
more details.

PR Close #40885
2021-02-17 06:51:47 -08:00
s4m0r4m4 53865c4517 docs(forms): fix link for browser compatibility of using selects in IE (#40855)
Co-authored-by: Andrew Kushnir <43554145+AndrewKushnir@users.noreply.github.com>
PR Close #40855
2021-02-16 13:06:54 -08:00
s4m0r4m4 5296ed6d40 docs(forms): remove reference to firefox bug that was fixed (#40855)
PR Close #40855
2021-02-16 13:06:54 -08:00
Kapunahele Wong 6794456a1c docs: edit builtin-directives doc (#39816)
Edit built-in-directives.md copy and headers, fixes affected
links, adds a docregion to make steps clearer.

PR Close #39816
2021-02-16 13:04:41 -08:00
Paul Gammans 4906bf6a50 fix(router): fix load interaction of navigation and preload strategies (#40389)
Fix router to ensure that a route module is only loaded once especially
in relation to the use of preload strategies with delayed or partial
loading.

Add test to check the interaction of PreloadingStrategy and normal
router navigation under differing scenarios.
Checking:
 * Prevention of duplicate loading of modules.
   related to #26557
 * Prevention of duplicate RouteConfigLoad(Start|End) events
   related to #22842
 * Ensuring preload strategy remains active for submodules if needed
   The selected preload strategy should still decide when to load submodules
 * Possibility of memory leak with unfinished preload subscription
   related to #26557
 * Ensure that the stored loader promise is cleared so that subsequent
   load will try the fetch again.
 * Add error handle error from loadChildren
 * Ensure we handle error from with NgModule create

Fixes #26557 #22842 #26557

PR Close #40389
2021-02-16 11:28:50 -08:00
Alexey Elin 5412cdfe43 docs: fix broken link in Default Architect builders and targets section (+ remove typo 'the') (#40847)
PR Close #40847
2021-02-16 10:04:48 -08:00
storm-sergey 8bb3550fe2 docs: update the copyright notice date (#40707)
PR Close #40707
2021-02-16 10:04:24 -08:00
David Shevitz d39f39115e docs: add observer-spy to resources page (#40624)
PR Close #40624
2021-02-16 10:03:58 -08:00
Alexey Elin b7d9761008 docs: use shorthand background CSS property in Routing example (#40834)
PR Close #40834
2021-02-16 09:26:27 -08:00
Alexey Elin 9db442fe56 docs: format null as code fragment + fix description of returned value (#40852)
PR Close #40852
2021-02-16 09:24:49 -08:00
Alexey Elin 4a23b2bcb1 docs: use TS Parameter properties in SkipSelf example (#40858)
PR Close #40858
2021-02-16 09:24:25 -08:00
Pete Bacon Darwin fb0ce2178a fix(compiler): support multiple selectors in :host-context() (#40494)
The previous commits refactored the `ShadowCss` emulator to support
desirable use-cases of `:host-context()`, but it dropped support
for passing a comma separated list of selectors to the `:host-context()` .

This commit rectifies that omission, despite the use-case not being
valid according to the ShadowDOM spec, to ensure backward compatibility
with the previous implementation.

PR Close #40494
2021-02-16 08:41:20 -08:00
Pete Bacon Darwin ab8ea87078 fix(compiler): handle :host-context and :host in the same selector (#40494)
In `ViewEncapsulation.Emulated` mode the compiler converts `:host` and
`:host-context` pseudo classes into new CSS selectors.

Previously, when there was both `:host-context` and `:host` classes in a
selector, the compiler was generating incorrect selectors. There are two
scenarios:

* Both classes are on the same element (i.e. not separated). E.g.
  `:host-context(.foo):host(.bar)`. This setup should only match the
  host element if it has both `foo` and `bar` classes. So the generated
  CSS selector should be: `.foo.bar<hostmarker>`.
* The `:host` class is on a descendant of the `:host-context`. E.g.
  `:host-context(.foo) :host(.bar)`. This setup should only match the
  `.foo` selector if it is a proper ancestor of the host (and not on the
  host itself). So the generated CSS selector should be:
  `.foo .bar<hostmarker>`.

This commit fixes the generation to handle these scenarios.

Fixes #14349

PR Close #40494
2021-02-16 08:41:20 -08:00
Pete Bacon Darwin c20e3047a5 fix(compiler): support multiple :host-context() selectors (#40494)
In `ViewEncapsulation.Emulated` mode, the compiler must generate additional
combinations of selectors to handle the `:host-context()` pseudo-class function.

Previously, when there is was more than one `:host-context()` selector in a
rule, the compiler was generating invalid selectors.

This commit generates all possible combinations of selectors needed to
match the same elements as the native `:host-context()` selector.

Fixes #19199

PR Close #40494
2021-02-16 08:41:20 -08:00
Pete Bacon Darwin bc816de4b5 docs: fix missing code line from tutorial example (#40789)
In #40419 we move the code that creates the `heroes` object
above the code that updates the message service. But this moved
that line of code outside of the docregion that is displayed in
the tutorial ealier on, making it non-sensical.

This commit ensures that this line of code is now rendered in the
tutorial be moving it within the correct docregion.

Closes #40788

PR Close #40789
2021-02-16 08:40:26 -08:00
George Kalpakas 8773385d8a fix(docs-infra): fix top padding of main content when a notification is visible (#40802)
This commit fixes the top padding of the main content on the homepage
and other pages when a notification is visible at the top of the page.
The problem was particularly obvious on the homepage (see images below).

Before: ![homepage top-right before][1]
After: ![homepage top-right after][2]

[1]: https://user-images.githubusercontent.com/8604205/107394349-74e2e480-6b04-11eb-8853-71a153cdc459.png
[2]: https://user-images.githubusercontent.com/8604205/107394336-71e7f400-6b04-11eb-9ef0-ff82f6f27875.png

PR Close #40802
2021-02-16 08:39:50 -08:00
George Kalpakas d876e4e6c3 fix(docs-infra): fix placement of TOC hover/active markers (dots) (#40802)
This commit fixes the placement of the TOC hover/active markers (dots)
so that they are horizontally in the middle of the marker "rail" and
vertically in the middle of the item's first line.

This commit also refactors the `_toc.scss` to be more DRY (wrt styling
the TOC markers/marker rail) and uses Sass variables and mixins to
ensure that the styling is kept up-to-date wrt future typography changes
to TOC items.

Before: ![toc marker before][1]
After: ![toc marker after][2]

[1]: https://user-images.githubusercontent.com/8604205/107270751-03e3f400-6a54-11eb-9d77-5b0a3cfb1c2b.png
[2]: https://user-images.githubusercontent.com/8604205/107270758-047c8a80-6a54-11eb-82c0-98b832c109a3.png

PR Close #40802
2021-02-16 08:39:49 -08:00
George Kalpakas 7b29cf7326 fix(docs-infra): improve line-spacing between TOC items (esp. for wrapped lines) (#40802)
Previously, the line-spacing between different TOC items was almost the
same as that between wrapped lines of the same item. This made it more
diffucult to distinguish the different items.

This commit fixes this by reducing the line-spacing between wrapped
lines of the same item and keeping a larger line-spacing between
different items.

Before: ![toc line-spacing before][1]
After: ![toc line-spacing after][2]

[1]: https://user-images.githubusercontent.com/8604205/107255272-ccb81780-6a40-11eb-9612-4e7b2058417d.png
[2]: https://user-images.githubusercontent.com/8604205/107255280-cd50ae00-6a40-11eb-8f60-9ce8fba10e12.png

PR Close #40802
2021-02-16 08:39:49 -08:00
George Kalpakas fb4cd6f39c fix(docs-infra): fix sidenav top position on narrow screens (#40802)
On larger screens the top-bar has a height of 64px. On screens smaller
than 600px, the top-bar has a height of 56px. As a result, the sidenav
should have a top position of 56px on screens smaller than 600px and
64px on other screens.

Previously, the style setting the top position to 56px was tied to the
presence of the `.collapsed` class, which depends on whether the sidenav
is docked or not. The change from docked to collapsed sidenav, however,
happens at 992px. As a result, the sidenav had an incorrect top position
(56px instead of 64px) on screens between 600px and 991px.

This commit fixes this by ensuring the change of the top position for
the sidenav happens at 600px.

PR Close #40802
2021-02-16 08:39:49 -08:00
George Kalpakas 2e52350c63 fix(docs-infra): improve line-spacing between search results (esp. for wrapped lines) (#40802)
Previously, the line-spacing between different search result items was
the same as that between wrapped lines of the same result. This made it
difficult to distinguish the different results.

This commit fixes it by reducing the line-spacing between wrapped lines
of the same result item and keeping a larger line-spacing between
different results.

Before: ![search-results before][1]
After: ![search-results after][2]

[1]: https://user-images.githubusercontent.com/8604205/107229685-ca48c400-6a26-11eb-8161-0c0768b10a2d.png
[2]: https://user-images.githubusercontent.com/8604205/107229691-ccab1e00-6a26-11eb-9594-d4c37d0d72b2.png

PR Close #40802
2021-02-16 08:39:49 -08:00
George Kalpakas 96bf63fec5 fix(docs-infra): avoid page-breaks inside an image when printing (#40802)
Previously, when printing, a page-break could be inserted inside an
image (contained in a `.lightbox` element).

This commit ensures no page-breaks are inserted inside `.lightbox`
elements (which contain images).

Before: ![print-page-break before][1]
After: ![print-page-break after][2]

[1]: https://user-images.githubusercontent.com/8604205/106939709-48f0e900-6729-11eb-912c-e5cd0cb40897.png
[2]: https://user-images.githubusercontent.com/8604205/106939707-48585280-6729-11eb-8d5f-a12312f32056.png

PR Close #40802
2021-02-16 08:39:49 -08:00
George Kalpakas 6c3a8d9564 fix(docs-infra): fix search results top padding when a notification is visible (#40802)
Previously, when a notification was visible at the top of the page, the
search results pane had more top padding than necessary.

This commit fixes it by removing the extra padding.

Before: ![search-results before][1]
After: ![search-results after][2]

[1]: https://user-images.githubusercontent.com/8604205/106938100-3970a080-6727-11eb-8ae8-4e7a33af1daf.png
[2]: https://user-images.githubusercontent.com/8604205/106938103-3aa1cd80-6727-11eb-96f5-f607bde314be.png

PR Close #40802
2021-02-16 08:39:49 -08:00
George Kalpakas e005228e5b fix(docs-infra): dim line-numbers in code examples (#40802)
This commit ensures that the line-numbers in code examples appear
"dimmed" to make it clearer that they are not part of the actual code.

Based on the CSS rules, it seems that the intention was to make it so,
but the color was incorrectly set on the `<ol>` elements instead of
targeting `li::marker`.

Before: ![line-numbers before][1]
After: ![line-numbers after][2]

[1]: https://user-images.githubusercontent.com/8604205/106937191-23aeab80-6726-11eb-9178-bdc067fa3d09.png
[2]: https://user-images.githubusercontent.com/8604205/106937184-227d7e80-6726-11eb-81d1-f709537b6a56.png

PR Close #40802
2021-02-16 08:39:49 -08:00
George Kalpakas 6bdc11e8cc fix(docs-infra): fix vertical alignment of contributor info items (#40802)
This commit fixes the vertical alignment of info items (i.e. links to
bio, Twitter, website) in the contributor list.

Before: ![contributor alignment before][1]
After: ![contributor alignment after][2]

[1]: https://user-images.githubusercontent.com/8604205/106926453-ca407f80-6719-11eb-9580-8614cc4f4907.png
[2]: https://user-images.githubusercontent.com/8604205/106926469-cd3b7000-6719-11eb-8ba8-c8ae01996c02.png

PR Close #40802
2021-02-16 08:39:49 -08:00
George Kalpakas 39638a768f fix(docs-infra): clear unneeded DOM nodes in CodeExample/TabsComponent (#40802)
Both `CodeExampleComponent` and `CodeTabsComponent` components receive
some code via content projection, grab the projected content and pass it
through to a `CodeComponent` instance for formatting and displaying.

Previously, the projected content was kept in the DOM (hidden). This
unnecessarily increased the number of DOM nodes.

This commit fixes this by clearing the projected DOM nodes once their
content has been captured.

PR Close #40802
2021-02-16 08:39:49 -08:00
Brandon Winchester 7f09945771 docs: Add documentation about the CLI failing (#35385)
The CLI seems to throw very non-descriptive errors. Adding a section to help users troubleshoot lazy-loading modules.

PR Close #35385
2021-02-16 08:04:06 -08:00
Pete Bacon Darwin 867c5aec09 docs(http): add custom JSONParser example (#40645)
Update the HTTP guide and associated example to demonstrate
how an interceptor can be used to provide a custom JSON parser.

Resolves #21079

PR Close #40645
2021-02-16 08:03:33 -08:00
Enea Jahollari f434eadc0d docs: remove unnecessary <hr /> tags in Getting Started sections (#40693)
After the docs UI redesign `h2` tags got a border top.
`border-top: 1px solid #dbdbdb;`;
In the sections of Getting Started guide in order to separate
`What's next` from above content an `<hr />` tag was used,
that now becomes unnecessary.

This commit removes unnecessary `<hr />` tags.

PR Close #40693
2021-02-16 08:00:42 -08:00
Dan Levy 0b401cce51 docs: add camelCase example to style notation (#40699)
PR Close #40699
2021-02-16 07:59:41 -08:00
Pete Bacon Darwin 52144948fa build(docs-infra): add a link to usage notes from description (#40835)
The "Usage Notes" section is often at the bottom of a long page of content
which can make it difficult to discover. This commit adds a link at the
end of the "Description" if there is a "Usage Notes" section on the page.
This link should help the reader to discover that there is more information
available further down the page.

This is basically a marginal fix. The longer term fix should be to
consider what content goes in which sections and how they should
be laid out on the page.

See #40753

PR Close #40835
2021-02-16 07:47:09 -08:00
Kristiyan Kostadinov 84b01127a7 refactor(docs-infra): use CDK clipboard service (#40840)
The CDK has had a service for copying strings to the clipboard. These changes switch
AIO to it, rather than having to maintain a custom solution.

PR Close #40840
2021-02-16 07:43:56 -08:00
Alexey Elin 7b4a8c898e docs: fix schematics' package name for ng generate sub-commands (#40846)
PR Close #40846
2021-02-16 07:43:02 -08:00
Daniel 378bf62938 docs: capitalize Angular word in upgrade-setup.md file (#40862)
PR Close #40862
2021-02-16 07:42:35 -08:00
mgechev 91c68f498e docs: add a style recommendation for initializing inputs (#40698)
This practice is to better align with `strictPropertyInitialization`
which is coming by default with strict mode in v12.

PR Close #40698
2021-02-12 17:07:30 -08:00
Bjarki b5f20700c2 fix(core): address Trusted Types bug in Chrome 83 (#40815)
In Chrome 83 passing a TrustedScript to eval just returns the
TrustedScript back without evaluating it, causing the
newTrustedFunctionFor{Dev,JIT} functions to fail. This is a browser bug
that has been fixed in Chrome 84, and only affects Angular applications
running with JIT (which includes unit tests).

As a temporary workaround for users still on Chrome 83, detect when this
occurs in the newTrustedFunctionFor* functions and fall back to the
straightforward, non-Trusted Types compatible implementation. The only
combination that is left affected consists of Angular applications
running with JIT, that have explicitly configured Trusted Types in
enforcement mode, with users that are still on Chrome 83.

Also correct docstring for newTrustedFunctionForJIT.

PR Close #40815
2021-02-12 16:59:58 -08:00
mgechev 7e3815cdc9 docs: add ng-conf 2021 (#40783)
PR Close #40783
2021-02-12 16:49:22 -08:00
Nils Mehlhorn d3d02f8897 docs: add NgRx book to resources (#39841)
PR Close #39841
2021-02-12 16:48:57 -08:00
Jeremy Elbourn a2fba9e2a5 docs: clarify that support schedule is subject to change (#40770)
Initially raised due to #39509, this change updates our
"Support policy and schedule" with the same disclaimer
from the "Release frequency" section above.

PR Close #40770
2021-02-12 16:14:52 -08:00
Sam Hrncir aa5c42af7e docs: Clarify new ng workspace options (#40816)
Hope this helps make the tutorial go even smoother for people after me.

PR Close #40816
2021-02-12 16:13:31 -08:00
JiaLiPassion 76dfcfbf4b release: cut the zone.js-0.11.4 release (#40775)
PR Close #40775
2021-02-12 13:33:05 -08:00
Daniel 1516b5d391 docs: capitalize Angular word in zone.md file (#40813)
PR Close #40813
2021-02-12 12:01:55 -08:00
Sam Hrncir ebbcf0cc04 docs: Update start-deployment.md (#40817)
Updated section reference to current name listed in sidebar.
PR Close #40817
2021-02-12 09:30:03 -08:00
Pete Bacon Darwin 8225bb5b57 refactor(compiler-cli): implement ɵɵngDeclarePipe() (#40803)
This commit implements creating of `ɵɵngDeclarePipe()` calls in partial
compilation, and processing of those calls in the linker and JIT compiler.

See #40677

PR Close #40803
2021-02-12 09:00:16 -08:00
Sam Hrncir f41637c459 docs: typo fix (#40804)
PR Close #40804
2021-02-12 08:59:47 -08:00
Sam Hrncir 9482a4df4c docs: copy paste error (#40812)
The removed bit was copied and pasted from a previous section.  Not relevent for the particular step of the tutorial.
The removed bit can we found as intended in __Adding Navigation__ section.
PR Close #40812
2021-02-11 15:59:55 -08:00
Alex Rickabaugh 87ac05290a fix(compiler-cli): set TS original node on imported namespace identifiers (#40711)
This commit causes imports added by ngtsc's `ImportManager` to have their
TypeScript "original node" set to the generated `ts.ImportDeclaration`
statement.

In g3, the tsickle transformer runs after the Angular transformer and post-
processes Angular's compilation output. One of its post-processing tasks is
to transform generated imports and references to imported symbols from the
commonjs module system to the g3 module system. Part of this transformation
involves recognizing modules with specific metadata and altering references
to symbols from those modules accordingly.

Normally, tsickle can rely on TypeScript's binding for an imported symbol to
find its origin module and thus the correct metadata for the symbol. However
the Angular transform generates new synthetic imports which don't have such
binding information. Angular's imports are always namespace imports of the
form:

```
import * as qualifier 'module/specifier';
```

References to such an import are then of the form `qualifier.SymbolName`.

To process such imports properly, tsickle needs to be able to associate the
reference to `qualifier` in the expression `qualifer.SymbolName` with the
`ts.ImportDeclaration` statement that defines it. It expects to do this by
looking at the `ts.getOriginalNode()` for the `qualifier` reference, which
should be the `ts.ImportDeclaration`. This commit changes ngtsc's import
generation mechanism to set the original node on `qualifier` identifiers
according to this expectation.

This commit is not tested in the direct compiler tests, since:

1) there is no observable behavior externally from setting the original node
2) we don't have tests that intercept transformer operations (which could be
   used to directly assert against the AST nodes)
3) tsickle's published version does not (yet) contain the g3-specific
   transformations which rely on the original node and would thus allow the
   behavior to be observed.

Instead, we rely on the g3 testing suite to validate the correctness of this
fix. Breaking this functionality would cause g3 compilation errors for
targets, since tsickle would be unable to transform imports correctly.

PR Close #40711
2021-02-11 15:58:25 -08:00
Joey Perrott 4c6d557ca9 build: update browserstacktunnel-wrapper (#40810)
Update browserstacktunnel-wrapper to address security vulnerabilities

PR Close #40810
2021-02-11 13:11:15 -08:00
Joey Perrott 75fb76c63b build: update cldr-data-downloader (#40810)
Update cldr-data-downloader to address security vulnerabilities.

PR Close #40810
2021-02-11 13:11:15 -08:00
Joey Perrott ac645ec951 build: update gulp and gulp-conventional-changelog (#40810)
Update gulp and gulp-conventional-changelog to address security vulnerabilities.

PR Close #40810
2021-02-11 13:11:15 -08:00
Joey Perrott 925e2b7434 build: remove jpm dependency (#40807)
Remove our dependency on jpm as it goes unused in our repository.

PR Close #40807
2021-02-11 12:30:55 -08:00
Joey Perrott b42497144d ci: remove BES usages from CI (#40809)
Removes BES configuration from CI bazel configuration as it is increasingly seeing timeouts
causing failures, but the uploaded results go largely unlooked at.

PR Close #40809
2021-02-11 12:28:55 -08:00
Joey Perrott 0227ca83ae Revert "fix(router): fix load interaction of navigation and preload strategies (#40389)" (#40806)
This reverts commit e9a19a6152.

PR Close #40806
2021-02-11 11:59:10 -08:00
GChuf 85a5336efb build: Update dependencies (#40726)
Updates some dependencies.

PR Close #40726
2021-02-11 11:17:21 -08:00
Paul Gammans bba1981c6e fix(router): fix load interaction of navigation and preload strategies (#40389)
Fix router to ensure that a route module is only loaded once especially
in relation to the use of preload strategies with delayed or partial
loading.

Add test to check the interaction of PreloadingStrategy and normal
router navigation under differing scenarios.
Checking:
 * Prevention of duplicate loading of modules.
   related to #26557
 * Prevention of duplicate RouteConfigLoad(Start|End) events
   related to #22842
 * Ensuring preload strategy remains active for submodules if needed
   The selected preload strategy should still decide when to load submodules
 * Possibility of memory leak with unfinished preload subscription
   related to #26557
 * Ensure that the stored loader promise is cleared so that subsequent
   load will try the fetch again.
 * Add error handle error from loadChildren
 * Ensure we handle error from with NgModule create

Fixes #26557 #22842 #26557

PR Close #40389
2021-02-11 09:15:09 -08:00
arturovt a2a5b4add5 fix(http): complete the request on timeout (#40771)
When using the [timeout attribute](https://xhr.spec.whatwg.org/#the-timeout-attribute) and an XHR
request times out, browsers trigger the `timeout` event (and execute the XHR's `ontimeout`
callback). Additionally, Safari 9 handles timed-out requests in the same way, even if no `timeout`
has been explicitly set on the XHR.

In the above cases, `HttpClient` would fail to capture the XHR's completing (with an error), so
the corresponding `Observable` would never complete.

PR Close #40771
2021-02-11 09:13:40 -08:00
Joey Perrott ce80d5ee19 fix(dev-infra): update npm package subsitutions to reflect no longer having an imported workspace (#40785)
Update replacements of the `//dev-infra/` piece of bazel path segments to reference the `@npm//`
workspace rather than creating its own workspace.

PR Close #40785
2021-02-11 09:13:00 -08:00
Joey Perrott 6ee5cdce9d ci: Remove language-service from testing group (#40795)
Much like the compiler-cli, the language-service package has internal testing
tools that are not intended for external use and do not need fw-testing review.
See #40679.

PR Close #40795
2021-02-11 09:03:23 -08:00
waterplea cadee6d63f docs(core): add missing dot at the end of the sentence (#40800)
PR Close #40800
2021-02-11 09:00:51 -08:00
waterplea 006a523815 docs(core): fix typo in interpolation property description (#40800)
PR Close #40800
2021-02-11 09:00:51 -08:00
Joey Perrott 9cbd9bed55 Revert "ci: Remove language-service from testing group (#40787)" (#40794)
This reverts commit 06671e85f9.

PR Close #40794
2021-02-10 16:06:21 -08:00
Nicholas Papadopoulos 636b6b4f94 docs: fix typo in workspace config docs (#40784)
PR Close #40784
2021-02-10 16:01:12 -08:00
Andrew Scott c23d029473 ci: Remove language-service from testing group (#40787)
Much like the compiler-cli, the language-service package has internal testing
tools that are not intended for external use and do not need fw-testing review.
See #40679.

PR Close #40787
2021-02-10 16:00:32 -08:00
Alex Rickabaugh e3f09ce845 release: cut the v11.2.0 release (#40790)
PR Close #40790
2021-02-10 14:08:21 -08:00
Amit Gharat cfbb1faa6f docs: add Angular + NgRx book by the asian BPB Publications (#39680)
PR Close #39680
2021-02-10 11:14:35 -08:00
Alexey Elin e2bb954a7a docs: fix absent documentation for digitsInfo parameter in the API docs (#40746)
PR Close #40746
2021-02-10 11:09:10 -08:00
Alexey Elin 5795c980b5 docs: add link to component-less routes description. (#40741)
Currently it's not clear what a component-less route is. Add a link to  make it clear

PR Close #40741
2021-02-10 11:08:40 -08:00
JoostK e99c4e230f fix(compiler): include parenthesis in expression source spans (#40740)
The parser does not include parenthesis in the AST, so if a LHS
expression would be parenthesized then its start span would start
after the opening parenthesis. Previously, some parent AST nodes would
be created with the start span of its LHS as its own start, so this
resulted in the parent AST node not encompassing the opening parenthesis
in its source span. This commit fixes the issue by capturing the start
index prior to parsing a child AST tree, which is then used as the
start of the source span of the the parent AST node that is parsed.

Fixes #40721

PR Close #40740
2021-02-10 11:07:12 -08:00
JoostK d36890c854 refactor(compiler-cli): remove event output helper from TCB (#40738)
In 5c547675b1 the `EventEmitter.subscribe`
API was extended with a new signature that allows the emitter's generic
type `T` to flow into the subscribe callback. This new signature removes
the need for the special `_outputHelper` function that used to be
emitted into TCBs when `strictOutputEventTypes`/`strictTemplates` is
enabled.

PR Close #40738
2021-02-10 11:06:36 -08:00
Mickael Istria 5adb47ff35 docs(language-service): Add note about Eclipse IDE support of Angular LS (#40551)
Mention Eclipse Wild Web Developer that ships with Angular language
service.

PR Close #40551
2021-02-10 11:05:53 -08:00
Kristiyan Kostadinov 7e0ff8cbb6 fix(compiler): throw error for duplicate template references (#40538)
Adds an error if a reference is used more than once on the same element (e.g. `<div #a #a>`).
We used to have this error in ViewEngine, but it wasn't ported over to Ivy.

Fixes #40536.

PR Close #40538
2021-02-10 11:05:16 -08:00
abarghoud bf85f04baf fix(common): date is not correctly formatted when year is between 0 and 99 (#40448)
use setFullYear method when parsing date to avoid javascript date factory behaviour

Fixes #40377

PR Close #40448
2021-02-10 11:04:38 -08:00
Kanstantsin Kamkou fffefd12e5 docs: clarify observables recommendation (#39237)
Observables are not the only async mechanism that Angular employs.
This change respects that application developers are not required to
use Observables in their own application architecture.

Closes #39155

PR Close #39237
2021-02-10 11:04:05 -08:00
stsogoo 9ae21ee118 fix(core): properly move embedded views of dynamic component's projectable nodes (#37167)
This commit fixes the issue of the ASSERTION ERROR issue when
a projected node(RNode) inside an array is checked against the types
of TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer,
TNodeType.IcuContainer, TNodeType.Projection. As it's inside an array,
it doesn't fall into any of those types, as a result, it throws
the ASSERTION ERROR.

PR Close #37120

PR Close #37167
2021-02-10 11:03:06 -08:00
Zach Arend 95446fb15c fix(compiler-cli): don't crash when we can't resolve a resource (#40660)
Produces a diagnostic when we cannot resolve a component's external style sheet or external template.

The previous behavior was to throw an exception, which crashed the
Language Service.

fixes angular/vscode-ng-language-service#1079

PR Close #40660
2021-02-10 10:48:34 -08:00
ayazhafiz ba6d8d44b1 refactor(language-service): pull out interfaces on package toplevel (#40773)
This is patch PR for #40621.

Two motivations behind this change:

1. We would like to expose the types of the Language Service to external
   users (like the VSCode extension) via the npm package, on the top
   level of the package
2. We would like the View Engine and Ivy LS to share a common interface
   (notably after the inclusion of `getTcb`, the Ivy LS upholds a
   strict superset of `ts.LanguageService`; previously both VE and Ivy
   LS were aligned on `ts.LanguageService`.)

To this end, this commit refactors the exports on the toplevel of the
`language-service/` package to just be types common to both the VE and
Ivy language services. The VE and Ivy build targets then import and use
these types accordingly, and the expectation is that an external user
will just import the relevant typings from the toplevel package without
diving into either the VE or Ivy sources.

Follow up on #40607

PR Close #40773
2021-02-10 10:37:58 -08:00
Valerij Dobler 3b0c51e045 docs: edit example to fetch hero before sending message (#40419)
PR Close #40419
2021-02-09 14:46:18 -08:00
Kapunahele Wong 80c21bf6b0 docs: add redirect from updating-v10 to v11 (#40108)
Redirects from https://angular.io/guide/updating-to-version-10 to
https://angular.io/guide/updating-to-version-11 to avoid 404 errors.

PR Close #40108
2021-02-09 14:45:39 -08:00
Kapunahele Wong c0d1e34d53 docs: update docs-style-guide (#36281)
This commit updates the documentation style guide
so that it is in line with current standards, those
of Google as well as those within the Angular docs.

PR Close #36281
2021-02-09 14:26:06 -08:00
George Kalpakas 6973a9919b build(docs-infra): upgrade cli command docs sources to ab638724c (#40760)
Updating [angular#11.2.x](https://github.com/angular/angular/tree/11.2.x) from
[cli-builds#11.2.x](https://github.com/angular/cli-builds/tree/11.2.x).

##
Relevant changes in
[commit range](https://github.com/angular/cli-builds/compare/829e1bae4...ab638724c):

**Modified**
- help/build.json
- help/lint.json
- help/new.json
- help/serve.json

##
Relevant changes in
[commit range](https://github.com/angular/cli-builds/compare/e98241829...ab638724c) since PR #40719:

**Modified**
- help/lint.json

##
Closes #40719

PR Close #40760
2021-02-09 14:25:26 -08:00
Pete Bacon Darwin 415ad8df13 fix(localize): support downleveled inlined helper localize calls (#40754)
When the downleveling helper function has been  inlined into the
`$localize` call, it is a bit more tricky to parse out the cooked and
raw strings. There was already code to do this but it assumed that
the `cooked` and `raw` items were both arrays.

Sometimes the `raw` array is just a copy of the `cooked` array
via an expression similar to `raw || (raw=tcookedslice(0))`. This
commit changes the `unwrapMessagePartsFromLocalizeCall()`
function to be able to handle such a situation.

Fixes #40702

PR Close #40754
2021-02-09 13:51:53 -08:00
George Kalpakas 9aa3e9f0fc fix(docs-infra): correctly handle entry-points with no public exports (#40737)
Previously, if an entry-point had no public exports (such as the
`@angular/platform-server/shims` introduced in #40559, which is a
side-effect-ful entry-point), it was incorrectly marked as having all
its exports deprecated (which marks the entry-point as deprecated as
well).

This commit fixes this by ensuring that an entry-point is not marked as
having all its exports deprecated if it has no public exports.

PR Close #40737
2021-02-09 10:56:18 -08:00
hilmer-martin 67333a98b9 docs: changes for typescript 2.7 (#40735)
Because of changes in Typescript a property must have an initializer
or be set to undefined.

PR Close #40735
2021-02-09 10:52:44 -08:00
Pete Bacon Darwin 24600ff77d fix(localize): improve invalid syntax in extraction error message (#40724)
Previously if the code is invalid the error message might look like:

```
Unexpected messageParts for `$localize` (expected an array of strings).
```

This is not very helpful for debugging where the problem occurs.

Now we build a "code-frame" description to give more useful information:

```
TypeError: Cannot create property 'message' on string '.../src/app/app.component.js:
Unexpected messageParts for `$localize` (expected an array of strings).
  4 | export class AppComponent {
  5 |     constructor() {
> 6 |         this.title = $localize(a = ['myapp'], []);
    |                                ^^^^^^^^^^^^^
  7 |     }
  8 | }
  ```

PR Close #40724
2021-02-09 10:52:18 -08:00
Matias Niemelä 74cb759c2a fix(animations): properly track listeners for a removed element (#40712)
Prior to this patch, if an element was removed multiple times (due
to the nature of parent/child elements), the leave listeners may
have been fired for an element that was already removed. This patch
adds a guard within the animations code to prevent this.

PR Close #40712
2021-02-09 10:50:20 -08:00
Joey Perrott a4e396dbcf fix(compiler-cli): update ngcc integration tests for latest changes in rules_nodejs (#40710)
Update the ngcc integration tests to handle the changes in the latest version of rules_nodejs.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott 1e064074ac fix(dev-infra): update build tooling for latest changes in rules_nodejs (#40710)
Update the build tooling to handle the changes in the latest version of rules_nodejs.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott 621c32d22a fix(bazel): update build tooling for latest changes in rules_nodejs (#40710)
Update the build tooling to handle the changes in the latest version of rules_nodejs.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott 305d41c0b0 fix(dev-infra): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott 36a3a6af7f fix(bazel): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott 52da337ca5 fix(benchpress): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott ceafef1a6a fix(compiler): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott bc7be8f1ab fix(compiler-cli): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott cd1b76478f fix(elements): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott 57d46d4293 fix(localize): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott 13857519e4 fix(platform-browser): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:46 -08:00
Joey Perrott 35c3d80f1d fix(router): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:45 -08:00
Joey Perrott 900bc87d20 fix(service-worker): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:45 -08:00
Joey Perrott 86a6be753d fix(zone.js): update build tooling for latest changes in rules_nodejs (#40710)
Update the zone.js build tooling to handle the changes in the latest version of rules_nodejs.

PR Close #40710
2021-02-09 10:48:45 -08:00
Joey Perrott 22f734f102 build: update tools directory for latest changes in rules_nodejs (#40710)
Update the scripts/tooling in the tools directory to handle the changes in the latest
version of rules_nodejs.

PR Close #40710
2021-02-09 10:48:45 -08:00
Joey Perrott 63f6273346 fix(bazel): update integration test to use rules_nodejs@3.1.0 (#40710)
Update the integraiton tests for bazel to the latest rules_nodejs version.

PR Close #40710
2021-02-09 10:48:45 -08:00
Joey Perrott 98defb6e68 build: update to rules_nodejs@3.1.0 (#40710)
Update to the latest version of rules_nodejs.

PR Close #40710
2021-02-09 10:48:45 -08:00
George Kalpakas 345eccad8e refactor(docs-infra): use a single CSS class to target the API list container (#40704)
Previously, the API list container (in the template of the
`<aio-api-list>` component) had three different CSS classes
(`.api-list-container`, `.docs-content`, `.l-content-small`) that were
all used for styling it. This seemed unnecessary and made it more difficult
to see what styles were applied to the container.

This commit removes the extra classes and consolidates the styles under
the `.api-list-container` class (which was the most descriptive one).

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 49c108e33c refactor(docs-infra): scope API list styles to the <aio-api-list> element (#40704)
This commit ensures that all styles for the API list page (which are
defined in `_api-list.scss`) only apply to elements inside an
`<aio-api-list>` element. This will prevent the styles accidentally
taking effect on a different part of the app.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas adcba1b9b2 refactor(docs-infra): move common .code-anchor styles to _code.scss (#40704)
The `.code-anchor` class can be used anywhere where we have code
examples (including API pages and docs guides). Previously, global
styles for `.code-anchor` were defined in `_api-list.scss` (i.e. the
styles from `_api-list.scss` were also applied to `.code-anchor`
elements in other pages/components).

This commit moves the `.code-anchor` styles to `_code.scss`, which
contains other common code-related styles.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas b282a94c31 refactor(docs-infra): move common .symbol styles to _api-symbols.scss (#40704)
The `.symbol` CSS class (which is primarily used to denote the type of
API symbols - classes, functions, interfaces, etc.) are used in several
places:
- In the API list page (with the corresponding styles defined in
  `_api-list.scss`).
- In search results (with the corresponding styles defined in
  `_errors.scss`).
- In error list page (with the corresponding styles defined in
  `search-results.scss`).
- In the `<aio-select>` component (with the corresponding styles defined
  in `_select-menu.scss`).

Previously, global styles for `.symbol` were defined in `_api-list.scss`
(i.e. the styles from `_api-list.scss` were also applied to `.symbol`
elements in other places/components). Also, some of the SCSS files
mentioned above defined some duplicate styles for `.symbol`.

This commit moves the `.symbol` styles to a new `_api-symbols.scss`
file, which contains common symbol-related styles.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas d79e62292c refactor(docs-infra): merge style rules in _api-list.scss (#40704)
This commit cleans up the styles in `_api-list.scss` by merging together
blocks that target the same elements.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 8505865587 refactor(docs-infra): remove unused styles from _api-list.scss (#40704)
This commit removes some styles from `_api-list.scss` that are no longer
used (i.e. either their CSS selectors do not match any element in the
app or they are overridden by other rules).

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas d05f157209 refactor(docs-infra): scope TOC styles to the <aio-toc> element (#40704)
This commit ensures that all styles for the TOC (which are defined in
`_toc.scss`) only apply to elements inside an `<aio-toc>` element. This
will prevent the styles accidentally taking effect on a different part
of the app.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 9bab583c58 refactor(docs-infra): merge style rules in _toc.scss (#40704)
This commit cleans up the styles in `_toc.scss` by merging together
blocks that target the same elements.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas ea3ec5361e refactor(docs-infra): scope select-menu styles to the <aio-select> element (#40704)
This commit ensures that all styles for the select-menu element (which
are defined in `_select-menu.scss`) only apply to elements inside an
`<aio-select>` element. This will prevent the styles accidentally taking
effect on a different part of the app.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas afce2987d1 refactor(docs-infra): scope Resources styles to the <aio-resource-list> element (#40704)
This commit ensures that all styles for the "Resources" page (which are
defined in `_resources.scss`) only apply to elements inside an
`<aio-resource-list>` element. This will prevent the styles accidentally
taking effect on a different part of the app.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 4e78e2196a refactor(docs-infra): merge style rules in _resources.scss (#40704)
This commit cleans up the styles in `_resources.scss` by merging
together blocks that target the same elements.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 5766c2d52f refactor(docs-infra): remove unused styles from _resources.scss (#40704)
This commit removes some styles from `_resources.scss` that are no
longer used (i.e. either their CSS selectors do not match any element in
the app or they are overridden by other rules).

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 7e6595b59b refactor(docs-infra): merge style rules in _presskit.scss (#40704)
This commit cleans up the styles in `_presskit.scss` by merging together
blocks that target the same elements.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 58ee0133e4 refactor(docs-infra): merge style rules in _label.scss (#40704)
This commit cleans up the styles in `_label.scss` by merging together
blocks that target the same elements.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas b8d6e15447 refactor(docs-infra): remove unused styles from _label.scss (#40704)
This commit removes some styles from `_label.scss` that are no longer
used (i.e. their CSS selectors do not match any element in the app).

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 7a68915d18 refactor(docs-infra): fix indentation in _label.scss (#40704)
This commit makes the indentation in `_label.scss` consistent with that
in most other `.scss` files in `aio/`.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 1e4c39ada8 refactor(docs-infra): remove unused _edit-page-cta.scss file (#40704)
This commit removes the `_edit-page-cta.scss` file, which is no longer
used (i.e. the rules it contains do not match any element in the app).

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas b12e798685 refactor(docs-infra): merge style rules in _details.scss (#40704)
This commit cleans up the styles in `_details.scss` by merging
together blocks that target the same elements.

It also changes the `summary` selector to `details > summary`, but that
should not make any difference in practice, since `<summary>` elements
always appear as direct childs of `<details>`.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas b0613b7329 refactor(docs-infra): scope contributor-list styles to the <aio-contributor-list> element (#40704)
This commit ensures that all styles for the contributor list (which are
defined in `_contributor.scss`) only apply to elements inside an
`<aio-contributor-list>` element. This will prevent the styles
accidentally taking effect on a different part of the app.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 9738878fbf refactor(docs-infra): remove unused styles from _contributor.scss (#40704)
This commit removes some styles from `_contributor.scss` that are no
longer used (i.e. either their CSS selectors do not match any element in
the app or they are overridden by other rules).

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 81c496d0a4 refactor(docs-infra): scope code example styles to the <aio-code> element (#40704)
This commit ensures that all styles for the code examples (which are
defined in `_code.scss`) only apply to elements inside an `<aio-code>`
element. This will prevent the styles accidentally taking effect on a
different part of the app.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 9675260a56 refactor(docs-infra): merge style rules in _code.scss (#40704)
This commit cleans up the styles in `_code.scss` by merging together
blocks that target the same elements.

It also normalizes the rules targeting Angular Material tabs to use
consistent selectors and use class names instead of tag names.

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 8216de27ed refactor(docs-infra): remove unused styles from _code.scss (#40704)
This commit removes some styles from `_code.scss` that are no longer
used (i.e. either their CSS selectors do not match any element in the
app or they are overridden by other rules).

PR Close #40704
2021-02-09 10:47:22 -08:00
George Kalpakas 7a45153266 refactor(docs-infra): move common .group-buttons styles to _buttons.scss (#40704)
Both `<aio-contributor-list>` and `<aio-resource-list>` contain
`.group-buttons` elements. Previously, global styles for
`.group-buttons` were defined in `_contributor.scss` (i.e. the styles
from `_contributor.scss` were also applied to `.group-buttons` in
`<aio-resource-list>`). Also, `_contributor.scss` and `_resources.scss`
defined some duplicate styles for `.group-buttons`.

This commit moves the `.group-buttons` styles to `_buttons.scss`, which
contains common button-related styles.

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas c3ed990f47 refactor(docs-infra): scope top-menu styles to the .app-toolbar element (#40704)
This commit ensures that all styles for the app top-menu (which are
defined in `_top-menu.scss`) only apply to elements inside an
`.app-toolbar` element. This will prevent the styles accidentally taking
effect on a different part of the app.

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas 07e071cec0 refactor(docs-infra): merge style rules in _top-menu.scss (#40704)
This commit cleans up the styles in `_top-menu.scss` by merging
together blocks that target the same elements.

It also makes similar changes to selectors in `_notification.scss` rules
that override top-menu styles (for consistency).

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas 3c1d9860d0 refactor(docs-infra): scope nav-item styles to the <aio-nav-item> element (#40704)
This commit ensures that all styles for the sidenav nav-items (which are
defined in `_sidenav.scss`) only apply to elements inside an
`<aio-nav-item>` element. This will prevent the styles accidentally
taking effect on a different part of the app.

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas ba16665073 refactor(docs-infra): merge style rules in _sidenav.scss (#40704)
This commit cleans up the styles in `_sidenav.scss` by merging
together blocks that target the same elements.

It also applies the equivalent changes in `_notification.scss` rules
that override sidenav styles.

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas d11cb25f4d refactor(docs-infra): remove unused styles from _sidenav.scss (#40704)
This commit removes some styles from `_sidenav.scss` that are no longer
used (i.e. either their CSS selectors do not match any element in the
app or they are overridden by other rules).

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas b01153cf84 refactor(docs-infra): remove unused styles from _layout-global.scss (#40704)
This commit removes some styles from `_layout-global.scss` that are no
longer used (i.e. either their CSS selectors do not match any element in
the app or they are overridden by other rules).

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas 698efeed63 refactor(docs-infra): scope footer styles to the <aio-footer> element (#40704)
This commit ensures that all styles for the page footer (which are
defined in `_footer.scss`) only apply to elements inside an
`<aio-footer>` element. This will prevent the styles accidentally taking
effect on a different part of the app.

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas eda6c6d5c9 refactor(docs-infra): merge style rules in _footer.scss (#40704)
This commit cleans up the styles in `_footer.scss` by merging together
blocks that target the same elements.

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas 506b6a2ab6 refactor(docs-infra): remove unused styles from _footer.scss (#40704)
This commit removes some styles from `_footer.scss` that are no longer
used (i.e. either their CSS selectors do not match any element in the
app or they are overridden by other rules).

PR Close #40704
2021-02-09 10:47:21 -08:00
George Kalpakas 3989a0a240 refactor(docs-infra): remove unused styles from _content-layout.scss (#40704)
This commit removes some styles from `_content-layout.scss` that are no
longer used (i.e. either their CSS selectors do not match any element in
the app or they are overridden by other rules).

PR Close #40704
2021-02-09 10:47:21 -08:00
mgechev 6345f89825 docs: clarify vscode integration maintenance (#40647)
PR Close #40647
2021-02-09 10:43:40 -08:00
Roman Sedov 4d05f533a8 docs: add Taiga UI to "EXPLORE ANGULAR RESOURCES" page (#40572)
PR Close #40572
2021-02-09 10:42:20 -08:00
Aristeidis Bampakos 192de59ddc docs(service-worker): copyedit getting started guide (#40543)
Fix numbered list for the `Making changes to your application` section

PR Close #40543
2021-02-09 10:34:15 -08:00
David Pine 7c1453614b docs: add Angular Global Summit to event pages (#40697)
/cc @mgechev

PR Close #40697
2021-02-04 10:48:55 -08:00
Enea Jahollari 11cc4c9dcf fix(docs-infra): switch code font from Droid Sans Mono to Roboto Mono (#40667)
`Droid Sans Mono` didn't look good on some screens.

Fixes #40666

PR Close #40667
2021-02-04 10:48:30 -08:00
Kristiyan Kostadinov 737bc7a3e5 fix(router): stop emitting to event observable on destroy (#40638)
No longer emits to `Router.events` after the router has been destroyed. Also
returns a resolved promise to the navigation methods.

Fixes #40502.

PR Close #40638
2021-02-04 10:46:46 -08:00
Jeremy Elbourn b1d589712c docs: add guide for branching process (#39924)
PR Close #39924
2021-02-04 10:45:32 -08:00
Misko Hevery 58f8ba0a8c release: cut the v11.2.0-rc.0 release 2021-02-03 15:38:34 -08:00
Misko Hevery 6ac05c05e9 release: cut the v11.2.0-next.1 release 2021-02-03 14:40:54 -08:00
Alan Agius 7c38a4a037 docs: clarify that fileReplacements only supports compilation source files (#40687)
fileReplacements is intended to only work on compilation source files

PR Close #40687
2021-02-03 09:10:24 -08:00
George Kalpakas 0b1f1930b9 build(docs-infra): upgrade cli command docs sources to 829e1bae4 (#40686)
Updating [angular#11.2.x](https://github.com/angular/angular/tree/11.2.x) from
[cli-builds#11.1.x](https://github.com/angular/cli-builds/tree/11.1.x).

##
Relevant changes in
[commit range](https://github.com/angular/cli-builds/compare/b427aeb88...829e1bae4):

**Modified**
- help/new.json

PR Close #40686
2021-02-03 09:09:45 -08:00
Andrew Kushnir 4877f687b5 refactor(forms): avoid duplicated code in AbstractControlStatus directive (#40651)
This commit updates `AbstractControlStatus` directive code to remove duplicated logic in getters and replaces
that logic with a new function that accepts an argument.

PR Close #40651
2021-02-03 09:08:02 -08:00
Pete Bacon Darwin 5c547675b1 fix(core): ensure the type T of EventEmitter<T> can be inferred (#40644)
The `AsyncPipe.transform<T>(emitter)` method must infer the `T`
type from the `emitter` parameter. Since we changed the `AsyncPipe`
to expect a `Subscribable<T>` rather than `Observable<T>` the
`EventEmitter.subscribe()` method needs to have a tighter signature.
Otherwise TypeScript struggles to infer the type and ends up making
it `unknown`.

Fixes #40637

PR Close #40644
2021-02-03 09:07:30 -08:00
Eliran Eliassy 1fbbb1e34d docs: add eliran eliassy to GDE list (#39521)
PR Close #39521
2021-02-03 09:06:20 -08:00
Alex Rickabaugh 4cc15fe78e refactor(compiler-cli): remove the overrideComponentTemplate API (#40585)
The `TemplateTypeChecker.overrideComponentTemplate` operation was originally
conceived as a "fast path" for the Language Service to react to a template
change without needing to go through a full incremental compilation step. It
served this purpose until the previous commit, which switches the LS to use
the new resource-only incremental change operation provided by `NgCompiler`.

`overrideComponentTemplate` is now no longer utilized, and is known to have
several hard-to-overcome issues that prevent it from being useful in any
other situations. As such, this commit removes it entirely.

PR Close #40585
2021-02-02 16:26:17 -08:00
Alex Rickabaugh 07a3d7a16b perf(language-service): update NgCompiler via resource-only path when able (#40585)
This commit changes the Language Service's "compiler factory" mechanism to
leverage the new resource-only update path for `NgCompiler`. When an
incoming change only affects a resource file like a component template or
stylesheet, going through the new API allows the Language Service to avoid
unnecessary incremental steps of the `NgCompiler` and return answers more
efficiently.

PR Close #40585
2021-02-02 16:26:10 -08:00
George Kalpakas 21994ee985 refactor(docs-infra): remove unused styles for .heading CSS class (#40427)
This commit removes some styles for the `.heading` CSS class which do
not have any effect (either because they are overridden in other rules
or because they do not make any difference).

NOTE:
The `.heading` class is kept in the HTML to make it easier to associate
the `.heading-children` element with its corresponding `.heading`
parent.

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas f25a1b9597 refactor(docs-infra): simplify the CSS rules for styling the "collapsed/expanded" sidenav icons (#40427)
This commit simplifies the styling of the "collapsed/expanded" icons in
sidenav nav-items with children by consolidating the CSS rules in one
block (instead of having duplicate blocks for different levels).

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas fa3f310745 fix(docs-infra): fix the styling of the cards in docs introduction page (#40427)
This commit fixes the layout and appearance of the cards shown in the
docs introduction page (`/docs`) in the following ways:

- Center the cards.
- Ensure two cards are shown per line (instead of 3 one the first line
  and 1 on the second).
- Adjust their widths to ensure their content fits well in them
  (given that the cards have a fixed height).
- Use more engaging styles to better indicate that the cards are
  clickable (as discussed [here][1]).

[1]: https://github.com/angular/angular/pull/40427#discussion_r560688953

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas e66b89a4e4 refactor(docs-infra): clean up styles in _card.scss (#40427)
This commit cleans up the styles in `_card.scss` by:
- Fixing incosistenct indentation/newlines.
- Removing rules for unused selectors.
- Removing unnecessary styles.

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas 95d8f58393 fix(docs-infra): improve legibility and focus on content (#40427)
This commit changes the layout of the main content to improve
legibility, especially on wider screens:

- Limit main content width to 50em (800px by default).
- Center main content on the page.

Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas 2fc618471a fix(docs-infra): improve typography styles (incl. bigger font size/line height) (#40427)
Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas 08252b2c5e fix(docs-infra): make content links more prominent on hover (#40427)
Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas 5f9053405a fix(docs-infra): improve heading styles (#40427)
This commit includes some general improvements to heading styles
(font-weight, margin/padding). It also adds a horizontal separator above
`<h2>` headings to segment important sections more easily.
(As a consequence, we can remove several `<hr />` elements right before
`<h2>` headings.)

Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas f1d2afa496 fix(docs-infra): fix padding in sidenav and ensure all nav-items have equal height (#40427)
This commit improves the padding nav-menus and nav-items in the sidenav.
It also ensures that all nav-items have the same height, regardless of
their level and of whether they have children or not.

Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas 6d5e6cf1cf fix(docs-infra): remove uppercase style from sidenav nav-items (#40427)
Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>

PR Close #40427
2021-02-02 12:04:57 -08:00
George Kalpakas 746792b838 fix(docs-infra): update the sidenav background to better distinguish from main content (#40427)
Previously, we used a box-shadow to indicate that the sidenav is
separate from the main content.

This commits updates the sidenav styling to remove the shadow and give
it a slightly different background color instead.

Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>

PR Close #40427
2021-02-02 12:04:57 -08:00
Viktor Uhryn da3dc29477 docs: fix typo in lazy-loading guide (#40668)
PR Close #40668
2021-02-02 12:04:22 -08:00
Alex Rickabaugh caafac2248 fix(compiler-cli): preserve user line endings in diagnostic template parse (#40597)
Normally the template parsing operation normalizes all template line endings
to '\n' only. This normalization operation causes source mapping errors when
the original template uses '\r\n' line endings.

The compiler already parses templates again to create a "diagnostic"
template AST with accurate source maps, to avoid other parsing issues that
affect source map accuracy. This commit configures this diagnostic parse to
also preserve line endings.

PR Close #40597
2021-01-29 11:15:17 -08:00
JiaLiPassion ff93a6723e refactor(router): fix several typos in router spec (#40626)
Fix a couple typos in router tests.

PR Close #40626
2021-01-29 11:14:36 -08:00
Pete Bacon Darwin 46d43267e3 fix(common): parse YYYY strings as UTC dates (#40629)
In b6cd38ff05 we fixed the DatePipe so
that when it parsed date strings that looked like `YYYY-MM` it created a UTC
date that was not affected by the local timezone of the JavaScript engine.

This commit does the same for date strings of the form `YYYY`.

(Note that the previous commit, mentioned above, attempted to fix this case
too but the test was not actually checking the correct input string.)

Fixes #33944

PR Close #40620

PR Close #40629
2021-01-29 11:14:05 -08:00
Pete Bacon Darwin 4c5f18dfda fix(common): parse YYYY-MM strings as UTC dates (#40620)
In 2aba8b0 we fixed the DatePipe so that when it parsed date strings
that looked like `YYYY-MM-DD` it created a UTC date that was not
affected by the local timezone of the JavaScript engine.

This commit does the same for date strings of the form `YYYY-MM`
and `YYYY`.

Fixes #33944

PR Close #40620
2021-01-28 16:00:58 -08:00
twerske 5fcf2f9a5f docs: add guide for NG0302 (#40580)
new guide for pipe not found common error
link from pipe error to new guide
add embedded debugging video

PR Close #40580
2021-01-28 15:56:41 -08:00
Pete Bacon Darwin 4d1b3177d8 ci: add pete to the fw-http group (#40619)
This allows @petebacondarwin to approve PRs for the
`@angular/common/http` package.

PR Close #40619
2021-01-28 15:54:53 -08:00
Teri Glover f261c1c66b docs: fix typo to remove space (#40601)
PR Close #40601
2021-01-28 15:54:20 -08:00
Misko Hevery 552009ec07 Revert "fix(core): remove duplicated EMPTY_ARRAY constant (#40587)"
This reverts commit cabe8bec40.
2021-01-28 14:35:58 -08:00
Andrew Scott 9d396f837c fix(compiler): Don't set expression text to synthetic $implicit when empty (#40583)
When parsing interpolations, if we encounter an empty interpolation
(`{{}}`), the current code uses a "pretend" value of `$implicit` for the
name as if the interplotion were really `{{$implicit}}`. This is
problematic because the spans are then incorrect downstream since they
are based off of the `$implicit` text.

This commit changes the interpretation of empty interpolations so that
the text is simply an empty string.

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

PR Close #40583
2021-01-28 09:06:18 -08:00
Pete Bacon Darwin daa9b7e608 docs: add a @reviewed tag to the i18n guide (#40582)
PR Close #40582
2021-01-28 09:04:50 -08:00
Pete Bacon Darwin 47fe75e19d build(docs-infra): implement @reviewed tag definition (#40582)
The `@reviewed` tag can be used to specify the date when the
document was last reviewed.

PR Close #40582
2021-01-28 09:04:50 -08:00
George Kalpakas 44298dfb65 build(docs-infra): upgrade cli command docs sources to b427aeb88 (#40612)
Updating [angular#11.2.x](https://github.com/angular/angular/tree/11.2.x) from
[cli-builds#11.1.x](https://github.com/angular/cli-builds/tree/11.1.x).

##
Relevant changes in
[commit range](https://github.com/angular/cli-builds/compare/c366e223b...b427aeb88):

**Modified**
- help/build.json
- help/serve.json

PR Close #40612
2021-01-28 09:03:46 -08:00
Joey Perrott 0463578944 fix(dev-infra): wait for changelog to cherry pick to next branch (#40605)
Wait for the cherry-picked changelog to be merged into the next
branch before completing the task.

PR Close #40605
2021-01-28 09:02:57 -08:00
George Kalpakas 584fd4513c build(zone.js): use npm_package.pack to build the Zone.js package (#40592)
Previously, we could not use `npm_package.pack` for building the Zone.js
package due to a bug in Windows. This bug has been fixed in version
2.3.0 of `bazelbuild/rules_nodejs`.

Now that we have updated `bazelbuild/rules_nodejs` to version 2.3.3
(in #40581) we can replace `npm pack` with `npm_package.pack`.

PR Close #40592
2021-01-28 09:01:57 -08:00
cexbrayat 5b0147512f refactor(animations): remove unused utils function (#40588)
The `mergeAnimationOptions` function is no longer used since 05472cb21b

PR Close #40588
2021-01-28 09:01:07 -08:00
JoostK 7a6d1e2bf2 fix(compiler): exclude trailing whitespace from element source spans (#40513)
If the template parse option `leadingTriviaChars` is configured to
consider whitespace as trivia, any trailing whitespace of an element
would be considered as leading trivia of the subsequent element, such
that its `start` span would start _after_ the whitespace. This means
that the start span cannot be used to mark the end of the current
element, as its trailing whitespace would then be included in its span.
Instead, the full start of the subsequent element should be used.

To harden the tests that for the Ivy parser, the test utility `parseR3`
has been adjusted to use the same configuration for `leadingTriviaChars`
as would be the case in its production counterpart `parseTemplate`. This
uncovered another bug in offset handling of the interpolation parser,
where the absolute offset was computed from the start source span
(which excludes leading trivia) whereas the interpolation expression
would include the leading trivia. As such, the absolute offset now also
uses the full start span.

Fixes #39148

PR Close #40513
2021-01-28 08:57:46 -08:00
cexbrayat cabe8bec40 fix(core): remove duplicated EMPTY_ARRAY constant (#40587)
The codebase currently contains several `EMPTY_ARRAY` constants,
and they can end up in the bundle of an application.
A recent commit 6fbe219 tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating with @petebacondarwin,
we decided to remove the duplicated symbols.

This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/empty`.

PR Close #40587
2021-01-28 08:55:53 -08:00
Pete Bacon Darwin e11e6cf8c4 docs: update release notes for the 11.1.1 release (#40602)
Remove commits that had been reverted.

PR Close #40602
2021-01-27 13:04:43 -08:00
Jessica Janiuk f44a8e2cf6 release: cut the v11.2.0-next.0 release (#40600) 2021-01-27 13:05:08 -07:00
485 changed files with 11210 additions and 8561 deletions
-7
View File
@@ -20,11 +20,4 @@ build --local_ram_resources=32768
# 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
+7 -15
View File
@@ -479,6 +479,7 @@ groups:
users:
- alxhub
- IgorMinar
- petebacondarwin
# =========================================================
@@ -681,7 +682,7 @@ groups:
- *can-be-global-approved
- *can-be-global-docs-approved
- >
contains_any_globs(files.exclude('packages/compiler-cli/**'), [
contains_any_globs(files.exclude('packages/compiler-cli/**').exclude('packages/language-service/**'), [
'packages/**/testing/**',
'aio/content/guide/testing.md',
'aio/content/guide/test-debugging.md',
@@ -919,7 +920,9 @@ groups:
'aio/content/examples/getting-started-v0/**',
'aio/content/examples/getting-started/**',
'aio/content/start/**',
'aio/content/images/guide/start/**'
'aio/content/images/guide/start/**',
'aio/content/examples/what-is-angular/**',
'aio/content/guide/what-is-angular.md'
])
reviewers:
users:
@@ -1166,19 +1169,7 @@ groups:
'.vscode/**',
'.yarn/**',
'dev-infra/**',
'docs/BAZEL.md',
'docs/CARETAKER.md',
'docs/CODING_STANDARDS.md',
'docs/COMMITTER.md',
'docs/DEBUG.md',
'docs/DEBUG_COMPONENTS_REPO_IVY.md',
'docs/DEVELOPER.md',
'docs/FIXUP_COMMITS.md',
'docs/GITHUB_PROCESS.md',
'docs/PR_REVIEW.md',
'docs/SAVED_REPLIES.md',
'docs/TOOLS.md',
'docs/TRIAGE_AND_LABELS.md',
'docs/*.md',
'docs/images/**',
'goldens/*',
'modules/*',
@@ -1234,6 +1225,7 @@ groups:
'aio/content/errors/*.md',
'aio/content/guide/glossary.md',
'aio/content/guide/styleguide.md',
'aio/content/examples/errors/**',
'aio/content/examples/styleguide/**',
'aio/content/images/guide/styleguide/*'
])
+97 -2
View File
@@ -1,14 +1,109 @@
## 11.2.2 (2021-02-22)
### Bug Fixes
* **animations:** error when setting position before starting animation ([#28255](https://github.com/angular/angular/issues/28255)) ([f1c64b3](https://github.com/angular/angular/commit/f1c64b3f38ed38c2d0c7369f6ee5dea5bbc24cf3))
* **http:** emit error on XMLHttpRequest abort event ([#40786](https://github.com/angular/angular/issues/40786)) ([4a32579](https://github.com/angular/angular/commit/4a32579a4d660b774c380314033e15787dfe4631)), closes [#22324](https://github.com/angular/angular/issues/22324)
* **http:** ignore question mark when params are parsed ([#40610](https://github.com/angular/angular/issues/40610)) ([3b884ed](https://github.com/angular/angular/commit/3b884ed1fc1b1c89c1da9aa6ee0e6b21ff4aa024)), closes [#28722](https://github.com/angular/angular/issues/28722)
* **platform-browser:** ensure that Hammer loader is called only once ([#40911](https://github.com/angular/angular/issues/40911)) ([f8055f6](https://github.com/angular/angular/commit/f8055f6fb839e5817a83c484d96afb77bae0aed5)), closes [#25995](https://github.com/angular/angular/issues/25995)
### Performance Improvements
* **core:** use `ngDevMode` to tree-shake warning ([#40876](https://github.com/angular/angular/issues/40876)) ([c8a2e3a](https://github.com/angular/angular/commit/c8a2e3ae1c12cadd505cdd5a12e26a7231682415))
* **language-service:** short-circuit LS operations when we know there is no Angular information to provide ([#40946](https://github.com/angular/angular/issues/40946)) ([73a3ff1](https://github.com/angular/angular/commit/73a3ff11cbca21ec0a64e064c7968c93c0bd8e0a))
## 11.2.1 (2021-02-17)
### Bug Fixes
* **compiler:** handle `:host-context` and `:host` in the same selector ([#40494](https://github.com/angular/angular/issues/40494)) ([ab8ea87](https://github.com/angular/angular/commit/ab8ea8707842b98b8154f5cbe942b4b24724b6ca)), closes [#14349](https://github.com/angular/angular/issues/14349)
* **compiler:** support multiple `:host-context()` selectors ([#40494](https://github.com/angular/angular/issues/40494)) ([c20e304](https://github.com/angular/angular/commit/c20e3047a58ce2404551c0b51d539e77687e7283)), closes [#19199](https://github.com/angular/angular/issues/19199)
* **compiler:** support multiple selectors in `:host-context()` ([#40494](https://github.com/angular/angular/issues/40494)) ([fb0ce21](https://github.com/angular/angular/commit/fb0ce2178add49f204486c41ef94936f0f178086))
* **compiler-cli:** set TS original node on imported namespace identifiers ([#40711](https://github.com/angular/angular/issues/40711)) ([87ac052](https://github.com/angular/angular/commit/87ac05290ac12ccca10580d10d092d747dae9b40))
* **core:** address Trusted Types bug in Chrome 83 ([#40815](https://github.com/angular/angular/issues/40815)) ([b5f2070](https://github.com/angular/angular/commit/b5f20700c2b9c5edebbfeac8c656f290e4d5d7ea))
* **http:** complete the request on timeout ([#40771](https://github.com/angular/angular/issues/40771)) ([a2a5b4a](https://github.com/angular/angular/commit/a2a5b4add5e68cebe89a4d2b6eff2d75e4cd23c7))
* **router:** fix load interaction of navigation and preload strategies ([#40389](https://github.com/angular/angular/issues/40389)) ([4906bf6](https://github.com/angular/angular/commit/4906bf6a50f307fb69080d276c3b91a60ba7fbae)), closes [#26557](https://github.com/angular/angular/issues/26557) [#22842](https://github.com/angular/angular/issues/22842) [#26557](https://github.com/angular/angular/issues/26557) [#26557](https://github.com/angular/angular/issues/26557) [#22842](https://github.com/angular/angular/issues/22842) [#26557](https://github.com/angular/angular/issues/26557)
* **router:** fix load interaction of navigation and preload strategies ([#40389](https://github.com/angular/angular/issues/40389)) ([bba1981](https://github.com/angular/angular/commit/bba1981c6e1963e5cd1f2c704bb656ca8fcec531)), closes [#26557](https://github.com/angular/angular/issues/26557) [#22842](https://github.com/angular/angular/issues/22842) [#26557](https://github.com/angular/angular/issues/26557) [#26557](https://github.com/angular/angular/issues/26557) [#22842](https://github.com/angular/angular/issues/22842) [#26557](https://github.com/angular/angular/issues/26557)
<a name="11.2.0"></a>
# 11.2.0 (2021-02-10)
### Bug Fixes
* **animations:** properly track listeners for a removed element ([#40712](https://github.com/angular/angular/issues/40712)) ([74cb759](https://github.com/angular/angular/commit/74cb759))
* **common:** date is not correctly formatted when year is between 0 and 99 ([#40448](https://github.com/angular/angular/issues/40448)) ([bf85f04](https://github.com/angular/angular/commit/bf85f04)), closes [#40377](https://github.com/angular/angular/issues/40377)
* **compiler:** include parenthesis in expression source spans ([#40740](https://github.com/angular/angular/issues/40740)) ([e99c4e2](https://github.com/angular/angular/commit/e99c4e2)), closes [#40721](https://github.com/angular/angular/issues/40721)
* **compiler:** throw error for duplicate template references ([#40538](https://github.com/angular/angular/issues/40538)) ([7e0ff8c](https://github.com/angular/angular/commit/7e0ff8c)), closes [#40536](https://github.com/angular/angular/issues/40536)
* **compiler-cli:** don't crash when we can't resolve a resource ([#40660](https://github.com/angular/angular/issues/40660)) ([95446fb](https://github.com/angular/angular/commit/95446fb)), closes [angular/vscode-ng-language-service#1079](https://github.com/angular/vscode-ng-language-service/issues/1079)
* **core:** properly move embedded views of dynamic component's projectable nodes ([#37167](https://github.com/angular/angular/issues/37167)) ([9ae21ee](https://github.com/angular/angular/commit/9ae21ee)), closes [#37120](https://github.com/angular/angular/issues/37120)
* **localize:** improve invalid syntax in extraction error message ([#40724](https://github.com/angular/angular/issues/40724)) ([24600ff](https://github.com/angular/angular/commit/24600ff))
* **localize:** support downleveled inlined helper localize calls ([#40754](https://github.com/angular/angular/issues/40754)) ([415ad8d](https://github.com/angular/angular/commit/415ad8d)), closes [#40702](https://github.com/angular/angular/issues/40702)
* **router:** stop emitting to event observable on destroy ([#40638](https://github.com/angular/angular/issues/40638)) ([737bc7a](https://github.com/angular/angular/commit/737bc7a)), closes [#40502](https://github.com/angular/angular/issues/40502)
<a name="11.2.0-rc.0"></a>
# 11.2.0-rc.0 (2021-02-03)
<a name="11.2.0-next.1"></a>
# 11.2.0-next.1 (2021-02-03)
### Bug Fixes
* **common:** parse `YYYY-MM` strings as UTC dates ([#40620](https://github.com/angular/angular/issues/40620)) ([4c5f18d](https://github.com/angular/angular/commit/4c5f18d)), closes [#33944](https://github.com/angular/angular/issues/33944)
* **common:** parse `YYYY` strings as UTC dates ([#40629](https://github.com/angular/angular/issues/40629)) ([46d4326](https://github.com/angular/angular/commit/46d4326)), closes [#33944](https://github.com/angular/angular/issues/33944) [#40620](https://github.com/angular/angular/issues/40620)
* **compiler:** Don't set expression text to synthetic `$implicit` when empty ([#40583](https://github.com/angular/angular/issues/40583)) ([9d396f8](https://github.com/angular/angular/commit/9d396f8))
* **compiler:** exclude trailing whitespace from element source spans ([#40513](https://github.com/angular/angular/issues/40513)) ([7a6d1e2](https://github.com/angular/angular/commit/7a6d1e2)), closes [#39148](https://github.com/angular/angular/issues/39148)
* **compiler-cli:** preserve user line endings in diagnostic template parse ([#40597](https://github.com/angular/angular/issues/40597)) ([caafac2](https://github.com/angular/angular/commit/caafac2))
* **core:** ensure the type `T` of `EventEmitter<T>` can be inferred ([#40644](https://github.com/angular/angular/issues/40644)) ([5c54767](https://github.com/angular/angular/commit/5c54767)), closes [#40637](https://github.com/angular/angular/issues/40637)
* **core:** remove duplicated EMPTY_ARRAY constant ([#40587](https://github.com/angular/angular/issues/40587)) ([cabe8be](https://github.com/angular/angular/commit/cabe8be))
### Performance Improvements
* **language-service:** update NgCompiler via resource-only path when able ([#40585](https://github.com/angular/angular/issues/40585)) ([07a3d7a](https://github.com/angular/angular/commit/07a3d7a))
<a name="11.2.0-next.0"></a>
# 11.2.0-next.0 (2021-01-27)
### Bug Fixes
* **core:** make DefaultIterableDiffer keep the order of duplicates ([#23941](https://github.com/angular/angular/issues/23941)) ([a826926](https://github.com/angular/angular/commit/a826926)), closes [#23815](https://github.com/angular/angular/issues/23815)
### Features
* **common:** implement `appendAll()` method on `HttpParams` ([#20930](https://github.com/angular/angular/issues/20930)) ([575a2d1](https://github.com/angular/angular/commit/575a2d1)), closes [#20798](https://github.com/angular/angular/issues/20798)
* **language-service:** Add diagnostics to suggest turning on strict mode ([#40423](https://github.com/angular/angular/issues/40423)) ([ecae75f](https://github.com/angular/angular/commit/ecae75f))
* **language-service:** Implement `getRenameInfo` ([#40439](https://github.com/angular/angular/issues/40439)) ([4e8198d](https://github.com/angular/angular/commit/4e8198d))
* **language-service:** initial implementation for `findRenameLocations` ([#40140](https://github.com/angular/angular/issues/40140)) ([9a5ac47](https://github.com/angular/angular/commit/9a5ac47))
* **language-service:** view template typecheck block ([#39974](https://github.com/angular/angular/issues/39974)) ([d482f5c](https://github.com/angular/angular/commit/d482f5c))
<a name="11.1.1"></a>
## 11.1.1 (2021-01-27)
### Bug Fixes
* **compiler:** support multiple `:host-context()` selectors ([#40494](https://github.com/angular/angular/issues/40494)) ([72c0ba6](https://github.com/angular/angular/commit/72c0ba6)), closes [#19199](https://github.com/angular/angular/issues/19199)
* **compiler-cli:** handle pseudo cycles in inline source-maps ([#40435](https://github.com/angular/angular/issues/40435)) ([566206b](https://github.com/angular/angular/commit/566206b)), closes [#40408](https://github.com/angular/angular/issues/40408)
* **compiler-cli:** use `Map` rather than `object` for map of partial linkers ([#40563](https://github.com/angular/angular/issues/40563)) ([33e0f2b](https://github.com/angular/angular/commit/33e0f2b))
* **core:** fix possible XSS attack in development through SSR ([#40525](https://github.com/angular/angular/issues/40525)) ([97ec6e4](https://github.com/angular/angular/commit/97ec6e4))
* **core:** fix possible XSS attack in development through SSR ([#40525](https://github.com/angular/angular/issues/40525)) ([3bf6a99](https://github.com/angular/angular/commit/3bf6a99))
* **core:** improve injector debug information in `ngDevMode` ([#40476](https://github.com/angular/angular/issues/40476)) ([4bb38c9](https://github.com/angular/angular/commit/4bb38c9))
* **forms:** allow `patchValue()` method of `FormGroup` and `FormArray` classes to skip `null` values ([#40534](https://github.com/angular/angular/issues/40534)) ([2fab148](https://github.com/angular/angular/commit/2fab148)), closes [#36672](https://github.com/angular/angular/issues/36672) [#21021](https://github.com/angular/angular/issues/21021)
* **forms:** properly cleanup in cases when FormControlName has no CVA ([#40526](https://github.com/angular/angular/issues/40526)) ([72fc6aa](https://github.com/angular/angular/commit/72fc6aa)), closes [#39235](https://github.com/angular/angular/issues/39235) [#40521](https://github.com/angular/angular/issues/40521)
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2020 Google LLC. https://angular.io/license
Copyright (c) 2010-2021 Google LLC. https://angular.io/license
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+3 -8
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 = "9d93d4e1340c43dbf6b2fd66b683d89630a6310bf8be3bf40ec96685dcacc26c",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.3.3/rules_nodejs-2.3.3.tar.gz"],
sha256 = "dd4dc46066e2ce034cba0c81aa3e862b27e8e8d95871f567359f7a534cccb666",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/3.1.0/rules_nodejs-3.1.0.tar.gz"],
)
# Check the rules_nodejs version and download npm dependencies
@@ -44,11 +44,6 @@ load("@npm//@bazel/protractor:package.bzl", "npm_bazel_protractor_dependencies")
npm_bazel_protractor_dependencies()
# Load karma dependencies
load("@npm//@bazel/karma:package.bzl", "npm_bazel_karma_dependencies")
npm_bazel_karma_dependencies()
# Setup the rules_webtesting toolchain
load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories")
@@ -59,7 +54,7 @@ load("//dev-infra/browsers:browser_repositories.bzl", "browser_repositories")
browser_repositories()
# Setup the rules_sass toolchain
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
load("@io_bazel_rules_sass//:defs.bzl", "sass_repositories")
sass_repositories()
+4 -4
View File
@@ -4,7 +4,7 @@
@shortDescription Expression has changed after it was checked
@description
Angular throws an `ExpressionChangedAfterItHasBeenCheckedError` when an expression value has been changed after change detection has completed. Angular only throws this error in development mode.
Angular throws an `ExpressionChangedAfterItHasBeenCheckedError` when an expression value has been changed after change detection has completed. Angular only throws this error in development mode.
In dev mode, Angular performs an additional check after each change detection run, to ensure the bindings haven’t changed. This catches errors where the view is left in an inconsistent state. This can occur, for example, if a method or getter returns a different value each time it is called, or if a child component changes values on its parent. If either of these occur, this is a sign that change detection is not stabilized. Angular throws the error to ensure data is always reflected correctly in the view, which prevents erratic UI behavior or a possible infinite loop.
@@ -13,8 +13,8 @@ This error commonly occurs when you’ve added template expressions or begun to
@debugging
The [source maps](https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map) generated by the CLI are very useful when debugging. Navigate up the call stack until you find a template expression where the value displayed in the error has changed.
Ensure that there are no changes to the bindings in the template after change detection is run. This often means refactoring to use the correct [component lifecycle hook](https://angular.io/guide/lifecycle-hooks) for your use case. If the issue exists within `ngAfterViewInit`, the recommended solution is to use a constructor or `ngOnInit` to set initial values, or use `ngAfterContentInit` for other value bindings.
Ensure that there are no changes to the bindings in the template after change detection is run. This often means refactoring to use the correct [component lifecycle hook](guide/lifecycle-hooks) for your use case. If the issue exists within `ngAfterViewInit`, the recommended solution is to use a constructor or `ngOnInit` to set initial values, or use `ngAfterContentInit` for other value bindings.
If you are binding to methods in the view, ensure that the invocation does not update any of the other bindings in the template.
If you are binding to methods in the view, ensure that the invocation does not update any of the other bindings in the template.
Read more about which solution is right for you in ['Everything you need to know about the "ExpressionChangedAfterItHasBeenCheckedError" error'](https://indepth.dev/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error/) and why this is useful at ['Angular Debugging "Expression has changed after it was checked": Simple Explanation (and Fix)'](https://blog.angular-university.io/angular-debugging/).
Read more about which solution is right for you in ['Everything you need to know about the "ExpressionChangedAfterItHasBeenCheckedError" error'](https://indepth.dev/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error/) and why this is useful at ['Angular Debugging "Expression has changed after it was checked": Simple Explanation (and Fix)'](https://blog.angular-university.io/angular-debugging/).
+2 -2
View File
@@ -4,9 +4,9 @@
@shortDescription Circular dependency in DI detected while instantiating a provider
@description
A cyclic dependency exists when a [dependency of a service](https://angular.io/guide/hierarchical-dependency-injection) directly or indirectly depends on the service itself. For example, if `UserService` depends on `EmployeeService`, which also depends on `UserService`. Angular will have to instantiate `EmployeeService` to create `UserService`, which depends on `UserService`, itself.
A cyclic dependency exists when a [dependency of a service](guide/hierarchical-dependency-injection) directly or indirectly depends on the service itself. For example, if `UserService` depends on `EmployeeService`, which also depends on `UserService`. Angular will have to instantiate `EmployeeService` to create `UserService`, which depends on `UserService`, itself.
@debugging
Use the call stack to determine where the cyclical dependency exists. You will be able to see if any child dependencies rely on the original file by [mapping out](https://angular.io/guide/dependency-injection-in-action) the component, module, or service’s dependencies and identify the loop causing the problem.
Use the call stack to determine where the cyclical dependency exists. You will be able to see if any child dependencies rely on the original file by [mapping out](guide/dependency-injection-in-action) the component, module, or service’s dependencies and identify the loop causing the problem.
Break this loop (or circle) of dependency to resolve this error. This most commonly means removing or refactoring the dependencies to not be reliant on one another.
+4 -4
View File
@@ -4,12 +4,12 @@
@shortDescription No provider for {token} found!
@description
You see this error when you try to inject a service but have not declared a corresponding provider. A provider is a mapping that supplies a value that you can inject into the constructor of a class in your application.
You see this error when you try to inject a service but have not declared a corresponding provider. A provider is a mapping that supplies a value that you can inject into the constructor of a class in your application.
Read more on providers in our [Dependency Injection guide](https://angular.io/guide/dependency-injection).
Read more on providers in our [Dependency Injection guide](guide/dependency-injection).
@debugging
Work backwards from the object where the error states that a [provider](https://angular.io/guide/architecture-services) is missing: `No provider for ${this}!`. This is commonly thrown in [services](https://angular.io/tutorial/toh-pt4), which require non-existing providers.
Work backwards from the object where the error states that a [provider](guide/architecture-services) is missing: `No provider for ${this}!`. This is commonly thrown in [services](tutorial/toh-pt4), which require non-existing providers.
To fix the error ensure that your service is registered in the list of providers of an `NgModule` or has the `@Injectable` decorator with a `providedIn` property at top.
@@ -17,4 +17,4 @@ The most common solution is to add a provider in `@Injectable` using `providedIn
```typescript
@Injectable({ providedIn: 'app' })
```
```
+4 -4
View File
@@ -1,13 +1,13 @@
@name Selector Collision
@name Selector Collision
@category runtime
@videoUrl https://www.youtube.com/embed/z_3Z5mOm59I
@shortDescription Multiple components match with the same tagname
@description
Two or more components use the same [element selector](https://angular.io/guide/component-overview#specifying-a-components-css-selector). Because there can only be a single component associated with an element, selectors must be unique strings to prevent ambiguity for Angular.
Two or more components use the same [element selector](guide/component-overview#specifying-a-components-css-selector). Because there can only be a single component associated with an element, selectors must be unique strings to prevent ambiguity for Angular.
@debugging
Use the element name from the error message to search for places where you’re using the same [selector declaration](https://angular.io/guide/architecture-components) in your codebase:
Use the element name from the error message to search for places where you’re using the same [selector declaration](guide/architecture-components) in your codebase:
```typescript
@Component({
@@ -18,4 +18,4 @@ Use the element name from the error message to search for places where you’re
Ensure that each component has a unique CSS selector. This will guarantee that Angular renders the component you expect.
If you’re having trouble finding multiple components with this selector tag name, check for components from imported component libraries, such as Angular Material. Make sure you're following the [best practices](https://angular.io/guide/styleguide#component-selectors) for your selectors to prevent collisions.
If you’re having trouble finding multiple components with this selector tag name, check for components from imported component libraries, such as Angular Material. Make sure you're following the [best practices](guide/styleguide#component-selectors) for your selectors to prevent collisions.
+2 -2
View File
@@ -4,7 +4,7 @@
@shortDescription Export not found!
@description
Angular can’t find a directive with `{{ PLACEHOLDER }}` export name. The export name is specified in the `exportAs` property of the directive decorator. This is common when using FormsModule or Material modules in templates, and you’ve forgotten to [import the corresponding modules](https://angular.io/guide/sharing-ngmodules).
Angular can’t find a directive with `{{ PLACEHOLDER }}` export name. The export name is specified in the `exportAs` property of the directive decorator. This is common when using FormsModule or Material modules in templates, and you’ve forgotten to [import the corresponding modules](guide/sharing-ngmodules).
<div class="alert is-helpful">
@@ -15,7 +15,7 @@ This is the runtime equivalent of a common compiler error [NG8003: No directive
@debugging
Use the export name to trace the templates or modules using this export.
Ensure that all dependencies are [properly imported and declared in your NgModules](https://angular.io/guide/sharing-ngmodules). For example, if the export not found is `ngForm`, we need to import `FormsModule` and declare it in the list of imports in `*.module.ts` to resolve the error.
Ensure that all dependencies are [properly imported and declared in your NgModules](guide/sharing-ngmodules). For example, if the export not found is `ngForm`, we need to import `FormsModule` and declare it in the list of imports in `*.module.ts` to resolve the error.
```typescript
import { FormsModule } from '@angular/forms';
+18
View File
@@ -0,0 +1,18 @@
@name Pipe Not Found
@category runtime
@videoUrl https://www.youtube.com/embed/maI2u6Sxk9M
@shortDescription Pipe not found!
@description
Angular can't find a pipe with this name.
The pipe referenced in the template has not been named or declared properly.
A [pipe](guide/pipes) must be either declared or imported in the `NgModule` where it is used, and the name used in a template must match the name defined in the pipe decorator.
@debugging
Use the pipe name to trace the templates or modules where this pipe is declared and used.
To resolve this error, ensure that:
- A local custom pipe is uniquely named in the pipe's decorator, and declared in the `NgModule`, or
- A pipe from another `NgModule` is added to the imports of the `NgModule` where it is used.
If you recently added an import or declaration, you may need to restart your server to see these changes.
+2 -2
View File
@@ -3,9 +3,9 @@
@shortDescription No suitable injection token for parameter
@description
There is no injection token for a constructor parameter at compile time. [InjectionTokens](https://angular.io/api/core/InjectionToken) are tokens that can be used in a Dependency Injection Provider.
There is no injection token for a constructor parameter at compile time. [InjectionTokens](api/core/InjectionToken) are tokens that can be used in a Dependency Injection Provider.
@debugging
Look at the parameter that throws the error and all uses of the class. This error is commonly thrown when a constructor defines parameters with primitive types like `string`, `number`, `boolean`, and `Object`.
Use the [@Injectable](https://angular.io/api/core/Injectable) method or [@Inject](https://angular.io/api/core/Inject) decorator from `@angular/core` to ensure that the type you are injecting is reified (has a runtime representation). Make sure to add a provider to this decorator so that you do not throw [NG0201: No Provider Found](https://angular.io/errors/NG0201).
Use the [@Injectable](api/core/Injectable) method or [@Inject](api/core/Inject) decorator from `@angular/core` to ensure that the type you are injecting is reified (has a runtime representation). Make sure to add a provider to this decorator so that you do not throw [NG0201: No Provider Found](errors/NG0201).
+55
View File
@@ -0,0 +1,55 @@
@name Import Cycle Detected
@category compiler
@shortDescription Import cycles would need to be created to compile this component
@description
A component, directive or pipe that is referenced by this component would require the compiler
to add an import that would lead to a cycle of imports. For example, consider a scenario where
a `ParentComponent` references a `ChildComponent` in its template:
<code-example path="errors/cyclic-imports/parent.component.ts" header="parent.component.ts"></code-example>
<code-example path="errors/cyclic-imports/child.component.ts" header="child.component.ts"></code-example>
There is already an import from `child.component.ts` to `parent.component.ts` since the `ChildComponent`
references the `ParentComponent` in its constructor.
But note that the parent component's template contains `<child></child>`. The generated code for this
template must therefore contain a reference to the `ChildComponent` class. In order to make this reference
the compiler would have to add an import from `parent.component.ts` to `child.component.ts`, which would
cause an import cycle:
```
parent.component.ts -> child.component.ts -> parent.component.ts
```
### Remote Scoping
To avoid adding imports that create cycles, additional code is added to the `NgModule` class where
the component is declared that wires up the dependencies. This is known as "remote scoping".
### Libraries
Unfortunately, "remote scoping" code is side-effectful, which prevents tree shaking, and cannot
be used in libraries. So when building libraries using the `"compilationMode": "partial"` setting,
any component that would require a cyclic import will cause this `NG3003` compiler error to be raised.
@debugging
The cycle that would be generated is shown as part of the error message. For example:
<code-example hideCopy="true">
<span class="nocode">The component ChildComponent is used in the template but importing it would create a cycle:
/parent.component.ts -> /child.component.ts -> /parent.component.ts</span>
</code-example>
Use this to identify how the referenced component, pipe or directive has a dependency back to the
component being compiled. Here are some ideas for fixing the problem:
* Try to re-arrange your dependencies to avoid the cycle. For example using an intermediate interface
that is stored in an independent file that can be imported to both dependent files without
causing an import cycle.
* Move the classes that reference each other into the same file, to avoid any imports between them.
+3 -3
View File
@@ -12,10 +12,10 @@ This is the compiler equivalent of a common runtime error `NG0304: '${tagName}'
</div>
@debugging
Use the element name in the error to find the file(s) where the element is being used.
Use the element name in the error to find the file(s) where the element is being used.
Check that the name and selector are correct. If the component is from a different module or import, check that the component is exported from its origin module and imported into the correct `*.modules.ts` file, and declared in the imports list.
Check that the name and selector are correct. If the component is from a different module or import, check that the component is exported from its origin module and imported into the correct `*.modules.ts` file, and declared in the imports list.
When using custom elements or web components, ensure that you add [`CUSTOM_ELEMENTS_SCHEMA`](https://angular.io/api/core/CUSTOM_ELEMENTS_SCHEMA) to the app module.
When using custom elements or web components, ensure that you add [`CUSTOM_ELEMENTS_SCHEMA`](api/core/CUSTOM_ELEMENTS_SCHEMA) to the app module.
If this does not resolve the error, check the imported libraries for any recent changes to the exports and properties you are using, and restart your server.
+1 -1
View File
@@ -13,4 +13,4 @@ This error arises when attempting to bind to a property that does not exist. Any
The runtime error for this is `NG0304: '${tagName}' is not a known element: …’`.
@debugging
Look at documentation for the specific [binding syntax](https://angular.io/guide/binding-syntax) used. This is usually a typo or incorrect import. There may also be a missing direction with property selector ‘name’ or missing input.
Look at documentation for the specific [binding syntax](guide/binding-syntax) used. This is usually a typo or incorrect import. There may also be a missing direction with property selector ‘name’ or missing input.
+2 -2
View File
@@ -4,7 +4,7 @@
@shortDescription No directive found with export
@description
Angular can’t find a directive with `{{ PLACEHOLDER }}` export name. This is common with a missing import or a missing [`exportAs`](https://angular.io/api/core/Directive#exportAs) on a directive.
Angular can’t find a directive with `{{ PLACEHOLDER }}` export name. This is common with a missing import or a missing [`exportAs`](api/core/Directive#exportAs) on a directive.
<div class="alert is-helpful">
@@ -16,7 +16,7 @@ This is the compiler equivalent of a common runtime error [NG0301: Export Not Fo
@debugging
Use the string name of the export not found to trace the templates or modules using this export.
Ensure that all dependencies are properly imported and declared in our Modules. For example, if the export not found is `ngForm`, we will need to import `FormsModule` and declare it in our list of imports in `*.module.ts` to resolve the missing export error.
Ensure that all dependencies are properly imported and declared in our Modules. For example, if the export not found is `ngForm`, we will need to import `FormsModule` and declare it in our list of imports in `*.module.ts` to resolve the missing export error.
```typescript
import { FormsModule } from '@angular/forms';
@@ -0,0 +1,14 @@
@Component({
selector: 'app-nav-bar',
template: `
<nav [style]='navStyle'>
<a [style.text-decoration]="activeLinkStyle">Home Page</a>
<a [style.text-decoration]="linkStyle">Login</a>
</nav>`
})
export class NavBarComponent {
navStyle = 'font-size: 1.2rem; color: cornflowerblue;';
linkStyle = 'underline';
activeLinkStyle = 'overline';
/* . . . */
}
@@ -4,11 +4,7 @@
<p appHighlight>Highlight me!</p>
<!-- #enddocregion applied -->
<!-- #docregion color-1 -->
<p appHighlight highlightColor="yellow">Highlighted in yellow</p>
<p appHighlight [highlightColor]="'orange'">Highlighted in orange</p>
<!-- #enddocregion color-1 -->
<!-- #docregion color-2 -->
<p appHighlight [highlightColor]="color">Highlighted with parent component's color</p>
<!-- #enddocregion color-2 -->
@@ -1,8 +1,8 @@
/* tslint:disable:no-unused-variable member-ordering */
// #docplaster
// #docregion imports,
// #docregion imports
import { Directive, ElementRef, HostListener } from '@angular/core';
// #enddocregion imports,
// #enddocregion imports
import { Input } from '@angular/core';
// #docregion
@@ -10,9 +10,8 @@ import { Input } from '@angular/core';
selector: '[appHighlight]'
})
export class HighlightDirective {
// #docregion ctor
constructor(private el: ElementRef) { }
// #enddocregion ctor
// #docregion mouse-methods
@HostListener('mouseenter') onMouseEnter() {
@@ -26,16 +25,10 @@ export class HighlightDirective {
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
// #enddocregion mouse-methods,
// #docregion color
@Input() highlightColor: string;
// #enddocregion color
// #enddocregion mouse-methods
// #docregion color-2
@Input() appHighlight: string;
// #enddocregion color-2
// #docregion
}
// #enddocregion
@@ -12,11 +12,9 @@ export class HighlightDirective {
@Input('appHighlight') highlightColor: string;
// #docregion mouse-enter
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || 'red');
}
// #enddocregion mouse-enter
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
@@ -12,9 +12,7 @@ export class HighlightDirective {
@Input() defaultColor: string;
// #enddocregion defaultColor
// #docregion color
@Input('appHighlight') highlightColor: string;
// #enddocregion color
// #docregion mouse-enter
@HostListener('mouseenter') onMouseEnter() {
@@ -7,11 +7,8 @@
<fieldset><h4>NgModel examples</h4>
<p>Current item name: {{currentItem.name}}</p>
<p>
<!-- #docregion without-NgModel -->
<label for="without">without NgModel:</label>
<input [value]="currentItem.name" (input)="currentItem.name=$event.target.value" id="without">
<!-- #enddocregion without-NgModel -->
</p>
<p>
@@ -27,10 +24,8 @@
</p>
<p>
<!-- #docregion NgModelChange -->
<label for="example-change">(ngModelChange)="...name=$event":</label>
<input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">
<!-- #enddocregion NgModelChange -->
</p>
<p>
@@ -77,12 +72,9 @@
<!-- NgStyle binding -->
<hr><h3>NgStyle Binding</h3>
<!-- #docregion without-ng-style -->
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">
This div is x-large or smaller.
</div>
<!-- #enddocregion without-ng-style -->
<h4>[ngStyle] binding to currentStyles - CSS property names</h4>
<p>currentStyles is {{currentStyles | json}}</p>
@@ -134,7 +126,6 @@
<hr>
<h4>Show/hide vs. NgIf</h4>
<!-- #docregion NgIf-3 -->
<!-- isSpecial is true -->
<div [class.hidden]="!isSpecial">Show with class</div>
<div [class.hidden]="isSpecial">Hide with class</div>
@@ -144,7 +135,6 @@
<div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div>
<div [style.display]="isSpecial ? 'none' : 'block'">Hide with style</div>
<!-- #enddocregion NgIf-3 -->
<hr>
@@ -21,7 +21,10 @@ export class AppComponent implements OnInit {
item: Item; // defined to demonstrate template context precedence
items: Item[];
// #docregion item
currentItem: Item;
// #enddocregion item
// trackBy change counting
@@ -5,9 +5,13 @@ import { Item } from './item';
selector: 'app-stout-item',
template: `I'm a little {{item.name}}, short and stout!`
})
// #docregion input
export class StoutItemComponent {
@Input() item: Item;
}
// #enddocregion input
@Component({
selector: 'app-best-item',
@@ -0,0 +1,13 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-not-great',
})
// #docregion not-great
export class NotGreatComponent {
buggyFunction() {
// things could be better here...
}
}
// #enddocregion not-great
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';
import { ParentComponent } from './parent.component';
@Component({selector: 'app-child', template: 'The child!'})
export class ChildComponent {
constructor(private parent: ParentComponent) {}
}
@@ -0,0 +1,8 @@
import { NgModule } from '@angular/core';
import { ChildComponent } from './child.component';
import { ParentComponent } from './parent.component';
@NgModule({
declarations: [ParentComponent, ChildComponent]
})
export class AppModule {}
@@ -0,0 +1,4 @@
import { Component } from '@angular/core';
@Component({selector: 'app-parent', template: '<app-child></app-child>'})
export class ParentComponent {}
@@ -66,6 +66,7 @@ describe('Http Tests', () => {
await checkLogForMessage('GET "assets/config.json"');
expect(await page.configSpan.getText()).toContain('Heroes API URL is "api/heroes"');
expect(await page.configSpan.getText()).toContain('Textfile URL is "assets/textfile.txt"');
expect(await page.configSpan.getText()).toContain('Date is "Wed Jan 29 2020" (date)');
});
it('can fetch the configuration JSON file with headers', async () => {
@@ -7,6 +7,7 @@
<span *ngIf="config">
<p>Heroes API URL is "{{config.heroesUrl}}"</p>
<p>Textfile URL is "{{config.textfile}}"</p>
<p>Date is "{{config.date.toDateString()}}" ({{getType(config.date)}})</p>
<div *ngIf="headers">
Response headers:
<ul>
@@ -2,7 +2,6 @@
// #docregion
import { Component } from '@angular/core';
import { Config, ConfigService } from './config.service';
import { MessageService } from '../message.service';
@Component({
selector: 'app-config',
@@ -40,7 +39,8 @@ export class ConfigComponent {
// #docregion v1
.subscribe((data: Config) => this.config = {
heroesUrl: data.heroesUrl,
textfile: data.textfile
textfile: data.textfile,
date: data.date,
});
}
// #enddocregion v1
@@ -71,5 +71,9 @@ export class ConfigComponent {
makeError() {
this.configService.makeIntentionalError().subscribe(null, error => this.error = error );
}
getType(val: any): string {
return val instanceof Date ? 'date' : Array.isArray(val) ? 'array' : typeof val;
}
}
// #enddocregion
@@ -14,6 +14,7 @@ import { catchError, retry } from 'rxjs/operators';
export interface Config {
heroesUrl: string;
textfile: string;
date: any;
}
// #enddocregion config-interface
// #docregion proto
@@ -0,0 +1,62 @@
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
// #docregion custom-json-interceptor
@Injectable()
export class CustomJsonInterceptor implements HttpInterceptor {
constructor(private jsonParser: JsonParser) {}
intercept(httpRequest: HttpRequest<any>, next: HttpHandler) {
if (httpRequest.responseType === 'json') {
// If the expected response type is JSON then handle it here.
return this.handleJsonResponse(httpRequest, next);
} else {
return next.handle(httpRequest);
}
}
private handleJsonResponse(httpRequest: HttpRequest<any>, next: HttpHandler) {
// Override the responseType to disable the default JSON parsing.
httpRequest = httpRequest.clone({responseType: 'text'});
// Handle the response using the custom parser.
return next.handle(httpRequest).pipe(map(event => this.parseJsonResponse(event)));
}
private parseJsonResponse(event: HttpEvent<any>) {
if (event instanceof HttpResponse && typeof event.body === 'string') {
return event.clone({body: this.jsonParser.parse(event.body)});
} else {
return event;
}
}
}
// The JsonParser class acts as a base class for custom parsers and as the DI token.
@Injectable()
export abstract class JsonParser {
abstract parse(text: string): any;
}
// #enddocregion custom-json-interceptor
// #docregion custom-json-parser
@Injectable()
export class CustomJsonParser implements JsonParser {
parse(text: string): any {
return JSON.parse(text, dateReviver);
}
}
function dateReviver(key: string, value: any) {
// #enddocregion custom-json-parser
if (typeof value !== 'string') {
return value;
}
const match = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(value);
if (!match) {
return value;
}
return new Date(+match[1], +match[2] - 1, +match[3]);
// #docregion custom-json-parser
}
// #enddocregion custom-json-parser
@@ -6,6 +6,7 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
// #enddocregion interceptor-providers
import { AuthInterceptor } from './auth-interceptor';
import { CachingInterceptor } from './caching-interceptor';
import { CustomJsonInterceptor , CustomJsonParser, JsonParser} from './custom-json-interceptor';
import { EnsureHttpsInterceptor } from './ensure-https-interceptor';
import { LoggingInterceptor } from './logging-interceptor';
// #docregion interceptor-providers
@@ -21,6 +22,10 @@ export const httpInterceptorProviders = [
// #docregion noop-provider
{ provide: HTTP_INTERCEPTORS, useClass: NoopInterceptor, multi: true },
// #enddocregion noop-provider, interceptor-providers
// #docregion custom-json-interceptor
{ provide: HTTP_INTERCEPTORS, useClass: CustomJsonInterceptor, multi: true },
{ provide: JsonParser, useClass: CustomJsonParser },
// #enddocregion custom-json-interceptor
{ provide: HTTP_INTERCEPTORS, useClass: EnsureHttpsInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: TrimNameInterceptor, multi: true },
@@ -1,4 +1,5 @@
{
"heroesUrl": "api/heroes",
"textfile": "assets/textfile.txt"
"textfile": "assets/textfile.txt",
"date": "2020-01-29"
}
@@ -1,7 +1,6 @@
.button {
box-shadow: inset 0px 1px 0px 0px #ffffff;
background: linear-gradient(to bottom, #ffffff 5%, #f6f6f6 100%);
background-color: #ffffff;
box-shadow: inset 0 1px 0 0 #ffffff;
background: #ffffff linear-gradient(to bottom, #ffffff 5%, #f6f6f6 100%);
border-radius: 6px;
border: 1px solid #dcdcdc;
display: inline-block;
@@ -12,13 +11,12 @@
font-weight: bold;
padding: 6px 24px;
text-decoration: none;
text-shadow: 0px 1px 0px #ffffff;
text-shadow: 0 1px 0 #ffffff;
outline: 0;
}
.activebutton {
box-shadow: inset 0px 1px 0px 0px #dcecfb;
background: linear-gradient(to bottom, #bddbfa 5%, #80b5ea 100%);
background-color: #bddbfa;
box-shadow: inset 0 1px 0 0 #dcecfb;
background: #bddbfa linear-gradient(to bottom, #bddbfa 5%, #80b5ea 100%);
border-radius: 6px;
border: 1px solid #84bbf3;
display: inline-block;
@@ -29,6 +27,6 @@
font-weight: bold;
padding: 6px 24px;
text-decoration: none;
text-shadow: 0px 1px 0px #528ecc;
text-shadow: 0 1px 0 #528ecc;
outline: 0;
}
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';
@Component({
selector: 'sg-app',
template: '<toh-hero-list></toh-hero-list>'
})
export class AppComponent { }
@@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { HeroComponent, HeroListComponent } from './heroes';
@NgModule({
imports: [
BrowserModule,
RouterModule.forChild([{ path: '05-18', component: AppComponent }])
],
declarations: [
AppComponent,
HeroComponent,
HeroListComponent
],
exports: [AppComponent]
})
export class AppModule {}
@@ -0,0 +1,24 @@
import { Component } from '@angular/core';
import { Hero } from '../shared/hero.model';
@Component({
selector: 'toh-hero-list',
template: `
<section>
Our list of heroes:
<toh-hero *ngFor="let hero of heroes">
</toh-hero>
Total powers: {{totalPowers}}<br>
Average power: {{avgPower}}
</section>
`
})
export class HeroListComponent {
heroes: Hero[] = [];
totalPowers = 1;
get avgPower() {
return this.totalPowers / this.heroes.length;
}
}
@@ -0,0 +1 @@
export * from './hero-list.component';
@@ -0,0 +1,15 @@
import { Component, Input } from '@angular/core';
// #docregion example
@Component({
selector: 'toh-hero',
template: `...`
})
export class HeroComponent {
// The exclamation mark suppresses errors that a property is
// not initialized.
// Ignoring this enforcement can prevent the type checker
// from finding potential issues.
@Input() id!: string;
}
// #enddocregion example
@@ -0,0 +1,17 @@
import { Component, Input } from '@angular/core';
// #docregion example
@Component({
selector: 'toh-hero',
template: `...`
})
export class HeroComponent {
@Input() id?: string;
process() {
if (this.id) {
// ...
}
}
}
// #enddocregion example
@@ -0,0 +1,11 @@
import { Component, Input } from '@angular/core';
// #docregion example
@Component({
selector: 'toh-hero',
template: `...`
})
export class HeroComponent {
@Input() id = 'default_id';
}
// #enddocregion example
@@ -0,0 +1 @@
export * from './hero.component';
@@ -0,0 +1,3 @@
export * from './hero';
export * from './hero-list';
export * from './shared';
@@ -0,0 +1,4 @@
export interface Hero {
id: number;
name: string;
}
@@ -0,0 +1 @@
export * from './hero.model';
@@ -0,0 +1,2 @@
export * from './heroes';
export * from './app.component';
@@ -19,7 +19,7 @@ export class HeroesComponent implements OnInit {
heroes = HEROES;
// #enddocregion component
// #docregion on-select
selectedHero: Hero;
selectedHero?: Hero;
// #enddocregion on-select
constructor() { }
@@ -35,4 +35,3 @@ export class HeroesComponent implements OnInit {
// #docregion component
}
// #enddocregion component
@@ -25,11 +25,11 @@ export class HeroService {
// #docregion getHeroes, getHeroes-1
getHeroes(): Observable<Hero[]> {
const heroes = of(HEROES);
// #enddocregion getHeroes-1
// TODO: send the message _after_ fetching the heroes
this.messageService.add('HeroService: fetched heroes');
// #docregion getHeroes-1
return of(HEROES);
return heroes;
}
// #enddocregion getHeroes, getHeroes-1
}
@@ -0,0 +1,61 @@
import { browser, element, by, logging } from 'protractor';
describe('What is Angular', () => {
const paragraphs = element.all(by.css('p'));
const buttons = element.all(by.css('button'));
const templateButton = buttons.get(1);
const templateText = paragraphs.get(3);
const messageButton = buttons.get(0);
const messageText = paragraphs.get(2);
const ngIfButton = buttons.get(2);
const ngIfText = paragraphs.get(4);
const diButton = buttons.get(3);
beforeEach(() => browser.get(''));
// helper function to test what's logged to the console
async function logChecker(contents) {
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
const messages = logs.filter(({ message }) => message.indexOf(contents) !== -1 ? true : false);
expect(messages.length).toBeGreaterThan(0);
}
it('should display Hello World', async () => {
expect(await element(by.css('hello-world h2')).getText()).toEqual('Hello World');
});
// Test for alert
it('should display js alert after button click', async () => {
await messageButton.click();
const alert = browser.switchTo().alert();
expect(await alert.getText()).toEqual('Hello, World');
await alert.accept();
});
it('should display blue a sentence', async () => {
expect(await messageText.getCssValue('color')).toEqual('rgba(0, 0, 255, 1)');
});
// Hello World Template section
it('should add 123 to editable p tag', async () => {
await templateButton.click();
await templateText.click();
await templateText.sendKeys('123');
expect(await templateText.getText()).toEqual('You can edit me!123');
});
// Test for ngIf section
it('should display edit instructions after button click', async () => {
await ngIfButton.click();
expect(await ngIfText.getText()).toEqual('You can edit the following paragraph.');
});
// Test for DI section
it('should log the count', async () => {
await diButton.click();
await logChecker(0);
});
});
@@ -0,0 +1,9 @@
<h1>Understanding Angular</h1>
<!-- #docregion hello-world-selector -->
<hello-world></hello-world>
<!-- #enddocregion hello-world-selector -->
<hello-world-interpolation></hello-world-interpolation>
<hello-world-bindings></hello-world-bindings>
<hello-world-template></hello-world-template>
<hello-world-ngif></hello-world-ngif>
<hello-world-di></hello-world-di>
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent { }
@@ -0,0 +1,30 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HelloWorldComponent } from './hello-world/hello-world.component';
import { HelloWorldTemplateComponent } from './hello-world-template.component';
import { HelloWorldNgIfComponent } from './hello-world-ngif/hello-world-ngif.component';
import { HelloWorldDependencyInjectionComponent } from './hello-world-di/hello-world-di.component';
import { HelloWorldInterpolationComponent } from './hello-world-interpolation/hello-world-interpolation.component';
import { HelloWorldBindingsComponent } from './hello-world-bindings/hello-world-bindings.component';
@NgModule({
declarations: [
AppComponent,
HelloWorldComponent,
HelloWorldTemplateComponent,
HelloWorldNgIfComponent,
HelloWorldDependencyInjectionComponent,
HelloWorldInterpolationComponent,
HelloWorldBindingsComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
@@ -0,0 +1,6 @@
<!-- #docregion event-binding -->
<button (click)="sayMessage()" [disabled]="canClick">Trigger alert message</button>
<!-- #enddocregion -->
<!-- #docregion bindings -->
<p [id]="sayHelloId" [style.color]="fontColor">You can set my color in the component!</p>
<!-- #enddocregion -->
@@ -0,0 +1,17 @@
import { Component } from '@angular/core';
@Component ({
selector: 'hello-world-bindings',
templateUrl: './hello-world-bindings.component.html'
})
export class HelloWorldBindingsComponent {
fontColor = 'blue';
sayHelloId = 1;
canClick = false;
message = 'Hello, World';
// #docregion method
sayMessage() {
alert(this.message);
}
// #enddocregion
}
@@ -0,0 +1,3 @@
<h2>Hello World: Dependency Injection</h2>
<button (click)="onLogMe()">Log me!</button>
<p>Be sure to open the console to view the output!</p>
@@ -0,0 +1,19 @@
import { Component } from '@angular/core';
import { Logger } from '../logger.service';
@Component({
selector: 'hello-world-di',
templateUrl: './hello-world-di.component.html'
})
export class HelloWorldDependencyInjectionComponent {
count = 0;
constructor(private logger: Logger) {
}
onLogMe(){
this.logger.writeCount(this.count);
this.count++;
}
}
@@ -0,0 +1,4 @@
<hello-world>
<h2>Hello World</h2>
<p>This is my first component!</p>
</hello-world>
@@ -0,0 +1,3 @@
<!-- #docregion say-hello -->
<p>{{ message }}</p>
<!-- #enddocregion say-hello -->
@@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component ({
selector: 'hello-world-interpolation',
templateUrl: './hello-world-interpolation.component.html'
})
export class HelloWorldInterpolationComponent {
message = 'Hello, World!';
}
@@ -0,0 +1,9 @@
<h2>Hello World: ngIf!</h2>
<button (click)="onEditClick()">Make text editable!</button>
<div *ngIf="canEdit; else noEdit">
<p>You can edit the following paragraph.</p>
</div>
<ng-template #noEdit>
<p>The following paragraph is read only. Try clicking the button!</p>
</ng-template>
<p [contentEditable]="canEdit">{{ message }}</p>
@@ -0,0 +1,21 @@
// #docplaster
import { Component } from '@angular/core';
@Component({
selector: 'hello-world-ngif',
templateUrl: './hello-world-ngif.component.html'
})
export class HelloWorldNgIfComponent {
message = 'I\'m read only!';
canEdit = false;
onEditClick(){
this.canEdit = !this.canEdit;
if (this.canEdit) {
this.message = 'You can edit me!';
} else {
this.message = 'I\'m read only!';
}
}
}
@@ -0,0 +1,24 @@
// #docplaster
import { Component } from '@angular/core';
@Component({
selector: 'hello-world-template',
template: `
<h2>Hello World Template</h2>
<button (click)="onEditClick()">Make text editable!</button>
<p [contentEditable]="canEdit">{{ message }}</p>
`
})
export class HelloWorldTemplateComponent {
message = 'I am read only!';
canEdit = false;
onEditClick(){
this.canEdit = !this.canEdit;
if (this.canEdit) {
this.message = 'You can edit me!';
} else {
this.message = 'I am read only!';
}
}
}
@@ -0,0 +1,14 @@
// #docplaster
import { Component } from '@angular/core';
@Component({
selector: 'hello-world',
template: `
<h2>Hello World</h2>
<p>This is my first component!</p>
`,
})
export class HelloWorldComponent {
// The code in this class drives the component's behavior.
}
@@ -0,0 +1,8 @@
import { Injectable } from '@angular/core';
@Injectable({providedIn: 'root'})
export class Logger {
writeCount(count: number) {
console.warn(count);
}
}
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Helloworld</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
@@ -0,0 +1,12 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
@@ -0,0 +1,8 @@
{
"description": "What is Angular?",
"files":[
"!**/*.d.ts",
"!**/*.js"
],
"tags":["overview", "angular"]
}
+2 -3
View File
@@ -140,8 +140,7 @@ 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/built-in-directives#microsyntax)
section of the [Built-in Directives](guide/built-in-directives) page.
For more information, see the [Template input variables](guide/structural-directives#template-input-variable) section of [Structural Directives](guide/structural-directives).
</td>
</tr>
@@ -641,7 +640,7 @@ The following are some of the key AngularJS built-in directives and their equiva
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 the [NgStyle](guide/built-in-directives#ngStyle)
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>
@@ -123,7 +123,7 @@ to the generated flat module index instead of the library index file.
Produces only one `.metadata.json` file, which contains all the metadata necessary
for symbols exported from the library index. In the generated `.ngfactory.js` files, the flat
module index is used to import symbols that includes both the public API from the library index
module index is used to import symbols that include both the public API from the library index
as well as shrowded internal symbols.
By default the `.ts` file supplied in the `files` field is assumed to be the library index.
-21
View File
@@ -15,8 +15,6 @@ The following are metadata errors you may encounter, with explanations and sugge
[Tagged template expressions are not supported](#tagged-template-expressions-not-supported)<br>
[Symbol reference expected](#symbol-reference-expected)<br>
<hr>
{@a expression-form-not-supported}
## Expression form not supported
@@ -47,8 +45,6 @@ Avoid this error by sticking to the compiler's [restricted expression syntax](gu
when writing Angular metadata
and be wary of new or unusual TypeScript features.
<hr>
{@a reference-to-a-local-symbol}
## Reference to a local (non-exported) symbol
@@ -128,8 +124,6 @@ The compiler needs the value of the `template` property _right now_ to generate
The variable reference alone is insufficient.
Prefixing the declaration with `export` merely produces a new error, "[`Only initialized variables and constants can be referenced`](#only-initialized-variables)".
<hr>
{@a only-initialized-variables}
## Only initialized variables and constants
@@ -187,8 +181,6 @@ export let someTemplate = '<h1>Greetings from Angular</h1>';
export class MyComponent {}
```
<hr>
{@a reference-to-a-non-exported-class}
## Reference to a non-exported class
@@ -228,7 +220,6 @@ export abstract class MyStrategy { }
]
...
```
<hr>
{@a reference-to-a-non-exported-function}
## Reference to a non-exported function
@@ -266,7 +257,6 @@ export function myStrategy() { ... }
]
...
```
<hr>
{@a function-calls-not-supported}
## Function calls are not supported
@@ -322,8 +312,6 @@ export function someValueFactory() {
...
```
<hr>
{@a destructured-variable-not-supported}
## Destructured variable or constant not supported
@@ -364,8 +352,6 @@ import { configuration } from './configuration';
...
```
<hr>
{@a could-not-resolve-type}
## Could not resolve type
@@ -437,7 +423,6 @@ export class MyComponent {
constructor (@Inject(DOCUMENT) private doc: Document) { ... }
}
```
<hr>
{@a name-expected}
## Name expected
@@ -462,8 +447,6 @@ Change the name of the property to something non-numeric.
provider: [{ provide: Foo, useValue: { '0': 'test' } }]
```
<hr>
{@a unsupported-enum-member-name}
## Unsupported enum member name
@@ -494,8 +477,6 @@ enum Colors {
Avoid referring to enums with complicated initializers or computed properties.
<hr>
{@a tagged-template-expressions-not-supported}
## Tagged template expressions are not supported
@@ -520,8 +501,6 @@ is a _tag function_ native to JavaScript ES2015.
The AOT compiler does not support tagged template expressions; avoid them in metadata expressions.
<hr>
{@a symbol-reference-expected}
## Symbol reference expected
+1 -1
View File
@@ -181,7 +181,7 @@ The `ngModel` directive, which implements two-way data binding, is an example of
Angular has more pre-defined directives that either alter the layout structure
(for example, [ngSwitch](guide/built-in-directives#ngSwitch))
or modify aspects of DOM elements and components
(for example, [ngStyle](guide/built-in-directives#ngStyle) and [ngClass](guide/built-in-directives#ngClass)).
(for example, [ngStyle](guide/built-in-directives#ngstyle) and [ngClass](guide/built-in-directives#ngClass)).
<div class="alert is-helpful">
+3 -4
View File
@@ -114,13 +114,12 @@ The router interprets a link URL according to your app's view navigation rules a
To define navigation rules, you associate *navigation paths* with your components. A path uses a URL-like syntax that integrates your program data, in much the same way that template syntax integrates your views with your program data. You can then apply program logic to choose which views to show or to hide, in response to user input and your own access rules.
<div class="alert is-helpful">
<div class="alert is-helpful">
For a more detailed discussion, see [Routing and navigation](guide/router).
For a more detailed discussion, see [Routing and navigation](guide/router).
</div>
</div>
<hr/>
## What's next
+14 -12
View File
@@ -34,7 +34,7 @@ Then, you set the attribute value with an expression that resolves to a string.
<div class="alert is-helpful">
When the expression resolves to `null`, Angular removes the attribute altogether.
When the expression resolves to `null` or `undefined`, Angular removes the attribute altogether.
</div>
@@ -74,10 +74,8 @@ For more information on how to bind to the `colSpan` property, see the [`colspan
</div>
<hr/>
{@a class-binding}
## Binding to the `class` attribute
You can use class binding to add and remove CSS class names from an element's `class` attribute.
@@ -159,10 +157,8 @@ The following table summarizes class binding syntax.
</tr>
</table>
<hr/>
{@a style-binding}
## Binding to the style attribute
You can use style binding to set styles dynamically.
@@ -178,6 +174,12 @@ Optionally, you can add a unit extension like `em` or `%`, which requires a numb
You can write a style property name in either [dash-case](guide/glossary#dash-case), or
[camelCase](guide/glossary#camelcase).
<code-example language="html">
&lt;nav [style.background-color]="expression"&gt;&lt;/nav&gt;
&lt;nav [style.backgroundColor]="expression"&gt;&lt;/nav&gt;
</code-example>
</div>
### Binding to multiple styles
@@ -185,8 +187,8 @@ You can write a style property name in either [dash-case](guide/glossary#dash-ca
To toggle multiple styles, bind to the `[style]` attribute&mdash;for example, `[style]="styleExpression"`.
The `styleExpression` can be one of:
* A string list of styles such as `"width: 100px; height: 100px;"`.
* An object with style names as the keys and style values as the values, such as `{width: '100px', height: '100px'}`.
* A string list of styles such as `"width: 100px; height: 100px; background-color: cornflowerblue;"`.
* An object with style names as the keys and style values as the values, such as `{width: '100px', height: '100px', backgroundColor: 'cornflowerblue'}`.
Note that binding an array to `[style]` is not supported.
@@ -197,6 +199,11 @@ Updating the property without changing object identity has no effect.
</div>
#### Single and multiple-style binding example
<code-example path="attribute-binding/src/app/single-and-multiple-style-binding.component.ts" header="nav-bar.component.ts">
</code-example>
If there are multiple bindings to the same style attribute, Angular uses [styling precedence](guide/style-precedence) to determine which binding to use.
The following table summarizes style binding syntax.
@@ -260,10 +267,7 @@ However, using the above style binding syntax without `NgStyle` is preferred bec
</div>
<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).
@@ -326,8 +330,6 @@ In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `widt
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.
<hr/>
## Injecting attribute values
There are cases where you need to differentiate the behavior of a [Component](api/core/Component) or [Directive](api/core/Directive) based on a static value set on the host element as an HTML attribute. For example, you might have a directive that needs to know the `type` of a `<button>` or `<input>` element.
+88 -325
View File
@@ -1,411 +1,174 @@
# Attribute directives
An **Attribute** directive changes the appearance or behavior of a DOM element.
With attribute directives, you can change the appearance or behavior of DOM elements and Angular components.
Try the <live-example title="Attribute Directive example"></live-example>.
<div class="alert is-helpful">
{@a directive-overview}
See the <live-example></live-example> for a working example containing the code snippets in this guide.
## Directives overview
</div>
There are three kinds of directives in Angular:
## Building an attribute directive
1. Components&mdash;directives with a template.
1. Structural directives&mdash;change the DOM layout by adding and removing DOM elements.
1. Attribute directives&mdash;change the appearance or behavior of an element, component, or another directive.
This section walks you through creating a highlight directive that sets the background color of the host element to yellow.
*Components* are the most common of the three directives.
You saw a component for the first time in the [Getting Started](start "Getting Started with Angular") tutorial.
1. To create a directive, use the CLI command [`ng generate directive`](cli/generate).
*Structural Directives* change the structure of the view.
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/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
An attribute directive minimally requires building a controller class annotated with
`@Directive`, which specifies the selector that identifies
the attribute.
The controller class implements the desired directive behavior.
This page demonstrates building a simple _appHighlight_ attribute
directive to set an element's background color
when the user hovers over that element. You can apply it like this:
<code-example path="attribute-directives/src/app/app.component.1.html" header="src/app/app.component.html (applied)" region="applied"></code-example>
{@a write-directive}
Please note that directives _do not_ support namespaces.
<code-example path="attribute-directives/src/app/app.component.avoid.html" header="src/app/app.component.avoid.html (unsupported)" region="unsupported"></code-example>
### Write the directive code
Create the directive class file in a terminal window with the CLI command [`ng generate directive`](cli/generate).
<code-example language="sh" class="code-shell">
<code-example language="sh" class="code-shell">
ng generate directive highlight
</code-example>
The CLI creates `src/app/highlight.directive.ts`, a corresponding test file `src/app/highlight.directive.spec.ts`, and _declares_ the directive class in the root `AppModule`.
The CLI creates `src/app/highlight.directive.ts`, a corresponding test file `src/app/highlight.directive.spec.ts`, and declares the directive class in the `AppModule`.
The CLI generates the default `src/app/highlight.directive.ts` as follows:
<code-example path="attribute-directives/src/app/highlight.directive.0.ts" header="src/app/highlight.directive.ts"></code-example>
The `@Directive()` decorator's configuration property specifies the directive's CSS attribute selector, `[appHighlight]`.
1. Import `ElementRef` from `@angular/core`.
`ElementRef` grants direct access to the host DOM element through its `nativeElement` property.
1. Add `ElementRef` in the directive's `constructor()` to [inject](guide/dependency-injection) a reference to the host DOM element, the element to which you apply `appHighlight`.
1. Add logic to the `HighlightDirective` class that sets the background to yellow.
<code-example path="attribute-directives/src/app/highlight.directive.1.ts" header="src/app/highlight.directive.ts"></code-example>
<div class="alert is-helpful">
_Directives_ must be declared in [Angular Modules](guide/ngmodules) in the same manner as _components_.
Directives _do not_ support namespaces.
</div >
The generated `src/app/highlight.directive.ts` is as follows:
<code-example path="attribute-directives/src/app/highlight.directive.0.ts" header="src/app/highlight.directive.ts"></code-example>
The imported `Directive` symbol provides Angular the `@Directive` decorator.
The `@Directive` decorator's lone configuration property specifies the directive's
[CSS attribute selector](https://developer.mozilla.org/docs/Web/CSS/Attribute_selectors), `[appHighlight]`.
It's the brackets (`[]`) that make it an attribute selector.
Angular locates each element in the template that has an attribute named `appHighlight` and applies the logic of this directive to that element.
The _attribute selector_ pattern explains the name of this kind of directive.
<div class="alert is-helpful">
#### Why not "highlight"?
Though *highlight* would be a more concise selector than *appHighlight* and it would work,
the best practice is to prefix selector names to ensure
they don't conflict with standard HTML attributes.
This also reduces the risk of colliding with third-party directive names.
The CLI added the `app` prefix for you.
Make sure you do **not** prefix the `highlight` directive name with **`ng`** because
that prefix is reserved for Angular and using it could cause bugs that are difficult to diagnose.
<code-example path="attribute-directives/src/app/app.component.avoid.html" header="src/app/app.component.avoid.html (unsupported)" region="unsupported"></code-example>
</div>
After the `@Directive` metadata comes the directive's controller class,
called `HighlightDirective`, which contains the (currently empty) logic for the directive.
Exporting `HighlightDirective` makes the directive accessible.
Now edit the generated `src/app/highlight.directive.ts` to look as follows:
<code-example path="attribute-directives/src/app/highlight.directive.1.ts" header="src/app/highlight.directive.ts"></code-example>
The `import` statement specifies an additional `ElementRef` symbol from the Angular `core` library:
You use the `ElementRef` in the directive's constructor
to [inject](guide/dependency-injection) a reference to the host DOM element,
the element to which you applied `appHighlight`.
`ElementRef` grants direct access to the host DOM element
through its `nativeElement` property.
This first implementation sets the background color of the host element to yellow.
{@a apply-directive}
## Applying an attribute directive
## Apply the attribute directive
1. To use the `HighlightDirective`, add a `<p>` element to the HTML template with the directive as an attribute.
To use the new `HighlightDirective`, add a paragraph (`<p>`) element to the template of the root `AppComponent` and apply the directive as an attribute.
<code-example path="attribute-directives/src/app/app.component.1.html" header="src/app/app.component.html" region="applied"></code-example>
<code-example path="attribute-directives/src/app/app.component.1.html" header="src/app/app.component.html" region="applied"></code-example>
Now run the application to see the `HighlightDirective` in action.
<code-example language="sh" class="code-shell">
ng serve
</code-example>
To summarize, Angular found the `appHighlight` attribute on the **host** `<p>` element.
It created an instance of the `HighlightDirective` class and
injected a reference to the `<p>` element into the directive's constructor
which sets the `<p>` element's background style to yellow.
Angular creates an instance of the `HighlightDirective` class and injects a reference to the `<p>` element into the directive's constructor, which sets the `<p>` element's background style to yellow.
{@a respond-to-user}
## Respond to user-initiated events
## Handling user events
Currently, `appHighlight` simply sets an element color.
The directive could be more dynamic.
It could detect when the user mouses into or out of the element
and respond by setting or clearing the highlight color.
This section shows you how to detect when a user mouses into or out of the element and to respond by setting or clearing the highlight color.
Begin by adding `HostListener` to the list of imported symbols.
1. Import `HostListener` from '@angular/core'.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (imports)" region="imports"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (imports)" region="imports"></code-example>
Then add two event handlers that respond when the mouse enters or leaves,
each adorned by the `HostListener` decorator.
1. Add two event handlers that respond when the mouse enters or leaves, each with the `@HostListener()` decorator.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (mouse-methods)" region="mouse-methods"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (mouse-methods)" region="mouse-methods"></code-example>
The `@HostListener` decorator lets you subscribe to events of the DOM
element that hosts an attribute directive, the `<p>` in this case.
With the `@HostListener()` decorator, you can subscribe to events of the DOM element that hosts an attribute directive, the `<p>` in this case.
<div class="alert is-helpful">
The handlers delegate to a helper method, `highlight()`, that sets the color on the host DOM element, `el`.
Of course you could reach into the DOM with standard JavaScript and attach event listeners manually.
There are at least three problems with _that_ approach:
1. You have to write the listeners correctly.
1. The code must *detach* the listener when the directive is destroyed to avoid memory leaks.
1. Talking to DOM API directly isn't a best practice.
</div>
The handlers delegate to a helper method that sets the color on the host DOM element, `el`.
The helper method, `highlight`, was extracted from the constructor.
The revised constructor simply declares the injected `el: ElementRef`.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (constructor)" region="ctor"></code-example>
Here's the updated directive in full:
The complete directive is as follows:
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts"></code-example>
Run the app and confirm that the background color appears when
the pointer hovers over the paragraph element and disappears as the pointer moves out.
The background color appears when the pointer hovers over the paragraph element and disappears as the pointer moves out.
<div class="lightbox">
<img src="generated/images/guide/attribute-directives/highlight-directive-anim.gif" alt="Second Highlight">
</div>
{@a bindings}
## Passing values into an attribute directive
## Pass values into the directive with an _@Input_ data binding
This section walks you through setting the highlight color while applying the `HighlightDirective`.
Currently the highlight color is hard-coded _within_ the directive. That's inflexible.
In this section, you give the developer the power to set the highlight color while applying the directive.
1. In `highlight.directive.ts`, import `Input` from `@angular/core`.
Begin by adding `Input` to the list of symbols imported from `@angular/core`.
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" header="src/app/highlight.directive.ts (imports)" region="imports"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" header="src/app/highlight.directive.ts (imports)" region="imports"></code-example>
Add a `highlightColor` property to the directive class like this:
1. Add an `appHighlight` `@Input()` property.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (highlightColor)" region="color"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts" region="color-2"></code-example>
{@a input}
The `@Input()` decorator adds metadata to the class that makes the directive's `appHighlight` property available for binding.
### Binding to an `@Input()` property
1. In `app.component.ts`, add a `color` property to the `AppComponent`.
Notice the `@Input()` decorator. It adds metadata to the class that makes the directive's `highlightColor` property available for binding.
<code-example path="attribute-directives/src/app/app.component.1.ts" header="src/app/app.component.ts (class)" region="class"></code-example>
It's called an *input* property because data flows from the binding expression _into_ the directive.
Without that `@Input()` metadata, Angular rejects the binding; see [below](guide/attribute-directives#why-input "Why add @Input?") for more information.
1. To simultaneously apply the directive and the color, use property binding with the `appHighlight` directive selector, setting it equal to `color`.
Try it by adding the following directive binding variations to the `AppComponent` template:
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (color)" region="color"></code-example>
<code-example path="attribute-directives/src/app/app.component.1.html" header="src/app/app.component.html (excerpt)" region="color-1"></code-example>
The `[appHighlight]` attribute binding performs two tasks:
Add a `color` property to the `AppComponent`.
* applies the highlighting directive to the `<p>` element
* sets the directive's highlight color with a property binding
<code-example path="attribute-directives/src/app/app.component.1.ts" header="src/app/app.component.ts (class)" region="class"></code-example>
### Setting the value with user input
Let it control the highlight color with a property binding.
This section guides you through adding radio buttons to bind your color choice to the `appHighlight` directive.
<code-example path="attribute-directives/src/app/app.component.1.html" header="src/app/app.component.html (excerpt)" region="color-2"></code-example>
1. Add markup to `app.component.html` for choosing a color as follows:
That's good, but it would be nice to _simultaneously_ apply the directive and set the color _in the same attribute_ like this.
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (v2)" region="v2"></code-example>
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (color)" region="color"></code-example>
1. Revise the `AppComponent.color` so that it has no initial value.
The `[appHighlight]` attribute binding both applies the highlighting directive to the `<p>` element
and sets the directive's highlight color with a property binding.
You're re-using the directive's attribute selector (`[appHighlight]`) to do both jobs.
That's a crisp, compact syntax.
<code-example path="attribute-directives/src/app/app.component.ts" header="src/app/app.component.ts (class)" region="class"></code-example>
You'll have to rename the directive's `highlightColor` property to `appHighlight` because that's now the color property binding name.
1. Serve your application to verify that the user can choose the color with the radio buttons.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (renamed to match directive selector)" region="color-2"></code-example>
This is disagreeable. The word, `appHighlight`, is a terrible property name and it doesn't convey the property's intent.
{@a input-alias}
### Bind to an _@Input_ alias
Fortunately you can name the directive property whatever you want _and_ **_alias it_** for binding purposes.
Restore the original property name and specify the selector as the alias in the argument to `@Input()`.
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (color property with alias)" region="color"></code-example>
_Inside_ the directive the property is known as `highlightColor`.
_Outside_ the directive, where you bind to it, it's known as `appHighlight`.
You get the best of both worlds: the property name you want and the binding syntax you want:
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (color)" region="color"></code-example>
Now that you're binding via the alias to the `highlightColor`, modify the `onMouseEnter()` method to use that property.
If someone neglects to bind to `appHighlight`, highlight the host element in red:
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" header="src/app/highlight.directive.ts (mouse enter)" region="mouse-enter"></code-example>
Here's the latest version of the directive class.
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" header="src/app/highlight.directive.ts (excerpt)"></code-example>
## Write a harness to try it
It may be difficult to imagine how this directive actually works.
In this section, you'll turn `AppComponent` into a harness that
lets you pick the highlight color with a radio button and bind your color choice to the directive.
Update <code>app.component.html</code> as follows:
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (v2)" region="v2"></code-example>
Revise the `AppComponent.color` so that it has no initial value.
<code-example path="attribute-directives/src/app/app.component.ts" header="src/app/app.component.ts (class)" region="class"></code-example>
Here are the harness and directive in action.
<div class="lightbox">
<img src="generated/images/guide/attribute-directives/highlight-directive-v2-anim.gif" alt="Highlight v.2">
</div>
<div class="lightbox">
<img src="generated/images/guide/attribute-directives/highlight-directive-v2-anim.gif" alt="Animated gif of the refactored highlight directive changing color according to the radio button the user selects">
</div>
{@a second-property}
## Bind to a second property
## Binding to a second property
This highlight directive has a single customizable property. In a real app, it may need more.
This section guides you through configuring your application so the developer can set the default color.
At the moment, the default color&mdash;the color that prevails until
the user picks a highlight color&mdash;is hard-coded as "red".
Let the template developer set the default color.
1. Add a second `Input()` property to `HighlightDirective` called `defaultColor`.
Add a second **input** property to `HighlightDirective` called `defaultColor`:
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (defaultColor)" region="defaultColor"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (defaultColor)" region="defaultColor"></code-example>
1. Revise the directive's `onMouseEnter` so that it first tries to highlight with the `highlightColor`, then with the `defaultColor`, and falls back to `red` if both properties are `undefined`.
Revise the directive's `onMouseEnter` so that it first tries to highlight with the `highlightColor`,
then with the `defaultColor`, and falls back to "red" if both properties are undefined.
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (mouse-enter)" region="mouse-enter"></code-example>
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (mouse-enter)" region="mouse-enter"></code-example>
1. To bind to the `AppComponent.color` and fall back to "violet" as the default color, add the following HTML.
In this case, the `defaultColor` binding doesn't use square brackets, `[]`, because it is static.
How do you bind to a second property when you're already binding to the `appHighlight` attribute name?
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (defaultColor)" region="defaultColor"></code-example>
As with components, you can add as many directive property bindings as you need by stringing them along in the template.
The developer should be able to write the following template HTML to both bind to the `AppComponent.color`
and fall back to "violet" as the default color.
As with components, you can add multiple directive property bindings to a host element.
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (defaultColor)" region="defaultColor"></code-example>
The default color is red if there is no default color binding.
When the user chooses a color the selected color becomes the active highlight color.
Angular knows that the `defaultColor` binding belongs to the `HighlightDirective`
because you made it _public_ with the `@Input()` decorator.
Here's how the harness should work when you're done coding.
<div class="lightbox">
<img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight">
</div>
<hr />
<div class="lightbox">
<img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Animated gif of final highlight directive that shows red color with no binding and violet with the default color set. When user selects color, the selection takes precedence.">
</div>
{@a ngNonBindable}
## `ngNonBindable`
## Deactivating Angular processing with `NgNonBindable`
With the built-in template primitive `ngNonBindable`, Angular won't
evaluate expressions in elements. For example:
To prevent expression evaluation in the browser, add `ngNonBindable` to the host element.
`ngNonBindable` deactivates interpolation, directives, and binding in templates.
In the following example, the expression `{{ 1 + 1 }}` renders just as it does in your code editor, and does not display `2`.
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html" region="ngNonBindable"></code-example>
The expression `{{ 1 + 1 }}` will render just as it does in your code editor,
and will not display `2`. This is helpful when you want to render code in the browser.
When you apply `ngNonBindable` to an element, it stops any binding starting at that element, including child elements. However, `ngNonBindable` still allows
directives to work to the element where you apply `ngNonBindable`. In the following example, the `appHighlight` directive will still be active but Angular will not evaluate the expression `{{ 1 + 1 }}`.
Applying `ngNonBindable` to an element stops binding for that element's child elements.
However, `ngNonBindable` still allows directives to work on the element where you apply `ngNonBindable`.
In the following example, the `appHighlight` directive is still active but Angular does not evaluate the expression `{{ 1 + 1 }}`.
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html" region="ngNonBindable-with-directive"></code-example>
Additionally, if you apply `ngNonBindable` to a parent element, interpolation and binding of any sort, such as property binding, or event binding, is disabled for its children.
## Summary
This page covered how to:
* [Build an **attribute directive**](guide/attribute-directives#write-directive) that modifies the behavior of an element.
* [Apply the directive](guide/attribute-directives#apply-directive) to an element in a template.
* [Respond to **events**](guide/attribute-directives#respond-to-user) that change the directive's behavior.
* [**Bind** values to the directive](guide/attribute-directives#bindings).
* [Prevent expression evaluation](guide/attribute-directives#ngNonBindable).
The final source code follows:
<code-tabs>
<code-pane header="app/app.component.ts" path="attribute-directives/src/app/app.component.ts"></code-pane>
<code-pane header="app/app.component.html" path="attribute-directives/src/app/app.component.html"></code-pane>
<code-pane header="app/highlight.directive.ts" path="attribute-directives/src/app/highlight.directive.ts"></code-pane>
<code-pane header="app/app.module.ts" path="attribute-directives/src/app/app.module.ts"></code-pane>
<code-pane header="main.ts" path="attribute-directives/src/main.ts"></code-pane>
<code-pane header="index.html" path="attribute-directives/src/index.html"></code-pane>
</code-tabs>
You can also experience and download the <live-example title="Attribute Directive example"></live-example>.
{@a why-input}
### Appendix: Why add `@Input()`?
In this demo, the `highlightColor` property is an `@Input()` property of
the `HighlightDirective`. You've seen it applied without an alias:
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
You've seen it with an alias:
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
Either way, the `@Input()` decorator tells Angular that this property is
_public_ and available for binding by a parent component.
Without `@Input()`, Angular refuses to bind to the property.
You've bound template HTML to component properties before and never used `@Input()`.
What's different?
The difference is a matter of trust.
Angular treats a component's template as _belonging_ to the component.
The component and its template trust each other implicitly.
Therefore, the component's own template may bind to _any_ property of that component,
with or without the `@Input()` decorator.
But a component or directive shouldn't blindly trust _other_ components and directives.
The properties of a component or directive are hidden from binding by default.
They are _private_ from an Angular binding perspective.
When adorned with the `@Input()` decorator, the property becomes _public_ from an Angular binding perspective.
Only then can it be bound by some other component or directive.
You can tell if `@Input()` is needed by the position of the property name in a binding.
* When it appears in the template expression to the ***right*** of the equals (=),
it belongs to the template's component and does not require the `@Input()` decorator.
* When it appears in **square brackets** ([ ]) to the **left** of the equals (=),
the property belongs to some _other_ component or directive;
that property must be adorned with the `@Input()` decorator.
Now apply that reasoning to the following example:
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (color)" region="color"></code-example>
* The `color` property in the expression on the right belongs to the template's component.
The template and its component trust each other.
The `color` property doesn't require the `@Input()` decorator.
* The `appHighlight` property on the left refers to an _aliased_ property of the `HighlightDirective`,
not a property of the template's component.
For security, the directive property must carry the `@Input()` decorator.
If you apply `ngNonBindable` to a parent element, Angular disables interpolation and binding of any sort, such as property binding or event binding, for the element's children.
-18
View File
@@ -353,24 +353,6 @@ The following polyfills are used to test the framework itself. They are a good s
</tr>
<tr>
<td>
<a id='intl' href="https://github.com/andyearnshaw/Intl.js">Intl</a>
</td>
<td>
MIT / Unicode license
</td>
<td>
13.5KB
</td>
</tr>
<tr>
<td>
+1 -1
View File
@@ -98,7 +98,7 @@ export class AppComponent {
## Configure target-specific file replacements
The main CLI configuration file, `angular.json`, contains a `fileReplacements` section in the configuration for each build target, which allows you to replace any file with a target-specific version of that file.
The main CLI configuration file, `angular.json`, contains a `fileReplacements` section in the configuration for each build target, which allows you to replace any file in the TypeScript program with a target-specific version of that file.
This is useful for including target-specific code or variables in a build that targets a specific environment, such as production or staging.
By default no files are replaced.
+195 -278
View File
@@ -1,6 +1,8 @@
# Built-in directives
Angular offers two kinds of built-in directives: [_attribute_ directives](guide/attribute-directives) and [_structural_ directives](guide/structural-directives).
Directives are classes that add additional behavior to elements
in your Angular applications.
With Angular's built-in directives, you can manage forms, lists, styles, and what users see.
<div class="alert is-helpful">
@@ -8,35 +10,31 @@ See the <live-example></live-example> for a working example containing the code
</div>
For more detail, including how to build your own custom directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives).
The different types of Angular directives are as follows:
<hr/>
1. [Components](guide/component-overview)&mdash;directives with a template.
This type of directive is the most common directive type.
1. [Attribute directives](guide/built-in-directives#built-in-attribute-directives)&mdash;directives that change the appearance or behavior of an element, component, or another directive.
1. [Structural directives](guide/built-in-directives#built-in-structural-directives)&mdash;directives that change the DOM layout by adding and removing DOM elements.
This guide covers built-in [attribute directives](guide/built-in-directives#built-in-attribute-directives) and [structural directives](guide/built-in-directives#built-in-structural-directives).
{@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.
Attribute directives listen to and modify the behavior of other HTML elements, attributes, properties, and components.
Many NgModules such as the [`RouterModule`](guide/router "Routing and Navigation")
and the [`FormsModule`](guide/forms "Forms") define their own attribute directives.
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.
* [`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}
## Adding and removing classes with `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>
You can add or remove multiple CSS classes simultaneously with `ngClass`.
<div class="alert is-helpful">
@@ -44,120 +42,72 @@ To add or remove a *single* class, use [class binding](guide/attribute-binding#c
</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.
### Using `NgClass` with an expression
<code-example path="built-in-directives/src/app/app.component.ts" region="setClasses" header="src/app/app.component.ts"></code-example>
On the element you'd like to style, add `[ngClass]` and set it equal to an expression.
In this case, `isSpecial` is a boolean set to `true` in `app.component.ts`.
Because `isSpecial` is true, `ngClass` applies the class of `special` to the `<div>`.
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="special-div" header="src/app/app.component.html"></code-example>
<code-example path="built-in-directives/src/app/app.component.html" region="NgClass-1" header="src/app/app.component.html"></code-example>
### Using `NgClass` with a method
<div class="alert is-helpful">
1. To use `NgClass` with a method, add the method to the component class.
In the following example, `setCurrentClasses()` sets the property `currentClasses` with an object that adds or removes three classes based on the `true` or `false` state of three other component properties.
Remember that in this situation you'd call `setCurrentClasses()`,
both initially and when the dependent properties change.
Each key of the object is a CSS class name.
If a key is `true`, `ngClass` adds the class.
If a key is `false`, `ngClass` removes the class.
</div>
<code-example path="built-in-directives/src/app/app.component.ts" region="setClasses" header="src/app/app.component.ts"></code-example>
<hr/>
1. In the template, add the `ngClass` property binding to `currentClasses` to set the element's classes:
{@a ngStyle}
<code-example path="built-in-directives/src/app/app.component.html" region="NgClass-1" header="src/app/app.component.html"></code-example>
## `NgStyle`
For this use case, Angular applies the classes on initialization and in case of changes.
The full example calls `setCurrentClasses()` initially with `ngOnInit()` and when the dependent properties change through a button click.
These steps are not necessary to implement `ngClass`.
For more information, see the <live-example></live-example> `app.component.ts` and `app.component.html`.
Use `NgStyle` to set many inline styles simultaneously and dynamically, based on the state of the component.
{@a ngstyle}
## Setting inline styles with `NgStyle`
### Without `NgStyle`
You can use `NgStyle` to set multiple inline styles simultaneously, based on the state of the component.
For context, consider setting a *single* style value with [style binding](guide/attribute-binding#style-binding), without `NgStyle`.
1. To use `NgStyle`, add a method to the component class.
<code-example path="built-in-directives/src/app/app.component.html" region="without-ng-style" header="src/app/app.component.html"></code-example>
In the following example, `setCurrentStyles()` sets the property `currentStyles` with an object that defines three styles, based on the state of three other component properties.
However, to set *many* inline styles at the same time, use the `NgStyle` directive.
<code-example path="built-in-directives/src/app/app.component.ts" region="setStyles" header="src/app/app.component.ts"></code-example>
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:
1. To set the element's styles, add an `ngStyle` property binding to `currentStyles`.
<code-example path="built-in-directives/src/app/app.component.ts" region="setStyles" header="src/app/app.component.ts"></code-example>
<code-example path="built-in-directives/src/app/app.component.html" region="NgStyle-2" header="src/app/app.component.html"></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/>
For this use case, Angular applies the styles upon initialization and in case of changes.
To do this, the full example calls `setCurrentStyles()` initially with `ngOnInit()` and when the dependent properties change through a button click.
However, these steps are not necessary to implement `ngStyle` on its own.
See the <live-example></live-example> `app.component.ts` and `app.component.html` for this optional implementation.
{@a ngModel}
## Displaying and updating properties with `ngModel`
## `[(ngModel)]`: Two-way binding
You can use the `NgModel` directive to display a data property and update that property when the user makes changes.
The `NgModel` directive allows you to display a data property and
update that property when the user makes changes. Here's an example:
1. Import `FormsModule` and add it to the NgModule's `imports` list.
<code-example path="built-in-directives/src/app/app.component.html" header="src/app/app.component.html (NgModel example)" region="NgModel-1"></code-example>
<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>
1. Add an `[(ngModel)]` binding on an HTML `<form>` element and set it equal to the property, here `name`.
### Import `FormsModule` to use `ngModel`
<code-example path="built-in-directives/src/app/app.component.html" header="src/app/app.component.html (NgModel example)" region="NgModel-1"></code-example>
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).
This `[(ngModel)]` syntax can only set a data-bound property.
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](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:
To customize your configuration, you can write the expanded form, which separates the property and event binding.
Use [property binding](guide/property-binding) to set the property and [event binding](guide/event-binding) to respond to changes.
The following example 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>
@@ -167,206 +117,146 @@ Here are all variations in action, including the uppercase version:
<img src='generated/images/guide/built-in-directives/ng-model-anim.gif' alt="NgModel variations">
</div>
<hr/>
### `NgModel` and value accessors
The `NgModel` directive works for an element supported by a [ControlValueAccessor](api/forms/ControlValueAccessor).
Angular provides *value accessors* for all of the basic HTML form elements.
For more information, see [Forms](guide/forms).
To apply `[(ngModel)]` to a non-form native element or a third-party custom component, you have to write a value accessor.
For more information, see the API documentation on [DefaultValueAccessor](api/forms/DefaultValueAccessor).
<div class="alert is-helpful">
When you write an Angular component, you don't need a value accessor or `NgModel` if you name the value and event properties according to Angular's [two-way binding syntax](guide/two-way-binding#how-two-way-binding-works).
</div>
{@a structural-directives}
## Built-in _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.
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:
This section introduces the most common built-in structural directives:
* [`NgIf`](guide/built-in-directives#ngIf)&mdash;conditionally creates or destroys subviews from the template.
* [`NgIf`](guide/built-in-directives#ngIf)&mdash;conditionally creates or disposes of 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">
For more information, see [Structural Directives](guide/structural-directives).
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.
* Why you [can only apply one structural directive](guide/structural-directives#one-per-element "one per host element") to an element.
</div>
<hr/>
{@a ngIf}
## Adding or removing an element with `NgIf`
## NgIf
You can add or remove an element by applying an `NgIf` directive to a host element.
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.
When `NgIf` is `false`, Angular removes an element and its descendants from the DOM.
Angular then disposes of their components, which frees up memory and resources.
To add or remove an element, bind `*ngIf` to a condition expression such as `isActive` in the following 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">
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 and disposes of the component and all of its sub-components.
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).
For more information on `NgIf` and `NgIfElse`, see the [NgIf API documentation](api/common/NgIf).
</div>
### Guarding against `null`
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.
By default, `NgIf` prevents display of an element bound to a null value.
### 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`.
To use `NgIf` to guard a `<div>`, add `*ngIf="yourProperty"` to the `<div>`.
In the following example, the `currentCustomer` name appears because there is a `currentCustomer`.
<code-example path="built-in-directives/src/app/app.component.html" region="NgIf-2" header="src/app/app.component.html"></code-example>
However, if the property is `null`, Angular does not display the `<div>`.
In this example, Angular does not display the `nullCustomer` because it is `null`.
<code-example path="built-in-directives/src/app/app.component.html" region="NgIf-2b" header="src/app/app.component.html"></code-example>
<hr/>
{@a ngFor}
## `NgFor`
## Listing items with `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.
You can use the `NgFor` directive to present a list of items.
The following example shows `NgFor` applied to a simple `<div>`.
1. Define a block of HTML that determines how Angular renders a single item.
1. To list your items, assign the short hand `let item of items` to `*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">
The string `"let item of items"` instructs Angular to do the following:
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).
* Store each item in the `items` array in the local `item` looping variable
* Make each item available to the templated HTML for each iteration
* Translate `"let item of items"` into an `<ng-template>` around the host element
* Repeat the `<ng-template>` for each `item` in the list
</div>
For more information see the [`<ng-template>` section](guide/structural-directives#the-ng-template) of [Structural directives](guide/structural-directives).
### Repeating a component view
You can also apply an `NgFor` to a component element, as in the following example.
To repeat a component element, apply `*ngFor` to the selector.
In the following example, the selector is `<app-item-detail>`.
<code-example path="built-in-directives/src/app/app.component.html" region="NgFor-2" header="src/app/app.component.html"></code-example>
{@a microsyntax}
You can reference a template input variable, such as `item`, in the following locations:
<div class="callout is-critical">
<header>*ngFor microsyntax</header>
* within the `ngFor` host element
* within the host element descendants to access the item's properties
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.
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).
For more information about template input variables, see [Structural Directives](guide/structural-directives#template-input-variable).
### `*ngFor` with `index`
### Getting the `index` of `*ngFor`
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.
You can get the `index` of `*ngFor` 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.
In the `*ngFor`, add a semicolon and `let i=index` to the short hand.
The following example gets 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">
The index property of the `NgFor` directive context returns the zero-based index of the item in each iteration.
`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).
{@a one-per-element}
</div>
## Repeating elements when a condition is true
{@a trackBy}
### *ngFor with `trackBy`
To repeat a block of HTML when a particular condition is true, put the `*ngIf` on a container element that wraps an `*ngFor` element.
One or both elements can be an `<ng-container>` so you don't have to introduce extra levels of HTML.
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.
Because structural directives add and remove nodes from the DOM, apply only one structural directive per element.
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`.
For more information about `NgFor` see the [NgForOf API reference](api/common/NgForOf).
<code-example path="built-in-directives/src/app/app.component.ts" region="trackByItems" header="src/app/app.component.ts"></code-example>
{@a ngfor-with-trackby}
### Tracking items with `*ngFor` `trackBy`
In the microsyntax expression, set `trackBy` to the `trackByItems()` method.
By tracking changes to an item list, you can reduce the number of calls your application makes to the server.
With the `*ngFor` `trackBy` property, Angular can change and re-render only those items that have changed, rather than reloading the entire list of items.
<code-example path="built-in-directives/src/app/app.component.html" region="trackBy" header="src/app/app.component.html"></code-example>
1. Add a method to the component that returns the value `NgFor` should track.
In this example, the value to track is the item's `id`.
If the browser has already rendered `id`, Angular keeps track of it and doesn't re-query the server for the same `id`.
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.
<code-example path="built-in-directives/src/app/app.component.ts" region="trackByItems" header="src/app/app.component.ts"></code-example>
1. In the short hand 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>
**Change ids** creates new items with new `item.id`s.
In the following illustration of the `trackBy` effect, **Reset items** creates new items with the same `item.id`s.
* With no `trackBy`, both buttons trigger complete DOM element replacement.
* With `trackBy`, only changing the `id` triggers element replacement.
@@ -375,55 +265,82 @@ Here is an illustration of the `trackBy` effect.
<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.
Built-in directives use only public APIs.
They do not have special access to any private APIs that other directives can't access.
</div>
<hr/>
{@a ngcontainer}
{@a ngSwitch}
## The `NgSwitch` directives
## Hosting a directive without a DOM element
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.
The Angular `<ng-container>` is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM.
You can use [`<ng-container>`](guide/structural-directives#ngcontainer) when there's no single element to host the directive.
Here's a conditional paragraph using `<ng-container>`.
<code-example path="structural-directives/src/app/app.component.html" header="src/app/app.component.html (ngif-ngcontainer)" region="ngif-ngcontainer"></code-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">
<img src='generated/images/guide/structural-directives/good-paragraph.png' alt="ngcontainer paragraph with proper style">
</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.
1. Import the `ngModel` directive from `FormsModule`.
**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.
1. Add `FormsModule` to the imports section of the relevant Angular module.
**Bind to `*ngSwitchCase` and `*ngSwitchDefault`**.
The `NgSwitchCase` and `NgSwitchDefault` directives are _structural_ directives
because they add or remove elements from the DOM.
1. To conditionally exclude an `<option>`, wrap the `<option>` in an `<ng-container>`.
* `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.
<code-example path="structural-directives/src/app/app.component.html" header="src/app/app.component.html (select-ngcontainer)" region="select-ngcontainer"></code-example>
* `NgSwitchDefault` adds its element to the DOM when there is no selected `NgSwitchCase`.
<div class="lightbox">
<img src='generated/images/guide/structural-directives/select-ngcontainer-anim.gif' alt="ngcontainer options work properly">
</div>
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.
{@a ngSwitch}
## Switching cases with `NgSwitch`
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.
Like the JavaScript `switch` statement, `NgSwitch` 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 a set of three directives:
* `NgSwitch`&mdash;an attribute directive that changes the behavior of its companion directives.
* `NgSwitchCase`&mdash;structural directive that 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`&mdash;structural directive that adds its element to the DOM when there is no selected `NgSwitchCase`.
1. On an element, such as a `<div>`, add `[ngSwitch]` bound 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.
1. Bind to `*ngSwitchCase` and `*ngSwitchDefault` on the elements for the cases.
<code-example path="built-in-directives/src/app/app.component.html" region="NgSwitch" header="src/app/app.component.html"></code-example>
1. In the parent component, define `currentItem` so you can use it in the `[ngSwitch]` expression.
<code-example path="built-in-directives/src/app/app.component.ts" region="item" header="src/app/app.component.ts"></code-example>
1. In each child component, add an `item` [input property](guide/inputs-outputs#input "Input property") which is bound to the `currentItem` of the parent component.
The following two snippets show the parent component and one of the child components.
The other child components are identical to `StoutItemComponent`.
<code-example path="built-in-directives/src/app/item-switch.component.ts" region="input" header="In each child component, here StoutItemComponent"></code-example>
<div class="lightbox">
<img src="generated/images/guide/built-in-directives/ngswitch.gif" alt="Animation of NgSwitch">
</div>
Switch directives also work with native HTML elements and web components.
For example, you could replace the `<app-best-item>` switch case with a `<div>` as follows.
<code-example path="built-in-directives/src/app/app.component.html" region="NgSwitch-div" header="src/app/app.component.html"></code-example>
<hr />
## What's next
For information on how to build your own custom directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives).
@@ -90,11 +90,8 @@ The revised second version does depend on `Logger` service.
</code-tabs>
In this example, the `getHeroes()` method uses the `Logger` service by logging a message when fetching heroes.
<hr />
## What's next
* [Dependency providers](guide/dependency-injection-providers)
-6
View File
@@ -156,10 +156,7 @@ Check out [angular-cli-ghpages](https://github.com/angular-buch/angular-cli-ghpa
</div>
<hr>
{@a server-configuration}
## Server configuration
This section covers changes you may have to make to the server or to files deployed on the server.
@@ -299,10 +296,7 @@ The server must be configured to accept the application's requests.
Read about how to enable CORS for specific servers at
<a href="https://enable-cors.org/server.html" title="Enabling CORS server">enable-cors.org</a>.
<hr>
{@a optimize}
## Production optimizations
The `--prod` _meta-flag_ engages the following build optimization features.
File diff suppressed because it is too large Load Diff
+1 -3
View File
@@ -52,8 +52,6 @@ When your custom element is placed on a page, the browser creates an instance of
<img src="generated/images/guide/elements/customElement1.png" alt="Custom element in browser" class="left">
</div>
<hr class="clear">
## Transforming components to custom elements
Angular provides the `createCustomElement()` function for converting an Angular component,
@@ -192,7 +190,7 @@ class MyDialog {
}
```
The most straight forward way to get accurate typings is to cast the return value of the relevant DOM methods to the correct type. For that, you can use the `NgElement` and `WithProperties` types (both exported from `@angular/elements`):
The most straightforward way to get accurate typings is to cast the return value of the relevant DOM methods to the correct type. For that, you can use the `NgElement` and `WithProperties` types (both exported from `@angular/elements`):
```ts
const aDialog = document.createElement('my-dialog') as NgElement & WithProperties<{content: string}>;
-2
View File
@@ -107,8 +107,6 @@ the tree shaker will throw it away. So, it's best to add only the components tha
as trim as possible.
<hr />
## More on Angular modules
You may also be interested in the following:
-2
View File
@@ -59,8 +59,6 @@ In the following example, Angular checks to see if `myClick` is an event on the
If the target event name, `myClick` fails to match an element event or an output property of `ClickDirective`, Angular reports an "unknown directive" error.
<hr />
## What's next
For more information on how event binding works, see [How event binding works](guide/event-binding-concepts).
-2
View File
@@ -106,8 +106,6 @@ Now, in addition to the title that renders by default, the `CustomerDashboardCom
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
</div>
<hr />
## More on NgModules
You may also be interested in the following:
-2
View File
@@ -115,8 +115,6 @@ Angular returns an error telling you to use `CommonModule` instead.
<img src="generated/images/guide/frequent-ngmodules/browser-module-error.gif" width=750 alt="BrowserModule error">
</div>
<hr />
## More on NgModules
@@ -1183,8 +1183,6 @@ its injector produces an instance of `Car` resolved by injector (C) with an `Eng
</div>
<hr />
## More on dependency injection
For more information on Angular dependency injection, see the [DI Providers](guide/dependency-injection-providers) and [DI in Action](guide/dependency-injection-in-action) guides.
+41 -4
View File
@@ -389,7 +389,7 @@ In the following example, the `HeroesService` makes an HTTP POST request when ad
The `HttpClient.post()` method is similar to `get()` in that it has a type parameter, which you can use to specify that you expect the server to return data of a given type. The method takes a resource URL and two additional parameters:
* *body* - The data to POST in the body of the request.
* *options*` - An object containing method options which, in this case, [specify required headers](#adding-headers).
* *options* - An object containing method options which, in this case, [specify required headers](#adding-headers).
The example catches errors as [described above](#error-details).
@@ -741,6 +741,10 @@ To do this, set the cloned request body to `null`.
newReq = req.clone({ body: null }); // clear the body
```
## Http interceptor use-cases
Below are a number of common uses for interceptors.
### Setting default headers
Apps often use an interceptor to set default headers on outgoing requests.
@@ -768,7 +772,7 @@ An interceptor that alters headers can be used for a number of different operati
* Caching behavior; for example, `If-Modified-Since`
* XSRF protection
### Using interceptors for logging
### Logging request and response pairs
Because interceptors can process the request and response _together_, they can perform tasks such as timing and logging an entire HTTP operation.
@@ -788,9 +792,42 @@ and reports the outcome to the `MessageService`.
Neither `tap` nor `finalize` touch the values of the observable stream returned to the caller.
{@a caching}
{@a custom-json-parser}
### Using interceptors for caching
### Custom JSON parsing
Interceptors can be used to replace the built-in JSON parsing with a custom implementation.
The `CustomJsonInterceptor` in the following example demonstrates how to achieve this.
If the intercepted request expects a `'json'` response, the `reponseType` is changed to `'text'`
to disable the built-in JSON parsing. Then the response is parsed via the injected `JsonParser`.
<code-example
path="http/src/app/http-interceptors/custom-json-interceptor.ts"
region="custom-json-interceptor"
header="app/http-interceptors/custom-json-interceptor.ts">
</code-example>
You can then implement your own custom `JsonParser`.
Here is a custom JsonParser that has a special date reviver.
<code-example
path="http/src/app/http-interceptors/custom-json-interceptor.ts"
region="custom-json-parser"
header="app/http-interceptors/custom-json-interceptor.ts">
</code-example>
You provide the `CustomParser` along with the `CustomJsonInterceptor`.
<code-example
path="http/src/app/http-interceptors/index.ts"
region="custom-json-interceptor"
header="app/http-interceptors/index.ts">
</code-example>
{@a caching}
### Caching requests
Interceptors can handle requests by themselves, without forwarding to `next.handle()`.
+9 -7
View File
@@ -762,7 +762,7 @@ The HTML `base` tag with the `href` attribute specifies the base URI, or URL, fo
"locales": {
"fr": {
"translation": "src/locale/messages.fr.xlf",
"baseHref": ""
"baseHref": ""
}
}
},
@@ -806,11 +806,11 @@ server {
server_name localhost;
root /www/data;
# Fallback to default language if no preference defined by browser
# Fallback to default language if no preference defined by browser
if ($accept_language ~ "^$") {
set $accept_language "fr";
}
# Redirect "/" to Angular app in browser's preferred language
rewrite ^/$ /$accept_language permanent;
@@ -834,17 +834,17 @@ The following is an example of an Apache configuration.
RewriteEngine on
RewriteBase /
RewriteRule ^../index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (..) $1/index.html [L]
RewriteCond %{HTTP:Accept-Language} ^de [NC]
RewriteRule ^$ /de/ [R]
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteRule ^$ /en/ [R]
RewriteCond %{HTTP:Accept-Language} !^en [NC]
RewriteCond %{HTTP:Accept-Language} !^de [NC]
RewriteRule ^$ /fr/ [R]
@@ -979,3 +979,5 @@ Both elements now use the same translation (`Bonjour`) because they were defined
<!-- ... -->
<p>Bonjour</p>
```
@reviewed 2020-04-10
+1 -1
View File
@@ -86,7 +86,7 @@ In the following snippet, the expression `recommended` and the expression `itemI
<code-example path="interpolation/src/app/app.component.html" region="component-context" header="src/app/app.component.html"></code-example>
An expression can also refer to properties of the _template's_ context such as a [template input variable](guide/built-in-directives#template-input-variables) or a [template reference variable](guide/template-reference-variables).
An expression can also refer to properties of the _template's_ context such as a [template input variable](guide/structural-directives#template-input-variables) or a [template reference variable](guide/template-reference-variables).
The following example uses a template input variable of `customer`.
+5 -5
View File
@@ -54,13 +54,13 @@ You can then click "Go to definition" or press F12 to go directly to the definit
## Angular Language Service in your editor
Angular Language Service is currently available as an extension for [Visual Studio Code](https://code.visualstudio.com/),
[WebStorm](https://www.jetbrains.com/webstorm), and [Sublime Text](https://www.sublimetext.com/).
[WebStorm](https://www.jetbrains.com/webstorm), [Sublime Text](https://www.sublimetext.com/) and [Eclipse IDE](https://www.eclipse.org/eclipseide/).
### Visual Studio Code
In [Visual Studio Code](https://code.visualstudio.com/), install the extension from the [Extensions: Marketplace](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template). You can open the marketplace from the editor using the Extensions icon on the left menu pane, or use VS Quick Open (⌘+P on Mac, CTRL+P on Windows) and type "? ext".
In [Visual Studio Code](https://code.visualstudio.com/), install the extension from the [Extensions: Marketplace](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template). You can open the marketplace from the editor using the Extensions icon on the left menu pane, or use VS Quick Open (⌘+P on Mac, CTRL+P on Windows) and type "? ext". In the marketplace, search for Angular Language Service extension, and click the **Install** button.
In the marketplace, search for Angular Language Service extension, and click the **Install** button.
The Visual Studio Code integration with the Angular language service is maintained and distributed by the Angular team.
### WebStorm
@@ -103,7 +103,9 @@ npm install --save-dev @angular/language-service
This allows the Angular Language Service to provide diagnostics and completions in `.ts` files.
### Eclipse IDE
Either directly install the "Eclipse IDE for Web and JavaScript developers" package which comes with the Angular Language Server included, or from other Eclipse IDE packages, use Help > Eclipse Marketplace to find and install [Eclipse Wild Web Developer](https://marketplace.eclipse.org/content/wild-web-developer-html-css-javascript-typescript-nodejs-angular-json-yaml-kubernetes-xml).
## How the Language Service works
@@ -123,8 +125,6 @@ The HTML AST can only tell the compiler that there is some text with the charact
That's when the template parser produces an expression AST, which resides within the template AST.
The Angular Language Services then looks at `data.---` within its context, asks the TypeScript Language Service what the members of `data` are, and returns the list of possibilities.
<hr>
## More information
* For more in-depth information on the implementation, see the
+7 -2
View File
@@ -17,7 +17,7 @@ For the final sample app with two lazy-loaded modules that this page describes,
This section introduces the basic procedure for configuring a lazy-loaded route.
For a step-by-step example, see the [step-by-step setup](#step-by-step) section on this page.
To lazy load Angular modules, use `loadchildren` (instead of `component`) in your `AppRoutingModule` `routes` configuration as follows.
To lazy load Angular modules, use `loadChildren` (instead of `component`) in your `AppRoutingModule` `routes` configuration as follows.
<code-example header="AppRoutingModule (excerpt)">
@@ -322,8 +322,13 @@ ngOnInit() {
For more information with a working example, see the [routing tutorial section on preloading](guide/router-tutorial-toh#preloading-background-loading-of-feature-areas).
## Troubleshooting lazy-loading modules
<hr>
A common error when lazy-loading modules is importing common modules in multiple places within an application. You can test for this condition by first generating the module using the Angular CLI and including the `--route route-name` parameter, where `route-name` is the name of your module. Next, generate the module without the `--route` parameter. If the Angular CLI generates an error when you use the `--route` parameter, but runs correctly without it, you may have imported the same module in multiple places.
Remember, many common Angular modules should be imported at the base of your application.
For more information on Angular Modules, see [NgModules](guide/ngmodules).
## More on NgModules and routing
+1 -1
View File
@@ -1,4 +1,4 @@
# Hooking into the component lifecycle
# Lifecycle hooks
A component instance has a lifecycle that starts when Angular instantiates the component class and renders the component view along with its child views.
The lifecycle continues with change detection, as Angular checks to see when data-bound properties change, and updates both the view and the component instance as needed.
@@ -152,7 +152,7 @@ abstract class LibHeaderToken {
@Component({
selector: 'lib-header',
providers: [
{provide: LibHeaderToken, useExisting: LibHeader}
{provide: LibHeaderToken, useExisting: LibHeaderComponent}
]
...,
})
-2
View File
@@ -220,8 +220,6 @@ The following table summarizes the `@NgModule` metadata properties.
</table>
<hr />
## More on NgModules
You may also be interested in the following:
-53
View File
@@ -12,17 +12,14 @@ Add [declarable](guide/bootstrapping#the-declarations-array) classes&mdash;compo
Declare these classes in _exactly one_ module of the application.
Declare them in a module if they belong to that particular module.
<hr/>
{@a q-declarable}
## What is a _declarable_?
Declarables are the class types&mdash;components, directives, and pipes&mdash;that
you can add to a module's `declarations` list.
They're the only classes that you can add to `declarations`.
<hr/>
## What classes should I _not_ add to `declarations`?
@@ -39,8 +36,6 @@ For example, don't declare `FORMS_DIRECTIVES` from `@angular/forms` because the
* Non-Angular classes and objects, such as
strings, numbers, functions, entity models, configurations, business logic, and helper classes.
<hr/>
## Why list the same component in multiple `NgModule` properties?
@@ -56,7 +51,6 @@ Membership in one list doesn't imply membership in another list.
* A component could be exported for inclusion in an external component's template
as well as dynamically loaded in a pop-up dialog.
<hr/>
## What does "Can't bind to 'x' since it isn't a known property of 'y'" mean?
@@ -70,7 +64,6 @@ The "x" class isn't visible to other modules until you add it to the `exports` l
</div>
<hr/>
## What should I import?
@@ -89,10 +82,8 @@ components, directives, and pipes.
Import [BrowserModule](guide/ngmodule-faq#q-browser-vs-common-module) only in the root `AppModule`.
<hr/>
{@a q-browser-vs-common-module}
## Should I import `BrowserModule` or `CommonModule`?
The root application module, `AppModule`, of almost every browser application
@@ -110,10 +101,8 @@ They need the common directives. They don't need to re-install the app-wide prov
Importing `CommonModule` also frees feature modules for use on _any_ target platform, not just browsers.
<hr/>
{@a q-reimport}
## What if I import the same module twice?
That's not a problem. When three modules all import Module 'A',
@@ -126,10 +115,8 @@ When Angular gets to the 'B' and 'A' in 'D', they're already cached and ready to
Angular doesn't like NgModules with circular references, so don't let Module 'A' import Module 'B', which imports Module 'A'.
<hr/>
{@a q-reexport}
## What should I export?
Export [declarable](guide/bootstrapping#the-declarations-array) classes that components in _other_ NgModules
@@ -143,7 +130,6 @@ it's declared in this NgModule or in an imported NgModule.
You _can_ re-export entire imported NgModules, which effectively re-export all of their exported classes.
An NgModule can even export a module that it doesn't import.
<hr/>
## What should I *not* export?
@@ -159,9 +145,6 @@ While there's no harm in exporting them, there's also no benefit.
For example, there's no point in re-exporting `HttpClientModule` because it doesn't export anything.
Its only purpose is to add http service providers to the application as a whole.
<hr/>
## Can I re-export classes and modules?
@@ -185,9 +168,6 @@ For example, there's no point in re-exporting `HttpClientModule` because it does
Its only purpose is to add http service providers to the application as a whole.
<hr/>
## What is the `forRoot()` method?
The `forRoot()` static method is a convention that makes it easy for developers to configure services and providers that are intended to be singletons. A good example of `forRoot()` is the `RouterModule.forRoot()` method.
@@ -211,9 +191,6 @@ configure services in root and feature modules respectively.
Follow this convention when you write similar modules with configurable service providers.
<hr/>
## Why is a service provided in a feature module visible everywhere?
Providers listed in the `@NgModule.providers` of a bootstrapped module have application scope.
@@ -238,10 +215,8 @@ not just the classes declared in the `HeroModule`.
To limit access to a service, consider lazy loading the NgModule that provides that service. See [How do I restrict service scope to a module?](guide/ngmodule-faq#service-scope) for more information.
<hr/>
{@a q-lazy-loaded-module-provider-visibility}
## Why is a service provided in a lazy-loaded module visible only to that module?
Unlike providers of the modules loaded at launch,
@@ -257,8 +232,6 @@ These providers are insulated from changes to application providers with the sam
When the router creates a component within the lazy-loaded context,
Angular prefers service instances created from these providers to the service instances of the application root injector.
<hr/>
## What if two modules provide the same service?
@@ -277,10 +250,8 @@ that also provides a service for token 'X', then NgModule A's service definition
The service provided by the root `AppModule` takes precedence over services provided by imported NgModules.
The `AppModule` always wins.
<hr/>
{@a service-scope}
## How do I restrict service scope to a module?
When a module is loaded at application launch,
@@ -329,11 +300,8 @@ Define child routes and let the router load module components into that outlet.
Though you can limit access to a service by providing it in a lazy loaded module or providing it in a component, providing services in a component can lead to multiple instances of those services. Thus, the lazy loading is preferable.
<hr/>
{@a q-root-component-or-module}
## Should I add application-wide providers to the root `AppModule` or the root `AppComponent`?
Define application-wide providers by specifying `providedIn: 'root'` on its `@Injectable()` decorator (in the case of services) or at `InjectionToken` construction (in the case where tokens are provided). Providers that are created this way automatically are made available to the entire application and don't need to be listed in any module.
@@ -366,10 +334,8 @@ But in routed applications, routing operates at the root level
where `AppComponent` services don't exist.
This means that lazy-loaded modules can't reach them.
<hr/>
{@a q-component-or-module}
## Should I add other providers to a module or a component?
Providers should be configured using `@Injectable` syntax. If possible, they should be provided in the application root (`providedIn: 'root'`). Services that are configured this way are lazily loaded if they are only used from a lazily loaded context.
@@ -389,11 +355,8 @@ The changes that editor makes in its service don't touch the instances elsewhere
[Always register _application-wide_ services with the root `AppModule`](guide/ngmodule-faq#q-root-component-or-module),
not the root `AppComponent`.
<hr/>
{@a q-why-bad}
## Why is it bad if a shared module provides a service to a lazy-loaded module?
### The eagerly loaded scenario
@@ -426,10 +389,8 @@ Then toggle between the "Contact" and "Heroes" links a few times.
The username goes bonkers as the Angular creates a new `UserService` instance each time.
I'd like to see the error so I can include it.-->
<hr/>
{@a q-why-child-injector}
## Why does lazy loading create a child injector?
Angular adds `@NgModule.providers` to the application root injector, unless the NgModule is lazy-loaded.
@@ -453,10 +414,8 @@ Angular must add the lazy-loaded module's providers to an injector somewhere.
It can't add them to the app root injector because that injector is closed to new providers.
So Angular creates a new child injector for the lazy-loaded module context.
<hr/>
{@a q-is-it-loaded}
## How can I tell if an NgModule or service was previously loaded?
Some NgModules and their services should be loaded only once by the root `AppModule`.
@@ -472,10 +431,8 @@ Here is a custom constructor for an NgModule called `GreetingModule`.
<code-example path="ngmodules/src/app/greeting/greeting.module.ts" region="ctor" header="src/app/greeting/greeting.module.ts (Constructor)"></code-example>
<hr/>
{@a q-entry-component-defined}
## What is an `entry component`?
An entry component is any component that Angular loads _imperatively_ by type.
@@ -498,7 +455,6 @@ loads the component dynamically into a `RouterOutlet`.
For more information, see [Entry Components](guide/entry-components).
<hr/>
## What's the difference between a _bootstrap_ component and an _entry component_?
@@ -514,7 +470,6 @@ although doing so is harmless.
For more information, see [Entry Components](guide/entry-components).
<hr/>
## When do I add components to _entryComponents_?
@@ -535,8 +490,6 @@ in the templates of other components.
For more information, see [Entry Components](guide/entry-components).
<hr/>
## Why does Angular need _entryComponents_?
@@ -559,7 +512,6 @@ and every component reachable from an entry component.
If a component isn't an _entry component_ or wasn't found in a template,
the compiler omits it.
<hr/>
## What kinds of modules should I have and how should I use them?
@@ -593,7 +545,6 @@ For more information, see [Feature Modules](guide/feature-modules) and
[Module Types](guide/module-types)
## What's the difference between NgModules and JavaScript Modules?
In an Angular app, NgModules and JavaScript modules work together.
@@ -610,10 +561,8 @@ You _export_ this NgModule's classes so they can be imported and used by compone
For more information, see [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
<hr/>
{@a q-template-reference}
## How does Angular find components, directives, and pipes in a template?<br>What is a <i><b>template reference</b></i>?
The [Angular compiler](guide/ngmodule-faq#q-angular-compiler) looks inside component templates
@@ -626,10 +575,8 @@ The compiler finds a pipe if the pipe's *name* appears within the pipe syntax of
Angular only matches selectors and pipe names for classes that are declared by this module
or exported by a module that this module imports.
<hr/>
{@a q-angular-compiler}
## What is the Angular compiler?
The Angular compiler converts the application code you write into highly performant JavaScript code.
-2
View File
@@ -57,8 +57,6 @@ The [Angular CLI](cli) generates the following basic `AppModule` when creating a
At the top are the import statements. The next section is where you configure the `@NgModule` by stating what components and directives belong to it (`declarations`) as well as which other modules it uses (`imports`). For more information on the structure of an `@NgModule`, be sure to read [Bootstrapping](guide/bootstrapping).
<hr />
## More on NgModules
You may also be interested in the following:
+2 -2
View File
@@ -1,7 +1,7 @@
# Using observables to pass values
Observables provide support for passing messages between parts of your application.
They are used frequently in Angular and are the recommended technique for event handling, asynchronous programming, and handling multiple values.
They are used frequently in Angular and are a technique for event handling, asynchronous programming, and handling multiple values.
The observer pattern is a software design pattern in which an object, called the *subject*, maintains a list of its dependents, called *observers*, and notifies them automatically of state changes.
This pattern is similar (but not identical) to the [publish/subscribe](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) design pattern.
@@ -11,7 +11,7 @@ The subscribed consumer then receives notifications until the function completes
An observable can deliver multiple values of any type&mdash;literals, messages, or events, depending on the context. The API for receiving values is the same whether the values are delivered synchronously or asynchronously. Because setup and teardown logic are both handled by the observable, your application code only needs to worry about subscribing to consume values, and when done, unsubscribing. Whether the stream was keystrokes, an HTTP response, or an interval timer, the interface for listening to values and stopping listening is the same.
Because of these advantages, observables are used extensively within Angular, and are recommended for app development as well.
Because of these advantages, observables are used extensively within Angular, and for app development as well.
## Basic usage and terms

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