Compare commits

..

882 Commits

Author SHA1 Message Date
30673090ec build(zone.js): add changelog gulptask for zone.js (#31852)
PR Close #31852
2019-07-26 11:30:08 -07:00
6033446d2d docs: release notes for the v8.2.0-rc.0 release 2019-07-26 10:25:18 -07:00
174770e6f3 docs: release notes for the v release 2019-07-25 20:32:22 -07:00
6ece7db37a build: TypeScript 3.5 upgrade (#31615)
https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#typescript-35

PR Close #31615
2019-07-25 17:05:23 -07:00
3a2b195a58 feat(ivy): translate type-check diagnostics to their original source (#30181)
PR Close #30181
2019-07-25 16:36:32 -07:00
489cef6ea2 feat(ivy): include value spans for attributes, variables and references (#30181)
Template AST nodes for (bound) attributes, variables and references will
now retain a reference to the source span of their value, which allows
for more accurate type check diagnostics.

PR Close #30181
2019-07-25 16:36:32 -07:00
985513351b feat(ivy): let ngtsc annotate type check blocks with source positions (#30181)
The type check blocks (TCB) that ngtsc generates for achieving type
checking of Angular templates needs to be annotated with positional
information in order to translate TypeScript's diagnostics for the TCB
code back to the location in the user's template. This commit augments
the TCB by attaching trailing comments with AST nodes, such that a node
can be traced back to its source location.

PR Close #30181
2019-07-25 16:36:32 -07:00
8f3dd85600 refactor(ivy): move ngtsc's TCB generation test util to separate file (#30181)
PR Close #30181
2019-07-25 16:36:32 -07:00
6b67cd5620 feat(ivy): index template references, variables, bound attributes/events (#31535)
Adds support for indexing template referenecs, variables, and property
and method calls inside bound attributes and bound events. This is
mostly an extension of the existing indexing infrastructure.

PR Close #31535
2019-07-25 13:09:10 -07:00
0cd4c019cf build: lock material unit tests job to specific commit (#31569)
No longer locks the Material unit tests job to a specific branch, but rather allows
locking to a specific commit from a given branch. This allows us to use the
"master" branch from the `components` repository.

PR Close #31569
2019-07-25 13:08:33 -07:00
7e46a6d99d test(ivy): update Material to recent commit from master branch (#31569)
Previously, the ivy-2019 branch of the Material (aka components) repo was
used, which contains some changes that were necessary to work with Ivy.
These changes are not longer necessary, as Material's master branch is
fully working with Ivy today. To be up-to-date with recent Material
development and its support for more recent dependencies, e.g. TypeScript,
it is desirable for us to be on a newer version of Material.

This commit moves the Material tests away from the ivy-2019 branch, to a
recent commit on master. We are not targeting the master branch itself,
as that would introduce a moving target into Angular's CI checks, which
is undesirable.

Lastly, the usage of gulp to run Material's tests is changed into using
Bazel, as Material itself is now also built with Bazel.

PR Close #31569
2019-07-25 13:08:33 -07:00
85d051f8d5 perf(ivy): introduce new benchmark for view create, destroy, traverse (#31797)
PR Close #31797
2019-07-25 13:07:38 -07:00
c7542a1d09 fix(zone.js): don't fire unhandledrejection if Zone handled error (#31718)
Close #31701

PR Close #31718
2019-07-24 16:10:59 -07:00
2172368eae build: update ivy file sizes (#31828)
PR Close #31828
2019-07-24 14:43:31 -07:00
2c402d5c99 fix(zone.js): handle MSPointer event correctly (#31722)
Close #31699

PR Close #31722
2019-07-24 14:42:49 -07:00
35a025fbca fix(zone.js): patch shadydom (#31717)
Close #31686

PR Close #31717
2019-07-24 14:42:14 -07:00
a86850e3f2 refactor(docs-infra): remove obsolete format attribute from code examples (#31674)
The `format` attribute is an artifact of an old version of the docs
tooling (before moving it into the angular/angular repo) and no longer
does anything. People are still copy-pasting it from existing examples.

This commit removes all occurrences of the `format` attribute on code
examples.

PR Close #31674
2019-07-24 14:38:54 -07:00
1bcd58cee8 refactor(docs-infra): remove linenums=false since it is now the default (#31674)
PR Close #31674
2019-07-24 14:38:54 -07:00
dd0be7feb7 fix(docs-infra): always default to no linenums in <aio-code> (#31674)
Previously, `linenums` defaulted to true if the content was more than 10
lines long and false otherwise.

Since in most cases linenums add unnecessary visual noise, this commit
changes `linenums` to always default to false (regardless of the size of
the content). It can be still be turned on by explicitly setting to true
or a number.

PR Close #31674
2019-07-24 14:38:54 -07:00
3d7303efc0 perf(ivy): avoid extra parameter in query instructions (#31667)
Currently we always generate the `read` parameter for the view and content query instructions, however since most of the time the `read` parameter won't be set, we'll end up generating `null` which adds 5 bytes for each query when minified. These changes make it so that the `read` parameter only gets generated if it has a value.

PR Close #31667
2019-07-24 14:37:51 -07:00
716af1059c fix(zone.js): move property patch to legacy (#31660)
Close #31659

PR Close #31660
2019-07-24 14:36:43 -07:00
a182714703 fix(zone.js): should remove on symbol property after removeAllListeners (#31644)
Close #31643

PR Close #31644
2019-07-24 14:35:37 -07:00
17b32b5fd4 fix(zone.js): hook should set correct current zone (#31642)
Close #31641

PR Close #31642
2019-07-24 14:34:58 -07:00
29e1c53a31 feat(upgrade): support $element in upgraded component template/templateUrl functions (#31637)
PR Close #31637
2019-07-24 14:34:20 -07:00
87ce4e997b fix(zone.js): zone-mix should import correct browser module (#31628)
Close #31626

PR Close #31628
2019-07-24 14:33:07 -07:00
2bb9a65351 fix(zone.js): don't wrap uncaught promise error. (#31443)
Close #27840

PR Close #31443
2019-07-24 14:31:17 -07:00
6b51ed29ef fix(zone.js): __load_patch and __symbol__ should be in zone_extern for closure compiler (#31350)
PR Close #31350
2019-07-24 13:30:01 -07:00
b696413a79 fix(ivy): support attribute selectors in dynamic component creation (#31812)
This commit fixes a bug where we assumed all dynamically created
components would have tag-name selectors, so we passed through the
"tag name" to the renderer as the first index of the selector. For
components with attribute selectors, the tag name would be "", so
the renderer would try to create an element with tag name "" and
throw. Now we default to a "div" element the same way that View
Engine did.

Closes #31785

PR Close #31812
2019-07-23 21:16:05 -07:00
b6aeaceb8e refactor(ivy): minor code cleanup (#31798)
PR Close #31798
2019-07-23 21:15:25 -07:00
5ae9b76a9b docs: add ngxs to library section (#31792)
PR Close #31792
2019-07-23 21:14:44 -07:00
82055b2fb8 feat(bazel): compile targets used for indexing by Kythe with Ivy (#31786)
This switches all Angular targets to be built with the same Angular compiler architecture (c.n. Ivy) that the Angular indexer uses. This eliminates issues with cross-references to transitive dependencies not being generated because of the way such dependencies are loaded by the legacy compiler arch.

PR Close #31786
2019-07-23 21:14:16 -07:00
44039a4b16 feat(ivy): pass information about used directive selectors on elements (#31782)
Extend indexing API interface to provide information about used
directives' selectors on template elements. This enables an indexer to
xref element attributes to the directives that match them.

The current way this matching is done is by mapping selectors to indexed
directives. However, this fails in cases where the directive is not
indexed by the indexer API, like for transitive dependencies. This
solution is much more general.

PR Close #31782
2019-07-23 21:13:49 -07:00
a445826dad fix(zone.js): handle new api of electron 4 (#31669)
Close #31668

PR Close #31669
2019-07-23 21:13:21 -07:00
7f7033bbd7 fix(zone.js): update dart zone link (#31646)
Close #31645

PR Close #31646
2019-07-23 21:12:52 -07:00
27997a16c0 docs: http api doc edit (#31613)
PR Close #31613
2019-07-23 21:12:25 -07:00
59c3700c8c feat(ivy): ngcc - implement UndecoratedParentMigration (#31544)
Implementing the "undecorated parent" migration described in
https://hackmd.io/sfb3Ju2MTmKHSUiX_dLWGg#Design

PR Close #31544
2019-07-23 21:11:40 -07:00
4d93d2406f feat(ivy): ngcc - support ngcc "migrations" (#31544)
This commit implements support for the ngcc migrations
as designed in https://hackmd.io/KhyrFV1VQHmeQsgfJq6AyQ

PR Close #31544
2019-07-23 21:11:40 -07:00
d39a2beae1 refactor(ivy): ngcc - move decorator analysis types into their own file (#31544)
PR Close #31544
2019-07-23 21:11:39 -07:00
c038992fae refactor(ivy): use ReflectionHost to find base classes (#31544)
When analyzing components, directives, etc we capture its base class.
Previously this assumed that the code is in TS format, which is not
always the case (e.g. ngcc).
Now this code is replaced with a call to
`ReflectionHost.getBaseClassExpression()`, which abstracts the work
of finding the base class.

PR Close #31544
2019-07-23 21:11:39 -07:00
8a470b9af9 feat(ivy): add getBaseClassIdentifier() to ReflectionHost (#31544)
This method will be useful for writing ngcc `Migrations` that
need to be able to find base classes.

PR Close #31544
2019-07-23 21:11:39 -07:00
399935c32b refactor(ivy): ngtsc - remove unnecessary type on helpers (#31544)
The `ClassDeclaration` already contains the `{name: ts.Identifier}`
type so there is no need to include it explicitly here.

PR Close #31544
2019-07-23 21:11:39 -07:00
97ab52c618 test(ivy): ensure that runInEachFileSystem cleans up after itself (#31544)
Previously the last file-system being tested was left as the current
file-system. Now it is reset to an `InvalidFileSystem` to ensure future
tests are not affected.

PR Close #31544
2019-07-23 21:11:39 -07:00
f69e4e6f77 refactor(core): move google3 migration rules into single directory (#30956)
Moves all google3 migration tslint rules into a single directory.
This makes it easier to wire up multiple migration rules in
google3 without having to update the rule directories each time
a new migration is available.

PR Close #30956
2019-07-23 15:52:40 -07:00
9f2ae5d6ff feat(ivy): introduce missing-injectable migration for google3 (#30956)
Introduces a new migration schematic for adding the "@Injectable()"
decorator to provider classes which are currently not migrated. Previously
in ViewEngine, classes which are declared as providers sometimes don't
require the "@Injectable()" decorator
(e.g. https://stackblitz.com/edit/angular-hpo7gw)

With Ivy, provider classes need to be explicitly decorated with
the "@Injectable()" decorator if they are declared as providers
of a given module. This commit introduces a migration schematic
which automatically adds the explicit decorator to places where
the decorator is currently missing.

The migration logic is designed in a CLI devkit and TSlint agnostic
way so that we can also have this migration run as part of a public
CLI migration w/ `ng update`. This will be handled as part of a follow-up to reiterate on console output etc.

Resolves FW-1371

PR Close #30956
2019-07-23 15:52:40 -07:00
9eefe25e2f fix(ivy): components created with wrong context when passing root node to component factory (#31661)
The way the `ComponentFactory.create` is set up at the moment is that if a `rootSelectorOrNode` is passed in, the root context will be injected instead of creating dedicated one for the component. As far as I can tell, there doesn't seem to be a reason to do this and nothing seems to break because of it. These changes switch to always create the root context.

PR Close #31661
2019-07-23 15:51:50 -07:00
221782a8a1 fix(ivy): DebugNode.query not picking up nodes inserted through Renderer2 (#31716)
In ViewEngine nodes that were inserted through `Renderer2` would also be picked up by `DebugNode.query` and `DebugNode.queryAll`. This worked because everything in ViewEngine went through `Renderer2` and `DebugRenderer2` in dev mode which was able to keep track of the child nodes as they're being inserted. This no longer works in Ivy, because we don't use `DebugRenderer2` and debug nodes work a little differently. These changes work around the issue by walking the DOM as the logical tree is being walked and looking for matches. Note that this is __not__ optimal, because we're walking similar trees multiple times. ViewEngine could do it more efficiently, because all the insertions go through Renderer2, however that's not the case in Ivy. This approach is being used because:
1. Matching the ViewEngine behavior would mean potentially introducing a depedency from `Renderer2` to Ivy which could bring Ivy code into ViewEngine.
2. We would have to make `Renderer3` "know" about debug nodes.
3. It allows us to capture nodes that were inserted directly via the DOM.

PR Close #31716
2019-07-23 15:51:00 -07:00
24ca582bc5 perf(compiler): avoid copying from prototype while cloning an object (#31638)
This commit updates the `_clone` function of the `_ApplySourceSpanTransformer` class, where the for-in loop was used, resulting in copying from prototype to own properties, thus consuming more memory. Prior to NodeJS 12 (V8 versions before 7.4) there was an optimization that was improving the situation and since that logic was removed in favor of other optimizations, the situation with memory consumption caused by the for-in loop got worse. This commit adds a check to make sure we copy only own properties over to cloned object.

Closes #31627.

PR Close #31638
2019-07-23 15:49:30 -07:00
b31a292955 test: update size-tracking golden for "core_all" bundling test (#31779)
Updates the size-tracking golden for the core_all test of the
@angular/core package.

PR Close #31779
2019-07-23 15:48:06 -07:00
1d7aa0a92c build: fix size-tracking tests not running (#31779)
Currently when someone wants to explicitly run the
size-tracking tool tests, the size-tracking tool never
runs because of recent changes for the rules_nodejs
update broke the `entry_point` attribute.

PR Close #31779
2019-07-23 15:48:06 -07:00
0aff4a6919 fix(ivy): incorrect ChangeDetectorRef injected into pipes used in component inputs (#31438)
When injecting a `ChangeDetectorRef` into a pipe, the expected result is that the ref will be tied to the component in which the pipe is being used. This works for most cases, however when a pipe is used inside a property binding of a component (see test case as an example), the current `TNode` is pointing to component's host so we end up injecting the inner component's view. These changes fix the issue by only looking up the component view of the `TNode` if the `TNode` is a parent.

This PR resolves FW-1419.

PR Close #31438
2019-07-23 15:46:23 -07:00
f50dede8f7 refactor(ivy): remove all old styling code prior to refactor (#31193)
In the previous patch () all the existing styling code was turned
off in favor of using the new refactored ivy styling code. This
patch is a follow up patch to that and removes all old, unused
styling code from the render3 directory.

PR Close #31193
2019-07-23 15:45:32 -07:00
0e68c7edf9 fix(ivy): support projecting containers created by query reads (#31790)
PR Close #31790
2019-07-22 23:07:01 -07:00
54ef63b0f4 fix(ivy): support ICU expressions inserted in ngTemplateOutlets inside ngFors (#31789)
This commit fixes a bug where ICU expressions inserted into ngTemplateOutlets
that are inside ngFor blocks would throw an error. We were assuming in view
insertion code that text nodes would always exist by the time a view\`s
creation block had executed. This is not true for text nodes created dynamically
by ICUs because this happens in the update block (in `i18nApply`).

This change ensures such dynamically created nodes are skipped when encountered
too early (as they will be attached later by i18n code anyway).

PR Close #31789
2019-07-22 23:06:42 -07:00
215ef3c5f4 fix(ivy): ensure NgClass does not overwrite other dir data (#31788)
We currently have a handwritten version of the Ivy directive def for NgClass so
we can switch between Ivy and View Engine behavior. This generated code needs to
be kept up-to-date with what the Ivy compiler generates.

PR 30742 recently changed `classMap` such that it now requires allocation of
host binding slots. This means that the `allocHostVars()` function must be
called in the NgClass directive def to match compiler output, but the
handwritten directive def was not updated. This caused a bug where NgClass
was inappropriately overwriting data for other directives because space was
not allocated for its values.

PR Close #31788
2019-07-22 16:56:27 -07:00
5a8eb924ba fix(bazel): increase memory limit of ngc under bazel from 2 to 4 GB (#31784)
This commit bumps the heap size of node/ngc under bazel to 4 GB instead of
the previous 2 GB. This brings it in sync with what the TS compiler uses
in g3, and fixes a bug where ngc would crash with OOM in worker mode.

PR Close #31784
2019-07-22 12:14:14 -07:00
c845a7b887 fix(docs-infra): fix logo to have branded red color (#31663)
Replace logo nav 2x logo file with one that has the correct branding red color in shield

PR Close #31663
2019-07-22 09:54:00 -07:00
8b26447c4f perf(ivy): avoid using array splice (#31656)
PR Close #31656
2019-07-22 09:53:18 -07:00
ce196105ce refactor(language-service): Remove unused class and method (#31597)
PR Close #31597
2019-07-22 09:52:42 -07:00
b9a94c6d02 fix(docs-infra): improve small screen experience for docs cards layout (#31576)
- Make docs cards expand to full width in smaller screen sizes.
- Reduce spacing around card container to match general spacing patterns seen in angular.io.
- Improve SCSS formatting.

PR Close #31576
2019-07-22 09:51:11 -07:00
ebc71f7caa fix(docs-infra): fix mobile toc styles (#31533)
Return mobile toc styles from bug in PR#31013
Give docs pages header a width limit so it does not run into the Github icon link

PR Close #31533
2019-07-22 09:50:21 -07:00
f65db20c6d feat(ivy): record absolute position of template expressions (#31391)
Currently, template expressions and statements have their location
recorded relative to the HTML element they are in, with no handle to
absolute location in a source file except for a line/column location.
However, the line/column location is also not entirely accurate, as it
points an entire semantic expression, and not necessarily the start of
an expression recorded by the expression parser.

To support record of the source code expressions originate from, add a
new `sourceSpan` field to `ASTWithSource` that records the absolute byte
offset of an expression within a source code.

Implement part 2 of [refactoring template parsing for
stability](https://hackmd.io/@X3ECPVy-RCuVfba-pnvIpw/BkDUxaW84/%2FMA1oxh6jRXqSmZBcLfYdyw?type=book).

PR Close #31391
2019-07-22 09:48:35 -07:00
8f084d7214 docs: clarify toh (#28571)
PR Close #28571
2019-07-22 09:46:27 -07:00
cb848b9410 refactor(ivy): reduce code duplication and code size (#31489)
PR Close #31489
2019-07-19 20:38:08 -07:00
d52ae7cbab perf(ivy): match query results on the TView level (#31489)
PR Close #31489
2019-07-19 20:38:08 -07:00
9c954ebc62 refactor(ivy): make styling instructions use the new styling algorithm (#30742)
This commit is the final patch of the ivy styling algorithm refactor.
This patch swaps functionality from the old styling mechanism to the
new refactored code by changing the instruction code the compiler
generates and by pointing the runtime instruction code to the new
styling algorithm.

PR Close #30742
2019-07-19 16:40:40 -07:00
f14693b9a4 refactor(ivy): correct circular dependency which causes g3 failures (#31665)
PR Close #31665
2019-07-19 15:06:46 -07:00
f10d6c66c9 ci: add info about test_saucelabs_bazel being limited to master builds (#31651)
Follow-up to #31636 (see
https://github.com/angular/angular/pull/31636#discussion_r305120859)

PR Close #31651
2019-07-19 09:57:32 -07:00
4495a46b99 refactor(ivy): clean up RNode retrieval; add better debug support for TNode (#31040)
PR Close #31040
2019-07-18 16:46:54 -07:00
ef75fb8ecd docs: rephrased explanation to fork before save (#31384)
PR Close #31384
2019-07-18 16:46:13 -07:00
7b6ee5e0d9 ci: move the test_saucelabs_bazel CircleCI job to default_workflow (#31636)
Previously, the `test_saucelabs_bazel` job was run as part of the
`saucelabs_test` workflow every hour (for every "publish branch";
currently 8.0.x, 8.1.x and master).

Since this job runs a subset of the tests in
`legacy-unit-tests-saucelabs` (see [BUILD.bazel][1]) and is just a
proof-of-concept for running tests on SauceLabs via bazel, there is
little point in running is on all branches. It is also wasteful to run
it every hour, even if there were no changes pushed into the branch
since the last run.

This commit makes the job part of `default_workflow`, but limits it to
only be run on master builds (not on other branches or PRs). Based on
its recent history, the job is relatively stable and (since it will only
be run on master builds) it is not expected to affect our dev workflow.

[1]: https://github.com/angular/angular/blob/ef44f51d5/BUILD.bazel#L66-L92

PR Close #31636
2019-07-18 16:45:27 -07:00
e822394075 refactor: group similar jobs in config.yml > default_workflow (#31636)
PR Close #31636
2019-07-18 16:45:27 -07:00
1b6e8411bd docs: fix typo in workspace config section (#31630)
This commit adds a missing word to the section on alternate build
configurations.

PR Close #31630
2019-07-18 14:27:17 -07:00
7151eae36d fix(elements): handle falsy initial value (#31604)
Fixes angular/angular#30834

PR Close #31604
2019-07-18 14:26:37 -07:00
376ad9c3cd refactor(ivy): remove deep imports into the compiler (#31376)
The compiler-cli should only reference code that can
be imported from the main entry-point of compiler.

PR Close #31376
2019-07-18 14:23:32 -07:00
4aecf9253b fix(ivy): support older CLI versions that do not pass a list of changed files (#31322)
Versions of CLI prior to angular/angular-cli@0e339ee did not expose the host.getModifiedResourceFiles() method.

This meant that null was being passed through to the IncrementalState.reconcile() method
to indicate that there were either no changes or the host didn't support that method.

This commit fixes a bug where we were checking for undefined rather than null when
deciding whether any resource files had changed, causing a null reference error to be thrown.

This bug was not caught by the unit testing because the tests set up the changed files
via a slightly different process, not having access to the CompilerHost, and these test
were making the erroneous assumption that undefined indicated that there were no
changed files.

PR Close #31322
2019-07-18 14:22:07 -07:00
60f58bf051 refactor: ensure zone.js can be built with typescript strict flag (#30993)
As part of FW-1265, the `zone.js` package is made compatible
with the TypeScript `--strict` flag. Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:26 -07:00
10a1e1974b fix(platform-browser): debug element query predicates not compatible with strictFunctionTypes (#30993)
Currently developers can use the `By` class to construct common
`DebugElement` query predicates. e.g. `By.directive(MyDirective)`.

The `directive()` and `all()` predicates are currently returning
a predicate that works for `DebugElement` nodes. This return type
is too strict since the predicate is not specific to `DebugElement`
instances and can also apply to `DebugNode` instances.

Meaning that developers are currently able to use the `directive()`
predicate when using `queryAllNodes()`. This is a common practice
but will break when the project is compiled with TypeScript's
`--strictFunctionTypes` flag as the `DebugElement` predicate type
is not assignable to predicates for `DebugNode`. In order to make
these predicates usable with `--strictFuntionTypes` enabled, we
adjust the predicate type to reflect what is actually needed for
evaluation of the predicate.

PR Close #30993
2019-07-18 14:21:26 -07:00
647d7bdd88 refactor: fix typescript strict flag failures in all tests (#30993)
Fixes all TypeScript failures caused by enabling the `--strict`
flag for test source files. We also want to enable the strict
options for tests as the strictness enforcement improves the
overall codehealth, unveiled common issues and additionally it
allows us to enable `strict` in the `tsconfig.json` that is picked
up by IDE's.

PR Close #30993
2019-07-18 14:21:26 -07:00
69a612d402 refactor(service-worker): ensure compatibility with typescript strict flag (#30993)
As part of FW-1265, the `@angular/service-worker` package is made compatible
with the TypeScript `--strict` flag. Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:26 -07:00
221cbd0b47 refactor(forms): ensure compatibility with typescript strict flag (#30993)
As part of FW-1265, the `@angular/forms` package is made compatible
with the TypeScript `--strict` flag. Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:26 -07:00
ce9d0de840 refactor(router): compatibility with typescript strict flag (#30993)
As part of FW-1265, the `@angular/router` package is made compatible
with the TypeScript `--strict` flag. Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:26 -07:00
18f0c2f1d4 refactor(platform-browser): compatibility with typescript strict flag (#30993)
As part of FW-1265, the `@angular/platform-browser` package is made compatible
with the TypeScript `--strict` flag. Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:26 -07:00
5bd12c5aa1 refactor(upgrade): ensure compatibility with typescript strict flag (#30993)
As part of FW-1265, the `@angular/upgrade` package is made compatible
with the TypeScript `--strict` flag. Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:26 -07:00
0139b11227 refactor(common): ensure compatibility with typescript strict flag (#30993)
As part of FW-1265, the `@angular/common` package is made compatible
with the TypeScript `--strict` flag. Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:26 -07:00
e061e638cb fix(ivy): semantic module check incorrectly handles nested arrays (#30993)
In View Engine, developers can pass bootstrap and entry components
as nested arrays. e.g.

```ts
export const MyOtherEntryComponents = [A, B, C]

@NgModule({
  entryComponents: [MyComp, MyOtherEntryComponents]
})
```

Currently using nested arrays for these properties causes
unexpected errors to be reported in Ivy since the semantic
NgModule checks aren't properly recursing into the nested
entry/bootstrap components. This issue has been unveiled by
enabling the strict function parameter checks.

PR Close #30993
2019-07-18 14:21:26 -07:00
dda781ecce fix(ivy): incorrect type definition for ɵɵdefineComponent (#30993)
Currently the `ɵɵdefineComponent` method has incorrect type
definitions the `directives` and `pipes` metadata property.

The incorrect types allow developers to pass in already instantiated
`DirectiveDef` or `ComponentDef` objects. This can cause unexpected
failures because the definition internally only expects `Type` objects
and now incorrectly tries to read the `ngDirectiveDef` or `ngComponentDef`
of existing definitions.

This issue has been unveiled by enabling the strict function parameter
types flag, where the directive definitions are determined from each array
element in the `directives` or `pipes` property (which can throw).

PR Close #30993
2019-07-18 14:21:26 -07:00
a27c5dd740 refactor: fix remaining typescript strict flag failures (#30993)
Fixes the remaining TypeScript --strict flag failures for source
files which are not part of any specific release package.

PR Close #30993
2019-07-18 14:21:25 -07:00
012b535147 refactor(compiler): ensure compatibility with typescript strict flag (#30993)
As part of FW-1265, the `@angular/compiler` package is made compatible
with the TypeScript `--strict` flag. This already unveiled a few bugs,
so the strictness flag seems to help with increasing the overall code health.

Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:25 -07:00
2200884e55 refactor(core): ensure compatibility with typescript strict flag (#30993)
As part of FW-1265, the `@angular/core` package is made compatible
with the TypeScript `--strict` flag. This already unveiled a few bugs,
so the strictness flag seems to help with increasing the overall code health.

Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:25 -07:00
78e7fdd98d fix(core): allow Z variations of CSS transforms in sanitizer (#29264)
PR Close #29264
2019-07-18 14:10:38 -07:00
1e9eeafa9e docs: clean up router api doc (#31476)
PR Close #31476
2019-07-18 10:33:17 -07:00
9ef9bfe76b docs: change to explicit label type in getting-started form (#31213)
PR Close #31213
2019-07-18 10:32:04 -07:00
a5f9a86520 feat(ivy): support undefined and null in static interpreter (#31150)
Previously, the usage of `null` and `undefined` keywords in code that is
statically interpreted by ngtsc resulted in a `DynamicValue`, as they were
not recognized as special entities. This commit adds support to interpret
these keywords.

PR Close #31150
2019-07-18 10:30:51 -07:00
dd664f694c fix(ivy): ngcc - render namespaced imported decorators correctly (#31426)
The support for decorators that were imported via a namespace,
e.g. `import * as core from `@angular/core` was implemented
piecemeal. This meant that it was easy to miss situations where
a decorator identifier needed to be handled as a namepsaced
import rather than a direct import.

One such issue was that UMD processing of decorators was not
correct: the namespace was being omitted from references to
decorators.

Now the types have been modified to make it clear that a
`Decorator.identifier` could hold a namespaced identifier,
and the corresponding code that uses these types has been
fixed.

Fixes #31394

PR Close #31426
2019-07-18 10:17:50 -07:00
b66d82e308 build(docs-infra): upgrade jasmine-/karma-related dependencies (#31527)
Note: `jasmine-ts` is intentionally held back at 0.2.1, because of a bug
in 0.3.0: svi3c/jasmine-ts#33

PR Close #31527
2019-07-18 10:17:13 -07:00
518bca0841 build(docs-infra): remove unused jasmine-marbles dependency (#31527)
PR Close #31527
2019-07-18 10:17:13 -07:00
d7ca263cc4 test(docs-infra): run tests in random order (and make them pass) (#31527)
This commit updates the necessary config files to run the angular.io and
docs tooling unit tests in random order (and fixes the tests that were
failing due to their dependence on the previous ordered execution).

Besides being a good idea anyway, running tests in random order is the
new [default behavior in jasmine@3.0.0][1], so this commit is in
preparation of upgrading jasmine to the latest version.

[1]: https://github.com/jasmine/jasmine/blob/v3.0.0/release_notes/3.0.md#breaking-changes

PR Close #31527
2019-07-18 10:17:13 -07:00
e8ae3c5f2e release: cut the v8.2.0-next.2 release 2019-07-17 14:16:22 -07:00
85a7fe8702 docs: release notes for the v8.1.2 release 2019-07-17 13:59:51 -07:00
32c07ceca0 docs(core): fix typo in event-binding code example (#31611)
`item` is an object, so it is stringified to `[object Object]`. Using
its `name` property produces a more meaningful message.

PR Close #31611
2019-07-17 13:26:48 -04:00
d3744457ab docs: fix typo in CLI overview (#31608)
PR Close #31608
2019-07-17 13:26:31 -04:00
fc61284dbe docs: remove prerequisite section in NgModules docs (#31169)
PR Close #31169
2019-07-17 13:26:00 -04:00
12fd06916b fix(ivy): don't match directives against attribute bindings (#31541)
Fixes Ivy matching directives against attribute bindings (e.g. `[attr.some-directive]="foo"`). Works by excluding attribute bindings from the attributes array during compilation. This has the added benefit of generating less code.

**Note:** My initial approach to implementing this was to have a different marker for attribute bindings so that they can be ignored when matching directives, however as I was implementing it I realized that the attributes in that array were only used for directive matching (as far as I could tell). I decided to drop the attribute bindings completely, because it results in less generated code.

PR Close #31541
2019-07-16 23:59:13 -04:00
9e83822679 fix(ivy): a couple of typos in error messages (#31571)
Fixes a couple of typos that were noticed after the initial PR (#31543) got merged in.

PR Close #31571
2019-07-16 23:58:52 -04:00
54794f9b31 docs: clarify docs for runtime validation change (#31596)
PR Close #31596
2019-07-16 23:58:11 -04:00
897bd18fbc docs: clarify meaning of injectable decorator (#31573)
PR Close #31573
2019-07-16 23:57:50 -04:00
1ac07757dd refactor(ivy): cleanup implementation of container related instructions (#31142)
PR Close #31142
2019-07-16 14:27:52 -04:00
0110de2662 fix(language-service): Eagarly initialize data members (#31577)
Data members in TypeScriptServiceHost of Map type should be eagerly
initialized to address issue/24571. This eliminates the need to
constantly check for truthiness and makes code much more readable.

More PRs to follow to address issue/24571.

PR Close #31577
2019-07-16 14:26:16 -04:00
f166b6d8f6 docs: add note about current working directory for cli projects (#31507)
Fixes #29878

PR Close #31507
2019-07-16 13:02:56 -04:00
09576e9683 fix(ivy): use goog.LOCALE for Closure Compiler to define default LOCALE_ID (#31519)
Prior to this commit, default value for LOCALE_ID was not setup for Closure Compiler. In Closure Compiler, we can use `goog.LOCALE` as a default value, which will be replaced at build time with current locale.

PR Close #31519
2019-07-16 13:02:10 -04:00
40d785f0a0 perf(ivy): avoid generating extra parameters for host property bindings (#31550)
Currently we reuse the same instruction both for regular property bindings and property bindings on the `host`. The only difference between the two is that when it's on the host we shouldn't support inputs. We have an optional parameter called `nativeOnly` which is used to differentiate the two, however since `nativeOnly` is preceeded by another optional parameter (`sanitizer`), we have to generate two extra parameters for each host property bindings every time (e.g. `property('someProp', 'someValue', null, true)`).

These changes add a new instruction called `hostProperty` which avoids the need for the two parameters by removing `nativeOnly` which is always set and it allows us to omit `sanitizer` when it isn't being used.

These changes also remove the `nativeOnly` parameter from the `updateSyntheticHostBinding` instruction, because it's only generated for host elements which means that we can assume that its value will always be `true`.

PR Close #31550
2019-07-16 13:01:42 -04:00
46c03bd866 build(docs-infra): never show linenums for triple-backticked code blocks (#31493)
PR Close #31493
2019-07-16 13:00:55 -04:00
d5d8657d30 docs(core): Remove repeated example (#31555)
PR Close #31555
2019-07-16 13:00:26 -04:00
8853f13f82 build(docs-infra): upgrade cli command docs sources to a8fe15cb6 (#31585)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](8fe3aa3c2...a8fe15cb6):

**Modified**
- help/analytics.json

##

PR Close #31585
2019-07-16 13:00:05 -04:00
3166cffd28 fix(compiler-cli): Return original sourceFile instead of redirected sourceFile from getSourceFile (#26036)
Closes #22524

PR Close #26036
2019-07-15 17:33:40 -04:00
40705f3366 docs: include svg files in stackblitz and download examples (#31559)
Fixes #31537

PR Close #31559
2019-07-15 16:48:23 -04:00
19bc11139d docs: fix typo in static query migration guide (#31572)
PR Close #31572
2019-07-15 16:46:33 -04:00
31ea254a07 fix(ivy): align NgModule assertions with ViewEngine (#31543)
Aligns Ivy's `NgModule` assertion messages with the ones from `ViewEngine` and adds a few that hadn't been implemented.

PR Close #31543
2019-07-15 13:58:19 -04:00
caf8c0a437 docs: add FAQ about updating libraries to static query migration guide (#31447)
PR Close #31447
2019-07-15 13:57:43 -04:00
d6c80871f5 docs: remove and update resource list (#31469)
PR Close #31469
2019-07-15 12:23:33 -04:00
edc51f76c4 style(docs-infra): fix indentation in rx-library example (#31553)
PR Close #31553
2019-07-15 12:13:19 -04:00
c529be9f24 docs: add microsyntax details (#31517)
PR Close #31517
2019-07-12 17:55:57 -04:00
b65e11e3c3 build(docs-infra): display CLI positional option enum values (#31529)
Previously we on;ly displayed enum values for named options.
Now positional options get equal justice.

Fixes https://github.com/angular/angular-cli/issues/15040

PR Close #31529
2019-07-12 17:55:28 -04:00
3a09d01c63 fix(docs-infra): fix API list search color and styles (#31272)
- Add more spacing to inputs.
- Correct placeholder colors in inputs.
- Add aria label to input for accessibility.
- Clean up layout styles and mobile view.

Fixes #31265

PR Close #31272
2019-07-12 17:55:02 -04:00
604d9063c5 feat(ivy): index template elements for selectors, attributes, directives (#31240)
Add support for indexing elements in the indexing module.
Opening and self-closing HTML tags have their selector indexed, as well
as the attributes on the element and the directives applied to an
element.

PR Close #31240
2019-07-12 17:54:08 -04:00
c4c340a7c4 fix(zone.js): fix zone for Jasmine 3.3. (#31497)
If zonejs is sent undefined callbacks it proceeds to attempt to call them, then fails, catches it own fail, rewrites the stack to hide the mistake, and reports a TypeError with a callstack unrelated to inputs.

Throw early if the callback is undefined (as can happen if JS or any-ified TS calls zone invokeTask).

Check for undefined onCommplete callback to zonejs jasmine wrapper.

PR Close #31497
2019-07-12 13:46:14 -04:00
32aa18be78 build: add tsconfig-test to dependency for tsconfig in core/test/strict_types (#31471)
PR Close #31471
2019-07-12 11:38:16 -04:00
80fa84c177 build: export tsconfig-test.json file in //tools/BUILD (#31471)
PR Close #31471
2019-07-12 11:38:16 -04:00
e44ba0ffa9 build: use standalone strategy for TypescriptCompile and AngularTemplateCompile (#31471)
PR Close #31471
2019-07-12 11:38:16 -04:00
19a28e599b build: Add incompatible_list_based_execution_strategy_selection flags back in (#31471)
PR Close #31471
2019-07-12 11:38:16 -04:00
14ad7562c6 build: use remote actions for TS/NG compilations on CircleCI (#31471)
PR Close #31471
2019-07-12 11:38:16 -04:00
0c61a35ea3 fix(bazel): pass custom bazel compiler host rather than rewriting one (#31496)
Switch back to passing a custom bazel host instead of rewriting one that
is passed to `compile` now that the Angular indexer is stable.

Revert "feat(bazel): allow passing and rewriting an old bazel host"

This reverts commit 0a4c1c8f803a65f5c156af90e67f7d7d68ebc7f8.

PR Close #31496
2019-07-12 11:37:58 -04:00
fac20bd8d1 fix(ivy): ngcc - resolve main property paths correctly (#31509)
There are two places in the ngcc processing where it needs to load the
content of a file given by a general path:

* when determining the format of an entry-point.
 To do this ngcc uses the value of the relevant property in package.json.
 But in the case of `main` it must parse the contents of the entry-point
 file to decide whether the format is UMD or CommonJS.

* when parsing the source files for dependencies to determine the order in
which compilation must occur. The relative imports in each file are parsed
and followed recursively, looking for external imports.

Previously, we naively assumed that the path would match the file name exactly.
But actually we must consider the standard module resolution conventions.
E.g. the extension (.js) may be missing, or the path may refer to a directory
containing an index.js file.

This commit fixes both places.

This commit now requires the `DependencyHost` instances to check
the existence of more files than before (at worst all the different possible
post-fixes). This should not create a significant performance reduction for
ngcc. Since the results of the checks will be cached, and similar work is
done inside the TS compiler, so what we lose in doing it here, is saved later
in the processing. The main performance loss would be where there are lots
of files that need to be parsed for dependencies that do not end up being
processed by TS. But compared to the main ngcc processing this dependency
parsing is a small proportion of the work done and so should not impact
much on the overall performance of ngcc.

// FW-1444

PR Close #31509
2019-07-12 11:37:35 -04:00
63e458dd3a fix(ivy): handle ICUs with placeholders in case other nested ICUs are present (#31516)
Prior to this fix, the logic to set the right placeholder format for ICUs was a bit incorrect: if there was a nested ICU in one of the root ICU cases, that led to a problem where placeholders in subsequent branches used the wrong ({$placeholder}) format instead of {PLACEHOLDER} one. This commit updates the logic to make sure we properly transform all placeholders even if nested ICUs are present.

PR Close #31516
2019-07-12 11:37:16 -04:00
d545bbeee4 fix(ivy): handle ModuleWithProviders in R3TestBed correctly (#31415)
Prior to this commit, it was impossible to override providers defined via ModuleWithProviders using TestBed.overrideProvider API. The problem was caused by the fact that we were not taking into account these providers while calculating accumulated set of provider overrides. This commit updates the logic to extract providers from ModuleWithProviders and calculate the final set of overrides taking them into account.

PR Close #31415
2019-07-11 18:27:13 -04:00
4bb283cbb2 build: remove redundant @types/source-map dependency (#31468)
In version 0.6.1 that we are using, `source-map` ships with
[its own typings][1], so there is no need to use `@types/source-map`.
The types were even removed from `DefinitelyTyped` in
DefinitelyTyped/DefinitelyTyped@1792bfaa2.

[1]: https://github.com/mozilla/source-map/blob/0.6.1/package.json#L72

PR Close #31468
2019-07-11 17:18:12 -04:00
a08b4b3519 build(compiler-cli): remove unused dependency (shelljs) (#31468)
Since, 7186f9c01 `compiler-cli` is no longer depending on `shelljs` for
production code. (We still use it in tests and infrastructure/tooling.)

Incidentally, this should also help with #29460.

PR Close #31468
2019-07-11 17:18:12 -04:00
0e86551a63 ci(docs-infra): run a11y audits on certain pages on CI (#31414)
PR Close #31414
2019-07-11 17:13:47 -04:00
5c738417db feat(docs-infra): support checking the scores on all audit categories (#31414)
Previously, the `test-pwa-score` script would only check the `pwa`
score. (All categories were reported, but a min. score could only be
specified for `pwa`.)

This commit adds support for checking the scores on all available
categories (such as a11y, performance, seo, etc.).

PR Close #31414
2019-07-11 17:13:47 -04:00
3d9ba19ff8 refactor(docs-infra): slightly improve log output of test-pwa-score (#31414)
This commit slightly improves the log outout of the `test-pwa-score`
script (e.g. by showing the total duration, indenting messages to group
them together, etc.). It, also, includes various minor refactorings.

These changes are in preparation of augmenting the script to support
checking the scores on all available categories (such as a11y,
performance, seo, etc.) in a subsequent commit.

PR Close #31414
2019-07-11 17:13:47 -04:00
8b7a4d7550 refactor(docs-infra): switch test-pwa-score to use headless Chrome (#31414)
This is slightly faster (15%-20%). Currently, this doesn't make a
noticeable difference, since the total time is 10s-15s, but it might
add up, if we decide to run audits on multiple pages.

PR Close #31414
2019-07-11 17:13:47 -04:00
76b755e292 build(docs-infra): upgrade lighthouse to 5.1.0 (#31414)
PR Close #31414
2019-07-11 17:13:47 -04:00
565a58e261 refactor(ivy): limit usage of global state (#31490)
PR Close #31490
2019-07-11 17:13:20 -04:00
7014b67e51 refactor(ivy): don't pass LView where only TView is needed (#31490)
PR Close #31490
2019-07-11 17:13:20 -04:00
6f50aad5c4 build(docs-infra): upgrade cli command docs sources to 8fe3aa3c2 (#31485)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](9edecc522...8fe3aa3c2):

**Modified**
- help/add.json
- help/build.json
- help/update.json

##

PR Close #31485
2019-07-11 17:12:59 -04:00
ef44f51d58 refactor(ivy): remove instruction usage from other instructions (#31456)
Removes direct calls from one instruction into another, moves the shared logic into a separate function and removes the state getters from the shared function.

This PR resolves FW-1340.

PR Close #31456
2019-07-11 15:10:20 -04:00
9204de96a1 fix: use the correct WTF array to iterate over (#31208)
PR Close #31208
2019-07-11 15:08:54 -04:00
7c62a8f9ca docs: remove heroes reference in i18n example (#31515)
Closes #31514

PR Close #31515
2019-07-11 15:07:55 -04:00
a55c6df07b feat(docs-infra): add prominent archive mode banner styling (#31245)
Fixes #25968

PR Close #31245
2019-07-11 13:00:11 -04:00
d33204956f fix(docs-infra): fix code hover style in TOC (#31173)
Fixes #31170

PR Close #31173
2019-07-11 12:57:32 -04:00
66d6b53fb1 fix(docs-infra): fix get started button rendering (#31470)
Fixes #31454

PR Close #31470
2019-07-11 12:56:29 -04:00
e85fa5d4ff fix(docs-infra): fix layout of file-not-found page (#31390)
The `.sidenav-content` element, [which is also][1] the `#file-not-found`
element, [already has][2] the necessary padding. Especially the top
padding is important to ensure the element is not obscured by the
top-bar.

[1]: https://github.com/angular/angular/blob/1d3e22766/aio/src/app/app.component.html#L51
[2]: https://github.com/angular/angular/blob/1d3e22766/aio/src/styles/1-layouts/_content-layout.scss#L10

PR Close #31390
2019-07-11 12:15:34 -04:00
0c00c94f34 test(docs-infra): clean up global listeners after ScrollService tests (#31390)
The `ScrollService` sets up some global `window` listeners.

Previously, these listeners were never unregistered. This was not a
problem in the real app, because the `ScrollService` instance exists for
the lifetime of a user session. In tests, however, where the `window`
instance is among all tests, the listeners would survive the
`ScrollService` tests. This, in addition to the fact that we used a mock
`ViewportScroller` which did not return the expected type from
`getScrollPosition()`, caused errors to be thrown in unrelated tests
(i.e. whenever a scroll event was emitted on `window`). See [here][1]
for an example failure.

This commit fixes it by adding an `ngOnDestroy()` method that
unregisters the listeners and ensuring it is called after each
`ScrollService` test.

[1]: https://circleci.com/gh/angular/angular/381649

PR Close #31390
2019-07-11 12:15:34 -04:00
9b29ca95a2 fix(docs-infra): show (and style correctly) the 'No results found' message (#31390)
PR Close #31390
2019-07-11 12:15:34 -04:00
479d926b4b fix(docs-infra): improve search-results layout on smaller screens (#31390)
Previously, the `search-results` layout was switch from horizontal to
vertical at 480px. Yes, since some search queries can yield more than 5
`.search-area`s, even 600px are too narrow to accomodate a horizontal
layout.

This commit changes the breakpoint at which the layout switches to
vertical from 480px to 600px.

PR Close #31390
2019-07-11 12:15:34 -04:00
b9195289a5 fix(docs-infra): remove redundant search-results styles (#31390)
Previously, `.search-area` had a default style of `display: flex`, but
it was overriden to `display: block` in media queries for
`max-width: 480px` and `min-width: 600px`. As a result, it only had
`display: flex` between 481px and 599px.

Since no flex layout features are necessary inside `.search-area`, this
commit changes the style to always be `display: block` (i.e. the default
for `div` elements).

PR Close #31390
2019-07-11 12:15:34 -04:00
75b6b0e1ba refactor(docs-infra): clean up aio-search-results styles (#31390)
PR Close #31390
2019-07-11 12:15:34 -04:00
2d4f507b61 style(docs-infra): make indentation in _search-results.scss consistent with other .scss files (#31390)
PR Close #31390
2019-07-11 12:15:34 -04:00
3246a8553c build(docs-infra): engine "yarn" versions can now be up to 1.16.0 (#31482)
PR Close #31482
2019-07-11 12:14:33 -04:00
db557221bc revert: fix(ivy): ngcc - resolve main property paths correctly (#31509)
This reverts commit 103a5b42ec.
2019-07-11 11:51:13 -04:00
7ea6073534 docs: add angular-in-depth to community curations (#31212)
PR Close #31212
2019-07-11 11:43:34 -04:00
1cba5d42d1 fix(ivy): handle rooted resource paths correctly (#31511)
Previously, resource paths beginning with '/' (aka "rooted" paths, which
are not actually absolute filesystem paths, but are relative to the
TypeScript project root directory) were not handled correctly. The leading
'/' was stripped and the path was resolved as if it was relative, but with
no containing file for context. This led to resources in different rootDirs
not being found.

Instead, such rooted paths are now resolved without TypeScript's help, by
checking each root directory. A test is added to this effect.

PR Close #31511
2019-07-11 11:42:33 -04:00
103a5b42ec fix(ivy): ngcc - resolve main property paths correctly (#31509)
When determining if a `main` path points to a UMD or CommonJS
format, the contents of the file need to be loaded and parsed.

Previously, it was assumed that the path referred to the exact filename,
but did not account for normal module resolution semantics, where the
path may be missing an extension or refer to a directory containing an
`index.js` file.

// FW-1444

PR Close #31509
2019-07-11 11:41:11 -04:00
fe1793844d docs: fix typo in Template Syntax headers (#31474)
Fixes #31467

PR Close #31474
2019-07-11 11:40:40 -04:00
68940f05d8 docs: add Renderer to deprecations doc (#31419)
PR Close #31419
2019-07-11 01:36:31 -04:00
53212db3ed refactor(ivy): remove duplicate forward ref logic (#31423)
Removes a file that duplicates the logic for resolving `forwardRef`, but isn't being used anywhere.

This PR resovles FW-1362.

PR Close #31423
2019-07-10 18:32:39 -04:00
dee16a4355 fix(ivy): update ICU placeholders format to match Closure compiler (#31459)
Since `goog.getMsg` does not process ICUs (post-processing is required via goog.i18n.MessageFormat, https://google.github.io/closure-library/api/goog.i18n.MessageFormat.html) and placeholder format used for ICUs and regular messages inside `goog.getMsg` are different, the current implementation (that assumed the same placeholder format) needs to be updated. This commit updates placeholder format used inside ICUs from `{$placeholder}` to `{PLACEHOLDER}` to better align with Closure. ICU placeholders (that were left as is prior to this commit) are now replaced with actual values in post-processing step (inside `i18nPostprocess`).

PR Close #31459
2019-07-10 18:31:33 -04:00
6da1446afc fix(ivy): handle &ngsp; in i18n translations correctly (#31479)
Prior to this commit, the `` unicode symbol that represents `&ngsp` in translations was not handled correctly, i.e. was not replaced with a whitespace, thus appearing on a screen. This commit adds post-processing and replaces the mentioned symbol with a whitespace.

PR Close #31479
2019-07-10 18:29:32 -04:00
76e3b57a12 test(ivy): verify no translations are generated for bound attributes (#31481)
This commit adds a test that verifies no translations are generated for bound attributes and also checks (as a part of the `verify` function) that VE and Ivy handle this case the same way.

PR Close #31481
2019-07-10 18:28:58 -04:00
524180c271 release: cut the v8.2.0-next.1 release 2019-07-10 10:32:57 -07:00
c69e552a83 docs: release notes for the v8.1.1 release 2019-07-10 10:27:06 -07:00
2844f2779f ci: install Bazel MSYS2 packages on Windows (#31486)
PR Close #31486
2019-07-10 10:23:39 -07:00
2b44be984e fix(ivy): i18n should not alloc expando slots when there is no new var (#31451)
`i18nStart` was calling `allocExpando` even if there was 0 new variable created.
This created a new expando instruction with the value 0 which was later interpreted as the start of a new expando block instead of just skipping 0 instructions.

FW-1417 #resolve

PR Close #31451
2019-07-09 14:31:10 -07:00
989ebcbb62 fix(ivy): inconsistent value returned by DebugNode.context (#31442)
Fixes Ivy's return value for `DebugNode.context` not being consistent for the case where there is both a structural directive and a component on a node. In `ViewEngine` the instance of the component would be returned, whereas in Ivy the context of the directive is returned.

Also adds a couple of extra test cases for how `DebugNode.context` deals with directives.

This PR resolves FW-1343.

PR Close #31442
2019-07-09 13:50:51 -07:00
23e0d65471 perf(ivy): add self-closing elementContainer instruction (#31444)
Adds a new `elementContainer` instruction that can be used to avoid two instruction (`elementContainerStart` and `elementContainerEnd`) for `ng-container` that has text-only content. This is particularly useful when we have `ng-container` inside i18n sections.

This PR resolves FW-1105.

PR Close #31444
2019-07-09 13:50:28 -07:00
e92fb68f3c build: remove usage of deprecated experimental_ui bazel flag (#31457)
PR Close #31457
2019-07-09 13:50:01 -07:00
7724f7446a refactor(bazel): remove unused lockfile (#31458)
The corresponding `package.json` file was removed in 15c2467db; it looks
like the lockfile was left behind by accident.

PR Close #31458
2019-07-09 13:49:43 -07:00
207f9b6017 fix(ivy): ngcc - handle pathMappings to files rather then directories (#30525)
Paths can be mapped directly to files, which was not being taken
into account when computing `basePaths` for the `EntryPointFinder`s.

Now if a `pathMapping` pattern does not exist or is a file, then we try
the containing folder instead.

Fixes #31424

PR Close #30525
2019-07-09 09:40:46 -07:00
a581773887 perf(ivy): ngcc - only find dependencies when targeting a single entry-point (#30525)
Previously, ngcc had to walk the entire `node_modules` tree looking for
entry-points, even if it only needed to process a single target entry-point
and its dependencies.

This added up to a few seconds to each execution of ngcc, which is noticeable
when being run via the CLI integration.

Now, if an entry-point target is provided, only that target and its entry-points
are considered rather than the whole folder tree.

PR Close #30525
2019-07-09 09:40:46 -07:00
7f2330a968 perf(ivy): ngcc - add a cache to the FileSystem (#30525)
When profiling ngcc it is notable that a large amount of time
is spent dealing with an exception that is thrown (and handled
internally by fs) when checking the existence of a file.

We check file existence a lot in both finding entry-points
and when TS is compiling code. This commit adds a simple
cached `FileSystem`, which wraps a real `FileSystem` delegate.
This will reduce the number of calls through to `fs.exists()` and
`fs.readFile()` on the delegate.

Initial benchmarks indicate that the cache is miss to hit ratio
for `exists()` is about 2:1, which means that we save about 1/3
of the calls to `fs.existsSync()`.

Note that this implements a "non-expiring" cache, so it is not suitable
for a long lived `FileSystem`, where files may be modified externally.
The cache will be updated if a file is changed or moved via
calls to `FileSystem` methods but it will not be aware of changes
to the files system from outside the `FileSystem` service.

For ngcc we must create a new `FileSystem` service
for each run of `mainNgcc` and ensure that all file operations
(including TS compilation) use the `FileSystem` service.
This ensures that it is very unlikely that a file will change
externally during `mainNgcc` processing.

PR Close #30525
2019-07-09 09:40:46 -07:00
aaaeb924ac fix(ivy): ngcc - remove unwanted logging message (#30525)
This message gets called if a format has already been
compiled and we only want the first. So the message itself
is wrong but it is also not very useful anyway.

PR Close #30525
2019-07-09 09:40:46 -07:00
98a68ad3e7 fix(ivy): handle namespaced imports correctly (#31367)
The ngcc tool adds namespaced imports to files when compiling. The ngtsc
tooling was not processing types correctly when they were imported via
such namespaces. For example:

```
export declare class SomeModule {
    static withOptions(...): ModuleWithProviders<ɵngcc1.BaseModule>;
```

In this case the `BaseModule` was being incorrectly attributed to coming
from the current module rather than the imported module, represented by
`ɵngcc1`.

Fixes #31342

PR Close #31367
2019-07-09 09:40:30 -07:00
36d3062a42 ci(docs-infra): increase waiting time to reduce flakiness on CI (#31408)
Example failure: https://circleci.com/gh/angular/angular/381763

PR Close #31408
2019-07-09 09:35:54 -07:00
83b19bf1a2 fix(ivy): ngcc - compute potential d.ts files from .js files (#31411)
If a package delcares a class internally on an NgModule, ngcc
needs to be able to add a public export to this class's type.

Previously, if the typing file for the declared is not imported
from the typings entry-point file, then ngcc cannot find it.
Now we try to guess the .d.ts files from the equivalent .js
files.

PR Close #31411
2019-07-09 09:35:26 -07:00
e6f1b04cd5 fix(zone.js): restore definition of global (#31453)
This partially reverts some changes from 71b9371180 (diff-dd469785fca8680a5b33b1e81c5cfd91R1420)
These broke the g3sync of zone.js because we use the output of the TypeScript compiler directly, rather than rely on the rollup commonjs plugin to define the global symbol

PR Close #31453
2019-07-09 09:34:50 -07:00
6aaca21c27 fix(compiler): give ASTWithSource its own visit method (#31347)
ASTWithSource contains more information that AST and should have its own
visit method, if desired. This implements that.

PR Close #31347
2019-07-08 10:29:07 -07:00
50c4ec6687 fix(ivy): ngcc - resolve path-mapped modules correctly (#31450)
Non-wild-card path-mappings were not being matched correctly.

Further path-mapped secondary entry-points that
were imported from the associated primary entry-point were not
being martched correctly.

Fixes #31274

PR Close #31450
2019-07-08 10:28:13 -07:00
9a2d1fab84 docs: add correct default cli ngModule (#31166)
PR Close #31166
2019-07-08 10:25:57 -07:00
8052de07e2 docs: update polyfill support doc (#31262)
PR Close #31262
2019-07-08 10:22:01 -07:00
40aaa42f44 docs: api doc cleanup (#31377)
PR Close #31377
2019-07-08 09:51:59 -07:00
35f8bfce8b fix(core): export provider interfaces that are part of the public API types (#31377)
Some of the provider interfaces that the [Provider][1] and
[StaticProvider][2] types comprise were not exported from
[@angular/core][3]. As a result, the docs for these symbols did not
appear on angular.io (even though both `Provider` and `StaticProvider`
are part of the public API. (See, also,
https://github.com/angular/angular/pull/31377#discussion_r299254408.)

This commit fixes it by exporting all necessary provider interfaces.

[1]: https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L365-L366
[2]: https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L283-L284
[3]: https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts#L23

PR Close #31377
2019-07-08 09:51:59 -07:00
4b05ebc804 docs: fix formatting in workspace config and add helpful info for universal (#31399)
PR Close #31399
2019-07-08 09:37:08 -07:00
e30f494a39 refactor(ivy): remove interpolation instructions (#31395)
Makes the `interpolateX` instructions internal-only and removes their use of global state.

This PR resolves FW-1387.

PR Close #31395
2019-07-08 09:34:13 -07:00
1d3e22766a fix(bazel): revert location of xi18n outputs to bazel-genfiles (#31410)
This is needed in g3 where the translation system is sensitive to the full path of the output.
For Bazel users, we don't want this because it would force them to
disable a Bazel option that prevents using the deprecated ctx.new_file
API

PR Close #31410
2019-07-03 14:15:12 -07:00
c0955975f4 feat(core): add automatic migration from Renderer to Renderer2 (#30936)
Adds a schematic and tslint rule that automatically migrate the consumer from `Renderer` to `Renderer2`. Supports:
* Renaming imports.
* Renaming property and method argument types.
* Casting to `Renderer`.
* Mapping all of the methods from the `Renderer` to `Renderer2`.

Note that some of the `Renderer` methods don't map cleanly between renderers. In these cases the migration adds a helper function at the bottom of the file which ensures that we generate valid code with the same return value as before. E.g. here's what the migration for `createText` looks like.

Before:
```
class SomeComponent {
  createAndAddText() {
    const node = this._renderer.createText(this._element.nativeElement, 'hello');
    node.textContent += ' world';
  }
}
```

After:
```
class SomeComponent {
  createAndAddText() {
    const node = __rendererCreateTextHelper(this._renderer, this._element.nativeElement, 'hello');
    node.textContent += ' world';
  }
}

function __rendererCreateTextHelper(renderer: any, parent: any, value: any) {
  const node = renderer.createText(value);
  if (parent) {
    renderer.appendChild(parent, node);
  }
  return node;
}
```

This PR resolves FW-1344.

PR Close #30936
2019-07-03 09:03:37 -07:00
9515f171b4 ci: update gcp_token (#31405)
PR Close #31405
2019-07-03 08:54:02 -07:00
1efaac5cb0 release: cut the v8.2.0-next.0 release 2019-07-02 14:14:53 -07:00
d27181fcdd docs: release notes for the v8.1.0 release 2019-07-02 14:10:45 -07:00
9e34670b25 docs: add accessibility guide (#30851)
PR Close #30851
2019-07-02 11:39:24 -07:00
5039faff8d docs: add doc for complex config values (#31010)
PR Close #31010
2019-07-02 11:34:58 -07:00
44c6534f3c docs: fix typo in Template Syntax (#31298)
Fixes #31282

PR Close #31298
2019-07-02 11:30:50 -07:00
09970d52e8 docs(core): in template syntax guide, make SVG example more clear (#31356)
add e2e test for SVG template example
fix template syntax example app
- linting errors
- runtime exceptions
- template type errors
- deprecated type casting
- deprecated currency pipe example

Relates to #30559

PR Close #31356
2019-07-02 11:30:15 -07:00
95a9d67599 test(zone.js): fix typos (#31358)
Relates to #31144

PR Close #31358
2019-07-02 11:29:33 -07:00
fde016bc38 docs: fix typo in deployment page (#31369)
PR Close #31369
2019-07-02 11:29:11 -07:00
11a208f55c feat(bazel): allow passing and rewriting an old bazel host (#31381)
Updates the decision made in #31341; this is for the Angular indexer
inside Google. The indexer currently passes (and ngc-wrapped#compile
accepts) a bazel host to use, but because many methods are overwritten
specially for Angular compilation a better approach is to pass an old
bazel compiler host and siphon methods needed off of it before creating
a new host. This enables that.

PR Close #31381
2019-07-02 11:28:41 -07:00
1db3ac457c build(docs-infra): update dgeni-packages dependency (#31368)
The new version 0.27.5 now has the `post-process-html` package, so we
don't need it in angular/angular any more.

PR Close #31368
2019-07-02 11:28:23 -07:00
02491a6ce8 refactor(ivy): move classMap interpolation logic internally (#31211)
Adds the new `classMapInterpolate1` through `classMapInterpolate8` instructions which handle interpolations inside the `class` attribute and moves the interpolation logic internally. This allows us to remove the `interpolationX` instructions in a follow-up PR.

These changes also add an error if an interpolation is encountered inside a `style` tag (e.g. `style="width: {{value}}"`). Up until now this would actually generate valid instructions, because `styleMap` goes through the same code path as `classMap` which does support interpolation. At runtime, however, `styleMap` would set invalid styles that look like `<div style="0:w;1:i;2:d;3:t;4:h;5::;7:1;">`. In `ViewEngine` interpolations inside `style` weren't supported either, however there we'd output invalid styles like `<div style="unsafe">`, even if the content was trusted.

PR Close #31211
2019-07-02 11:07:14 -07:00
dca713c087 test(ivy): verify equality of ngBaseDef metadata between compiler and core (#31210)
There's no build time dependency from @angular/core to @angular/compiler,
so core can't directly refer to compiler types. To overcome this limitation,
there's a facade layer defined in the compiler and duplicated in core,
such that during runtime all types will correctly align.

There's a testcase in the compiler that verifies that all such facade types
are compatible across core and compiler, such that the core types can't get
misaligned with the actual definitions in the compiler. This suite of
tests were missing the `R3BaseMetadataFacade` facade type, so it was possible
for this type to get out of sync.

PR Close #31210
2019-07-02 11:06:46 -07:00
eb6281f5b4 fix(ivy): include type parameter for ngBaseDef declaration (#31210)
When a class uses Angular decorators such as `@Input`, `@Output` and
friends without an Angular class decorator, they are compiled into a
static `ngBaseDef` field on the class, with the TypeScript declaration
of the class being altered to declare the `ngBaseDef` field to be of type
`ɵɵBaseDef`. This type however requires a generic type parameter that
corresponds with the type of the class, however the compiler did not
provide this type parameter. As a result, compiling a program where such
invalid `ngBaseDef` declarations are present will result in compilation
errors.

This commit fixes the problem by providing the generic type parameter.

Fixes #31160

PR Close #31210
2019-07-02 11:06:46 -07:00
a4a423a083 build: fix build failures with worker mode cache and @types/events (#31325)
Errors observed only in tests on CircleCI — was not reproducible locally.

```
ERROR: /home/circleci/ng/packages/http/test/BUILD.bazel:3:1: Compiling TypeScript (devmode) //packages/http/test:test_lib failed (Exit 1): tsc_wrapped failed: error executing command
  (cd /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular && \
  exec env - \
    BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \
    PATH=/bin:/usr/bin:/usr/local/bin \
  bazel-out/host/bin/external/npm/@bazel/typescript/bin/tsc_wrapped @@bazel-out/k8-fastbuild/bin/packages/http/test/test_lib_es5_tsconfig.json)
Execution platform: //tools:rbe_ubuntu1604-angular
Compilation failed Error: missing input digest for /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/external/npm/node_modules/@types/events/index.d.ts.

ERROR: /home/circleci/ng/packages/benchpress/test/BUILD.bazel:3:1: Compiling TypeScript (devmode) //packages/benchpress/test:test_lib failed (Exit 1): tsc_wrapped failed: error executing command
  (cd /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular && \
  exec env - \
    BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \
    PATH=/bin:/usr/bin:/usr/local/bin \
  bazel-out/host/bin/external/npm/@bazel/typescript/bin/tsc_wrapped @@bazel-out/k8-fastbuild/bin/packages/benchpress/test/test_lib_es5_tsconfig.json)
Execution platform: //tools:rbe_ubuntu1604-angular
Compilation failed Error: missing input digest for /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/external/npm/node_modules/@types/events/index.d.ts

ERROR: C:/codefresh/volume/angular/packages/compiler/test/css_parser/BUILD.bazel:3:1: Compiling TypeScript (devmode) //packages/compiler/test/css_parser:css_parser_lib failed (Exit 1):
tsc_wrapped.exe failed: error executing command
  cd C:/users/containeradministrator/_bazel_containeradministrator/zquin2l6/execroot/angular
  SET PATH=C:\msys64\usr\bin;C:\msys64\bin;C:\Windows;C:\Windows\System32;C:\Windows\System32\WindowsPowerShell\v1.0
    SET RUNFILES_MANIFEST_ONLY=1
  bazel-out/host/bin/external/npm/@bazel/typescript/bin/tsc_wrapped.exe @@bazel-out/x64_windows-fastbuild/bin/packages/compiler/test/css_parser/css_parser_lib_es5_tsconfig.json
Execution platform: @bazel_tools//platforms:host_platform
Compilation failed Error: missing input digest for C:/users/containeradministrator/_bazel_containeradministrator/zquin2l6/execroot/angular/external/npm/node_modules/@types/events/index.
d.ts
```

PR Close #31325
2019-07-01 14:16:43 -07:00
ba5b3af077 build(bazel): update //packages/bazel/test/ngc-wrapped:ngc_test test (#31325)
after update to rules_nodejs 0.32.1, @types are no longer automatically discovered by ngc-wrapped (which uses parts of ts_library) so this test needed updating so that the types files it generates is added as an explicit dep

PR Close #31325
2019-07-01 14:16:42 -07:00
64e7af4e43 build(bazel): add build --incompatible_list_based_execution_strategy_selection=false flag (#31325)
This option is changed to true in Bazel 0.27 and exposes a possible
regression in Bazel 0.27.0.
Error observed is in npm_package target `//packages/common/locales:package`:
```
ERROR: /home/circleci/ng/packages/common/locales/BUILD.bazel:13:1: Assembling
npm package packages/common/locales/package failed: No usable spawn strategy found
for spawn with mnemonic SkylarkAction.  Your --spawn_strategyor --strategy flags
are probably too strict. Visit https://github.com/bazelbuild/bazel/issues/7480 for
migration advises
```
Suspect is https://github.com/bazelbuild/rules_nodejs/blob/master/internal/npm_package/npm_package.bzl#L75-L82:
```
 execution_requirements = {
    # Never schedule this action remotely because it's not computationally expensive.
    # It just copies files into a directory; it's not worth copying inputs and outputs to a remote worker.
    # Also don't run it in a sandbox, because it resolves an absolute path to the bazel-out directory
    # allowing the .pack and .publish runnables to work with no symlink_prefix
    # See https://github.com/bazelbuild/rules_nodejs/issues/187
    "local": "1",
},
```

PR Close #31325
2019-07-01 14:16:42 -07:00
d2d84c4460 build(bazel): remove deprecated rules_nodejs NodeModuleInfo provider (#31325)
PR Close #31325
2019-07-01 14:16:42 -07:00
29f5582af5 build: disable must-use-promises check in ts_library tsetse for tests as... (#31325)
...tsetse now falsely asserting on  some lines in a few tests such as packages/core/schematics/test/injectable_pipe_migration_spec.ts.

```
    await runMigration();
    expect(tree.readContent('/index.ts'))
```

it asserts that "await is required on promise" on the 2nd line when there is no promise there

PR Close #31325
2019-07-01 14:16:42 -07:00
63bdfca580 build(bazel): cleanup entry_point target (#31325)
PR Close #31325
2019-07-01 14:16:42 -07:00
361109d80f build: update to rules_nodejs 0.32.2 (#31325)
Brings in ts_library fixes required to get angular/angular building after 0.32.0:
typescript: exclude typescript lib declarations in node_module_library transitive_declarations
typescript: remove override of @bazel/tsetse (+1 squashed commit)

@npm//node_modules/foobar:foobar.js labels changed to @npm//:node_modules/foobar/foobar.js with fix for bazelbuild/rules_nodejs#802

also updates to rules_rass commit compatible with rules_nodejs 0.32.0

PR Close #31325
2019-07-01 14:16:42 -07:00
b7a099d27e build(bazel): update to bazel 0.27.0 and fix compat in @angular/bazel package (#31325)
ctx.actions.declare_file now used in @angular/bazel ng_module rule as ctx.new_file is now deprecated. Fixes error:

```
        File "ng_module.bzl", line 272, in _expected_outs
                ctx.new_file(ctx.genfiles_dir, (ctx.label.name ..."))
Use ctx.actions.declare_file instead of ctx.new_file.
Use --incompatible_new_actions_api=false to temporarily disable this check.
```

This can be worked around with incompatible_new_actions_api flag but may as well fix it proper so downstream doesn't require this flag due to this code.

Also, depset() is no longer iterable by default without a flag. This required fixing in a few spots in @angular/bazel.

fix: foo

PR Close #31325
2019-07-01 14:16:42 -07:00
f83dfd6f5a fix(core): handle undefined meta in injectArgs (#31333)
In the recent versions of the CLI we introduced a ctor downleveler tranformer for VE JIT builds based on the one found in tsickle, to fix the TDZ issue of `forwardRef`.

However this caused a regression as the injector is not handling that a position `paramType` can be undefined. Which is bubbled down to c6b29f4c6d/packages/core/src/di/injector_compatibility.ts (L162) and will crash c6b29f4c6d/packages/core/src/di/injector_compatibility.ts (L174-L186)

Fixes https://github.com/angular/angular-cli/issues/14888

PR Close #31333
2019-07-01 10:11:08 -07:00
dd36f3ac99 feat(ivy): ngcc - handle top-level helper calls in CommonJS (#31335)
Some formats of CommonJS put the decorator helper calls
outside the class IIFE as statements on the top level of the
source file.

This commit adds support to the `CommonJSReflectionHost`
for this format.

PR Close #31335
2019-07-01 10:09:41 -07:00
0d6fd134d4 docs(core): update link to external i18n doc (#31353)
PR Close #31353
2019-07-01 10:08:53 -07:00
bbb27b5517 docs: change order of Angular Elements article (#30521)
PR Close #30268

PR Close #30521
2019-06-28 12:22:45 -07:00
7ca611cd12 fix(ivy): properly handle re-projection with an empty set of nodes to re-project (#31306)
PR Close #31306
2019-06-28 12:21:37 -07:00
c12b6fa028 fix(ivy): attach host element for views created via TestBed.createComponent (#31318)
Prior to this commit, host element of a view created via TestBed.createComponent was not attached to the component's host, making it problematic to use TestBed.createComponent API in component factories, which might be used for testing purposes only. This behavior is observed in google3 app tests and was supported by VE, so this commit aligns Ivy and VE.

PR Close #31318
2019-06-28 12:20:53 -07:00
a29dc961a2 feat(bazel): allow passing a custom bazel compiler host to ngc compile (#31341)
Enable users to pass a custom Bazel CompilerHost to use for an Angular
compilation. This supports users who must override the TypeScript
compiler host.

PR Close #31341
2019-06-28 12:18:20 -07:00
0de5d79bf6 Revert "fix(router): adjust UrlTree redirect to replace URL if in eager update (#31168)" (#31344)
This reverts commit 15e397816f.

Reason: it broke an internal g3 app.

PR Close #31344
2019-06-28 11:40:27 -07:00
f57e77eeb4 build(docs-infra): upgrade cli command docs sources to 9edecc522 (#31331)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](e819d9b77...9edecc522):

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

##

PR Close #31331
2019-06-28 09:27:13 -07:00
2b5d52fbdc docs: add tests for lazy loading angularjs example (#30622)
PR Close #30622
2019-06-28 09:26:49 -07:00
81332150aa perf(ivy): chain host binding instructions (#31296)
Adds chaining to the `property`, `attribute` and `updateSyntheticHostBinding` instructions when they're used in a host binding.

This PR resolves FW-1404.

PR Close #31296
2019-06-28 09:26:20 -07:00
c6b29f4c6d docs: added svg example (#30559)
Fixes #30441

PR Close #30559
2019-06-27 15:56:26 -07:00
261dc04d8e fix(docs-infra): detect docregions on more file types (pug, svg, yml) (#30559)
PR Close #30559
2019-06-27 15:56:26 -07:00
15e397816f fix(router): adjust UrlTree redirect to replace URL if in eager update (#31168)
Without this change when using UrlTree redirects in `urlUpdateStrategy="eager"`, the URL would get updated to the target location, then redirected. This resulted in having an additional entry in the `history` and thus the `back` button would be broken (going back would land on the URL causing a new redirect).

Additionally, there was a bug where the redirect, even without `urlUpdateStrategy="eager"`, could create a history with too many entries. This was due to kicking off a new navigation within the navigation cancelling logic. With this PR the new navigation is pushed to the next tick with a `setTimeout`, allowing the page being redirected from to be cancelled before starting a new navigation.

Related to #27148

PR Close #31168
2019-06-27 15:54:20 -07:00
f96a81a818 docs: fix example misprints (#31284)
PR Close #31284
2019-06-27 15:53:25 -07:00
4f38419e33 fix(ivy): handle ICU expressions in executeActionOnNode (#31313)
When `walkTNodeTree` was refactored, the case of ICU expressions was forgotten (because it was handled in the `else` previously).
This PR fixes that to handle it like `ElementContainer`.

FW-1411 #resolve
PR Close #31313
2019-06-27 15:53:10 -07:00
119004c7d4 ci: add branch info to CircleCI failure notifications (#31319)
PR Close #31319
2019-06-27 15:52:14 -07:00
d171006083 fix(ivy): ngtsc - NgtscCompilerHost should cope with directories that look like files (#31289)
The TS compiler is likely to test paths with extensions and try to
load them as files. Therefore `fileExists()` and methods that rely
on it need to be able to distinguish between real files and directories
that have paths that look like files.

This came up as a bug in ngcc when trying to process `ngx-virtual-scroller`,
which relies upon a library called `@tweenjs/tween.js`.

PR Close #31289
2019-06-27 12:34:51 -07:00
19e8570ac0 refactor(service-worker): remove redundant cache operation (#30977)
At this point, the response will have been cached (or scheduled to be
cached) in other code paths, so caching it again is redundant.

PR Close #30977
2019-06-27 09:52:29 -07:00
93abc35213 fix(service-worker): cache opaque responses when requests exceeds timeout threshold (#30977)
PR Close #30977
2019-06-27 09:52:29 -07:00
d7be38f84b fix(service-worker): cache opaque responses in data groups with freshness strategy (#30977)
Previously, (presummably due to a typo) the `okToCacheOpaque` argument
of `DataGroup#cacheResponse()` was essentially never taken into account
(since opaque responses have a non-200 status code and thus `res.ok` is
always false).

This commit fixes the typo, which allows opaque responses to be cached
when `okToCacheOpaque` is true (i.e. in data groups using the
`freshness` strategy).

Fixes #30968

PR Close #30977
2019-06-27 09:52:29 -07:00
2d38623974 refactor(service-worker): make the caching behavior more explicit (#30977)
This commit doesn't change the behavior wrt caching, but it makes it
more explicit that only non-timed-out responses are cached. In case of a
timeout, `res` would be set to a programmatically created 504
`Response`, so `cacheResponse()` (which checks for `res.ok`) would not
have cached it anyway, but this makes change makes it more explicit (and
more similar to the equivalent part in [handleFetchWithFreshness()][1]).

[1]: https://github.com/angular/angular/blob/2b4d5c754/packages/service-worker/worker/src/data.ts#L379-L388

PR Close #30977
2019-06-27 09:52:28 -07:00
5306330d85 test(service-worker): better simulate opaque requests (#30977)
Previously, opaque responses where handled a little differently than
other responses from the mock server. More specifically, they were not
tracked (so no assertions could be made for them) and their
[`Body` mixin][1] methods (such as `arrayBuffer()`, `json()`, `text()`)
would throw an error due to `body` being `null`.

This commit ensures opaque responses are also captured on the mock
server and also changes `Body` mixin methods to better simulate the
[spec'd behavior][2].

(These improvements will be necessary to test caching of opaque
responses in a subsequent commit.)

[1]: https://developer.mozilla.org/en-US/docs/Web/API/Body
[2]: https://fetch.spec.whatwg.org/#concept-body-consume-body

PR Close #30977
2019-06-27 09:52:28 -07:00
c150354464 test(service-worker): properly reset mock server state for each test (#30977)
PR Close #30977
2019-06-27 09:52:28 -07:00
7217525da4 test(service-worker): simplify test helpers (#30977)
PR Close #30977
2019-06-27 09:52:28 -07:00
b6e8d19313 test(service-worker): remove obsolete async test helpers (#30977)
Jasmine natively supports returning promises from spec functions for
quite some time now. We don't need special async helpers.

PR Close #30977
2019-06-27 09:52:28 -07:00
6c0cca093a docs: couple of small UI fixes throughout some documents (#31155)
PR Close #31155
2019-06-27 09:51:28 -07:00
f2360aab9d fix(ivy): incorrect namespace for root node created through ViewContainerRef (#31232)
Currently in Ivy whenever we encounter a new namespace, we set it in the global state so that all subsequent nodes are created under the same namespace. Next time a template is run the namespace will be reset back to HTML.

This breaks down if the last node that was rendered was under the SVG or MathML namespace and we create a component through `ViewContainerRef.create`, because the next template function hasn't run yet and it hasn't had the chance to update the namespace. The result is that the root node of the new component will retain the wrong namespace and may not end up rendering at all (e.g. if we're trying to show a `div` inside the SVG namespace). This issue has the potential to affect a lot of apps, because all components inserted through the router also go through `ViewContainerRef.create`.

PR Close #31232
2019-06-27 09:50:52 -07:00
d7b4172678 build(docs-infra): upgrade cli command docs sources to e819d9b77 (#31307)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](01a7186bb...e819d9b77):

**Modified**
- help/generate.json

##

PR Close #31307
2019-06-27 09:50:20 -07:00
641a4ea763 release: cut the v8.1.0-rc.0 release 2019-06-26 14:06:11 -07:00
da4f7fbe1b docs: release notes for the v8.0.3 release 2019-06-26 13:56:16 -07:00
9c87d223ee ci: target default pool for linux RBE executions (#31297)
PR Close #31297
2019-06-26 13:31:36 -07:00
2be061a96e docs: add "ivy" and "zone.js" to known scopes in contributing guide (#31291)
Currently the contributing guide misses entries for the `ivy` and `zone.js`
scopes. This commit adds these to the contributing guide as it is useful
for new contributors to know which scopes are supported.

PR Close #31291
2019-06-26 13:30:23 -07:00
3851544674 style: fix code style in several files (#31295)
These files have not been formatted properly, due to issues in the
`gulp format*` tasks. See previous commits (or #31295) for more details.

PR Close #31295
2019-06-26 13:29:29 -07:00
6b7b4ee891 build: fix formatting tasks by ignoring the zone.js/ directory (#31295)
This was causing issues, because `zone.js` looks like a JS file (despite
it being a directory). The contents of `zone.js/` are still matched by
the globs (it is only the directory itself that is excluded).

Related to #30962.

PR Close #31295
2019-06-26 13:29:29 -07:00
279e74603e refactor: move negative glob patterns of files to format close to their positive counterparts (#31295)
This makes it easier to identify which files in directory will be
included and which will be ignored.

PR Close #31295
2019-06-26 13:29:29 -07:00
8503901746 build: downgrade gulp-clang-format to 1.0.23 (#31295)
The `gulp format*` tasks have been broken since 5eb742621. These include
the `gulp format:enforce` task, which is what runs on CI to enforce
consistent code style. Here is what (I believe) happened:

- I assume formatting was failing in 5eb742621 (moving `zone.js` into
  `angular/angular`). The reason must have been that
  [this glob pattern][1] matches `packages/zone.js/` (which is a
  directory) and passes it to `clang-format` claiming it is a file.
- I further assume that in an attempt to fix the issue,
  `gulp-clang-format` was updated to the latest version (1.0.27) in
  5eb742621.
- `gulp format:enforce` stopped complaining, so everyone thought
  formatting was fine and moved on.
- Formatting still wasn't fine, but the task completed successfully
  nevertheless 😱
- The reason is that angular/gulp-clang-format@55b697c5c (and subsequent
  commits) changed the way the `done()` callback was called, leaving it
  to `clang-format` to call it (while previously it was also called when
  the associated stream ended).
- In the old version of `clang-format` that we are using (1.0.41), there
  is a bug (which has been fixed in angular/clang-format@4cce2c4ee):
  The callback is not called
  [unless the process exits with an error][2].

One can also see that the `gulp format:enforce` task is not completed in
`gulp lint`. Example output from [build 374722][3]:

```
yarn gulp lint
...
Starting 'format:enforce'...
Starting 'validate-commit-messages'...
...
Finished 'validate-commit-messages' after 833 ms
Starting 'tools:build'...
Finished 'tools:build' after 1.75 s
Starting 'tslint'...
Finished 'tslint' after 19 s
Done in 21.82s.
```

Notice that all tasks have a corresponding "Finished X` log, except for
`format:enforce`.

For reference:
The problem was originally reported by @ocombe on Slack ([discussion][4]).

---
This commit fixes the issue by downgrading `gulp-clang-format` to
1.0.23. The linting failures due to formatting issues will be addressed
in subsequent commits.

[1]: https://github.com/angular/angular/blob/a8f3b317f/tools/gulp-tasks/format.js#L13
[2]: https://github.com/angular/clang-format/blob/b8c7df0b7/index.js#L95
[3]: https://circleci.com/gh/angular/angular/374722
[4]: https://angular-team.slack.com/archives/C042EU9T5/p1561480241191000

PR Close #31295
2019-06-26 13:29:29 -07:00
e01d697eed build: filter out changelog entries for zone.js from framework changelog (#31277)
We don't want to show entries for the `zone.js` scope in the main framework
changelog file. The zone.js changelog will be handled separately within the
`packages/zone.js` folder. (see [here](https://github.com/angular/angular/pull/31277#issuecomment-505934681))

PR Close #31277
2019-06-26 09:23:02 -07:00
59d2edfebe build: allow "zone.js" as scope for commit messages (#31277)
Adds `zone.js` as valid scope for commit messages. This
is necessary because the `zone.js` repository has been
moved into the mono-repo and future changes should be
categorized properly through commit messages.

Currently the pre-commit git hook or CircleCI will fail when
`zone.js` is used as commit scope.

PR Close #31277
2019-06-26 09:23:02 -07:00
a8f3b317f1 build(docs-infra): upgrade cli command docs sources to 01a7186bb (#31281)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](a7d4472eb...01a7186bb):

**Modified**
- help/doc.json
- help/test.json

##

PR Close #31281
2019-06-26 08:17:16 -07:00
3788ebb714 fix(ivy): ngcc - don't crash if entry-points have multiple invalid dependencies (#31276)
If an entry-point has missing dependencies then it cannot be
processed and is marked as invalid. Similarly, if an entry-point
has dependencies that have been marked as invalid then that
entry-point too is invalid. In all these cases, ngcc should quietly
ignore these entry-points and continue processing what it can.

Previously, if an entry-point had more than one entry-point that
was transitively invalid then ngcc was crashing rather than
ignoring the entry-point.

PR Close #31276
2019-06-26 08:01:43 -07:00
32c760f5e7 fix(ivy): don't mask errors by calling lifecycle hooks after a crash (#31244)
The Angular runtime frequently calls into user code (for example, when
writing to a property binding). Since user code can throw errors, calls to
it are frequently wrapped in a try-finally block. In Ivy, the following
pattern is common:

```typescript
enterView();
try {
  callUserCode();
} finally {
  leaveView();
}
```

This has a significant problem, however: `leaveView` has a side effect: it
calls any pending lifecycle hooks that might've been scheduled during the
current round of change detection. Generally it's a bad idea to run
lifecycle hooks after the application has crashed. The application is in an
inconsistent state - directives may not be instantiated fully, queries may
not be resolved, bindings may not have been applied, etc. Invariants that
the app code relies upon may not hold. Further crashes or broken behavior
are likely.

Frequently, lifecycle hooks are used to make assertions about these
invariants. When these assertions fail, they will throw and "swallow" the
original error, making debugging of the problem much more difficult.

This commit modifies `leaveView` to understand whether the application is
currently crashing, via a parameter `safeToRunHooks`. This parameter is set
by modifying the above pattern:

```typescript
enterView();
let safeToRunHooks = false;
try {
  callUserCode();
  safeToRunHooks = true;
} finally {
  leaveView(..., safeToRunHooks);
}
```

If `callUserCode` crashes, then `safeToRunHooks` will never be set to `true`
and `leaveView` won't call any further user code. The original error will
then propagate back up the stack and be reported correctly. A test is added
to verify this behavior.

PR Close #31244
2019-06-26 08:01:14 -07:00
f690a4e0af fix(ivy): ngcc - do not analyze files outside the current package (#30591)
Our module resolution prefers `.js` files over `.d.ts` files because
occasionally libraries publish their typings in the same directory
structure as the compiled JS files, i.e. adjacent to each other.

The standard TS module resolution would pick up the typings
file and add that to the `ts.Program` and so they would be
ignored by our analyzers. But we need those JS files, if they
are part of the current package.

But this meant that we also bring in JS files from external
imports from outside the package, which is not desired.
This was happening for the `@fire/storage` enty-point
that was importing the `firebase/storage` path.

In this commit we solve this problem, for the case of imports
coming from a completely different package, by saying that any
file that is outside the package root directory must be an external
import and so we do not analyze those files.

This does not solve the potential problem of imports between
secondary entry-points within a package but so far that does
not appear to be a problem.

PR Close #30591
2019-06-26 08:00:03 -07:00
42036f4b79 refactor(ivy): ngcc - pass bundle to DecorationAnalyzer (#30591)
Rather than passing a number of individual arguments, we can
just pass an `EntryPointBundle`, which already contains them.

This is also a precursor to using more of the properties in the bundle.

PR Close #30591
2019-06-26 08:00:03 -07:00
74f637f98d refactor(ivy): ngcc - no need to pass isCore explicitly (#30591)
It is part of `EntryPointBundle` so we can just use that, which
is generally already passed around.

PR Close #30591
2019-06-26 08:00:03 -07:00
e943859843 refactor(ivy): ngcc - expose the entryPoint from the EntryPointBundle interface (#30591)
This will allow users of the `EntryPointBundle` to use some of the `EntryPoint`
properties without us having to pass them around one by one.

PR Close #30591
2019-06-26 08:00:03 -07:00
a94bdc6793 refactor(ivy): ngcc - pass whole entry-point object to makeEntryPointBundle() (#30591)
This simplifies the interface somewhat but also allows us to make use of
other properties of the EntryPoint object in the future.

PR Close #30591
2019-06-26 08:00:03 -07:00
2dfd97d8f0 fix(ivy): ngcc - support bare array constructor param decorators (#30591)
Previously we expected the constructor parameter `decorators`
property to be an array wrapped in a function. Now we also support
an array not wrapped in a function.

PR Close #30591
2019-06-26 08:00:03 -07:00
869e3e8edc fix(ivy): ngcc - infer entry-point typings from format paths (#30591)
Some packages do not actually provide a `typings` field in their
package.json. But TypeScript naturally infers the typings file from
the location of the JavaScript source file.

This commit modifies ngcc to do a similar inference when finding
entry-points to process.

Fixes #28603 (FW-1299)

PR Close #30591
2019-06-26 08:00:02 -07:00
7c4c676413 feat(ivy): customize ngcc via configuration files (#30591)
There are scenarios where it is not possible for ngcc to guess the format
or configuration of an entry-point just from the files on disk.

Such scenarios include:

1) Unwanted entry-points: A spurious package.json makes ngcc think
there is an entry-point when there should not be one.

2) Deep-import entry-points: some packages allow deep-imports but do not
provide package.json files to indicate to ngcc that the imported path is
actually an entry-point to be processed.

3) Invalid/missing package.json properties: For example, an entry-point
that does not provide a valid property to a required format.

The configuration is provided by one or more `ngcc.config.js` files:

* If placed at the root of the project, this file can provide configuration
for named packages (and their entry-points) that have been npm installed
into the project.

* If published as part of a package, the file can provide configuration
for entry-points of the package.

The configured of a package at the project level will override any
configuration provided by the package itself.

PR Close #30591
2019-06-26 08:00:02 -07:00
4004d15ba5 test(ivy): ngcc refactor mock file-systems to make each spec independent (#30591)
Previously each test relied on large shared mock file-systems, which
makes it difficult to reason about what is actually being tested.

This commit breaks up these big mock file-systems into smaller more
focused chunks.

PR Close #30591
2019-06-26 08:00:02 -07:00
abbbc69e64 test(ivy): ngcc - remove use of mock-fs in tests (#30591)
Now that ngcc uses a `FileSystem` throughout we no longer need
to rely upon mocking out the real file-system with mock-fs.

PR Close #30591
2019-06-26 08:00:02 -07:00
4fe0e75365 refactor(ivy): rename applyXYZ to executeActionOnXYZ for clarity (#31182)
PR Close #31182
2019-06-25 17:03:52 -07:00
103064a3d0 refactor(ivy): remove code duplication from applyXYZ functions (#31182)
PR Close #31182
2019-06-25 17:03:51 -07:00
29a9909232 refactor(ivy): simplify walkTNodeTree method for readability (#31182)
PR Close #31182
2019-06-25 17:03:51 -07:00
7186f9c016 refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921)
To improve cross platform support, all file access (and path manipulation)
is now done through a well known interface (`FileSystem`).

For testing a number of `MockFileSystem` implementations are provided.
These provide an in-memory file-system which emulates operating systems
like OS/X, Unix and Windows.

The current file system is always available via the static method,
`FileSystem.getFileSystem()`. This is also used by a number of static
methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass
`FileSystem` objects around all the time. The result of this is that one
must be careful to ensure that the file-system has been initialized before
using any of these static methods. To prevent this happening accidentally
the current file system always starts out as an instance of `InvalidFileSystem`,
which will throw an error if any of its methods are called.

You can set the current file-system by calling `FileSystem.setFileSystem()`.
During testing you can call the helper function `initMockFileSystem(os)`
which takes a string name of the OS to emulate, and will also monkey-patch
aspects of the TypeScript library to ensure that TS is also using the
current file-system.

Finally there is the `NgtscCompilerHost` to be used for any TypeScript
compilation, which uses a given file-system.

All tests that interact with the file-system should be tested against each
of the mock file-systems. A series of helpers have been provided to support
such tests:

* `runInEachFileSystem()` - wrap your tests in this helper to run all the
wrapped tests in each of the mock file-systems.
* `addTestFilesToFileSystem()` - use this to add files and their contents
to the mock file system for testing.
* `loadTestFilesFromDisk()` - use this to load a mirror image of files on
disk into the in-memory mock file-system.
* `loadFakeCore()` - use this to load a fake version of `@angular/core`
into the mock file-system.

All ngcc and ngtsc source and tests now use this virtual file-system setup.

PR Close #30921
2019-06-25 16:25:24 -07:00
1e7e065423 docs: correct indention for code example in deployment guide (#31255)
PR Close #31255
2019-06-25 14:44:34 -07:00
ae1ac45981 docs(core): update code sample for "outputs" attribute (#31199)
The current code sample for (directive) "outputs" attribute is incorrect as it does not provide the usage of "outputs" attribute rather it provides the usage of "exportAs" attribute. This commit update the code sample by correcting the code sample with correct usage of "outputs" attribute.

Fixes https://github.com/angular/angular/issues/29523
Related work https://github.com/angular/angular/pull/30014

This commit continues from the unfinished (https://github.com/angular/angular/pull/30014#issuecomment-485419124, https://github.com/angular/angular/issues/29523#issuecomment-497333146) work.

PR Close #31199
2019-06-25 14:44:08 -07:00
280e8563f0 Revert "build(bazel): update to bazel 0.27.0 and fix compat in @angular/bazel package (#31019)" (#31267)
This reverts commit 28d3bfc416.

Reason: this causes failures in g3 with i18n extraction. See #31267.

PR Close #31267
2019-06-25 14:36:01 -07:00
660800ca4e Revert "build: update to rules_nodejs 0.32.2 (#31019)" (#31267)
This reverts commit a38433f36b.

Reason: this causes failures in g3 with i18n extraction. See #31267.

PR Close #31267
2019-06-25 14:36:00 -07:00
2c07820636 Revert "build(bazel): cleanup entry_point target (#31019)" (#31267)
This reverts commit cd617b15e8.

Reason: this causes failures in g3 with i18n extraction. See #31267.

PR Close #31267
2019-06-25 14:36:00 -07:00
44b1ce6c72 Revert "build: disable must-use-promises check in ts_library tsetse for tests as... (#31019)" (#31267)
This reverts commit 5bec683692.

Reason: this causes failures in g3 with i18n extraction. See #31267.

PR Close #31267
2019-06-25 14:36:00 -07:00
5eb4691dec Revert "build(bazel): remove deprecated rules_nodejs NodeModuleInfo provider (#31019)" (#31267)
This reverts commit 72e4ff7591.

Reason: this causes failures in g3 with i18n extraction. See #31267.

PR Close #31267
2019-06-25 14:36:00 -07:00
35acd44a07 Revert "build(bazel): add build --incompatible_list_based_execution_strategy_selection=false flag (#31019)" (#31267)
This reverts commit ab27337612.

Reason: this causes failures in g3 with i18n extraction. See #31267.

PR Close #31267
2019-06-25 14:36:00 -07:00
8afc998ec4 Revert "build(bazel): update //packages/bazel/test/ngc-wrapped:ngc_test test (#31019)" (#31267)
This reverts commit 708d0a2db2.

Reason: this causes failures in g3 with i18n extraction. See #31267.

PR Close #31267
2019-06-25 14:36:00 -07:00
26a85a82ff Revert "build: fix build failures with worker mode cache and @types/events (#31019)" (#31267)
This reverts commit 6ba42f1da4.

Reason: this causes failures in g3 with i18n extraction. See #31267.

PR Close #31267
2019-06-25 14:36:00 -07:00
98685e6f85 docs: change note about cli (#31216)
PR Close #31216
2019-06-25 11:58:06 -07:00
61f2353467 docs: add note about cli commands (#31216)
PR Close #31216
2019-06-25 11:58:06 -07:00
ef9cb6a034 perf(ivy): chain multiple i18nExp calls (#31258)
Implement function chaining for `i18nExp` to reduce the output size.

FW-1391 #resolve
PR Close #31258
2019-06-25 11:26:29 -07:00
3846192bde ci: add owners for zone.js to CODEOWNERS (#31203)
Follow-up to #30962.

PR Close #31203
2019-06-25 11:20:01 -07:00
a1d436e6a4 docs: fix formatting (#31120)
PR Close #31120
2019-06-25 10:28:50 -07:00
02d98ed823 docs: fix testing example (#31120)
PR Close #31120
2019-06-25 10:28:50 -07:00
e8d0265c1e ci: enable remote build caching for CI jobs (#31204)
Enables remote caching for CI jobs.

This configuration:

always reads from build cache on CI
only write to build cache for local builds for non-PR CI run

PR Close #31204
2019-06-25 10:26:43 -07:00
00ecfc7f9a fix(docs-infra): separate vendor-specific CSS selectors (#31252)
In #31118, some vendor-specific selectors were combined in one rule-set.
As pointed out in [this comment][1], this would result in the whole
rule-set being ignored by all browsers, since one invalid/unrecognized
selector invalidates the declaration block.

This commit fixes it by defining a separate rule-set per selector. The
list of vendor-specific selectors is also adjusted to better target the
currently supported browsers.

[1]: https://github.com/angular/angular/pull/31118/files#r296923652

PR Close #31252
2019-06-25 10:25:31 -07:00
6ff3970ec7 style(docs-infra): clean up some styles (#31252)
PR Close #31252
2019-06-25 10:25:31 -07:00
1d5c44551d build: use checked-in configuration from bazel-toolchains (#31251)
No longer uses docker in order to pull down the toolchain configs
for remote build execution. We don't need to make docker a prerequisite
for working on the Angular repository since we can leverage the checked-in
toolchain configurations from the `@bazel-toolchains` repository.

PR Close #31251
2019-06-25 10:24:43 -07:00
2aba485118 refactor(ivy): use FatalDiagnosticError to throw more descriptive errors while extracting queries information (#31123)
Prior to this commit, the logic to extract query information from class fields used an instance of regular Error class to throw an error. As a result, some useful information (like reference to a specific field) was missing. Replacing Error class with FatalDiagnosticError one makes the error more verbose that should simplify debugging.

PR Close #31123
2019-06-25 10:23:24 -07:00
b11a2057c6 docs(core): change from CSS Event to DOM event (#31229)
PR Close #31229
2019-06-25 10:22:34 -07:00
6ba42f1da4 build: fix build failures with worker mode cache and @types/events (#31019)
Errors observed only in tests on CircleCI — was not reproducible locally.

```
ERROR: /home/circleci/ng/packages/http/test/BUILD.bazel:3:1: Compiling TypeScript (devmode) //packages/http/test:test_lib failed (Exit 1): tsc_wrapped failed: error executing command
  (cd /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular && \
  exec env - \
    BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \
    PATH=/bin:/usr/bin:/usr/local/bin \
  bazel-out/host/bin/external/npm/@bazel/typescript/bin/tsc_wrapped @@bazel-out/k8-fastbuild/bin/packages/http/test/test_lib_es5_tsconfig.json)
Execution platform: //tools:rbe_ubuntu1604-angular
Compilation failed Error: missing input digest for /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/external/npm/node_modules/@types/events/index.d.ts.

ERROR: /home/circleci/ng/packages/benchpress/test/BUILD.bazel:3:1: Compiling TypeScript (devmode) //packages/benchpress/test:test_lib failed (Exit 1): tsc_wrapped failed: error executing command
  (cd /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular && \
  exec env - \
    BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \
    PATH=/bin:/usr/bin:/usr/local/bin \
  bazel-out/host/bin/external/npm/@bazel/typescript/bin/tsc_wrapped @@bazel-out/k8-fastbuild/bin/packages/benchpress/test/test_lib_es5_tsconfig.json)
Execution platform: //tools:rbe_ubuntu1604-angular
Compilation failed Error: missing input digest for /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/external/npm/node_modules/@types/events/index.d.ts

ERROR: C:/codefresh/volume/angular/packages/compiler/test/css_parser/BUILD.bazel:3:1: Compiling TypeScript (devmode) //packages/compiler/test/css_parser:css_parser_lib failed (Exit 1):
tsc_wrapped.exe failed: error executing command
  cd C:/users/containeradministrator/_bazel_containeradministrator/zquin2l6/execroot/angular
  SET PATH=C:\msys64\usr\bin;C:\msys64\bin;C:\Windows;C:\Windows\System32;C:\Windows\System32\WindowsPowerShell\v1.0
    SET RUNFILES_MANIFEST_ONLY=1
  bazel-out/host/bin/external/npm/@bazel/typescript/bin/tsc_wrapped.exe @@bazel-out/x64_windows-fastbuild/bin/packages/compiler/test/css_parser/css_parser_lib_es5_tsconfig.json
Execution platform: @bazel_tools//platforms:host_platform
Compilation failed Error: missing input digest for C:/users/containeradministrator/_bazel_containeradministrator/zquin2l6/execroot/angular/external/npm/node_modules/@types/events/index.
d.ts
```

PR Close #31019
2019-06-25 10:21:07 -07:00
708d0a2db2 build(bazel): update //packages/bazel/test/ngc-wrapped:ngc_test test (#31019)
after update to rules_nodejs 0.32.1, @types are no longer automatically discovered by ngc-wrapped (which uses parts of ts_library) so this test needed updating so that the types files it generates is added as an explicit dep

PR Close #31019
2019-06-25 10:21:07 -07:00
ab27337612 build(bazel): add build --incompatible_list_based_execution_strategy_selection=false flag (#31019)
This option is changed to true in Bazel 0.27 and exposes a possible
regression in Bazel 0.27.0.
Error observed is in npm_package target `//packages/common/locales:package`:
```
ERROR: /home/circleci/ng/packages/common/locales/BUILD.bazel:13:1: Assembling
npm package packages/common/locales/package failed: No usable spawn strategy found
for spawn with mnemonic SkylarkAction.  Your --spawn_strategyor --strategy flags
are probably too strict. Visit https://github.com/bazelbuild/bazel/issues/7480 for
migration advises
```
Suspect is https://github.com/bazelbuild/rules_nodejs/blob/master/internal/npm_package/npm_package.bzl#L75-L82:
```
 execution_requirements = {
    # Never schedule this action remotely because it's not computationally expensive.
    # It just copies files into a directory; it's not worth copying inputs and outputs to a remote worker.
    # Also don't run it in a sandbox, because it resolves an absolute path to the bazel-out directory
    # allowing the .pack and .publish runnables to work with no symlink_prefix
    # See https://github.com/bazelbuild/rules_nodejs/issues/187
    "local": "1",
},
```

PR Close #31019
2019-06-25 10:21:07 -07:00
72e4ff7591 build(bazel): remove deprecated rules_nodejs NodeModuleInfo provider (#31019)
PR Close #31019
2019-06-25 10:21:07 -07:00
5bec683692 build: disable must-use-promises check in ts_library tsetse for tests as... (#31019)
...tsetse now falsely asserting on  some lines in a few tests such as packages/core/schematics/test/injectable_pipe_migration_spec.ts.

```
    await runMigration();
    expect(tree.readContent('/index.ts'))
```

it asserts that "await is required on promise" on the 2nd line when there is no promise there

PR Close #31019
2019-06-25 10:21:07 -07:00
cd617b15e8 build(bazel): cleanup entry_point target (#31019)
PR Close #31019
2019-06-25 10:21:07 -07:00
a38433f36b build: update to rules_nodejs 0.32.2 (#31019)
Brings in ts_library fixes required to get angular/angular building after 0.32.0:
typescript: exclude typescript lib declarations in node_module_library transitive_declarations
typescript: remove override of @bazel/tsetse (+1 squashed commit)

@npm//node_modules/foobar:foobar.js labels changed to @npm//:node_modules/foobar/foobar.js with fix for bazelbuild/rules_nodejs#802

also updates to rules_rass commit compatible with rules_nodejs 0.32.0

PR Close #31019
2019-06-25 10:21:07 -07:00
28d3bfc416 build(bazel): update to bazel 0.27.0 and fix compat in @angular/bazel package (#31019)
ctx.actions.declare_file now used in @angular/bazel ng_module rule as ctx.new_file is now deprecated. Fixes error:

```
        File "ng_module.bzl", line 272, in _expected_outs
                ctx.new_file(ctx.genfiles_dir, (ctx.label.name ..."))
Use ctx.actions.declare_file instead of ctx.new_file.
Use --incompatible_new_actions_api=false to temporarily disable this check.
```

This can be worked around with incompatible_new_actions_api flag but may as well fix it proper so downstream doesn't require this flag due to this code.

Also, depset() is no longer iterable by default without a flag. This required fixing in a few spots in @angular/bazel.

fix: foo

PR Close #31019
2019-06-25 10:21:06 -07:00
f7e9659c4d fix(docs-infra): return full width highlight to sidenav (#31246)
PR Close #31246
2019-06-24 20:17:27 -07:00
16717fa12c fix(bazel): exclude all angular schematics folders from metadata build (#31237)
Fixes #31235

PR Close #31237
2019-06-24 18:48:44 -07:00
74f4f5dfab feat(ivy): integrate indexing pipeline with NgtscProgram (#31151)
Add an IndexingContext class to store indexing information and a
transformer module to generate indexing analysis. Integrate the indexing
module with the rest of NgtscProgram and add integration tests.

Closes #30959

PR Close #31151
2019-06-24 18:47:56 -07:00
3fb73ac62b fix(ivy): support equality operators in static interpreter (#31145)
Previously, the usage of equality operators ==, ===, != and !== was not
supported in ngtsc's static interpreter. This commit adds support for
such operators and includes tests.

Fixes #31076

PR Close #31145
2019-06-24 18:47:02 -07:00
a5dd4edab9 fix(service-worker): registration failed on Safari (#31140)
Since Angular v8, and commit b3dda0e, `parseUrl()` can be called without
`relativeTo`, thus `new URL()` can be called with `relativeTo = undefined`.

Safari does not like it and the service worker registration fails:
```js
new URL('https://angular.io/') // OK
new URL('https://angular.io/', undefined) // TypeError
```

Closes #31061

PR Close #31140
2019-06-24 14:58:58 -07:00
e83667ad76 fix(bazel): remove unsupported Css pre-processors from ng new (#31234)
Under Bazel, we don't yet support Stylus and Less, and thus we should not offer the users to generate applications which are known not to work.

Closes #31209

PR Close #31234
2019-06-24 14:57:06 -07:00
805fc8698c fix(bazel): update ng new schema to match the current ng new schema of @schematics/angular (#31234)
The schema used in ng-new bazel, includes several outdated options. With this update we match the current version of @schematics/angular: https://github.com/angular/angular-cli/blob/master/packages/schematics/angular/ng-new/schema.json

Relates to #31233

PR Close #31234
2019-06-24 14:57:06 -07:00
23c017121e perf(ivy): chain multiple attribute instructions (#31152)
Similarly to what we did in #31078, these changes implement chaining for the `attribute` instruction.

This PR resolves FW-1390.

PR Close #31152
2019-06-24 12:33:49 -07:00
fcb03abc72 fix(ivy): injecting incorrect Renderer2 into child components (#31063)
In ViewEngine injecting a Renderer2 returns a renderer that is specific to the particular component, however in Ivy we inject the renderer for the parent view instead. This causes it to set incorrect `ngcontent` attributes when creating elements through the renderer.

The issue comes from the fact that the `Renderer2` is created according to the current `LView`, but because DI happens before we've entered the `LView` of the component that's injecting the renderer, we end up with one that's one level up. We work around the issue by finding the `LView` that corresponds to the `previousOrParentTNode` inside of the parent view and associating the `Renderer2` with it.

This PR resolves FW-1382.

PR Close #31063
2019-06-24 11:33:31 -07:00
6f5d910ddd ci: send failure notifications from saucelabs_tests to dev-infra-ci-failures (#31202)
PR Close #31202
2019-06-21 15:29:35 -07:00
d72f8c949f ci: make logic for failure notifications more re-usable (#31202)
PR Close #31202
2019-06-21 15:29:35 -07:00
29df3b0ee2 ci: send aio_monitoring failure notifications to the dev-infra-ci-failures channel (#31202)
PR Close #31202
2019-06-21 15:29:35 -07:00
a4fc98cace ci: add josephperrott to dev-infra owners (#31205)
PR Close #31205
2019-06-21 15:29:09 -07:00
131e2440f2 build: Set up Build Event Service Configuration for RBE executed bazel (#31197)
The Build Event Service (https://docs.bazel.build/versions/master/build-event-protocol.html#the-build-event-service),
allows for build events from bazel builds to be transmitted as opaque bytes to be processed.

Our usage is to send our build events to a Build Event Service an Angular team owned Google Cloud Project which collects
build results and makes each invocation available via a provided URL to view.  The information uploaded includes information
about the build environment, configuration, build status/events, build options, results and actions.

Build Event Protocol Proto: https://github.com/bazelbuild/bazel/blob/0.27.0/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto

PR Close #31197
2019-06-21 15:28:50 -07:00
65974154e2 feat(docs-infra): change typography font sizes to be rem based (#31118)
PR Close #31118
2019-06-21 14:22:20 -07:00
7035f225ad fix(compiler): fix Elements not making a new ParseSourceSpan (#31190)
Change the Element constructor in r3_ast to create a new ParseSourceSpan when regenerating it rather than extending an object, which does not contain the overloaded toString().

PR Close #31190
2019-06-21 12:03:01 -07:00
9c06af2dfc docs: update node minimum version (#31192)
Docs for for Travis CI setup suggest using node version 8 when the minimum should be 10. This commit updates the documentation by specifying the minimum required version as 10.

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

PR Close #31192
2019-06-21 12:02:38 -07:00
83f0304cfc docs: clarify wording in Template Syntax (#31119)
PR Close #31119
2019-06-21 10:23:38 -07:00
a9502886b1 docs: mark interfaces as public (#30955)
PR Close #30955
2019-06-21 10:21:13 -07:00
4bd6fca4ef docs: fix typo of zone.js README.md (#31178)
PR Close #31178
2019-06-21 10:20:26 -07:00
bd3b0564e6 fix(ivy): sync ViewRefs between multiple ViewContainerRefs (#30985)
Previously, multiple ViewContainerRef instances (obtained by injecting
ViewContainerRef multiple times) each had private state that could be out of
sync with actual LContainer, if views were inserted/removed/queried across
the different instances. In particular each instance had its own array which
tracked ViewRefs inserted via that instance.

This commit moves the ViewRefs array onto the LContainer itself, so that it
can be shared across multiple ViewContainerRef instances. A test is added
that verifies ViewContainerRefs now provide a consistent view of the
container.

FW-1377 #resolve

PR Close #30985
2019-06-21 10:18:06 -07:00
b1664425a9 build(docs-infra): upgrade cli command docs sources to a7d4472eb (#31184)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](ab6f36229...a7d4472eb):

**Modified**
- help/generate.json

##

PR Close #31184
2019-06-21 10:15:20 -07:00
ecd7f6ecdc docs: fix javascript module link (#31181)
PR Close #31181
2019-06-21 10:14:39 -07:00
6a381d9246 docs: fix typo in browser-support.md (ES1015 --> ES2015) (#31157)
PR Close #31157
2019-06-21 10:14:23 -07:00
1f1cf1a169 docs: add Mosaic library to resources (#31026)
PR Close #31026
2019-06-21 10:14:04 -07:00
48def92cad fix(ivy): ensure that changes to component resources trigger incremental builds (#30954)
Optimizations to skip compiling source files that had not changed
did not account for the case where only a resource file changes,
such as an external template or style file.

Now we track such dependencies and trigger a recompilation
if any of the previously tracked resources have changed.

This will require a change on the CLI side to provide the list of
resource files that changed to trigger the current compilation by
implementing `CompilerHost.getModifiedResourceFiles()`.

Closes #30947

PR Close #30954
2019-06-21 10:13:46 -07:00
dc613b336d refactor(ivy): removing unused properties from i18n interfaces (#31171)
Fixes #31165
PR Close #31171
2019-06-20 18:46:20 -07:00
7ff628f8d5 refactor(ivy): make bind an internal-only function (#31131)
The function `bind` has been internalized wherever it was needed, this PR makes sure that it is no longer publicly exported.

FW-1385 #resolve
PR Close #31131
2019-06-20 17:20:56 -07:00
3fb78aaacc feat(upgrade): provide unit test helpers for wiring up injectors (#16848)
Adds two new helper functions that can be used when unit testing Angular services
that depend upon upgraded AngularJS services, or vice versa.
The functions return a module (AngularJS or NgModule) that is configured to wire up
the Angular and AngularJS injectors without the need to actually bootstrap a full
hybrid application.

This makes it simpler and faster to unit test services.

PR Close #16848
2019-06-20 17:04:01 -07:00
5e53956c2b fix(compiler): stringify Object.create(null) tokens (#16848)
PR Close #16848
2019-06-20 17:04:01 -07:00
fad03c3c14 refactor: early compatibility with TypeScript 3.5 (#31174)
This commit fixes a couple of issues with TS 3.5 compatibility in order to
unblock migration of g3. Mostly 'any's are added, and there are no behavior
changes.

PR Close #31174
2019-06-20 16:42:37 -07:00
34eaafdf40 build: correct zone.js bazel test visibilty rule (#31175)
PR Close #31175
2019-06-20 16:05:21 -07:00
bf7d046269 style: fix bazel lint in zone.js (#31172)
Update to latest buildifier to fix a false positive error

PR Close #31172
2019-06-20 12:44:06 -07:00
5eb7426216 build: move zone.js to angular repo (#30962)
PR Close #30962
2019-06-20 11:27:39 -07:00
7b3bcc23af build: user bazelrc should be able to overwrite all flags (#31164)
After eb00a37eb8 we accidentally regressed due to some
recent changes where more flags were added at the end of the bazelrc. This means that all
flags which were added after the `try-import` can no longer be overwritten easily in the
user project bazelrc file. Technically developers can always overwrite flags though the
command line, but it's a productivity blocker if developers can't permanently overwrite these
flags  through the user config

PR Close #31164
2019-06-20 11:18:12 -07:00
b356fb01d5 build(docs-infra): upgrade @angular/cli to 8.1.0-beta.2 (#31137)
PR Close #31137
2019-06-20 11:16:35 -07:00
f2219081e3 refactor(compiler): allow parsing templates with custom leadingTriviaChars (#31136)
Move the definition leadingTriviaChars included in parsing a template
to the parameters of parseTemplate. This allows overriding of the
default leadingTriviaChars, which is needed by some pipelines like the
indexing pipeline because leadingTriviaChars may throw off the recorded
span of selectors.

PR Close #31136
2019-06-20 11:13:05 -07:00
70ad91ed8b refactor(compiler): recursive ast expression visitor not passing context (#31085)
Currently the `RecursiveAstVisitor` that is part of the template expression
parser does not _always_ properly pass through the context that can be
specified when visting a given expression. Only a handful of AST types
pass through the context while others are accidentally left out. This causes
unexpected and inconsistent behavior and basically makes the `context`
parameter not usable if the type of template expression is not known.

e.g. the template variable assignment migration currently depends on
the `RecursiveAstVisitor` but sometimes breaks if developers use
things like conditionals in their template variable assignments.

Fixes #31043

PR Close #31085
2019-06-20 11:12:16 -07:00
75ac724842 fix(ivy): quote dots in directive inputs and outputs (#31146)
A temporary check is in place to determine whether a key in an object
literal needs to be quoted during emit. Previously, only the presence of
a dash caused a key to become quoted, this however is not sufficient for
@angular/flex-layout to compile properly as it has dots in its inputs.

This commit extends the check to also use quotes when a dot is present.

Fixes #30114

PR Close #31146
2019-06-19 17:57:13 -07:00
4c45aa39e4 ci: re-enable payload size tracking (#31138)
Payload size tracking was temporarily disabled in #31057, due to
`CIRCLE_COMPARE_URL` stopping being available. It turned out this was
related to turning on the new [Pipelines][1] feature, which was required
for testing Windows on CircleCI.

Since then, we have turned `Pipelines` off and got `CIRCLE_COMPARE_URL`
back (e.g. see [build 362971][2]). According to CircleCI, failing to
populate `CIRCLE_COMPARE_URL` with `Pipelines` on is a bug and they are
working on fixing it.

[1]: https://circleci.com/docs/2.0/build-processing/
[2]: https://circleci.com/gh/angular/angular/362971

Fixes #31121

PR Close #31138
2019-06-19 15:55:10 -07:00
c5d1e1a3da docs: fix bad tag (#31115)
PR Close #31115
2019-06-19 15:52:46 -07:00
b1fe1aa8fa docs: fix bad anchors (#31115)
PR Close #31115
2019-06-19 15:52:46 -07:00
9177ffaf58 docs: fix code example formats (#31115)
PR Close #31115
2019-06-19 15:52:46 -07:00
f4fe1f65be docs: add instructions for es5 serve and test targets (#31115)
PR Close #31115
2019-06-19 15:52:46 -07:00
029f1be204 perf(ivy): avoid unnecessary function call in i18n instruction (#31106)
Currently the `placeholders` parameter inside `i18nLocalize` is defaulted to `{}`, which means that we'll always hit the `Object.keys` call below. Since it's very likely that we won't have placeholders in the majority of strings, these changes add an extra guard so that we don't hit it on every invocation.

PR Close #31106
2019-06-19 15:51:42 -07:00
91008bd979 fix(ivy): improve error message when NgModule properties are not arrays (#30796)
PR Close #30796
2019-06-19 15:47:54 -07:00
f0395836b6 fix(ivy): evaluate non existing property access as undefined (#30738)
Closes #30726

PR Close #30738
2019-06-19 15:44:05 -07:00
4b16d98955 perf(ivy): chain multiple property instructions (#31078)
Currently each property binding generates an instruction like this:

```
property('prop1', ctx.value1);
property('prop2', ctx.value2);
```

The problem is that we're repeating the call to `property` for each of the properties. Since the `property` instruction returns itself, we can chain all of the calls which is more compact and it looks like this:

```
property('prop1', ctx.value1)('prop2', ctx.value2);
```

These changes implement the chaining behavior for regular property bindings and for synthetic ones, however interpolated ones are still handled like before, because they use a separate instruction.

This PR resolves FW-1389.

PR Close #31078
2019-06-19 15:42:37 -07:00
ab86a58f27 docs: remove inappropriate link (#31091)
PR Close #31091
2019-06-19 15:31:56 -07:00
4ec50811d4 refactor(language-service): Remove NgLSHost -> NgLS dependency (#31122)
```
NgLSHost: AngularLanguageServiceHost
NgLS: AngularLanguageService
```

NgLSHost should not depend on NgLS, because it introduces circular
dependency.
Instead, the `getTemplateAst` and `getTemplatAstAtPosition` methods should
be moved to NgLSHost and exposed as public methods.
This removes the circular dependency, and also removes the need for the
awkward 'setSite' method in NgLSHost.

PR Close #31122
2019-06-19 15:19:56 -07:00
c34abf2cbc refactor(docs-infra): move auto-link filters to dedicated directory (#31051)
These filters have generic names (e.g. `filterPipes`), which do not make
their purpose obvious. Moving them to a dedicated `auto-link-filters`
directory should help with that.

PR Close #31051
2019-06-19 14:59:34 -07:00
c6b180380a fix(docs-infra): do not auto-link http:// to the common/http (#31051)
Previously, our auto-linking feature would match `http` in URLs (such as
`http://...`) to the `common/http` package and automatically create a
link to that, which was undesirable. While it is possible to work around
that via `<code class="no-auto-link">http://...</code>`, most people
didn't even realize the issue.

Since in this case it is possible to reliably know it is a false match,
this commit fixes it by applying a custom auto-link filter that ignores
all docs for `http`, if it comes before `://`.

Fixes #31012

PR Close #31051
2019-06-19 14:59:34 -07:00
7814ef55c5 release: cut the v8.1.0-next.3 release 2019-06-19 10:57:13 -07:00
f72772b038 docs: release notes for the v8.0.2 release 2019-06-19 10:50:12 -07:00
0bf810022a docs: add core and cli version alignment note (#30976)
docs: add core and cli version alignment note
PR Close #30976
2019-06-19 08:49:24 -07:00
bc04d18420 test: update side-effects test to be more descriptive (#31005)
This test will now list diffs for failed expectations and the full command to update them.

Fix #30570

PR Close #31005
2019-06-18 13:58:58 -07:00
7a53b9090e ci: add jasonaden to forms owners (#31117)
PR Close #31117
2019-06-18 13:58:29 -07:00
db08fd2607 build: enable shard_count for some jasmine tests that have many specs (#31009)
This partitions the spects across multiple processes so they run in parallel.

PR Close #31009
2019-06-18 12:11:30 -07:00
3998335188 build: update buildifier to version that supports windows (#31112)
* Updates buildifier to a version that also comes with windows binaries.
* Fixes a few new formatting/lint warnings
* Removes the `args-order` warning because it is no longer a warning.. and is now part of the formatter.

PR Close #31112
2019-06-18 12:09:41 -07:00
f4cd2b75b4 docs: add missing word in build and deploy guide to clarify sentence (#31093)
PR Close #31093
2019-06-18 11:00:27 -07:00
5909c442b7 docs: update group() link to point to the animations group API (#30618)
PR Close #30618
2019-06-18 10:49:46 -07:00
f5fa9dc6b8 ci: propagate xml results to CI (#31100)
PR Close #31100
2019-06-18 09:51:41 -07:00
87665fe324 build(docs-infra): upgrade cli command docs sources to ab6f36229 (#31102)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](032be4e17...ab6f36229):

**Modified**
- help/doc.json

##

PR Close #31102
2019-06-18 09:51:11 -07:00
16ac611a84 build: ts-api-guardian npm package contains invalid references (#31096)
Currently when building the `ts-api-guardian` npm package,
the labels are not properly replaced after recent changes to
the `entry_point` attribute. This means that the `ts-api-guardian`
package is currently not usable externally.

PR Close #31096
2019-06-18 09:50:41 -07:00
beaab27a49 feat(ivy): index identifiers discovered in templates (#30963)
Add support for indexing of property reads, method calls in a template.
Visit AST of template syntax expressions to extract identifiers.

Child of #30959

PR Close #30963
2019-06-18 09:50:06 -07:00
87168acf39 refactor(ivy): move bind instruction into i18nExp (#31089)
i18nExp now uses `bind` internally rather than having the compiler generate it in order to bring it in line with other functions like `textBinding` & `property`.

FW-1384 #resolve
PR Close #31089
2019-06-18 09:49:27 -07:00
65544ac742 fix(ivy): reprojected ICU expression nodes when creating embedded views (#30979)
When using `createEmbeddedView` after the creation of an ICU expression, the nodes for the current selected case were not reprojected (only the anchor comment node was moved to the new location).
Now we reproject correctly all the child nodes of an ICU expression when an anchor comment node is projected.

FW-1372 #resolve

PR Close #30979
2019-06-18 09:48:46 -07:00
57c4788bc7 docs: refresh TypeScript configuration guide with updated info and files (#31097)
This removes the hard-coded tsconfig.json to use a separate file.
The tsconfig.0.json is added to the getting-started example folder
because have to check it with every major release
Also updates the text regarding defaults for TypeScript compilation targets
and typings

PR Close #31097
2019-06-18 09:47:48 -07:00
7e49beb8cd docs: rewrite Observable examples with pipable operators (#31074)
PR Close #31074
2019-06-18 09:47:06 -07:00
036294d566 docs: change interceptor documentation (#30969)
PR Close #30969
2019-06-18 09:46:34 -07:00
98515e1ecf docs: add mock heroes to the code review tabs for TOH pt. 2 (#31080)
PR Close #31080
2019-06-17 16:34:38 -07:00
c52ade2878 fix(docs-infra): fix search result header color (#30924)
PR Close #30924
2019-06-17 16:33:53 -07:00
4adf95ed6f ci: publish snapshots job is unable to decode github token (#31099)
The publish_snapshots job is currently not able to decode the Github
token because the openssl version changed. This is because the default
digest for more recent openssl version has been updated and the github
token file has been encrypted with an old digest. We need to ensure
that the md5 digest is used for decryption as that matches the
digest used for encryption.

PR Close #31099
2019-06-17 13:56:12 -07:00
a1fc4deff3 fix(bazel): builder workspace should use nodejs v10.16.0 (#31088)
The generated Bazel workspace by the `@angular/bazel` builder should
use the latest stable NodeJS version. This is necessary because some
packages like `selenium-webdriver` which are part of the default bazel
setup in order to support `ng e2e` depend on a minimum NodeJS version
of `10.15.0`.. This means that running e2e tests in a plain new bazel CLI
project (`ng new {projectName} --collection=@angular/bazel`) errors.

```
command.
 (error selenium-webdriver@4.0.0-alpha.3: The engine "node" is incompatible with
 this module. Expected version ">= 10.15.0". Got "10.13.0"
error Found incompatible module
)
```

PR Close #31088
2019-06-17 13:07:27 -07:00
e0969b2480 ci: update nodejs version to v10.16.0 (#31088)
Updates the NodeJS version to the latest stable version at the time of
writing (v10.16.0). We need to update our image to use a minimum NodeJS
version of v10.15.0 because new CLI apps automatically install a non-locked
version of selenium-webdriver that now requires NodeJS >= 10.15.0 since the
latest release of 17th June 2019 (4.0.0-alpha.3).

See CI failures: https://circleci.com/gh/angular/angular/359077

PR Close #31088
2019-06-17 13:07:27 -07:00
c596795e64 ci(docs-infra): check and track payload sizes for test_aio_local and test_aio_local_ivy (#31047)
PR Close #31047
2019-06-14 14:38:10 -07:00
a6cb20cbe7 ci(docs-infra): run PWA score tests after unit/e2e tests (#31047)
Previously, we run the PWA score tests before unit/e2e tests, because
the latter would destroy the `dist/` directory required by the former.

Since cli@6, unit/e2e tests no longer detroy the `dist/` directory, so
it is now safe to run the unit/e2e tests first. This is preferrable,
since they are conceptually lower-level and any error messages (in case
of breakage) are more specific/actionable.

Related discussion about cli behavior:
- angular/angular-cli#4366
- angular/angular-cli#14701

PR Close #31047
2019-06-14 14:38:10 -07:00
6fbfb5a159 feat(ivy): ngcc - recognize static properties on the outer symbol in ES5 (#30795)
Packages that have been compiled using an older version of TypeScript
can have their decorators at the top-level of the ES5 bundles, instead
of inside the IIFE that is emitted for the class. Before this change,
ngcc only took static property assignments inside the IIFE into account,
therefore missing the decorators that were assigned at the top-level.

This commit extends the ES5 host to look for static properties in two
places. Testcases for all bundle formats that contain ES5 have been added
to ensure that this works in the various flavours.

A patch is included to support UMD bundles. The UMD factory affects how
TypeScripts binds the static properties to symbols, see the docblock of
the patch function for more details.

PR Close #30795
2019-06-14 13:09:56 -07:00
16aa6ceff8 refactor(ivy): update ɵɵtextBinding to not take index (#30792)
- Splits core functionality off into a shared internal function
- ɵɵtextBinding will no longer require an index
- Alters the compiler to stop generating an index argument for the instruction
- Updates tests
- Updates some usage of ɵɵtextBinding in i18n to use the helper function instead

PR Close #30792
2019-06-14 12:22:11 -07:00
b5aa0473fc docs: rewrite attribute binding section and add example (#26004)
PR Close #26004
2019-06-14 12:21:28 -07:00
e76690be29 docs: edit codeowners for new Template Syntax examples (#31060)
PR Close #31060
2019-06-14 11:54:29 -07:00
6c4d91297e docs: edit and add example for Template Expression Operators section of Template Syntax (#28087)
PR Close #28087
2019-06-14 11:53:50 -07:00
f41242f18e docs: rewrite inputs/outputs section of Template Syntax (#27685)
PR Close #27685
2019-06-14 11:53:13 -07:00
e2fd628618 docs: edit template ref vars copy and example (#27371)
PR Close #27371
2019-06-14 11:52:33 -07:00
2c2135d331 docs: rewrite built-in directives section (#27273)
PR Close #27273
2019-06-14 11:51:47 -07:00
7e3a60ad31 docs: add example and edit two-way-binding section of Template Syntax (#26278)
PR Close #26278
2019-06-14 11:50:03 -07:00
85d38ae564 docs: rewrite property binding section and add example (#25770)
PR Close #25770
2019-06-14 11:47:34 -07:00
4ad323a4d6 feat(ivy): setup boilerplate for component indexing API (#30961)
Set up the skeleton for a compiler API that indexes components and their
templates on an independent indexing step.

Part of #30959

PR Close #30961
2019-06-14 10:48:12 -07:00
a4601eca68 fix(language-service): Remove 'any' in getQuickInfoAtPosition (#31014)
PR Close #31014
2019-06-14 10:46:16 -07:00
e84b51d2b6 refactor(ivy): remove LView argument from locateDirectiveOrProvider (#31006)
The DI's `locateDirectiveOrProvider` function operates on `TView` / `TNode`
data structures only so doesn't need to access `LView`. This refactoring
changes the argument list so the mentioned function takes less info to do
its work.

This refactoring is also mandatory for the upcoming query matching move
to TView.

PR Close #31006
2019-06-14 10:44:59 -07:00
8f5c396a7c fix(ivy): don't throw when attempting to destroy a destroyed ComponentRef (#31022)
Currently in Ivy we throw when attempting to destroy a `ComponentRef` that has been destroyed, however in ViewEngine we didn't which can cause some tests to break. These changes remove the error to match ViewEngine.

These changes resolve FW-1379.

PR Close #31022
2019-06-14 10:44:30 -07:00
0c3bb6a731 fix(ivy): ngcc - capture entry-points in top-level path-mapped folders (#31027)
The `EntryPointFinder` computes the base paths to consider
when searching for entry-points. When there are `pathMappings`
provided it works out the best top level base-paths that cover all
the potential mappings.

If this computed basePath happens to coincide with an entry-point
path itself then we were missing it.

Now we check for an entry-point even at the base-path itself.

Related to https://github.com/angular/angular-cli/pull/14755

PR Close #31027
2019-06-14 10:43:59 -07:00
cc0bd11a5e build(docs-infra): update browserlist configuration file (#31045)
More specifically:
- Remove Chrome 41, which was needed for googlebot support but not any
  more.
- Remove IE 9-10, because we don't expect developers to be using them.
- Expand support from _last 2 versions_ to _last 2 **major** versions_.

PR Close #31045
2019-06-14 10:43:22 -07:00
5d24a75ac9 docs: minor fix in get-commit-range.js docs (#31049)
PR Close #31049
2019-06-14 10:41:43 -07:00
799d1fd333 docs(aio): add missing description to dev.to link (#30960)
PR Close #30960
2019-06-14 10:41:12 -07:00
6bc9c78d76 fix(core): temporarily remove @deprecated jsdoc tag for a TextBedStatic.get overload (#30714)
Followup to #30514 which did the same for `TestBed`, but `TestBedStatic` was necessary too.

PR Close #30714
2019-06-14 10:40:42 -07:00
bb4e230eae docs: rewrite binding-syntax section in template-syntax.md (#25561)
PR Close #25561
2019-06-14 10:25:06 -07:00
48d11d5fa0 ci: temporarily disable payload size tracking (#31057)
The `CIRCLE_COMPARE_URL` is not available in builds any more since we
enabled `Pipelines` on CircleCI. We have contected CircleCI, but until
this is solved we cannot get the commit range and thus disabling
uploading of payload size data to avoid broken builds.

PR Close #31057
2019-06-14 09:19:17 -07:00
1a5c7112e0 docs: fix broken link in singleton services doc (#31007)
PR Close #31007
2019-06-13 17:05:20 -07:00
352f9672c0 docs: add no-auto-link instructions to docs style guide (#30980)
PR Close #30980
2019-06-13 17:00:46 -07:00
76584804c8 docs: add angular.tw (Traditional Chinese) site to navigation.json (#30723)
PR Close #30723
2019-06-13 16:04:40 -07:00
2c78da00ae release: cut the v8.1.0-next.2 release 2019-06-13 15:47:23 -07:00
bb8a18e72d docs: release notes for the v8.0.1 release 2019-06-13 15:37:47 -07:00
82e0b4a4fb fix(docs-infra): enable only vertical scrolling for contributors bio (#30991)
- `auto` will enable scrolling only when needed
- `overflow-y` will ensure to keep the scrolling horizontally only

PR Close #30991
2019-06-12 11:47:13 -07:00
574990e0fd docs: add platform to glossary (#30731)
PR Close #30731
2019-06-12 11:46:25 -07:00
aa9eb55e3c build(docs-infra): upgrade cli command docs sources to 032be4e17 (#30998)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](9d13ba4b6...032be4e17):

**Modified**
- help/build.json

##

PR Close #30998
2019-06-12 16:21:26 +00:00
052ef654d2 test(compiler-cli): fix failing ivy template compliance test (#30983)
Commit 58be2ff884 has been created
before c0386757b1 landed, and therefore
the newly created compliance test was using an outdated expectation.

This commit updates the compliance test to no longer contain
the outdated expectation.

PR Close #30983
2019-06-11 15:17:01 -07:00
58be2ff884 fix(ivy): unable to bind to implicit receiver in embedded views (#30897)
To provide some context: The implicit receiver is part of the
parsed Angular template AST. Any property reads in bindings,
interpolations etc. read from a given object (usually the component
instance). In that case there is an _implicit_ receiver which can also
be specified explicitly by just using `this`.

e.g.

```html
<ng-template>{{this.myProperty}}</ng-template>
```

This works as expected in Ivy and View Engine, but breaks in case the
implicit receiver is not used for property reads. For example:

```html
<my-dir [myFn]="greetFn.bind(this)"></my-dir>
```

In that case the `this` will not be properly translated into the generated
template function code because the Ivy compiler currently always treats
the `ctx` variable as the implicit receiver. This is **not correct** and breaks
compatibility with View Engine. Rather we need to ensure that we retrieve
the root context for the standalone implicit receiver similar to how it works
for property reads (as seen in the example above with `this.myProperty`)

Note that this requires some small changes to the `expression_converter`
because we only want to generate the `eenextContent()` instruction if the
implicit receiver is _actually_ used/needed. View Engine determines if that is the case by recursively walking through the converted output AST and
checking for usages of the `o.variable('_co')` variable ([see here][ve_check]). This would work too for Ivy, but involves most likely more code duplication
since templates are isolated in different functions and it another pass
through the output AST for every template expression.

[ve_check]: 0d6c9d36a1/packages/compiler/src/view_compiler/view_compiler.ts (L206-L208)

Resolves FW-1366.

PR Close #30897
2019-06-11 14:29:42 -07:00
7912db3829 fix(ivy): call factory functions with correct type for derived classes (#30855)
In a derived service class with no decorator (and therefore no factory) of
its own, the factory function of the base class will be used instead.
Previously this logic had a bug where the factory function would be called
with no arguments, which would incorrectly create an instance of the base
class.

This commit adds logic to call the base class' factory and pass the type of
the derived class, which will correctly construct an instance of the
derived class using the base class' factory. A test is also added to verify
correctness of this behavior.

PR Close #30855
2019-06-11 14:27:17 -07:00
0ee09cdd7e refactor(ivy): fix type of factory functions to allow explicit types (#30855)
Factory functions written by the compiler optionally allow an explicit type
to be passed. If called with this type, an instance of the given type will
be created instead of the type for which the factory was generated. This is
used to power inheritance of Angular types, as if the constructor of a class
is inherited from its superclass, then the factory function of the
superclass must be used (it has all the DI info) to construct an instance of
the derived class.

This commit adjusts typings in a few places to allow factory functions to be
called with this extra type parameter.

PR Close #30855
2019-06-11 14:27:17 -07:00
b2937b16c3 fix(ivy): distinguish inherited injectable defs by token (#30855)
In older browsers such as IE10, inheritance of static properties on class
types is implemented by copying the properties. This makes hasOwnProperty
unreliable for checking if a static property is defined directly on a class
or is inherited. This causes problems when trying to read the
ngInjectableDef properties of inherited services, as in IE10 even inherited
definitions will appear to be local.

Instead, the 'token' property on ngInjectableDef can be leveraged to detect
when a definition is read which doesn't belong to the type itself.

PR Close #30855
2019-06-11 14:27:16 -07:00
a4b4f35533 feat(ivy): require 'token' for ngInjectableDef (#30855)
The compiler generates a 'token' field when it emits an ngInjectableDef,
but this field was not required by defineInjectable or the InjectableDef
interface, nor was it added by InjectionToken.

This commit makes 'token' required and adds it where missing.

PR Close #30855
2019-06-11 14:27:16 -07:00
b0866769b0 fix(bazel): do not modify tsconfig.json (#30877)
Before this change, user's tsconfig.json is cloned and some options
controlled by Bazel are removed otherwise Bazel would complain about:

```
WARNING: your tsconfig.json file specifies options which are overridden by Bazel:
 - compilerOptions.target and compilerOptions.module are controlled by downstream dependencies, such as ts_devserver
 - compilerOptions.typeRoots is always set to the @types subdirectory of the node_modules attribute
 - compilerOptions.rootDir and compilerOptions.baseUrl are always the workspace root directory
```

Since the warning has been removed in rules_typescript/8d8d398, there's no
need to clone and backup tsconfig.json

PR Close #30877
2019-06-11 14:23:00 -07:00
699283c4ee feat(docs-infra): layout ui polish (#30883)
PR Close #30883
2019-06-11 14:20:35 -07:00
bb635c09fd docs: use const in dynamic-component-loader example (#30888)
Use const instead of let. Some of the variables are never reassigned, so it is preferred to use const over let

PR Close #30888
2019-06-11 14:20:00 -07:00
c15e6750d5 docs: fix a grammar mistake (#30949)
Grammar mistake is in the JsonPipe section
PR Close #30949
2019-06-11 14:19:16 -07:00
87bf1791a9 build(docs-infra): upgrade cli command docs sources to 9d13ba4b6 (#30970)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](c21c3c4f2...9d13ba4b6):

**Modified**
- help/build.json
- help/generate.json
- help/new.json
- help/serve.json
- help/test.json

##

PR Close #30970
2019-06-11 14:18:35 -07:00
8c4bd61b2f test(core): add missing static flag to view_insertion test view queries (#30967)
17d87d4e10 has been created before the changes
to the `@ViewChild` and `@ContentChild` decorators. Meaning that it still uses the queries
without the `static` flag. This results in failures in `master` because #30625 has been merged.

PR Close #30967
2019-06-11 09:37:19 -07:00
230e9766f6 test(ivy): fix strict null checks failures in ngcc tests (#30967)
9d9c9e43e5 has been created a few days ago
and wasn't rebased on top of recent changes that introduces a commonjs host.

This means that tests for the commonjs host haven't been updated to work with
the changes from from #30492 and now fail in `master`.

PR Close #30967
2019-06-11 09:37:19 -07:00
2b4d5c7548 fix(ivy): ngcc should process undecorated base classes (#30821)
Currently undecorated classes are intentionally not processed
with ngcc. This is causing unexpected behavior because decorator
handlers such as `base_def.ts` are specifically interested in class
definitions without top-level decorators, so that the base definition
can be generated if there are Angular-specific class members.

In order to ensure that undecorated base-classes work as expected
with Ivy, we need to run the decorator handlers for all top-level
class declarations (not only for those with decorators). This is similar
to when `ngtsc` runs decorator handlers when analyzing source-files.

Resolves FW-1355. Fixes https://github.com/angular/components/issues/16178

PR Close #30821
2019-06-11 00:19:34 +00:00
271d2b51a9 fix(ivy): ngcc - prevent crash for packages without "main" property (#30950)
When determining the module type of a bundle pointed to by the "main"
property, ngcc needs to read the bundle to figure out if it is CommonJS
or UMD format. However, when the "main" property does not exist ngcc
would crash while determining the path to the main bundle file.

This commit fixes the crash by checking if the "main" property is present
at all, before attempting to derive a full path to the bundle file.

Fixes #30916
Fixes FW-1369

PR Close #30950
2019-06-11 00:12:03 +00:00
7b0bee73de build(docs-infra): update @angular/* to v8.1.0-next.1 and @angular/material to v8.0.0 (#30935)
PR Close #30935
2019-06-11 00:11:36 +00:00
c9ce485ce0 build(docs-infra): update @angular/cli to v8.0.2 (#30935)
This restores named lazy chunks, which were broken during beta/rc (i.e.
the lazy chunks were named 0/1/2/...).

PR Close #30935
2019-06-11 00:11:36 +00:00
ba4ca5f9a5 docs: use Node.js consistently (#30934)
PR Close #30934
2019-06-11 00:09:49 +00:00
4155ed439a fix(ivy): correctly set TView.firstChild with runtime i18n (#30920)
`TView.firstChild` was defined as the first node with index 0, but when we use runtime i18n then the instruction `i18nStart` can be the one with index 0 and the first node will be index 1 or more.
With this fix we set `TView.firstChild` when we see the first node with index 0 or later if `TView.firstChild` is still null.

FW-1367 #resolve
PR Close #30920
2019-06-11 00:09:32 +00:00
2b9a4cc6a6 refactor(ivy): remove repeated getLView() calls (#30918)
PR Close #30918
2019-06-11 00:09:08 +00:00
016b3f16a3 refactor(ivy): improve debug message for assertDataInRange (#30918)
PR Close #30918
2019-06-11 00:09:08 +00:00
87b1a2af4d refactor(docs-infra): avoid hard-coding URLs to redirect on archive mode (#30894)
Related discussion:
https://github.com/angular/angular/pull/30894#pullrequestreview-246731995

PR Close #30894
2019-06-11 00:07:43 +00:00
a2cd401a2e fix(docs-infra): do not redirect docs URLs on archive deployments (#30894)
To avoid showing outdated info (such as events, resources, etc.) but
still allow people to see docs for older versions, we redirect
non-documentation URLs to `/docs`. Recently(-ish) we have added
documentation content under the `/cli/...` and `/start/...`
path-prefixes, but we haven't added them to the list of documentation
URLs that should not be redirected. As a result, on archive deployments
(e.g. https://v7.angular.io/cli), they are redirected to `/docs`, making
it impossible to see the documentation for these versions (unless you
know about the `?mode=stable` work-around).

This commit fixes it by adding `cli` and `start` to the list of
documentation URLs that are excluded from redirection.

PR Close #30894
2019-06-11 00:07:42 +00:00
93af1f8456 refactor(docs-infra): make archive redirection tests DRY (#30894)
PR Close #30894
2019-06-11 00:07:42 +00:00
5193acb0a3 build: set symlink_node_modules = False for yarn_install in main WORKSPACE and bazel schematics (#30627)
This is needed to work-around issue: yarn_install & npm_install with managed directories can't handle deleted or manually regenerated node_modules folder [https://github.com/bazelbuild/rules_nodejs/issues/802]
Underlying issue has been fixed in Bazel https://github.com/bazelbuild/bazel/issues/8487 but hasn't landed in a release yet

PR Close #30627
2019-06-11 00:03:11 +00:00
532c1cb485 build: update to Bazel 0.26.1 (#30627)
PR Close #30627
2019-06-11 00:03:11 +00:00
ef0b2cc74d build: convert entry_point to label (#30627)
PR Close #30627
2019-06-11 00:03:11 +00:00
a794143820 build(bazel): update to nodejs rules 0.31.1 (#30627)
* entry_point attribute of nodejs_binary & rollup_bundle is now a label
* symlinking of node_modules for yarn_install temporarily disabled (except for integration/bazel) until the fix for https://github.com/bazelbuild/bazel/issues/8487 makes it into a future bazel release

PR Close #30627
2019-06-11 00:03:11 +00:00
ba83d33dd0 build(bazel): update to nodejs rules 0.30.1 & bazel 0.26.0 (#30627)
nodejs rules 0.30.1 has new feature to symlink node_modules with yarn_install and bazel 0.26.0 includes new managed_directories feature which enables this

PR Close #30627
2019-06-11 00:03:11 +00:00
17d87d4e10 test(ivy): Add acceptance tests for view insertion (#30625)
This work is being done ahead of changes to how view insertion is done in Ivy in accordance with [this design document](https://hackmd.io/Ae3W_2pOQlKouu9YNy1t6A?view).

The idea is to make sure we have acceptance tests ahead of that change.

PR Close #30625
2019-06-10 23:53:34 +00:00
9d9c9e43e5 feat(ivy): static evaluation of TypeScript's __spread helper (#30492)
The usage of array spread syntax in source code may be downleveled to a
call to TypeScript's `__spread` helper function from `tslib`, depending
on the options `downlevelIteration` and `emitHelpers`. This proves
problematic for ngcc when it is processing ES5 formats, as the static
evaluator won't be able to interpret those calls.

A custom foreign function resolver is not sufficient in this case, as
`tslib` may be emitted into the library code itself. In that case, a
helper function can be resolved to an actual function with body, such
that it won't be considered as foreign function. Instead, a reflection
host can now indicate that the definition of a function corresponds with
a certain TypeScript helper, such that it becomes statically evaluable
in ngtsc.

Resolves #30299

PR Close #30492
2019-06-10 23:53:04 +00:00
c0386757b1 refactor(ivy): inherently call ɵɵselect(0) (#30830)
- Refactors compiler to stop generating `ɵɵselect(0)` instructions
- Alters template execution to always call the equivalent of `ɵɵselect(0)` before running a template in update mode
- Updates tests to not check for or call `ɵɵselect(0)`.

The goal here is to reduce the size of generated templates

PR Close #30830
2019-06-07 08:48:31 -07:00
5c18f23788 fix(common): expose the HttpUploadProgressEvent interface as public API (#30852)
Fixes #30814

PR Close #30852
2019-06-07 08:47:47 -07:00
7afd2603c9 docs: add dev.to link to the help section (#30873)
PR Close #30873
2019-06-07 08:47:01 -07:00
81c2a94310 fix(service-worker): avoid uncaught rejection warning when registration fails (#30876)
Service worker API `navigator.serviceWorker.register` can fail in multiple ways.
For example, in Chrome, with an unstable network connection you can have the
following error: `An unknown error occurred when fetching the script.`

In the current state, it creates an `Uncaught (in promise) TypeError:` style of
error, which cannot be caught by the user on his own.

I think it's better to log the error over raising an error that cannot be
caught.

PR Close #30876
2019-06-07 08:46:25 -07:00
297222f892 build(docs-infra): fail hard if the CLI source is not what we expect (#30901)
Previously we just logged a warning but we should fail
to prevent silently allowing the docs to look wrong if
something changes on the CLI side of things.

PR Close #30901
2019-06-07 08:45:47 -07:00
64488b12ac build(docs-infra): upgrade cli command docs sources to c21c3c4f2 (#30908)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](2bbd7f288...c21c3c4f2):

**Modified**
- help/serve.json

##

PR Close #30908
2019-06-07 08:45:10 -07:00
8b6fbf8655 build(docs-infra): remove unneeded allowEmptyCodegenFiles option in Ivy mode (#30911)
Previously, when switching to Ivy mode (e.g. to run tests on CI), we had
to add `allowEmptyCodegenFiles: true` to the `angularCompilerOptions` in
`tsconfig.app.json`.

This isn't necessary any more (potentially since we switched to dynamic
imports for loading lazy modules in #30704), so this commit removes it
from the `switch-to-ivy.js` script.

PR Close #30911
2019-06-07 08:43:49 -07:00
383ab8515d feat(docs-infra): white background and corresponding figure updates (#28396)
PR Close #28396
2019-06-06 13:48:15 -07:00
11a4454ab3 perf(ivy): remove check for function type in renderStringify (#30838)
The `renderStringify` function shows up pretty high in the CPU profiling.
Turns out that this function contained unnecessary `typeof` check for
function types - the check only makes sense / is used in error messages.

The PR also alligns how ivy and view engine stringify functions used in
interpolations.

PR Close #30838
2019-06-06 13:47:41 -07:00
04587a33c5 fix(ivy): DebugNode.attributes not preserving attribute name casing (#30864)
In Ivy the `DebugNode.attributes` is populated directly from the DOM, but the problem is that the browser will lowercase all attribute names. These changes preserve the case by first going through the `TNode.attrs`, populating the map with the case-sensitive names and saving a reference to the lower case name. Afterwards when we're going through the attributes from the DOM, we can check whether we've mapped the attribute by its case-sensitive name already.

This PR resolves FW-1358.

PR Close #30864
2019-06-06 13:47:16 -07:00
b4b7af86c2 fix(ivy): trigger directive inputs for each template creation (#30870)
A directive input that doesn't use a binding is triggered during the creation phase. But this was only executed at the first template pass, and not on subsequent ones.
Now only the creation of the update instruction is executed on the first template pass, anything else is executed every time a template is created.

FW-1361 #resolve
PR Close #30870
2019-06-06 13:46:40 -07:00
f440bd1793 build(docs-infra): fix CLI command github links (#30889)
The "view" links were broken because the version used to
compute the git tag for the GitHub URL included a build SHA.
Now we clean that off before using it in the URL.

The links are to the JSON schema that defines the documentation for
the command. This is accurate but confusing because the content for the
long description is stored in a separate markdown file referenced from this
schema file.
This commit adds a second set of links for the long description, if it exists,
which links directly to the markdown file.

Closes #30700

PR Close #30889
2019-06-06 08:49:37 -07:00
3859bcc70c refactor(ivy): remove ɵɵelementAttribute instruction (#30640)
PR Close #30640
2019-06-05 21:29:38 -07:00
30efb6b8ea fix(ivy): don't project removed placeholders with runtime i18n (#30783)
When translated content was projected, all of the content was reappended, even the placeholders that had been removed in the translation.
To avoid that we added a new flag on `TNode` that specifies that a node is detached, in which case it should be ignored by the projection.

FW-1319 #resolve
PR Close #30783
2019-06-05 21:28:39 -07:00
05a43ca869 fix(bazel): exclude components schematics from build (#30825)
See https://github.com/angular/components/issues/16189

Without this, bazel attempts to build schematics templates as srcs

PR Close #30825
2019-06-05 21:27:46 -07:00
b51d8dd438 fix(ivy): error for empty bindings on ng-template (#30829)
Fixes Ivy throwing an error if it runs into an empty property binding on an `ng-template` (e.g. `<ng-template [something]=""></ng-template>`) by not generating an update instruction for it.

Fixes #30801.
This PR resoves FW-1356.

PR Close #30829
2019-06-05 21:26:13 -07:00
ea2d453118 fix(ivy): ngcc - use spaces in overwritten package.json content for readability (#30831)
When ngcc processes an entrypoint, it updates `package.json` with
metadata about the processed format. Previously, it overwrote the
`package.json` with the stringified JSON object without spaces. This
made the file difficult to read (for example when looking at the file
while debugging an ngcc failure).

This commit fixes it by using spaces in the new `package.json` content.

PR Close #30831
2019-06-05 21:22:49 -07:00
17bfedd224 fix(bazel): Load global stylesheet in dev and prod (#30879)
Global stylesheet should be injected as a <link> tag in index.html for
both dev and prod app.

PR Close #30879
2019-06-05 21:20:58 -07:00
540b01402f release: cut the v8.1.0-next.1 release 2019-06-05 12:27:26 -07:00
8852b793df build: unable to run build-packages-dist script on windows (#30853)
Currently it's not possible to run the `./scripts/build-packages-dist.sh` script on Windows because
`bazel query` returns CRLF line-endings which result on array expansion in Bazel target names
that end with a carriage return (e.g. `//packages/core\r`). This then results in a build failure where
Bazel complains that target names should not end with a carriage return.

In order to fix this, we just strip off the carriage return line-endings from the bazel query stdout. Ideally
the script will be ported to a plain Node script eventually, but for now it prevents Windows users from
building the release packages and the simple workaround seems reasonable and sufficient.

PR Close #30853
2019-06-05 09:05:28 -07:00
d1df0a94d4 refactor(ivy): remove ɵɵelementProperty instruction (#30645)
- Removes ɵɵelementProperty instruction
- Updates tests that were using it
- NOTE: There is one test under `render3/integration_spec.ts` that is commented out, and needs to be reviewed. Basically, I could not find a good why to test what it was doing, because it was doing things that I am not sure we could generate in an acceptance test.

PR Close #30645
2019-06-05 09:04:43 -07:00
00cc905b98 feat(ivy): support ng-content in runtime i18n translations (#30782)
Added a new syntax for projections (`¤` will represent `ng-content` nodes) so that we can treat them specifically.
When we enter an i18n block with the instruction `i18nStart`, a new `delayProjection` variable is set to true to prevent the instruction `projection` from projecting the nodes. Once we reach the `i18nEnd` instruction and encounter a projection in the translation we will project its nodes.
If a projection was removed from a translation, then its nodes won't be projected at all.
The variable `delayProjection` is restored to `false` at the end of `i18nEnd` so that it doesn't stop projections outside of i18n blocks.

FW-1261 #resolve
PR Close #30782
2019-06-05 09:04:13 -07:00
337b6fe003 build: remove unreferenced tsconfig-build.json files (#30858)
These are no longer needed since Bazel generates a tsconfig for each compilation

PR Close #30858
2019-06-05 09:03:36 -07:00
ef4a15bc0b docs: correct typos and formatting in the Getting Started guide (#30758)
PR Close #30758
2019-06-04 13:37:27 -07:00
0d4f8c7dd9 fix(ivy): allow empty cases for ICU expressions (#30846)
We used to ignore empty strings for optimization purposes, but it turns out that empty strings are also valid values for ICU cases and we shouldn't ignore those.

FW-1290 #resolve
PR Close #30846
2019-06-04 13:36:28 -07:00
b74df20c2a docs(service-worker): mention that HTTPS is required, unless on localhost (#30847)
Fixes #30823

PR Close #30847
2019-06-04 12:03:11 -07:00
4ecff42e7f refactor: Move away from index signature based "updateCache". (#30518)
We're deprecating the index signature overloads in favor of using a Map.

PR Close #30518
2019-06-04 12:02:13 -07:00
55a14e4866 feat(ivy): in ngDevMode use named object literals and arrays for easier debugging/profiling (#30542)
PR Close #30542
2019-06-04 12:01:46 -07:00
c7850fff3b refactor(ivy): rename debug.ts to lview_debug.ts (#30542)
PR Close #30542
2019-06-04 12:01:46 -07:00
456f2e70af fix(ivy): type checking - handle $implicit ng-template variables (#30675)
When an `ng-template` element has a variable declaration without a value,
it is assigned the value of the `$implicit` property in the embedded view's
context. The template compiler inserts a property access to `$implicit` for
template variables without a value, however the type-check code generation
logic did not. This resulted in incorrect type-checking code being generated.

Fixes FW-1326

PR Close #30675
2019-06-04 12:01:18 -07:00
4da5e9a156 fix(ivy): type checking - apply attribute to property name mapping (#30675)
Some HTML attributes don't correspond to their DOM property name, in which
case the runtime will apply the appropriate transformation when assigning
a property using its attribute name. One example of this is the `for`
attribute, for which the DOM property is named `htmlFor`.

The type-checking machinery in ngtsc must also take this mapping into
account, as it generates type-check code in which unclaimed property bindings
are assigned to properties of (subtypes of) `HTMLElement`.

Fixes #30607
Fixes FW-1327

PR Close #30675
2019-06-04 12:01:18 -07:00
812c231b0c docs: update example dependencies to 8.x release (#30755)
PR Close #30755
2019-06-04 11:53:55 -07:00
3ed7463ad7 docs: rename component for constructor example (#30845)
PR Close #30845
2019-06-04 11:52:57 -07:00
8154433130 perf(ivy): limit allocation of LQueries_ objects (#30664)
Before this change we would systematically call LQueries.clone() when executting
elementStart / elementContainerStart instructions. This was often unnecessary as
LQueries can be mutated under 2 conditions only:
- we are crossing an element that has directives with content queries
  (new queries must be added);
- we are descending into element hierarchy (creating a child element of an existing element)
  and the current LQueries object is tracking shallow queries (shallow queries are removed).

With this PR LQueires.clone() is only done when needed and this gratelly reduces number
of LQueries object created: in the "expanding rows" benchmark number of allocated
(and often GCed just after!) LQueries is reduced from ~100k -> ~35k. This represents
over 1MB of memory that is not allocated.

PR Close #30664
2019-06-03 12:01:35 -07:00
07cd65b5ec docs: fix quickstart link in readme (#30807)
PR Close #30807
2019-06-03 11:43:58 -07:00
cd6fc8bf06 docs: document UrlTree in guard return type in cheatsheet (#30822)
Add UrlTree to the types of returned values in guard methods

PR Close #30822
2019-06-03 11:43:25 -07:00
fcdd784667 refactor(core): cleanup code with side-effects which was preventing tree-shaking (#30580)
PR Close #30580
2019-06-03 09:01:51 -07:00
a981dd2aab docs(core): fix typo in style bindings comment (#30661)
PR Close #30661
2019-06-03 09:01:05 -07:00
b4e68025f8 refactor(ivy): add ɵɵupdateSyntheticHostBinding command (#30670)
- Refactors `ɵɵcomponentHostSyntheticProperty` into `ɵɵupdateSyntheticHostBinding`, to better align it with other new instructions.

PR Close #30670
2019-06-03 09:00:13 -07:00
680d38513b fix(ivy): correctly project bare ICU expressions (#30696)
Projecting bare ICU expressions failed because we would assume that component's content nodes would be projected later and doing so at that point would be wasteful. But ICU nodes are handled independently and should be inserted immediately because they will be ignored by projections.

FW-1348 #resolve

PR Close #30696
2019-06-03 08:59:14 -07:00
21328f2373 fix(ivy): add back ngDevMode to r3_injector (#30707)
Import the definition so that it doesn't cause breakage with closure conformance rules.

FW-1307 #resolve

PR Close #30707
2019-06-03 08:57:14 -07:00
dd8cf19352 docs: fix a small typo in injectable decorator description (#30785)
PR Close #30785
2019-06-03 08:56:21 -07:00
8bedf50073 docs: update example references from "my-app" to "app-root" (#30789)
"app" is the default prefix for CLI projects when generating components.
This updates our examples to conform that that default

Closes #19778

PR Close #30789
2019-06-03 08:55:39 -07:00
32886cf9ac docs(docs-infra): compile module first for Ivy when loading element modules (#30704)
In View Engine, NgModule factories are created for each NgModule and loaded when the module is requested. Ivy doesn't generate the
factories by design and only loads the module class, so it must be compiled after being loaded.

PR Close #30704
2019-05-31 15:24:22 -07:00
fcef39048a refactor(docs-infra): update loading of custom elements to use dynamic import syntax (#30704)
Removes the usage of `NgModuleFactoryLoader` and string-based imports for lazy loading.

PR Close #30704
2019-05-31 15:24:22 -07:00
1315d23aa4 docs: increase color contrast on elements in tutorial
This increases the color contrast of elements in the tutorial (parts 1-6)
in order to meet WCAG 2.0 AA standards.
2019-05-31 15:23:32 -07:00
8ce288a852 fix(docs-infra): add v7 in versions dropdown (#30775)
Fixes #30769

PR Close #30775
2019-05-31 15:19:54 -07:00
f936590573 fix(ivy): DebugNode.queryAll matching sibling nodes (#30788)
Inside of `DebugNode.queryAll` we walk through all of the descendants of the node that we're querying against, however the logic that walks sideways through a node siblings also applies to the root node. This means that eventually we'll match against its nodes as well which will give us invalid results. These changes add an extra check to ensure that we aren't matching against the siblings of the root node.

This PR resolves FW-1353.

PR Close #30788
2019-05-31 15:19:18 -07:00
876cd603f1 docs(docs-infra): remove deprecated Buffer usage from stackblitz builder (#30369)
Fixes #30364

PR Close #30369
2019-05-31 09:56:22 -07:00
aca339e864 fix(ivy): unable to project into multiple slots with default selector (#30561)
With View engine it was possible to declare multiple projection
definitions and to programmatically project nodes into the slots.

e.g.

```html
<ng-content></ng-content>
<ng-content></ng-content>
```

Using `ViewContainerRef#createComponent` allowed projecting
nodes into one of the projection defs (through index)

This no longer works with Ivy as the `projectionDef` instruction only
retrieves a list of selectors instead of also retrieving entries for
reserved projection slots which appear when using the default
selector multiple times (as seen above).

In order to fix this issue, the Ivy compiler now passes all
projection slots to the `projectionDef` instruction. Meaning that
there can be multiple projection slots with the same wildcard
selector. This allows multi-slot projection as seen in the
example above, and it also allows us to match the multi-slot node
projection order from View Engine (to avoid breaking changes).

It basically ensures that Ivy fully matches the View Engine behavior
except of a very small edge case that has already been discussed
in FW-886 (with the conclusion of working as intended).

Read more here: https://hackmd.io/s/Sy2kQlgTE

PR Close #30561
2019-05-31 09:52:32 -07:00
f4cd3740b2 fix(docs-infra): update tooltip of events link (#30643)
PR Close #30643
2019-05-31 09:50:45 -07:00
6d861f240b fix(ivy): module with providers are processed too early (#30688)
Currently with Ivy, `ModuleWithProvider` providers are processed in order
of declaration in the `NgModule` imports. This technically makes makes
sense but is a potential breaking change as `ModuleWithProvider` providers
are processed after all imported modules in View Engine.

In order to keep the behavior of View Engine, the `r3_injector` is updated
to no longer process `ModuleWithProvider` providers egarly.

Resolves FW-1349

PR Close #30688
2019-05-31 09:48:39 -07:00
1f79c827a0 build(docs-infra): upgrade cli command docs sources to 2bbd7f288 (#30776)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](30036352e...2bbd7f288):

**Modified**
- help/update.json

##

PR Close #30776
2019-05-31 09:45:58 -07:00
e0c36620c1 test: resotre "async" around tests where "await" is used (#30762)
The "async" around a couple tests was removed because of the merge conflict in one of the previous commits (80394ce08b). This change restores missing "async"s.

PR Close #30762
2019-05-30 23:14:16 -07:00
80394ce08b fix(core): TypeScript related migrations should cater for BOM (#30719)
fix(@schematics/angular): TypeScript related migrations should cater for BOM

In the CLI `UpdateRecorder` methods such as `insertLeft`, `remove` etc.. accepts positions which are not offset by a BOM. This is because when a file has a BOM a different recorder will be used https://github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts#L72 which caters for an addition offset/delta.

The main reason for this is that when a developer is writing a schematic they shouldn't need to compute the offset based if a file has a BOM or not and is handled out of the box.

Example
```ts
recorder.insertLeft(5, 'true');
```

However this is unfortunate in the case if a ts SourceFile is used and one uses `getWidth` and `getStart` method they will already be offset by 1, which at the end it results in a double offset and hence the problem.

Fixes #30713

PR Close #30719
2019-05-30 20:48:45 -07:00
99c9bcab03 test: move away from deprecated testing method (#30747)
Switches all of the tests away from the `runSchematic` method which was deprecated in 8.0 (see https://github.com/angular/angular-cli/pull/14412). Along the same lines as https://github.com/angular/components/pull/16150.

PR Close #30747
2019-05-30 20:46:48 -07:00
fa354888b1 ci: add reviewer group for deprecations guide (#30722)
PR Close #30722
2019-05-30 20:45:58 -07:00
d82adbe8c4 fix(ivy): align DebugNode/DebugElement behavior with View Engine (#30756)
Two issues with DebugNode/DebugElement in Ivy were causing problems in user
tests.

1. The DebugNodes returned by Ivy were not actually instances of DebugNode.

This was due to an issue with the Ivy switch logic in debug_node.ts.
The declaration of the exported DebugNode reference was set to
`DebugNode__PRE_R3__ as any`. The cast prevented the Ivy switch transform
from detecting this as a switchable declaration. The transform cannot handle
arbitrary syntax, and exports *must* be of the form "const x = y__PRE_R3__;"
or they will not work. The cast to any in this case was not needed, so this
commit removes it.

2. DebugNodes returned by Ivy multiple times for the same element were not
reference-identical. This was previously considered a minor breaking change
in Ivy, but testing has shown that users depend on referential equality of
DebugNodes. This commit caches a DebugNode on a DOM node when first creating
it, to allow returning the same instance in subsequent operations.

PR Close #30756
2019-05-30 20:45:31 -07:00
09c57ecf95 docs: add final release date and update future schedule (#30712)
PR Close #30712
2019-05-30 19:39:23 -07:00
282abdb02d release: cut the v8.1.0-beta.0 release 2019-05-30 14:31:57 -07:00
19bbf4bc8e test(ivy): fix sanitization state leaking issue
Due to sanitization being stored as a temp/global value between
instructions, unit tests randomly failed because one test failed
to clean up its temporary value. This patch fixes this issue.
2019-05-30 13:53:06 -07:00
53c6b78c51 feat(ivy): add AttributeMarker.I18n for i18n attributes (#30402)
`i18nAttributes` instructions always occur after the element instruction. This means that we need to treat `i18n-` attributes differently.
By defining a specific `AttributeMarker` we can ensure that we won't trigger directive inputs with untranslated attribute values.

FW-1332 #resolve
PR Close #30402
2019-05-30 16:39:24 -04:00
91699259b2 fix(ivy): trigger directive inputs with i18n translations (#30402)
Changed runtime i18n to define attributes with bindings, or matching directive inputs/outputs as element properties as we are supposed to do in Angular.
This PR fixes the issue where directive inputs wouldn't be trigged.

FW-1315 #resolve
PR Close #30402
2019-05-30 16:39:24 -04:00
41f372fe79 ci: fix payload limits value 2019-05-30 12:54:39 -07:00
8e8c1ad47d refactor(ivy): name LQuery object for easier memory allocation tracking (#30656)
PR Close #30656
2019-05-30 15:17:30 -04:00
b61784948a fix(ivy): template inputs/outputs should not be bound in template scope (#30669)
The R3TargetBinder "binds" an Angular template AST, computing semantic
information regarding the template and making it accessible.

One of the binding passes previously had a bug, where for the following
template:

<div *ngIf="foo as foo"></div>

which desugars to:

<ng-template ngIf [ngIf]="foo" let-foo="ngIf">
  <div></div>
</ng-template>

would have the `[ngIf]` binding processed twice - in both the scope which
contains the `<ng-template>` and the scope inside the template. The bug
arises because during the latter, `foo` is a variable defined by `let-foo`,
and so the R3TargetBinder would incorrectly learn that `foo` inside `[ngIf]`
maps to that variable.

This commit fixes the bug by only processing inputs, outputs, and
templateAttrs from `Template`s in the outer scope.

PR Close #30669
2019-05-30 15:17:07 -04:00
b4644d7bb0 fix(ivy): correct timing of NgModuleFactory registration (#30706)
Commit 0df719a46 introduced registration of NgModules with ids when compiled
with AOT, and f74373f2d corrected the timing to avoid issues with tree
shaking. Neither of these approaches were correct.

This commit fixes the timing to match View Engine and avoid tree shaking
issues, as well as fixes a bug with the registration of imported module ids.

A new Ivy-only test is added which verifies that modules get registered
correctly under real-world conditions.

PR Close #30706
2019-05-30 15:13:20 -04:00
7a0f8ac36c fix(ivy): generate explicit type annotation for NgModuleFactory calls in ngfactories (#30708)
Prior to this commit there were no explicit types setup for NgModuleFactory calls in ngfactories, so TypeScript inferred the type based on a given call. In some cases (when generic types were used for Components/Directives) that turned out to be problematic, so we add explicit typing for NgModuleFactory calls.

PR Close #30708
2019-05-30 15:09:56 -04:00
5e0f982961 feat(ivy): use i18n locale data to determine the plural form of ICU expressions (#29249)
Plural ICU expressions depend on the locale (different languages have different plural forms). Until now the locale was hard coded as `en-US`.
For compatibility reasons, if you use ivy with AOT and bootstrap your app with `bootstrapModule` then the `LOCALE_ID` token will be set automatically for ivy, which is then used to get the correct plural form.
If you use JIT, you need to define the `LOCALE_ID` provider on the module that you bootstrap.
For `TestBed` you can use either `configureTestingModule` or `overrideProvider` to define that provider.
If you don't use the compat mode and start your app with `renderComponent` you need to call `ɵsetLocaleId` manually to define the `LOCALE_ID` before bootstrap. We expect this to change once we start adding the new i18n APIs, so don't rely on this function (there's a reason why it's a private export).
PR Close #29249
2019-05-30 15:09:02 -04:00
f5b0c8a323 docs: remove mention of project settings from analytics (#30701)
This settings are not yet implemented and will be available in 8.1.

PR Close #30701
2019-05-30 13:42:34 -04:00
d2b0ac7de8 docs(ivy): fix symbol in example AST (#30745)
PR Close #30745
2019-05-30 13:41:52 -04:00
a2d26c6f2a docs: improve glossary for entry-point. (#29433)
PR Close #29433
2019-05-30 13:40:55 -04:00
62332b80da docs: fix typo in upgrade guide example (#30428)
An code snippet from a `package.json` file used `script`
rather than `scripts`.

Fixes #30418

PR Close #30428
2019-05-30 13:40:06 -04:00
e3f3b106ac docs(ivy): improve debug documentation (#30562)
PR Close #30562
2019-05-30 13:39:44 -04:00
fd23663a29 docs: fix closing tags in deprecation summary (#30735)
fix closing tags in "Cannot assign to template variables" section

PR Close #30735
2019-05-30 13:38:54 -04:00
71be1da0ad docs: fix deprecation information (#30717)
PR Close #30717
2019-05-30 13:38:34 -04:00
6a5cc8f95c docs: merge duplicated platform-webworker content in Deprecation Guide (#30651)
fix issue of duplicate anchors/ids

PR Close #30651
2019-05-30 13:36:30 -04:00
2c406fb1a9 docs(elements): move clarification about custom elements (#30594)
Moved clarification that "custom elements" are a subtype of Web Components to the first use of the term "custom elements"

PR Close #30594
2019-05-30 13:35:15 -04:00
0b23adca80 docs(common): fix typo in ngSwitch directive description (#30483)
PR Close #30483
2019-05-30 13:34:22 -04:00
671f64324b ci: remove buildkite setup (#30510)
We don't use it anymore and it's pretty stable by now.

PR Close #30510
2019-05-30 13:33:34 -04:00
f1f8d70a41 ci: remove msys workaround (#30510)
Verified it isn't a problem anymore https://github.com/docker/for-win/issues/2920

PR Close #30510
2019-05-30 13:33:34 -04:00
8301028319 ci: add descriptive titles to Codefresh steps (#30510)
PR Close #30510
2019-05-30 13:33:34 -04:00
ba5309c1f8 ci: describe next steps for Bazel cache on Windows CI (#30510)
PR Close #30510
2019-05-30 13:33:34 -04:00
fa5d8ca041 ci: do not override bazel action_env on Windows (#30510)
Fix #27514

PR Close #30510
2019-05-30 13:33:34 -04:00
24ca8ba7ce docs: fix the sequence of creating class in HTTP tutorial (#30566)
For more accurate procedure of creating a class in the "Tour of Heroes" app, updated the sequence of creating one class.

PR Close #30566
2019-05-30 13:32:52 -04:00
af4925f374 docs: clarify usage of using /deep/ in component styles guide (#30452)
Updated the description regarding the (deprecated) /deep/ pseudo-selector to clarify its propensity to bleed styles across components and its solution

closes #29967

PR Close #30452
2019-05-30 13:32:31 -04:00
77578266fd docs: code sample closing in ivy.md (#30711)
PR Close #30711
2019-05-30 13:32:11 -04:00
7bf7244ba3 docs(changelog): cleanup 8.0.0 release notes (#30740)
The removal of @angular/http is now mentioned under breaking changes.

This removes several duplicate entries from the changelog and removes
long and incorrect "closes" links to sources on Github. Those links were
present in the commit message and are incorrectly seen as issue references.

Additionally, code references are wrapped in backticks for proper formatting.

PR Close #30740
2019-05-30 13:31:46 -04:00
1a98d51f98 docs: change wording for more clarity in TypeScript Configuration guide (#30748)
"You need to do nothing" indicates the presence of an action (the action of doing nothing) while the goal is to tell the user that no action is required from them. I think "You don’t need to do anything" is better suitable in this context.

PR Close #30748
2019-05-30 13:31:23 -04:00
82682bb93f refactor(ivy): enable sanitization support for the new styling algorithm (#30667)
This patch is one of the final patches to refactor the styling algorithm
to be more efficient, performant and less complex.

This patch enables sanitization support for map-based and prop-based
style bindings.

PR Close #30667
2019-05-30 01:03:39 -04:00
d72479b628 docs(core): template-var-assignment schematic should link to deprecation guide (#30702)
Instead of linking to a markdown file explaining what the migration warnings
are about, we should link to the deprecation guide which now also contains
an entry for that schematic. This makes the deprecation explanations
consistent and more centralized.

PR Close #30702
2019-05-29 13:50:34 -04:00
dd0815095f feat(ivy): add ɵɵtextInterpolateX instructions (#30011)
- `ɵɵtextBinding(..., ɵɵinterpolationX())` instructions will now just be `ɵɵtextInterpolate(...)` instructions

PR Close #30011
2019-05-29 12:38:58 -04:00
48093823cb docs: add note to platform-webworker deprecation (#30705)
PR Close #30705
2019-05-28 16:37:58 -07:00
51cb5925c5 release: cut the v8.0.0 release 2019-05-28 16:22:00 -07:00
a36cacae79 docs: remove core.module.ts from file tree in style guide (#30679)
PR Close #30679
2019-05-28 09:27:49 -07:00
1b5096d5a9 docs: add missing preposition (#30691)
You need do nothing -> You need to do nothing
PR Close #30691
2019-05-28 09:27:23 -07:00
875eedbfb0 docs: add default AOT to migrating projects to Ivy (#30697)
Followup to https://github.com/angular/angular/pull/29380, https://github.com/angular/angular/pull/30238, https://github.com/angular/angular-cli/pull/14537.

PR Close #30697
2019-05-28 09:27:02 -07:00
75cdda5f0a docs: fix typo in a declaration alert (#30545)
Co-Authored-By: CaerusKaru <caerus.karu@gmail.com>
PR Close #30545
2019-05-28 09:25:10 -07:00
6363db89d0 docs: add dynamic import allowed syntax to the deprecation guide (#30545)
PR Close #30545
2019-05-28 09:25:10 -07:00
573f57ac90 build(docs-infra): upgrade cli command docs sources to 30036352e (#30608)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](f960a8e4a...30036352e):

**Modified**
- help/analytics.json
- help/build.json
- help/e2e.json
- help/serve.json
- help/test.json
- help/xi18n.json

##

PR Close #30608
2019-05-24 18:18:50 -04:00
41cf066906 test: improve language service tests performance (#30585)
With this change we reduce the amount of IO operations. This is especially a huge factor in windows since IO ops are slower.

With this change mainly we cache `existsSync` and `readFileSync` calls

Here's the results

Before
```
//packages/language-service/test:test
INFO: Elapsed time: 258.755s, Critical Path: 253.91s
```

After
```
//packages/language-service/test:test
INFO: Elapsed time: 66.403s, Critical Path: 63.13s
```

PR Close #30585
2019-05-24 18:17:21 -04:00
661c6e6f10 fix(ivy): fix PR collision with static: true and new test (#30666)
This fixes a collision between #30639 and #30543 where the latter added
usages of @ViewChild without the static flag present, but the former
made the flag required.

PR Close #30666
2019-05-24 18:02:17 -04:00
84dd2679a9 fix(core): require 'static' flag on queries in typings (#30639)
This commit makes the static flag on @ViewChild and @ContentChild required.

BREAKING CHANGE:

In Angular version 8, it's required that all @ViewChild and @ContentChild
queries have a 'static' flag specifying whether the query is 'static' or
'dynamic'. The compiler previously sorted queries automatically, but in
8.0 developers are required to explicitly specify which behavior is wanted.
This is a temporary requirement as part of a migration; see
https://angular.io/guide/static-query-migration for more details.

@ViewChildren and @ContentChildren queries are always dynamic, and so are
unaffected.

PR Close #30639
2019-05-24 16:55:00 -04:00
dc6406e5e8 refactor(ivy): evaluate map-based styling bindings with a new algorithm (#30543)
This patch in the second runtime change which refactors how styling
bindings work in Angular. This patch refactors how map-based
`[style]` and `[class]` bindings work using a new algorithm which
is faster and less complex than the former one.

This patch is a follow-up to an earlier refactor which enabled
support for prop-based `[style.name]` and `[class.name]`
bindings (see f03475cac8).

PR Close #30543
2019-05-24 14:31:35 -04:00
deb77bd3df feat(ivy): TestBed support for reusing non-exported components (#30578)
This is a new feature of the Ivy TestBed.

A common user pattern is to test one component with another. This is
commonly done by creating a `TestFixture` component which exercises the
main component under test.

This pattern is more difficult if the component under test is declared in an
NgModule but not exported. In this case, overriding the module is necessary.

In g3 (and View Engine), it's possible to use an NgSummary to override the
recompilation of a component, and depend on its AOT compiled factory. The
way this is implemented, however, specifying a summary for a module
effectively overrides much of the TestBed's other behavior. For example, the
following is legal:

```typescript
TestBed.configureTestingModule({
  declarations: [FooCmp, TestFixture],
  imports: [FooModule],
  aotSummaries: [FooModuleNgSummary],
});
```

Here, `FooCmp` is declared in both the testing module and in the imported
`FooModule`. However, because the summary is provided, `FooCmp` is not
compiled within the context of the testing module, but _is_ made available
for `TestFixture` to use, even if it wasn't originally exported from
`FooModule`.

This pattern breaks in Ivy - because summaries are a no-op, this amounts
to a true double declaration of `FooCmp` which raises an error.

Fixing this in user code is possible, but is difficult to do in an
automated or backwards compatible way. An alternative solution is
implemented in this PR.

This PR attempts to capture the user intent of the following previously
unsupported configuration:

```typescript
TestBed.configureTestingModule({
  declarations: [FooCmp, TestFixture],
  imports: [FooModule],
});
```

Note that this is the same as the configuration above in Ivy, as the
`aotSummaries` value provided has no effect.

The user intent here is interpreted as follows:

1) `FooCmp` is a pre-existing component that's being used in the test
   (via import of `FooModule`). It may or may not be exported by this
   module.

2) `FooCmp` should be part of the testing module's scope. That is, it
   should be visible to `TestFixture`. This is because it's listed in
   `declarations`.

This feature effectively makes the `TestBed` testing module special. It's
able to declare components without compiling them, if they're already
compiled (or configured to be compiled) in the imports. And crucially, the
behavior matches the first example with the summary, making Ivy backwards
compatible with View Engine for tests that use summaries.

PR Close #30578
2019-05-24 14:01:44 -04:00
d5f96a887d refactor(ivy): refactor getBeforeNodeForView for readability (#30614)
PR Close #30614
2019-05-24 13:58:43 -04:00
68cd0cab8c fix(ivy): don't throw on unmatched placeholder replacements in i18nPostprocess (#30632)
Depending on which placeholders the translation uses, there are some legitimate cases where we might not use all placeholder replacements in `i18nPostprocess`. For example if some of the placeholders of the original messages have been removed in the translation.

FW-1312 #resolve
PR Close #30632
2019-05-24 13:57:44 -04:00
9b3af1468d docs(bazel): remove out of date known issue with Webstorm (#30650)
https://github.com/bazelbuild/intellij/issues/246 was resolved in 2018

PR Close #30650
2019-05-24 13:51:29 -04:00
be0bc799f3 docs: drop coding conventions from style guide (#30334)
PR Close #30334
2019-05-24 13:46:11 -04:00
0d23cedab8 docs: add Michael Hladky to GDE resources (#30596)
PR Close #30596
2019-05-24 13:40:33 -04:00
6bf5ec241d docs(core): static-query migration should use permalink for migration guide (#30649)
8479cb4233 updated the static-query migration
to refer to the new guide on AIO. Unfortunately these URLs are currently not
valid as the guide is only available on `next.angular.io` right now. In order to
make the link work permanently (e.g. if we eventually remove the guide in future
major versions), we use the permalink from the `v8` subdomain.

PR Close #30649
2019-05-24 10:08:16 -05:00
cdb5ea4200 docs: update link to static queries in changelog (#30649)
PR Close #30649
2019-05-24 10:08:16 -05:00
bfedfa79ed docs: release notes for the v8.0.0-rc.5 release 2019-05-23 22:53:07 -07:00
911a8160ec docs(core): add more info to static query guide (#30646)
PR Close #30646
2019-05-23 22:14:49 -07:00
8479cb4233 docs(core): update static query schematic with guide link (#30646)
PR Close #30646
2019-05-23 22:14:49 -07:00
250887244e docs(core): update deprecations guide (#30644)
PR Close #30644
2019-05-23 16:25:48 -07:00
9b035e4038 docs(core): add migration guide for static queries (#30644)
PR Close #30644
2019-05-23 16:25:48 -07:00
ccc76f7498 feat(platform-webworker): deprecate platform-webworker (#30642)
DEPRECATION:

platform-webworker has been around since the initial release of Angular
version 2. It began as an experiment to leverage Angular's rendering
architecture and try something different: to run an entire web application
in a web worker.

We've learned a lot from this experiment, and have come to the conclusion
that pushing entire applications to run in a web worker is not a recipe for
success for most applications. This is due to a number of unresolved issues,
including:

* Poor or non-existent support for web worker APIs in web crawlers/indexers.
* Poor support in build and bundling tooling.

As a result, as of Angular version 8, we are deprecating the
`platform-webworker` APIs in Angular. This consists of both NPM packages,
`@angular/platform-webworker` and `@angular/platform-webworker-dynamic`.

Going forward, we will focus our efforts related to web workers around their
primary use case of offloading CPU-intensive but not critical work.

FW-1339 #resolve

PR Close #30642
2019-05-23 15:09:48 -07:00
f310a5960e feat(core): deprecate integration with the Web Tracing Framework (WTF) (#30642)
DEPRECATION:

Angular previously has supported an integration with the Web Tracing
Framework (WTF) for performance testing of Angular applications. This
integration has not been maintained and likely does not work for the
majority of Angular applications today. As a result, we are deprecating
the integration in Angular version 8.

This deprecation covers the following public APIs:
* `WtfScopeFn`
* `wtfCreateScope`
* `wtfStartTimeRange`
* `wtfEndTimeRange`
* `wtfLeave`

FW-1338 #resolve

PR Close #30642
2019-05-23 15:09:48 -07:00
b5c893916d docs: add v8 deprecations (#30598)
PR Close #30598
2019-05-23 13:31:13 -07:00
132c61dfd4 refactor(core): static-query migration should warn about syntax failures (#30628)
Currently if a project has source-files with syntax failures and the migration
has been started on a broken project, we silently migrate *as much as possible*,
but never notify the developer that the project was in a broken state and that
he can re-run the migration after the failures are fixed.

Additionally the template strategy does not need to exit gracefully if it detects
Angular semantic diagnostics on generated files (template type checking). These
diagnostics are not relevant for the query timing analysis.

PR Close #30628
2019-05-23 10:31:48 -07:00
5640cedc82 refactor(core): static-query migration should always use template strategy (#30628)
We are removing the prompt for the `static-query` migration and make the
template strategy the migration strategy for the migration. The usage
strategy is good for best-practices, but for now we want to ensure that
the migration is a seamless as possible and that is only achievable my
re-using the same logic that View Engine uses for determining the
timing of a query.

PR Close #30628
2019-05-23 10:31:48 -07:00
faac51fd2e test(core): update query-specific tests in core (#30626)
PR Close #30626
2019-05-23 10:31:32 -07:00
214ae0ea4c test(compiler): update examples and compiler tests (#30626)
PR Close #30626
2019-05-23 10:31:32 -07:00
dcdecfa9a8 test(common): update common tests to use static flag (#30626)
PR Close #30626
2019-05-23 10:31:32 -07:00
4299ecf9be test(core): update core tests (unrelated to queries) to use static flag (#30626)
PR Close #30626
2019-05-23 10:31:32 -07:00
21e8ac1e02 refactor(ivy): createNodeAtIndex no longer depends on L* (#30453)
PR Close #30453
2019-05-23 10:30:59 -07:00
01cf04c85f refactor(ivy): createNodeAtIndex links TNodes on first pass only (#30453)
PR Close #30453
2019-05-23 10:30:59 -07:00
5c5cee9f39 refactor(ivy): t-functions should not depend on l-data (#30453)
PR Close #30453
2019-05-23 10:30:59 -07:00
2f336f15be refactor(core): unify setPreviousOrParentTNode and setIsParent into single setPreviousOrParentTNode (#30453)
PR Close #30453
2019-05-23 10:30:59 -07:00
e122b44269 perf(ivy): clean up findComponentView for speed (#30453)
PR Close #30453
2019-05-23 10:30:59 -07:00
9ce9561737 perf(ivy): clean up createNodeAtIndex for speed (#30453)
PR Close #30453
2019-05-23 10:30:59 -07:00
2545445ffb perf(ivy): extract multiple reads to local var (#30453)
PR Close #30453
2019-05-23 10:30:59 -07:00
300f1b289a fix(ivy): improve assert error message (#30453)
PR Close #30453
2019-05-23 10:30:59 -07:00
975845596d perf(ivy): use string concatination instead template string (#30453)
PR Close #30453
2019-05-23 10:30:58 -07:00
2cdbe9b2ef refactor(ivy): ensure new attribute instructons are available in JIT (#30503)
PR Close #30503
2019-05-22 16:30:29 -07:00
988afad2af refactor(ivy): generate new ɵɵattribute instruction in host bindings (#30503)
PR Close #30503
2019-05-22 16:30:29 -07:00
1537aec1f9 refactor(ivy): extract repetitious code for adding update instructions (#30503)
PR Close #30503
2019-05-22 16:30:29 -07:00
7555a46e23 refactor(ivy): add new attribute interpolation instructions (#30503)
PR Close #30503
2019-05-22 16:30:28 -07:00
38d7acee4d refactor(ivy): add new ɵɵattribute instruction (#30503)
- adds the ɵɵattribute instruction
- adds compilation handling for Δattribute instruction
- updates tests

PR Close #30503
2019-05-22 16:30:28 -07:00
10f48278c2 test(ivy): add attribute interpolation test (#30503)
PR Close #30503
2019-05-22 16:30:28 -07:00
d4e6263453 docs: update simple stackblitz deployment instructions (#30465)
PR Close #30465
2019-05-22 16:29:44 -07:00
86c46908d4 fix(ivy): R3TestBed doesn't allow template overrides with an empty string (#30602)
Prior to this change a component was considered unresolved (i.e. having dynamic resources that should be loaded, like external template or stylesheets) even if template override was provided as an empty string (for example, via TestBed.overrideTemplateUsingTestingModule call). This commit fixes the condition that previously treated empty string as an absent template value.

PR Close #30602
2019-05-22 16:25:56 -07:00
fa6cbb3ffe fix(ivy): ng-container with ViewContainerRef creates two comments (#30611)
With Ivy, injecting a `ViewContainerRef` for a `<ng-container>` element
results in two comments generated in the DOM. One comment as host
element for the `ElementContainer` and one for the generated `LContainer`
which is needed for the created `ViewContainerRef`.

This is problematic as developers expect the same anchor element for
the `LContainer` and the `ElementContainer` in order to be able to move
the host element of `<ng-container>` without leaving the actual
`LContainer` anchor element at the original location.

This worked differently in View Engine and various applications might
depend on the behavior where the `ViewContainerRef` shares the anchor
comment node with the host comment node of the `<ng-container>`. For
example `CdkTable` from `@angular/cdk` moves around the host element of
a `<ng-container>` and also expects embedded views to be inserted next
to the moved `<ng-container>` host element.

See: f8be5329f8/src/cdk/table/table.ts (L999-L1016)

Resolves FW-1341

PR Close #30611
2019-05-22 16:25:22 -07:00
e20b92ba37 feat(ivy): ngcc - turn on CommonJS support (#30200)
PR Close #30200
2019-05-22 16:24:15 -07:00
c7a9987067 feat(ivy): ngcc - implement CommonJsRenderingFormatter (#30200)
PR Close #30200
2019-05-22 16:24:15 -07:00
1bdec3ed6a feat(ivy): ngcc - implement CommonJsDependencyHost (#30200)
PR Close #30200
2019-05-22 16:24:15 -07:00
620cd5c148 feat(ivy): ngcc - implement CommonJsReflectionHost (#30200)
PR Close #30200
2019-05-22 16:24:15 -07:00
76391f8999 fix(ivy): use ReflectionHost in AbsoluteModuleStrategy (#30200)
The AbsoluteModuleStrategy in ngtsc assumed that the source code is
formatted as TypeScript with regards to module exports.

In ngcc this is not always the case, so this commit changes
`AbsoluteModuleStrategy` so that it relies upon a `ReflectionHost`  to
compute the exports of a module.

PR Close #30200
2019-05-22 16:24:14 -07:00
02523debe5 fix(ivy): handle pipes in i18n attributes properly (#30573)
Prior to this change we processed binding expression (including bindings with pipes) in i18n attributes before we generate update instruction. As a result, slot offsets for pipeBind instructions were calculated incorrectly. Now we perform binding expression processing when we generate "update block" instructions, so offsets are calculated correctly.

PR Close #30573
2019-05-22 16:23:18 -07:00
70fd4300f4 test(compiler-cli): compliance tests not always reporting test failure (#30597)
Currently the `@angular/compiler-cli` compliance tests sometimes do
not throw an exception if the expected output does not match the
generated JavaScript output. This can happen for the following cases:

1. Expected code includes character that is not part of known alphabet
    (e.g. `Δ` is still used in a new compliance test after rebasing a PR)
2. Expected code asserts that a string literal matches a string with
    escaped quotes. e.g. expects `const $var$ = "\"quoted\"";`)

PR Close #30597
2019-05-22 16:22:52 -07:00
3125376ec1 fix(bazel): allow ts_library interop with list-typed inputs (#30600)
_compile_action should take a list since we compute it within one node in the build graph
This needs to be cleaned up since Bazel is getting stricter with
disallowing iteration over depsets

PR Close #30600
2019-05-22 16:22:10 -07:00
2cd5294394 docs: add new cli builder api guide (#29964)
PR Close #29964
2019-05-22 16:19:54 -07:00
3c548189b1 docs: update node and typescript versions mentioned in docs (#30601)
PR Close #30601
2019-05-22 16:17:41 -07:00
ae91f45b27 docs: update file structure and workspace config for v8 (#30595)
PR Close #30595
2019-05-22 11:20:18 -07:00
f74e0fd825 refactor(core): migrations should parse cli workspace config as json5 (#30582)
Currently we try to parse CLI workspace configurations gracefully by
using the native `JSON.parse()` method. This means that the CLI workspace
configuration needs to follow the strict JSON specification because otherwise
the migrations would not be able to find TypeScript configurations in the CLI
project where JSON5 workspace configurations are supported.

In order to handle such workspace configurations, we leverage the JSON
parsing logicfrom the `@angular-devkit/core` which is also used by the CLI.

PR Close #30582
2019-05-21 17:26:22 -07:00
f1ea78ba09 build(docs-infra): upgrade cli command docs sources to f960a8e4a (#30530)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](73d875a70...f960a8e4a):

**Modified**
- help/update.json

##

PR Close #30530
2019-05-21 17:09:57 -07:00
87a2366eeb build: update base SHA for rebase on merge-pr script 2019-05-21 17:07:19 -07:00
0f5da82cfd docs: deprecations summary fix api heading level, remove inject, add index by version (#30400)
PR Close #30400
2019-05-21 13:51:26 -07:00
66f269c077 refactor(ivy): rename query-related functions for clarity (#30587)
PR Close #30587
2019-05-21 13:14:15 -07:00
b613f90146 refactor(ivy): avoid calling query instructions from static query instructions (#30587)
PR Close #30587
2019-05-21 13:14:14 -07:00
2fe6f350cb refactor(ivy): avoid repeated read of LView from global state (#30587)
PR Close #30587
2019-05-21 13:14:14 -07:00
514ebf402a refactor(ivy): avoid calling other instructions from the loadViewQuery instruction (#30587)
PR Close #30587
2019-05-21 13:14:14 -07:00
7c0667d215 docs: delete double dashes on ng command in testing guide (#30551)
Closes #30550

PR Close #30551
2019-05-21 13:12:47 -07:00
f6bf8928f2 fix(core): temporarily remove @deprecated jsdoc tag for a TextBed.get overload (#30514)
PR #29290 introduced a new `TestBed.get` signature and deprecated the existing one.
This raises a lot of TSLint deprecation warnings in projects using a strict TS config (see #29905 for context), so we are temporarily removing the `@deprecated` annotation in favor of a plain text warning until we properly fix it.

Refs #29905
Fixes FW-1336

PR Close #30514
2019-05-21 13:11:21 -07:00
6debe9dfb9 docs(docs-infra): add common/upgrade to authors package for API docs (#30567)
This fixes an issue where the common/upgrade packge isn't included
on page reload when changes are made to the common/upgrade package

PR Close #30567
2019-05-21 13:09:09 -07:00
0d52a27f41 docs(common): update API docs for unified location service for upgrading (#30567)
PR Close #30567
2019-05-21 13:09:08 -07:00
697046c2b2 docs: document the PR action: rerun CI at HEAD label in TRIAGE_AND_LABELS.md (#30171)
Related to #29098.

PR Close #30171
2019-05-21 13:07:37 -07:00
53a0b26348 docs: document the PR action: review label in TRIAGE_AND_LABELS.md (#30171)
PR Close #30171
2019-05-21 13:07:37 -07:00
8c00fced1c docs: add info about who adds/removes labels in TRIAGE_AND_LABELS.md (#30171)
PR Close #30171
2019-05-21 13:07:37 -07:00
a50c1bb7bc docs: fix spelling of 'its' (#30455)
PR Close #30455
2019-05-21 13:07:13 -07:00
f3c69e7f6b refactor(ivy): rewrite flatten function to be more memory efficient (#30468)
The `flatten` function used `concat` and `slice` which created a lot of intermediary
object allocations. Because `flatten` is used from query any benchmark which
used query would exhibit high minor GC counts.

PR Close #30468
2019-05-21 13:06:23 -07:00
c9f5f3d802 docs: add section to upgrade guide on lazy loading AngularJS (#30541)
PR Close #30541
2019-05-21 13:06:01 -07:00
a96976e88f fix(core): remove deprecated TestBed.deprecatedOverrideProvider API (#30576)
BREAKING CHANGE

In PR #19558, we fixed a bug in `TestBed.overrideProvider` where
eager providers were not being instantiated correctly. However,
it turned out that since this bug had been around for quite a bit,
many apps were relying on the broken behavior where the providers
would not be instantiated. To assist in the transition, the
`TestBed.deprecatedOverrideProvider` method was temporarily
introduced to mimic the old behavior so that apps would have a
longer time period to migrate their code.

2 years and 3 versions later, it is time to remove the temporary
method. This commit removes `TestBed.deprecatedOverrideProvider`
altogether. Any usages of `TestBed.deprecatedOverrideProvider`
should be replaced with `TestBed.overrideProvider`. This may mean
that providers that were not created before will now be instantiated,
which could mean that your tests need to provide more mocks or stubs
for the dependencies of the newly instantiated providers.

PR Close #30576
2019-05-21 12:37:17 -07:00
ebfbc04000 ci(docs-infra): fix test_docs_examples_ivy job (#30593)
Context:
As part of the `test_docs_examples_ivy` job, we run 5 concurrent builds
on each VM (each for a different example/project). Additionally, all
example projects share the same `node_modules/` (via a symlink to
`aio/tools/examples/shared/node_modules/`), so all concurrent builds
operate on the same files.

Previously, we pre-ran ngcc with `--properties module` to process the
fesm5 bundles. Since we have switched to es2015 in 661a57d9e, we now
need the esm2015 bundles. As a result, the initial ngcc run is
redundant and ngcc runs again during each build (to process the fesm2015
bundles). Since there are 5 concurrent builds, we often end up with
multiple ngcc instances processing the same package and trying to write
to the same directories at the same time, causing a
`file already exists` error

This commit fixes it by pre-processing the esm2015 bundles, so there is
no need to re-run ngcc during each concurrent build.

Fixes #30577

PR Close #30593
2019-05-21 12:32:57 -07:00
e1af6e3c70 docs: use dynamic import syntax in examples using lazy loading (#30563)
PR Close #30563
2019-05-21 09:09:35 -07:00
9e946c9715 docs(changelog): remove docs-infra changes (#25833)
PR Close #25833
2019-05-21 09:06:45 -07:00
0d97143965 docs: correct typo in changelog (#30422)
Fixes #30420

PR Close #30422
2019-05-21 09:06:02 -07:00
df1d3fbd7b perf(ivy): minor cleanup; prevent sparse arrays (#30495)
PR Close #30495
2019-05-21 09:04:39 -07:00
e946594bf8 docs: move instructions to see changes after the error is fixed in the tutorial (#30529)
docs: List only appears after the error is fixed

When the error happens, the list is not displayed too. Once the error is removed, the heroes list appears, so we can click and see the details.

PR Close #30529
2019-05-21 09:03:49 -07:00
abe4433202 test(ivy): add tests around directive attribute ghosting (#30544)
This battery of tests is to ensure the instructions we are generating have the same behavior in Ivy has they did in ViewEngine.

PR Close #30544
2019-05-21 09:03:03 -07:00
c79bffaacb docs: remove gender prefixes from examples (#29972)
PR Close #29972
2019-05-20 16:42:59 -07:00
e58e5ec6a6 docs: improve consistency of style guide example (#30504)
The text for entry Style 04-10 of the style guide talks about
FilterTextService however, the example folder structure has the inversed
filename.

PR Close #30504
2019-05-20 16:42:16 -07:00
e688e02ee4 fix(bazel): ng test should run specific ts_web_test_suite (#30526)
PR closes https://github.com/angular/angular/issues/30191

PR Close #30526
2019-05-20 16:40:11 -07:00
d7eaae6f22 refactor(ivy): Move instructions back to ɵɵ (#30546)
There is an encoding issue with using delta `Δ`, where the browser will attempt to detect the file encoding if the character set is not explicitly declared on a `<script/>` tag, and Chrome will find the `Δ` character and decide it is window-1252 encoding, which misinterprets the `Δ` character to be some other character that is not a valid JS identifier character

So back to the frog eyes we go.

```
    __
   /ɵɵ\
  ( -- ) - I am ineffable. I am forever.
 _/    \_
/  \  /  \
==  ==  ==
```

PR Close #30546
2019-05-20 16:37:47 -07:00
1c3ee41902 docs: move old quick start content into new local setup guide (#29651)
PR Close #29651
2019-05-20 10:16:23 -07:00
f78bda9ff0 build: add recommended config files for VSCode remote development (#30450)
Add some recommended config files to use (as is or as basis) for setting
up [remote development using docker containers][1] with VSCode. This is
an opt-in feature. See `.devcontainer/README.md` for more info.

The configuration can be further tweaked/improved, but is a good
starting point.

[1]: https://code.visualstudio.com/docs/remote/containers

PR Close #30450
2019-05-20 10:13:53 -07:00
6454f76cf6 refactor(ivy): remove ngPrivateData megamorphic prop access (#30548)
PR Close #30548
2019-05-20 10:12:07 -07:00
28ae22ecb9 refactor(ivy): move renderTemplate into render_util.ts because it is only used in tests (#30548)
PR Close #30548
2019-05-20 10:12:07 -07:00
c1135ee18f build: update version to 8.0.0-rc.4 in package.json (#30493)
PR Close #30493
2019-05-17 14:25:01 -07:00
1114053daa build: remove obsolete branchPattern field from package.json (#30493)
PR Close #30493
2019-05-17 14:25:00 -07:00
95830ee584 feat(common): stricter types for SlicePipe (#30156)
Adds overloads to the `transform` methods of `SlicePipe`,
to have better types than `any` for `value` and `any` as a return.
With this commit, using `slice` in an `ngFor` still allow to type-check the content of the `ngFor`
with `fullTemplateTypeCheck` enabled in Ivy:

    <div *ngFor="let user of users | slice:0:2">{{ user.typo }}</div>
                                                        |
                                                        `typo` does not exist on type `UserModel`

whereas it is currently not catched (as the return of `slice` is `any`) neither in VE nor in Ivy.

BREAKING CHANGE
`SlicePipe` now only accepts an array of values, a string, null or undefined.
This was already the case in practice, and it still throws at runtime if another type is given.
But it is now a compilation error to try to call it with an unsupported type.

PR Close #30156
2019-05-17 14:21:36 -07:00
661a57d9e2 docs: update docs example dependencies to version 8 (#30385)
PR Close #30385
2019-05-17 14:16:55 -07:00
660a091f41 ci: increase codefresh memory limit to decrease flakyness of known big tests (#30472)
Such tests are:
```
//packages/language-service/test:test
//packages/bazel/test/ngc-wrapped:ngc_test
```

PR Close #30472
2019-05-17 13:34:11 -07:00
7d31f7b540 ci: include more tests in windows ci (#30472)
We added most of the tests excluded the once which are tagged with `browser:chromium-local` as they are currently not working in CI but work locally.

The `--test_tag_filters` option is now passed via command line as it seems that it has no effect as it is passed in both RC and command line. IE command line options are not merged with the RC options but rather overridden.

PR Close #30472
2019-05-17 13:34:11 -07:00
ab4a23d0e0 ci: update windows docker image for codefresh (#30472)
This commit changes a couple of things

1) Sets the escape character to backtick. Setting the escape character to backtick is especially useful on Windows where `\` is the directory path separator.
2) Install Python since it is a requirement for certain bazel tool chains that are now used.
3) Install VS Build Tools with C++ components as they C++ compilation is required for certain bazel tools chains.
4) Removes Visual C++ Redistributable as it seems that is no longer required because of the VS Builds Tools

PR Close #30472
2019-05-17 13:34:11 -07:00
a39f4e2301 test: fix paths tests to work cross platform (#30472)
In Windows when `/test.txt` is resolved it will be resolved to `[DRIVE]:/test.txt`

PR Close #30472
2019-05-17 13:34:11 -07:00
8e2e9dcee6 test(ivy): move render3 view_container_ref tests to acceptance (#30488)
Moves all manual render3 view_container_ref tests that use property
bindings to acceptance tests with TestBed.

Two issues surfaced and refer to a difference between Ivy and View
engine:

* Multi-slot projection is not working with Ivy: FW-1331
* ViewContainerRef throws if index is invalid while View Engine clamped index: FW-1330

PR Close #30488
2019-05-17 13:33:22 -07:00
9d5abfb3d9 docs: add kamil mysliwiec to GDE resources (#30508)
PR Close #30508
2019-05-17 13:32:44 -07:00
fd7dd4d9fc refactor: clean up language service from unused code and imports (#30534)
PR Close #30534
2019-05-17 13:32:06 -07:00
01919fbaae test(ivy): Add TODOs (#30522)
PR Close #30522
2019-05-17 09:56:49 -07:00
80d4fc5e26 test(ivy): remove new Component use from inheritance tests (#30522)
PR Close #30522
2019-05-17 09:56:49 -07:00
eda09e69ea fix(ivy): ngtsc - do not wrap arguments unnecessarily (#30349)
Previously we defensively wrapped expressions in case they ran afoul of
precedence rules. For example, it would be easy to create the TS AST structure
Call(Ternary(a, b, c)), but might result in printed code of:

```
a ? b : c()
```

Whereas the actual structure we meant to generate is:

```
(a ? b : c)()
```

However the TypeScript renderer appears to be clever enough to provide
parenthesis as necessary.

This commit removes these defensive paraenthesis in the cases of binary
and ternary operations.

FW-1273

PR Close #30349
2019-05-17 09:55:46 -07:00
0937062a64 fix(ivy): type-checking should infer string type for interpolations (#30177)
Previously, interpolations were generated into TCBs as a comma-separated
list of expressions, letting TypeScript infer the type of the expression
as the type of the last expression in the chain. This is undesirable, as
interpolations always result in a string type at runtime. Therefore,
type-checking of bindings such as `<img src="{{ link }}"/>` where `link`
is an object would incorrectly report a type-error.

This commit adjusts the emitted TCB code for interpolations, where a
chain of string concatenations is emitted, starting with the empty string.
This ensures that the inferred type of the interpolation is of type string.

PR Close #30177
2019-05-17 09:55:11 -07:00
6f073885b0 refactor(ivy): translate template nodes to typescript using a visitor (#30177)
PR Close #30177
2019-05-17 09:55:11 -07:00
f03475cac8 refactor(ivy): evaluate prop-based styling bindings with a new algorithm (#30469)
This is the first refactor PR designed to change how styling bindings
(i.e. `[style]` and `[class]`) behave in Ivy. Instead of having a heavy
element-by-element context be generated for each element, this new
refactor aims to use a single context for each `tNode` element that is
examined and iterated over when styling values are to be applied to the
element.

This patch brings this new functionality to prop-based bindings such as
`[style.prop]` and `[class.name]`.

PR Close #30469
2019-05-17 09:54:19 -07:00
848e53efd0 test(platform-browser-dynamic): avoid swallowing error in CachedResourceLoader test (#30515)
Previously, in order to assert that the promise was not resolved, an
error was thrown when the promise was resolved successfully. At the
same, `.catch()` was used to silence the (expected) promise rejection.
However, the chained `.catch()` handler would also catch (and swallow)
the error thrown on resolving the promise, making the test pass, even if
the promise was not rejected.

This commit fixes it by ensuring that the error thrown on resolving the
promise is not caught by the rejection handler.

PR Close #30515
2019-05-16 20:14:04 -07:00
6bf8b1007c test(platform-browser-dynamic): make CachedResourceLoader tests more reliable (#30515)
Previously, [this test][1] would occasionally fail (e.g. on CI) with
"Template cache was not found in $templateCache". This was due to a
combination of:
1. [That test][2] (which removes the cache) being run right before the
   failing test.
2. The async `TestBed.compileComponents()` operation run in the
   `beforeEach()` block (which sets the cache) not having completed
   before the `it()` block.

This commit fixes the issue by ensuring the cache is always set, before
instantiating `CachedResourceLoader`.

This commit also moves some operations that are only needed in one test
from the `beforeEach()` block to that test's `it()` block.

[1]: 79903b1842/packages/platform-browser-dynamic/test/resource_loader/resource_loader_cache_spec.ts (L50)
[2]: 79903b1842/packages/platform-browser-dynamic/test/resource_loader/resource_loader_cache_spec.ts (L37)

Fixes #30499

PR Close #30515
2019-05-16 20:14:03 -07:00
98ded949dd fixup! test(ivy): make the test run with benchpress (#30449)
PR Close #30449
2019-05-16 20:04:04 -07:00
a5a1f4f52f fixup! test(ivy): enableProdMode (#30449)
PR Close #30449
2019-05-16 20:04:03 -07:00
8c1a041411 fixup! test(ivy): rebase, format and lint (#30449)
PR Close #30449
2019-05-16 20:04:03 -07:00
b1ba2d6f4e test(ivy): add expanding_rows performance benchmark which runs in ViewEngine and Ivy (#30449)
PR Close #30449
2019-05-16 20:04:03 -07:00
1714451a6d test(ivy): move integration tests into acceptance (#30461)
Moves most of the tests from `render3/integration_spec` into `acceptance`. Note that there are still a handful of tests left in render3, because we don't have a way of moving all of them to go through `TestBed` since they either have r3-specific assertions or we don't have access to the same APIs as the raw instructions.

PR Close #30461
2019-05-16 14:40:47 -07:00
1f6fcb6cd3 fix(ivy): unable to bind SafeValue to clip-path (#30491)
Fixes not being able to pass in a `SafeValue` to a `clip-path` binding, because `clip-path` wasn't in the list of exceptions.

PR Close #30491
2019-05-16 14:40:21 -07:00
60235b5aef test(ivy): add additional lifecycle hook acceptance tests (#30445)
Moves additional lifecycle hook tests from render3 to acceptance

PR Close #30445
2019-05-16 14:39:22 -07:00
d18c58816f test(ivy): add onChanges acceptance tests (#30445)
- moves render3 tests to acceptance tests.

PR Close #30445
2019-05-16 14:39:22 -07:00
222dde129d test(ivy): add onDestroy acceptance tests (#30445)
Ports render3 onDestroy tests over to be acceptance tests. Removes old render3 tests if possible.

Note the onlyInIvy test for one area where Ivy has a different behavior than ViewEngine

PR Close #30445
2019-05-16 14:39:22 -07:00
257e9646d0 test(ivy): add afterViewInit acceptance tests (#30445)
Migrates afterViewInit and afterViewChecked render3 tests to acceptance tests

PR Close #30445
2019-05-16 14:39:22 -07:00
a5e06ba629 test(ivy): onAfterContentInit acceptance tests (#30445)
- Ports onAfterContentInit tests from render3 to acceptance tests

PR Close #30445
2019-05-16 14:39:22 -07:00
9a6d298ca7 test(ivy): doCheck lifecycle acceptance tests (#30445)
- ports render3 doCheck tests to acceptance tests

PR Close #30445
2019-05-16 14:39:21 -07:00
6ec621b72d test(ivy): onInit lifecycle acceptance tests (#30445)
Ports render3 lifecycle onInit tests to acceptance tests

PR Close #30445
2019-05-16 14:39:21 -07:00
07ebe9624f docs(ivy): document rules for the global state access (#30485)
PR Close #30485
2019-05-16 14:38:46 -07:00
b4014e9a39 build(bazel): update to latest stable chromium 74 on osx and linux for karma under bazel (#30502)
We were on 69 for both of these platforms which is fairly old. This update also requires a temporary patch to the @bazel/karma npm package to disable chrome sandboxing on OSX as it is broken under Bazel as of chromium 73. Windows is still on Chromium 66 but updating this will require upstream changes to rules_webtesting as the archive name & executable name has changed as of 72 for Windows and hard-coded paths in rules_webtesting break things.

PR Close #30502
2019-05-16 14:38:14 -07:00
73e3f565e0 test(ivy): ngcc - fix tests to work on Windows (#30520)
PR Close #30520
2019-05-16 13:32:02 -07:00
757d4c33df refactor(ivy): ngcc - use .has() to check Map membership (#25445)
Previously we were relying upon the `.get()` method to return `undefined`
but it is clearer and safer to always check with `.has()` first.

PR Close #25445
2019-05-16 12:11:05 -07:00
edd775eabc feat(ivy): ngcc - implement UmdDependencyHost (#25445)
The dependency resolution that works out the order in which
to process entry-points must also understand UMD formats.

PR Close #25445
2019-05-16 12:11:04 -07:00
c613596658 fix(ivy): ngcc - separate typings rendering from src rendering (#25445)
Previously the same `Renderer` was used to render typings (.d.ts)
files. But the new `UmdRenderer` is not able to render typings files
correctly.

This commit splits out the typings rendering from the src rendering.
To achieve this the previous renderers have been refactored from
sub-classes of the abstract `Renderer` class to  classes that implement
the `RenderingFormatter` interface, which are then passed to the
`Renderer` and `DtsRenderer` to modify its rendering behaviour.

Along the way a few utility interfaces and classes have been moved
around and renamed for clarity.

PR Close #25445
2019-05-16 12:11:04 -07:00
f4655ea98a feat(ivy): ngcc - turn on UMD processing (#25445)
PR Close #25445
2019-05-16 12:11:04 -07:00
f6aa60c03c feat(ivy): ngcc - implement UmdRenderer (#25445)
PR Close #25445
2019-05-16 12:11:04 -07:00
7fec1771fc feat(ivy): ngcc - implement UmdReflectionHost (#25445)
PR Close #25445
2019-05-16 12:11:04 -07:00
c9b588b349 feat(ivy): ngtsc - support namespaced forwardRef calls (#25445)
In some cases the `forwardRef` helper has been imported via a namespace,
e.g. `core.forwardRef(...)`.

This commit adds support for unwrapping such namespaced imports when
ngtsc is statically evaluating code.

PR Close #25445
2019-05-16 12:11:04 -07:00
37f69eddc7 test(ivy): ngcc - remove unnecessary code (#25445)
PR Close #25445
2019-05-16 12:11:04 -07:00
0fa72a8bc8 refactor(ivy): ngcc - fake core and tslib should be typings files (#25445)
Previously these fake files were full TypeScript source
files (`.ts`) but this is not necessary as we only need the
typings not the implementation.

PR Close #25445
2019-05-16 12:11:04 -07:00
48b77459ef refactor(ivy): ngcc - abstract how module statements are found (#25445)
This will be important for UMD support.

PR Close #25445
2019-05-16 12:11:04 -07:00
989bfd2e97 fix(ivy): ngcc - support namespaced identifiers (#25445)
In UMD formats, imports are always namespaced. This commit makes
ngcc more tolerant of such structures.

PR Close #25445
2019-05-16 12:11:04 -07:00
aeec66b657 test(ivy): enhance the in-memory-typescript helper (#25445)
The `getDeclaration()` function now searches down into the AST for
matching nodes, which is needed for UMD testing.

PR Close #25445
2019-05-16 12:11:04 -07:00
e68490c5e4 test(ivy): fix ESM5 test code to use var rather than const (#25445)
PR Close #25445
2019-05-16 12:11:04 -07:00
95c5b1a7f6 refactor(ivy): use a named type for ImportManager import structures (#25445)
Previously we were using an anonymous type `{specifier: string; qualifier: string;}`
throughout the code base. This commit gives this type a name and ensures it
is only defined in one place.

PR Close #25445
2019-05-16 12:11:03 -07:00
8e201f713a test(ivy): ngcc - check the actual file that is passed to renderImports (#25445)
Previously we were just checking that the object was "any" object but now
we check that it is the file object that we expected.

PR Close #25445
2019-05-16 12:11:03 -07:00
ac34a1429b refactor: remove toplevel property accesses (#29329)
PR Close #29329
2019-05-16 12:08:49 -07:00
739e5a4f53 test: add integration test for side effects (#29329)
This new tests keeps track of the known side effects for Angular ES modules.

PR Close #29329
2019-05-16 12:08:49 -07:00
bf94932c7a docs: add link to location upgrade config (#30331)
PR Close #30331
2019-05-16 11:47:16 -07:00
6cb3b50a03 docs(docs-infra): add common/upgrade to API package sources (#30331)
Closes #30332

PR Close #30331
2019-05-16 11:47:16 -07:00
0e92332491 refactor(common): update argument length in UrlCodec.areEqual method and AngularJSUrlCodec.areEqual methods (#30331)
dgeni requires that method arguments be at least 2 characters long

PR Close #30331
2019-05-16 11:47:16 -07:00
f5127f601d docs: add section to upgrade guide on using the unified location service (#30331)
The LocationUpgradeModule provides a unified way of handling URL updates
across AngularJS and Angular.

PR Close #30331
2019-05-16 11:47:16 -07:00
1b613c3ebf fix(ivy): evaluate external declaration usages as dynamic (#30247)
Previously, ngtsc would fail to evaluate expressions that access properties
from e.g. the `window` object. This resulted in hard to debug error messages
as no indication on where the problem originated was present in the output.

This commit cleans up the handling of unknown property accesses, such that
evaluating such expressions no longer fail but instead result in a `DynamicValue`.

Fixes #30226

PR Close #30247
2019-05-16 11:46:00 -07:00
3f7e823b80 test(ivy): add exhaustive inheritance tests (#30442)
- Adds inheritance tests for many combinations of directive, component and bare class inheritance
- Adds tests that are failing in ivy, but should work, marks them with `xit` and a TODO.
- Removes render3 unit tests that cover the same things.

PR Close #30442
2019-05-16 11:45:17 -07:00
e9ead2bc09 feat(ivy): more accurate type narrowing for ngIf directive (#30248)
A structural directive can specify a template guard for an input, such that
the type of that input's binding can be narrowed based on the guard's return
type. Previously, such template guards could only be methods, of which an
invocation would be inserted into the type-check block (TCB). For `NgIf`,
the template guard narrowed the type of its expression to be `NonNullable`
using the following declaration:

```typescript
export declare class NgIf {
  static ngTemplateGuard_ngIf<E>(dir: NgIf, expr: E): expr is NonNullable<E>
}
```

This works fine for usages such as `*ngIf="person"` but starts to introduce
false-positives when e.g. an explicit non-null check like
`*ngIf="person !== null"` is used, as the method invocation in the TCB
would not have the desired effect of narrowing `person` to become
non-nullable:

```typescript
if (NgIf.ngTemplateGuard_ngIf(directive, ctx.person !== null)) {
  // Usages of `ctx.person` within this block would
  // not have been narrowed to be non-nullable.
}
```

This commit introduces a new strategy for template guards to allow for the
binding expression itself to be used as template guard in the TCB. Now,
the TCB generated for `*ngIf="person !== null"` would look as follows:

```typescript
if (ctx.person !== null) {
  // This time `ctx.person` will successfully have
  // been narrowed to be non-nullable.
}
```

This strategy can be activated by declaring the template guard as a
property declaration with `'binding'` as literal return type.

See #30235 for an example where this led to a false positive.

PR Close #30248
2019-05-16 09:48:40 -07:00
b6b1aec22b fix(bazel): Disable sandbox on Mac OS (#30460)
Removing the sandbox improves build time by almost 40%.

For a hello world (ng new) application:
ng build with sandbox: 22.0 seconds
ng build without sandbox: 13.3 seconds

PR Close #30460
2019-05-16 09:43:54 -07:00
1aff524b63 feat(common): add ability to watch for AngularJS URL updates through onUrlChange hook (#30466)
The LocationShim (replacement for `$location`) was added to centralize dealing with the browser URL. Additionally, an `onUrlChange` method was added to Angular's Location service. This PR adds a corresponding method to the LocationShim so updates from AngularJS can be tracked in Angular.

PR Close #30466
2019-05-16 09:43:32 -07:00
077809398c test: fix compiler tests in windows ci (#30482)
This is a tentative fix for the error `Cannot write file '/node_modules/@angular/core/core.ngfactory.d.ts' because it would overwrite input file.` that is showing in codefresh windows ci.

PR Close #30482
2019-05-16 09:43:01 -07:00
f9404d9e7c refactor: remove unused local imports and use spread instead of slice (#30482)
This is a purly estatic change and a minor cleanup

PR Close #30482
2019-05-16 09:43:01 -07:00
b766987b98 build: remove extra unused deps for compiler:test (#30482)
It's unnecessary for a jasmine_node_test rule to depend on a TypeScript library. This dependency is already satisfied via the 'data' and also having it in 'deps' causes CI flakiness on Windows

PR Close #30482
2019-05-16 09:43:01 -07:00
c62c5e2999 fix(ivy): do not throw if host style is on a template node (#30498)
In View Engine, we would simply ignore host style bindings on template nodes. In Ivy,
we are throwing a "Cannot read length of undefined" error instead. For backwards
compatibility, we should also ignore these bindings rather than blowing up.

PR Close #30498
2019-05-16 09:42:34 -07:00
f2ae452f01 perf(ivy): don't relink the whole tree when TNode exists (#30511)
PR Close #30511
2019-05-16 09:42:01 -07:00
79903b1842 docs: fix typo in animations doc (#30457)
PR Close #30457
2019-05-15 14:26:11 -07:00
0051ddf0f3 docs: correct types in transform method to match specification. (#29812)
PR Close #29812
2019-05-15 14:24:20 -07:00
3a8f74e392 docs: fix example "testing" app compilation (#30427)
PR Close #30427
2019-05-15 14:12:22 -07:00
8555016eec docs: fix the payload in event-binding sample code (#30429)
after reading the context. there are  some clues to infer the payload should be the `item`, not `item.name`.
1.  EventEmitter<Item>.
2.  the desc say that:
The component defines a deleteRequest property that returns an EventEmitter. When the user clicks delete, the component invokes the delete() method, telling the EventEmitter to emit an **Item** object.

PR Close #30429
2019-05-15 14:12:02 -07:00
45e11915dc test(ivy): move render3 query tests to acceptance (#30382)
Moves all manual render3 query tests that use the `elementProperty`
instructions to TestBed acceptance tests.

PR Close #30382
2019-05-15 14:11:38 -07:00
1a0e500eea fix(ivy): support sub-class services that only inherit @Injectable (#30388)
In View engine it is possible to instantiate a service that that has no
`@Injectable` decorator as long as it satisfies one of:

1) It has no dependencies and so a constructor with no parameters.
This is already supported in Ivy.
2) It has no constructor of its own and sub-classes a service which has
dependencies but has its own `@Injectable` decorator. This second
scenario was broken in Ivy.

In Ivy, previous to this commit, if a class to be instantiated did not have
its own `@Injectable` decorator and did not provide a constructor of
its own, then it would be created using `new` with no arguments -
i.e. falling back to the first scenario.

After this commit Ivy correctly uses the `ngInjectableDef` inherited
from the super-class to provide the `factory` for instantiating the
sub-class.

FW-1314

PR Close #30388
2019-05-15 14:10:33 -07:00
35c1750fcc test(ivy): port TemplateRef tests over to acceptance tests (#30443)
- Moves template ref tests from render3 unit tests to acceptance tests.
- Marks tests testing ivy specific changes as `onlyInIvy`.
- Deletes old render3 unit tests that are no longer necessary

PR Close #30443
2019-05-15 14:10:18 -07:00
53f356427f fix(router): type cast correctly for IE 11 bug breaking URL Unification when comparing objects (#30464)
PR #30393 corrected behavior where Object.keys sometimes returns an `undefined` value. However, the types didn't reflect this in the code. That fix actually missed one value that could return `undefined`. This PR corrects this by casting the types to what they can be in IE 11. This ensures the code behaves as it should when this edge case comes up.

PR Close #30464
2019-05-15 14:09:53 -07:00
d20b0f4b93 docs: release notes for the v8.0.0-rc.4 release 2019-05-15 12:49:41 -07:00
79d4b16f8a Revert "Revert "fix(router): fix a problem with router not responding to back button (#30160)" (#30320)" (#30344)
This reverts commit 8ced321bb6.

PR Close #30344
2019-05-15 10:14:47 -07:00
0fd9d086e4 fix(router): ensure navigations start with the current URL value incase redirect is skipped (#30344)
In some cases where multiple navigations happen to the same URL, the router will not process a given URL. In those cases, we fall into logic that resets state for the next navigation. One piece of this resetting is to set the `browserUrlTree` to the most recent `urlAfterRedirects`i.

However, there was bug in this logic because in some cases the `urlAfterRedirects` is a stale value. This happens any time a URL won't be processed, and the previous URL will also not be processed. This creates unpredictable behavior, not the least of which ends up being a broken `back` button.

This PR kicks off new navigations with the current value the router assumes is in the browser. All the logic around how to handle future navigations is based on this value compared to the current transition, so it's important to kick off all new navigations with the current value so in the edge case described above we don't end up with an old value being set into `browserUrlTree`.

Fixes #30340
Related to #30160

PR Close #30344
2019-05-15 10:14:47 -07:00
4f9b16783b refactor(ivy): deprecate ɵɵinject and ɵɵdefineInjectable (#30362)
- They are to be removed before the end of RC

PR Close #30362
2019-05-14 16:52:15 -07:00
018a5168a5 refactor(ivy): mark ΔdefineInjectable as codeGenApi. (#30362)
PR Close #30362
2019-05-14 16:52:15 -07:00
cf86ed7b29 refactor(ivy): migrate ɵɵ prefix back to Δ (#30362)
Now that issues are resolved with Closure compiler, we can move back to our desired prefix of `Δ`.

PR Close #30362
2019-05-14 16:52:15 -07:00
dbb150a9bd Revert "fix(core): CSS sanitizer now allows parens in file names (#30322)" (#30463)
This reverts commit 728db88280.

We're reverting this commit for now, until it can be subjected to a more
thorough security review.

PR Close #30463
2019-05-14 14:49:39 -07:00
9e5377a2e3 refactor(core): improve messages for static-query migrations (#30458)
Slightly improves the messages for the static-query migration in order
to make the terminal output less verbose but more helpful. Unfortunately
we are limited in what we can print due to the devkit not providing much
utilities for printing good messages from a migration schematic.

PR Close #30458
2019-05-14 14:04:44 -07:00
0cdf5980e2 fix(core): static-query migration should not fallback to test strategy (#30458)
Currently if something fails in the selected strategy (e.g. AOT failures),
the migration currently accidentally falls back to the test strategy. This
is not helpful as we want to give developers the possibility to re-run
the migration after fixing potential AOT failures.

PR Close #30458
2019-05-14 14:04:43 -07:00
6ceb9034dc fix(core): static-query migration errors not printed properly (#30458)
Apparently the devkit logger is not able to properly print
out error objects, so we need to convert them to a string
before in order to make the error visible to the user.

This is not testable without an e2e test that validates the CLI
terminal output.

PR Close #30458
2019-05-14 14:04:43 -07:00
f9fb921f91 docs: update ivy preview page (#30355)
PR Close #30355
2019-05-14 12:17:26 -07:00
1b059e595f test(ivy): move common integration tests to acceptance (#30213)
PR Close #30213
2019-05-14 11:37:50 -07:00
ff29cccb77 fix(bazel): Use existing npm/yarn lock files (#30438)
This PR fixes Bazel builder to create yarn_install rule in WORKSPACE if
yarn.lock is present, otherwise npm_install rule if package-lock.json is
present. If none is present, default to yarn_install and create an empty
yarn.lock file.

PR closes https://github.com/angular/angular/issues/30164
PR closes https://github.com/angular/angular/pull/30359

PR Close #30438
2019-05-14 11:37:33 -07:00
c7f9a95a3f test: fix tests in windows ci (#30451)
PR Close #30451
2019-05-14 10:35:55 -07:00
06efc340b6 build: update rules_nodejs and clean up bazel warnings (#30370)
Preserve compatibility with rollup_bundle rule.
Add missing npm dependencies, which are now enforced by the strict_deps plugin in tsc_wrapped

PR Close #30370
2019-05-14 10:08:45 -07:00
3fecab64b1 build: update to Bazel 0.26 (#30370)
PR Close #30370
2019-05-14 10:08:45 -07:00
34e0d621fd build(docs-infra): update http-server to 0.11.1 (#30401)
Fixes #30363

PR Close #30401
2019-05-14 09:55:46 -07:00
cc2f175617 test(ivy): move discovery_utils tests to acceptance (#30416)
Rewrites the discovery util tests to use `TestBed`.

PR Close #30416
2019-05-14 09:55:17 -07:00
96baff3a85 test(ivy): move change detection tests into acceptance (#30425)
Moves most of the r3 change detection tests into `acceptance`. Notes:
* A handful of tests weren't migrated, because they were testing an API that isn't exposed publicly yet.
* The `should throw if bindings in children of current view have changed` and `should NOT throw if bindings in ancestors of current view have changed` tests were removed, because there's not nice way of hitting the same code path with `TestBed` and doing the same assertion as with the raw instructions. I'm open to ideas on how we could do them.
* There were a few tests that assert that the `innerHTML` looks in a particular way. I've switched them to use `textContent`, because Ivy and ViewEngine produce slightly different DOM. The tests were only checking whether the text has changed anyway.

PR Close #30425
2019-05-14 09:54:45 -07:00
090eac068a test(ivy): move property render3 tests to acceptance (#30426)
Moves all manual render3 property binding tests to
TestBed acceptance tests. Unfortunately three property
binding tests could not be migrated as these rely on
manual Ivy template code that is not supported within
TestBed. These can be revisited as discussed in the
framework team meeting.

PR Close #30426
2019-05-14 09:39:22 -07:00
d09d8e0adf test(ivy): move render3 directive tests to acceptance (#30432)
Moves all manual render3 directive tests to TestBed acceptance
tests.

PR Close #30432
2019-05-14 09:37:01 -07:00
a57f3e7bbf test(ivy): move render3 renderer_factory tests to acceptance (#30435)
Moves all manual render3 tests which are located within the
`renderer_factory_spec.ts` file to acceptance tests. A few tests
that use Ivy-specific logic which is not replicable with `TestBed`
remain in the render3 folder (e.g. using `renderTemplate`)

Additionally migrated tests that assert the lifecycles of the
renderer_factory are set to *ivy only* as the lifecycle seems
to be different in Ivy. Tracked with: FW-1320

PR Close #30435
2019-05-14 09:36:24 -07:00
197584d1af fix(router): IE 11 bug can break URL unification when comparing objects (#30393)
This PR fixes an issue where IE 11 can return `undefined` in with an `Object.keys` call. Solution is to add a runtime check on the value. Based on the types being passed, this shouldn't be necessary, but is needed only for IE 11. Unit test doesn't work for this PR because it can't be replicated easily.

PR Close #30393
2019-05-13 11:40:43 -07:00
18c0ba5272 test: fix ngcc integration tests in windows (#30297)
```
//packages/compiler-cli/ngcc/test:integration
```

Partially addresses #29785

PR Close #30297
2019-05-13 11:26:56 -07:00
1bd4891c9a test: fix ngcc unit tests in windows (#30297)
```
//packages/compiler-cli/ngcc/test:test
```

Partially addresses #29785

PR Close #30297
2019-05-13 11:26:56 -07:00
3a7bfc721e fix(ivy): handle windows drives correctly (#30297)
At the moment the module resolver will end up in an infinite loop in Windows because we are assuming that the root directory is always `/` however in windows this can be any drive letter example `c:/` or `d:/` etc...

With this change we also resolve the drive letter in windows, when using `AbsoluteFsPath.from` for consistence so under `/foo` will be converted to `c:/foo` this is also needed because of relative paths with different drive letters.

PR Close #30297
2019-05-13 11:26:55 -07:00
f74373f2dd fix(ivy): align NgModule registration timing with ViewEngine (#30244)
Currently in Ivy `NgModule` registration happens when the class is declared, however this is inconsistent with ViewEngine and requires extra generated code. These changes remove the generated code for `registerModuleFactory`, pass the id through to the `ngModuleDef` and do the module registration inside `NgModuleFactory.create`.

This PR resolves FW-1285.

PR Close #30244
2019-05-13 11:13:25 -07:00
2f35dbfd3b test: fix ngtsc tests in windows (#30146)
This commit fixes the following test target in windows

```
//packages/compiler-cli/test/ngtsc:ngtsc
```

PR Close #30146
2019-05-13 11:06:12 -07:00
31df5139c5 test: fix several Bazel compiler tests in windows (#30146)
```
//packages/compiler-cli/test:ngc
//packages/compiler/test:test
```

This also address `node_modules` to the ignored paths for ngc compiler as otherwise the `ready` is never fired

Partially addresses #29785

PR Close #30146
2019-05-13 11:06:12 -07:00
7569a2e0d9 test(ivy): pure function acceptance tests (#30406)
- Moves tests related to the pureFunction instructions from render3 to acceptance tests
- Leaves behind one test for in-template javascript that is not supported syntax yet

PR Close #30406
2019-05-13 10:55:59 -07:00
7dad3284e3 release: ts_api_guardian (#30120)
PR Close #30120
2019-05-13 10:53:34 -07:00
0cf09fc981 test(ivy): use TestBed for render3 i18n tests (#30352)
PR Close #30352
2019-05-13 10:51:31 -07:00
877b2285f9 docs: change reference to jQuery programmers (#30386)
The section on Data Binding makes a reference to "any experienced jQuery programmer" which is a bit too narrow since there are also  programmers that write their front end in pure JavaScript.
PR Close #30386
2019-05-13 10:49:26 -07:00
0d4a0b6519 build(docs-infra): upgrade cli command docs sources to 73d875a70 (#30414)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](8dd9b98ac...73d875a70):

**Modified**
- help/build.json
- help/e2e.json
- help/serve.json
- help/test.json
- help/xi18n.json

##

PR Close #30414
2019-05-13 10:22:46 -07:00
4feb9b1c72 build: ignore .devcontainer/ directory (#30417)
This makes it easier to experiment with VSCode's
[remote development using docker containers][1] feature.

In the future, we may check in the necessary files for users to use this
feature, but for now ignoring the directory makes it easier play around
and evaluate the feature.

[1]: https://code.visualstudio.com/docs/remote/containers

PR Close #30417
2019-05-13 10:17:15 -07:00
cb6dea473f test(ivy): move pipe tests into acceptance (#30389)
Moves over the tests from `pipe_spec` into `acceptance`. Note that the two `WrappedValue` tests haven't been moved over, because impure pipes always throw "changed after checked" errors in `TestBed`. This seems to be consistent with ViewEngine.

PR Close #30389
2019-05-10 14:35:57 -07:00
5ab809ddf9 build: upgrade zone.js to 0.9.1 (#30260)
Close 30203

resolves the issue that zone-legacy XHR issue

PR Close #30260
2019-05-10 14:25:56 -07:00
fbff03b476 feat(ivy): skip analysis of unchanged components (#30238)
Now that the dependent files and compilation scopes are being tracked in
the incremental state, we can skip analysing and emitting source files if
none of their dependent files have changed since the last compile.

The computation of what files (and their dependencies) are unchanged is
computed during reconciliation.

This commit also removes the previous emission skipping logic, since this
approach covers those cases already.

PR Close #30238
2019-05-10 12:10:40 -07:00
411524d341 feat(ivy): track compilation scope dependencies for components (#30238)
To support skipping analysis of a file containing a component
we need to know that none of the declarations that might affect
its ngtsc compilation have not changed. The files that we need to
check are those that contain classes from the `CompilationScope`
of the component. These classes are already tracked in the
`LocalModuleScopeRegistry`.

This commit modifies the `IvyCompilation` class to record the
files that are in each declared class's `CompilationScope` via
a new method, `recordNgModuleScopeDependencies()`, that is called
after all the handlers have been "resolved".

Further, if analysis is skipped for a declared class, then we need
to recover the analysis from the previous compilation run. To
support this, the `IncrementalState` class has been updated to
expose the `MetadataReader` and `MetadataRegistry` interfaces.
This is included in the `metaRegistry` object to capture these analyses,
and also in the `localMetaReader` as a fallback to use if the
current compilation analysis was skipped.

PR Close #30238
2019-05-10 12:10:40 -07:00
0a0b4c1d8f feat(ivy): track file dependencies due to partial evaluation (#30238)
As part of incremental compilation performance improvements, we need
to track the dependencies of files due to expressions being evaluated by
the `PartialEvaluator`.

The `PartialEvaluator` now accepts a `DependencyTracker` object, which is
used to track which files are visited when evaluating an expression.
The interpreter computes this `originatingFile` and stores it in the evaluation
`Context` so it can pass this to the `DependencyTracker.

The `IncrementalState` object implements this interface, which allows it to be
passed to the `PartialEvaluator` and so capture the file dependencies.

PR Close #30238
2019-05-10 12:10:40 -07:00
5887ddfa3c refactor(ivy): clean up ngtsc code (#30238)
No behavioural changes.

PR Close #30238
2019-05-10 12:10:40 -07:00
d80ae6ba0d build(docs-infra): ensure hidden cli commands are excluded from sitemap.xml (#30395)
Previously, the processor that excludes certain cli commands
(`filterHiddenCommand`) was being run after the `createSitemap`
processor, resulting in those commands to be present in `sitemap.xml`,
while the actual pages where missing. This also resulted in 404s, when
search engine crawlers tried to index the missing URLs.

This commit fixes it by ensuring that the `filterHiddenCommand`
processor is run before the `createSitemap` processor.

PR Close #30395
2019-05-10 11:56:39 -07:00
44cf981407 docs: remove mention of chrome 41 from differential loading (#30390)
PR Close #30390
2019-05-10 11:55:12 -07:00
5fd39283ec test(ivy): move output tests to acceptance (#30372)
Moves most of the tests in `output_spec` into `acceptance`. Note that one test is left in `render3`, because it's testing mixing in custom logic with instructions which we can't replicate using `TestBed`.

PR Close #30372
2019-05-10 09:27:57 -07:00
1f2b39ad7d test(ivy): move content projection tests to acceptance (#30357)
Moves all manual `render3` content projection tests that use
the `ɵɵelementProperty` to acceptance tests. Additionally a
few other content projection tests were moved over to
acceptance. Eventually we'll be able to move all remaining
content projection tests to acceptance.

PR Close #30357
2019-05-10 09:18:37 -07:00
24e172d779 test(ivy): use TestBed for render3 component tests (#30282)
PR Close #30282
2019-05-10 09:18:19 -07:00
b68850215a refactor(core): clean up support for ES2015 constructor delegation (#30368)
This commit moves the delegated constructor detection to a helper
function and also adds more test coverage.

The original code for this came from https://github.com/angular/angular/pull/24156
thanks to @ts2do.

Closes #24156
Closes #27267

// FW-1310

PR Close #30368
2019-05-10 09:17:20 -07:00
9abf114fbb feat(bazel): use rbe_autoconfig() and new container. (#29336)
After this PR is merged, maintainers no longer need to update .bazelrc
file, toolchain and platform related flags for RBE builds and tests
(unless there is a breaking change in Bazel related to those flags).

Maintainers just need to update the pin of @bazel-toolchains repo
regularly in the packages/bazel/package.bzl file according to
https://releases.bazel.build/bazel-toolchains.html to include the
latest checked-in toolchain configs. If rbe_autoconfig() cannot find
appropriate toolchain configs for the version of Bazel in the version of
@bazel_toolchains repo that is currently used by this project, it will pull
down the container and generate the configs on the fly as the beginning
of the build/test.

PR Close #29336
2019-05-09 14:58:34 -07:00
8d3365e4fc fix(core): static-query usage migration strategy should detect ambiguous query usage (#30215)
Currently we always just set the timing to `false` if we aren't
able to analyze a given call expression or new expression. e.g.

```ts
ngOnInit() {
  thirdPartyCallSync(() => this.query.doSomething())
}
```

In that case the `thirdPartyCallSync` function comes from the `node_modules`
and is only defined through types while there is no code for the
actual function logic that can be analyzed. This makes it impossible
to tell whether the given call expression actually causes the specified
arrow function to be executed synchronously or not. In order to be able
to make this better, we now peek into the passed arrow function and
check for a synchronous query usage. If so, we set the query timing to
static and mark it as ambiguous. This ensures that the usage strategy is
less "magical" and more correct with third-party code.

Additionally since functions like `setTimeout` are not analyzable but known
to be asynchronous, there is a hard-coded list of known functions which
shouldn't be marked as ambiguous.

Resolves FW-1214. As planned within https://hackmd.io/hPiLWpPlQ4uynC1luIBdfQ

PR Close #30215
2019-05-09 14:39:06 -07:00
8cec8f5584 test(core): update core_all size-tracking golden file (#30257)
Even though we don't run the size-tracking test on CI
right now, we update the golden size map as part of
the size-tracking tool update. The size-map difference
should generally be kept up-to-date to be able to
determine which PRs contribute size to a given file.

PR Close #30257
2019-05-09 12:55:17 -07:00
741a5dc5f7 build: size-tracking test should support max-byte threshold (#30257)
Based on discussion that happened on the PR that introduced
the size-tracking tool, we want to have another threshold for
the raw byte difference. This allows us to better control for
which changes the size-tracking tool should report a difference.

See: https://github.com/angular/angular/pull/30070#discussion_r278332315

PR Close #30257
2019-05-09 12:55:16 -07:00
de996c6d56 docs(forms): properly convert number to string for formControlName input (#29473)
PR Close #29473
2019-05-09 11:27:48 -07:00
d750b1e10d docs: fix filename in example headers for provider guides (#29889)
PR Close #29889
2019-05-09 11:27:00 -07:00
d2c83ea81b docs(forms): add comment of the value (#29898)
PR Close #29898
2019-05-09 11:25:58 -07:00
bf031fc56b test(ivy): update devkit in hello world tests to rc.2 (#30162)
PR Close #30162
2019-05-09 11:24:52 -07:00
b1d45ee6d2 test(ivy): move property and attribute tests to acceptance (#30321)
- splits existing property acceptance tests into property_binding and property_interpolation
- ports tests from render3 instructions tests to acceptance tests
- removes redundant or unnecessary tests that are covered by existing acceptance tests

:)

PR Close #30321
2019-05-09 11:23:35 -07:00
f26f036286 docs: remove reference to e2e applications (#30324)
This is no longer applicable in angular version 8.

PR Close #30324
2019-05-09 11:23:05 -07:00
0ffdb48f62 fix(core): static-query migration should handle queries on accessors (#30327)
Currently the static-query migration ignores queries declared on getters
or setters as these are not part of a `PropertyDeclaration`. We need to
handle these queries in order to cover all queries within a given project.

The usage strategy is not able to detect timing for queries on accessors,
so we add a TODO and print a message. The template strategy is able
to detect the proper timing for such queries because it's not dependent
on detecting the usage of the query.

Resolves FW-1215

PR Close #30327
2019-05-09 11:22:37 -07:00
cb6ad971c3 test(ivy): add onlyInIvy perf counter expectations (#30339)
We have an issue where we would like to be able to test perf counter metrics in acceptance tests, but we are unable to do so, because it will break when those same tests are run with ViewEngine. This PR adds a testing utility to `onlyInIvy` that allows for testing of performance counters, and even gives readable errors for what value on `ngDevMode` is incorrect. Has typings for decent autocompletion as well.

PR Close #30339
2019-05-09 11:22:00 -07:00
d70b1ff177 fix(docs-infra): Handle search criteria from Chrome search providers (#30345)
fixes #30242

PR Close #30345
2019-05-09 11:21:11 -07:00
3aff79c251 fix(bazel): pass correct arguments to http_server in Windows (#30346)
Under Windows, the server binary has an extension of  `.exe` and the current logic is not handling that.

Partially addresses: #29785

PR Close #30346
2019-05-09 11:20:51 -07:00
d8665e639b refactor(ivy): drop element prefixes for all styling-related instructions (#30318)
This is the final patch to migrate the Angular styling code to have a
smaller instruction set in preparation for the runtime refactor. All
styling-related instructions now work both in template and hostBindings
functions and do not use `element` as a prefix for their names:

BEFORE:
  elementStyling()
  elementStyleProp()
  elementClassProp()
  elementStyleMap()
  elementClassMap()
  elementStylingApply()

AFTER:
  styling()
  styleProp()
  classProp()
  styleMap()
  classMap()
  stylingApply()

PR Close #30318
2019-05-08 15:33:39 -07:00
c016e2c4ec refactor(ivy): migrate all host-specific styling instructions to element-level styling instructions (#30336)
This patch removes all host-specific styling instructions in favor of
using element-level instructions instead. Because of the previous
patches that made sure `select(n)` worked between styling calls, all
host level instructions are not needed anymore. This patch changes each
of those instruction calls to use any of the `elementStyling*`,
`elementStyle*` and `elementClass*` styling instructions instead.

PR Close #30336
2019-05-08 14:54:44 -07:00
452f121486 fix: ensure strict mode when evaluating in JIT (#30122)
PR Close #30122
2019-05-08 14:34:10 -07:00
728db88280 fix(core): CSS sanitizer now allows parens in file names (#30322)
Resolves an issue where images that were created with a name like `'foo (1).png'` would not pass CSS url sanitization.

PR Close #30322
2019-05-08 14:22:43 -07:00
9a807bd26a docs(router): Move ActivatedRoute example to mini-app (#29755)
PR Close #29755
2019-05-08 13:52:22 -07:00
eccc41c5cf refactor: using ᐱ instead of Δ in tests (#30338)
This is in preparation to move instructions back to using `Δ` prefix

PR Close #30338
2019-05-08 12:00:25 -07:00
509352fc36 fix(core): static-query migration should gracefully exit if AOT compiler throws (#30269)
The static-query template strategy leverages the AOT compiler
in order to determine the query timing. Unfortunately the AOT
compiler has open bugs that can cause unexpected failures which
make the template strategy unusable in rare cases. These rare
exceptions need to be handled gracefully in order to avoid confusion
and to provide a more smooth migration.

Additionally migration strategy setup failures are now reported with
stack traces as the `ng update` command does not print stack traces.
This makes it easier to reproduce and report migration issues.

PR Close #30269
2019-05-08 11:54:33 -07:00
349935a434 fix(core): migrations not always migrating all files (#30269)
In an Angular CLI project scenario where projects only reference
top-level source-files through the `tsconfig` `files` option, we currently
do not migrate referenced source-files. This can be fixed checking all
referenced source-files which aren't coming from an external library.

This is similar to how `tslint` determines project source-files.

PR Close #30269
2019-05-08 11:54:33 -07:00
6357d4a0d3 fix(core): static-query migration fails with default parameter values (#30269)
Currently when someone has a call expression within the `ngOnInit` call
and we try to peek into that function with respect to the current function
context, the schematic errors because a call expression argument is
undefined. This is valid because the target function declaration defines
that parameter with a default value. In order to fix this, we need to
respect parameter default values.

PR Close #30269
2019-05-08 11:54:33 -07:00
29786e856d fix(ivy): unable to bind SafeStyle as camel case property (#30328)
Fixes not being able to bind a `SafeStyle` as a camel cased style property (e.g. `[style.backgroundImage]="someSafeStyle"`). The issue was due to the fact that we only check the dash case property names to determine whether to sanitize a value.

This PR resolves FW-1279.

PR Close #30328
2019-05-08 10:17:26 -07:00
bf6bedd714 fix(docs-infra): remove scroll position from sessionStorage when a ServiceWorker update has been activated (#29958)
closes #29893

PR Close #29958
2019-05-08 09:23:42 -07:00
f094bb54a7 test(core): run schematic tests with public migration collection (#30198)
572b54967c changed how the schematic
tests are executed. Tests no longer use the schematic collection
that is also used by the CLI `ng update` command and therefore
the migration collection could  technically be invalid.

In order to ensure that the public migration collection is guaranteed
to work and to avoid duplication within two schematic collections, the
changes are partially reverted and only the disabled `injectable-pipe`
schematic has its own collection.

PR Close #30198
2019-05-08 09:23:28 -07:00
4c12d742dc fix(core): static-query migration should not prompt if no queries are used (#30254)
Currently we always prompt when the static-query migration runs. This is not
always needed because some applications do not even use `ViewChild` or
`ContentChild` queries and it just causes confusion if developers need to
decide on a migration strategy while there is nothing to migrate.

In order to avoid this confusion, we no longer prompt for a strategy
if there are no queries declared within the project.

PR Close #30254
2019-05-08 09:22:48 -07:00
04a9f28c3d build: add jasonaden to angular/upgrade in CODEOWNERS (#30307)
PR Close #30307
2019-05-08 09:20:24 -07:00
d9b9ed56b6 test(ivy): move host binding tests to acceptance (#30308)
Switches over all host binding tests to use `TestBed` and to be under `acceptance`.

PR Close #30308
2019-05-08 09:19:44 -07:00
7c8a62d64d refactor(ivy): remove elementIndex param from all element-level styling instructions (#30313)
This patch is one commit of many patches that will unify all styling instructions
across both template-level bindings and host-level bindings. This patch in particular
removes the `elementIndex` param because it is already set prior to each styling
instruction via the `select(n)` instruction.

PR Close #30313
2019-05-08 09:18:19 -07:00
de651122a5 feat(ivy): add more DOM manipulation counters to ngDevMode (#30315)
PR Close #30315
2019-05-08 09:16:44 -07:00
4a96ddfb54 build(docs-infra): upgrade cli command docs sources to 8dd9b98ac (#30325)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](73c53266f...8dd9b98ac):

**Modified**
- help/add.json
- help/e2e.json
- help/generate.json
- help/update.json

##

PR Close #30325
2019-05-08 09:12:52 -07:00
8ced321bb6 Revert "fix(router): fix a problem with router not responding to back button (#30160)" (#30320)
This reverts commit 3327bd8eab.

PR Close #30320
2019-05-07 17:22:24 -07:00
2a0f497e94 fix(bazel): Directly spawn native Bazel binary (#30306)
Instead of launching a Node.js process that in turn spawns Bazel binary,
the Builder could now directly spawn the native binary. This makes the
bootup process slightly more efficient, and allows the Builder to
control spawn options. This works with both Bazel and iBazel.

PR Close #30306
2019-05-07 16:51:41 -07:00
392473ec79 fix(core): consistently use ng:/// for sourcemap URLs (#29826)
Currently, in jit mode, `ngInjectableDef`, `ngDirectiveDef`, `ngPipeDef` and `ngModuleDef` use `ng://`,
which display them in the top domain in Chrome Dev Tools, whereas `ngComponentDef` uses `ng:///` which display components in a separate domain.

You can currently see:

```
AppModule
UserService
ng://
|_ AppComponent
   |_ template.html
|_ AppComponent.js
...
```

This commits replaces all `ng://` with `ng:///` to display every Angular entity in the `ng://` domain.

```
ng://
|_ AppModule
|_ UserService
|_ AppComponent
...
```

PR Close #29826
2019-05-07 15:37:21 -07:00
345a3cd9aa fix(ivy): ensure select(n) instructions are always generated around style/class bindings (#30311)
Prior to this patch, the `select(n)` instruction would only be generated
when property bindings are encountered which meant that styling-related
bindings were skipped. This patch ensures that all styling-related bindings
(i.e. class and style bindings) are always prepended with a `select()`
instruction prior to being generated in AOT.

PR Close #30311
2019-05-07 14:56:17 -07:00
bd37622050 docs: release notes for the v8.0.0-rc.3 release 2019-05-07 14:49:45 -07:00
48de6e87f0 docs: release notes for the v7.2.15 release 2019-05-07 14:21:48 -07:00
3b551e0fcd docs(aio): add awade jigsaw into resources (#30204)
PR Close #30204
2019-05-07 13:13:22 -07:00
be8fbac942 refactor(ivy): break apart stylingMap into styleMap and classMap instructions (#30293)
This patch breaks up the existing `elementStylingMap` into
`elementClassMap` and `elementStyleMap` instructions. It also breaks
apart `hostStlyingMap` into `hostClassMap` and `hostStyleMap`
instructions. This change allows for better tree-shaking and reduces
the complexity of the styling algorithm code for `[style]` and `[class]`
bindings.

PR Close #30293
2019-05-07 11:06:04 -07:00
98a38ec98b docs: update date pipe example for minutes and seconds (#30281) (#30295)
PR Close #30295
2019-05-07 10:29:31 -07:00
4f055d4257 refactor: remove tslint no-use-before-declare rule (#30288)
PR Close #30288
2019-05-07 10:25:36 -07:00
c59717571e fix(ivy): ngcc - handle missing entry-point dependencies better (#30270)
If an entry-point has a missing dependency then all the entry-points
that would have pointed to that dependency are also removed from
the dependency graph.

Previously we were still processing the dependencies of an entry-point
even if it had already been removed from the graph because it depended
upon a missing dependency that had previously been removed due to another
entry-point depending upon it.

This caused the dependency processing to crash rather than gracefully
logging and handling the missing invalid entry-point.

Fixes #29624

PR Close #30270
2019-05-07 10:24:48 -07:00
f5b2ae616f feat(ivy): ngcc - add debug message for invalid entry-points (#30270)
PR Close #30270
2019-05-07 10:24:48 -07:00
1660b34e2d test: fix several bazel compiler-cli tests in windows (#30189)
```
//packages/compiler-cli/integrationtest:integrationtest
//packages/compiler-cli/test/compliance:compliance
```

Partially addresses #29785

PR Close #30189
2019-05-07 10:21:36 -07:00
b40f6f3eae fix(router): ensure history.state is set in eager update mode (#30154)
Without this change, `history.state` isn't being set when updating the browser URL in `eager` update mode.

PR Close #30154
2019-05-06 16:09:58 -07:00
3327bd8eab fix(router): fix a problem with router not responding to back button (#30160)
There was a problem with a combination of the `eager` URL update, browser `back` button, and hybrid applications. Details provided in internal ticket http://b/123667227.

This fix handles the problem by setting `router.browserUrlTree` when all conditions have failed, meaning the browser doesn't do anything with the navigation other than update internal data structures. Without this change, the problem was an old value was stored in `router.broserUrlTree` causing some new navigations to be compared to an old value and breaking future navigations.

PR Close #30160
2019-05-06 16:06:58 -07:00
ea9a381c8c docs(forms): fix import line ending (#30290)
PR Close #30290
2019-05-06 16:05:23 -07:00
b2437c4500 perf(ivy): avoid unnecessary function calls when bound value doesn't change (#30255)
In the existing implementation the `elementPropertyInternal` function (meant to
set element properties) was executed even if a bound value didn't change. The
`elementPropertyInternal` was inspecting the incoming value and after comparing it
to `NO_CHANGE` - exiting early. All in all it meant that we were unnecessarily
invoking the `elementPropertyInternal` function for cases where bound value didn't
change.

Based on my bencharks (running change detection without any model update in a tight
loop) this unnecessary function call was causing ~5% slowdown in the change detection
process.

PR Close #30255
2019-05-06 14:09:54 -07:00
d6538eb2fd docs: fix naming miss and improve anchor reference in router guide (#30225)
Signed-off-by: Richard Lea <chigix@zoho.com>

PR Close #30225
2019-05-06 11:48:05 -07:00
0926119977 docs: add explanation on what lazy loading is (#29667)
PR Close #29667
2019-05-06 10:16:58 -07:00
39f2c9f46b docs(forms): fix ControlValueAccessor registerOnChange code example (#30276)
PR Close #30276
2019-05-06 09:27:12 -07:00
60a8888b4f fix(compiler-cli): log ngcc skipping messages as debug instead of info (#30232)
Related to https://github.com/angular/angular-cli/issues/14194, https://github.com/angular/angular-cli/pull/14320

PR Close #30232
2019-05-06 09:24:15 -07:00
4537816c1d docs: fix targetEntryPointPath description (#30237)
PR Close #30237
2019-05-06 09:21:23 -07:00
bf73fb7420 docs: update Wikipedia link to Polyfill description (#30214)
PR Close #30214
2019-05-06 09:20:14 -07:00
1ec092ba32 docs: fix example header in singleton services guide to match styleguide (#30097)
Removes the ".0" from code header, as that doesn't match the
recommended code style for service files names.

fixes #29862

PR Close #30097
2019-05-06 09:19:36 -07:00
30d1f292c9 fix(core): fix interpolate identifier in AOT (#30243)
This commit fixes a regression introduced in PR 29692 where
the interpolate symbol in View Engine was improperly prefixed
with the ɵɵ that signifies private instructions for Ivy. It
resulted in interpolations of 10+ values not working correctly
in AOT mode. This commit removes the prefix.

PR Close #30243
2019-05-02 10:33:34 -07:00
b70d20b510 fix(docs-infra): update app code to work with Ivy (#28530)
This commit also enables more tests to be run on CI with Ivy.

PR Close #28530
2019-05-01 16:38:32 -07:00
066ec33342 fix(ivy): allow R3TestBedCompiler to work in ngcc-processed apps (#28530)
Previously, `R3TestBedCompiler` was dynamically defining an
`@NgModule`-decorated `CompilerModule` class inside a method call.
Since ngcc only processes top-level classes, this class was not
transformed causing failures in unit tests (see #30121 for details).

This commit fixes it by using `compileNgModuleDefs()` directly (similar
to the fix in #30037).

Fixes #30121

PR Close #28530
2019-05-01 16:38:32 -07:00
5b80ab372d fix(ivy): use CompilerHost.resolveModuleNames() if available (#30017)
Sometimes we need to override module resolution behaviour.
We do this by implementing the optional method `resolveModuleNames()`
on `CompilerHost`.

This commit ensures that we always try this method first before falling
back to the standard `ts.resolveModuleName`

PR Close #30017
2019-05-01 15:41:53 -07:00
638ba4a2cf fix(ivy): ngcc - prefer JavaScript source files when resolving module imports (#30017)
Packages that do not follow APF may have the declaration files in the same
directory as one source format, typically ES5. This is problematic for ngcc,
as it needs to create a TypeScript program with all JavaScript sources of
an entry-point, whereas TypeScript's module resolution mechanism would have
resolved an internal module import to the external facing .d.ts declaration
file, instead of the JavaScript source file. This behavior results in the
program to be analysed being incomplete.

This commit introduces a custom compiler host that recognizes the above
scenario and rewires the resolution of a .d.ts declaration file to its
JavaScript counterpart, if applicable.

Fixes #29939

PR Close #30017
2019-05-01 15:41:53 -07:00
7ec8806dc5 docs: explicitly state purpose of components (#29879)
Current description is vague. I'd love to see this doc explicitly state that components are for reusable sets of UI features instead.

PR Close #29879
2019-05-01 13:38:13 -07:00
7d6f4885b2 fix(ivy): properly tree-shake away StaticInjector (#30219)
Ivy uses R3Injector, but we are currently pulling in both the StaticInjector
(View Engine injector) and the R3Injector when running with Ivy. This commit
adds an ivy switch so calling Injector.create() pulls in the correct
implementation of the injector depending on whether you are using VE or Ivy.
This saves us about 3KB in the bundle.

PR Close #30219
2019-04-30 21:35:54 -07:00
b1506a3271 fix(ivy): support injection flags for provider deps without new (#30216)
Previously, we were supporting injection flags for provider deps, but only
if they fit the format `new Optional()`. This commit fixes resolution of
provider deps to also support `Optional` (without the new). This keeps us
backwards compatible with what View Engine supported.

PR Close #30216
2019-04-30 20:37:56 -07:00
b15a403c71 ci(docs-infra): re-enable aio_monitoring CircleCI jobs and change time (#30168)
The `aio_monitoring_next` CircleCI job was disabled due to a failure in
[302254](https://circleci.com/gh/angular/angular/302254). It turned out
the failure was caused because the job happened to run after a change
had been merged into master and right before it was deployed to
https://next.angular.io/ causing the tests not to match the deployed
version.

This commit re-enables the job and moves it to a different time, when it
is less likely that PRs will be being merged (and thus reducing the risk
of a similar timming issue).

Fixes #30101

PR Close #30168
2019-04-30 16:17:52 -07:00
37c598db04 fix(ivy): inherited listeners from grand super classes invoked multiple times (#30169)
Fixes event listeners that come from more than one level of inheritance being invoked multiple times.

This PR resolves FW-1294.

PR Close #30169
2019-04-30 16:14:26 -07:00
ad94e02981 perf(ivy): store views directly on LContainer (#30179)
Stores the views that are part of a container directly on the `LContainer`, rather than maintaining a dedicated sub-array.

This PR resolves FW-1288.

PR Close #30179
2019-04-30 16:13:58 -07:00
00ffc03523 fix(ivy): support forward refs in provider deps (#30201)
Currently, we are not properly resolving forward refs when they appear
in deps for providers created with the useFactory strategy. This commit
wraps provider deps in the resolveForwardRef call so the tokens are
passed into the inject function as expected.

PR Close #30201
2019-04-29 20:03:10 -07:00
e53cf81689 build(docs-infra): upgrade material and cdk to 8.0.0-rc.0 (#30202)
I bumped the payload size limits to reflect the current values - the changes have been insignificant.

PR Close #30202
2019-04-29 18:46:53 -07:00
089fcbf369 build(docs-infra): upgrade framework and cli to 8.0.0-rc.2 (#30202)
Brings in small payload size fixes.

PR Close #30202
2019-04-29 18:46:53 -07:00
68ff2cc323 fix(ivy): host bindings and listeners not being inherited from undecorated classes (#30158)
Fixes `HostBinding` and `HostListener` declarations not being inherited from base classes that don't have an Angular decorator.

This PR resolves FW-1275.

PR Close #30158
2019-04-29 13:35:14 -07:00
164d160b22 refactor(core): static-query migrations fails if options cannot be transformed (#30178)
Currently the `static-query` migrations fails at the final step of
updating a query when the query already specifies options which
cannot be transformed easily. e.g. the options are computed through
a function call: `@ViewChild(..., getQueryOpts());` or `@ViewChild(..., myOptionsVar)`.

In these cases we technically could add additionally logic to update
the query options, but given that this is an edge-case and it's
potentially over-engineering the migration schematic, we just
always add a TODO for the timing and print out the determined
query timing in the console. The developer in that case just needs
to manually update the logic for the query options to contain the
printed query timing.

Potentially related to: https://github.com/angular/angular-cli/issues/14298

PR Close #30178
2019-04-29 13:30:37 -07:00
1353bf0277 fix(bazel): Bump ibazel to 0.10.1 for windows fixes (#30196)
PR Close #30196
2019-04-29 13:29:12 -07:00
6dc884f2ab test(language-service): Load language service from tsconfig (#30153)
This PR changes the integration test to load language service the way it would be loaded in the editor.
If the language service is specified in tsconfig, it'd only be loaded for Angular projects.
Specifying it as `globalPlugins` loads it unconditionally whenever tsserver is brought up.

PR Close #30153
2019-04-29 13:28:18 -07:00
05eabb19d6 test(language-service): Add external template (#30128)
This is in preparation for more rigorous testing of external templates, since it'll work differently under the new tsserver plugin model.

PR Close #30128
2019-04-29 13:27:38 -07:00
f4916730b5 feat(language-service): Implement definitionAndBoundSpan (#30125)
This PR adds the implementation for `definitionAndBoundSpan` because
it's now preferred over `definition`. vscode would send this new request
for `Go to definition`. As part of this PR the implementation for
`definition` is refactored and simplified. Goldens for both methods are
checked in.

PR Close #30125
2019-04-29 13:27:01 -07:00
67012509a8 test: fix ngc-wrapped bazel tests in windows (#30111)
Partially addresses #29785

PR Close #30111
2019-04-29 13:23:44 -07:00
28a1caa0ed docs: add in-page nav, change title to match left nav better (#30093)
PR Close #30093
2019-04-29 13:23:14 -07:00
f015dbe1ba docs: add architect terms (#26963)
PR Close #26963
2019-04-29 13:22:20 -07:00
029a93963a refactor(ivy): ngcc - remove the last remnants of path and canonical-path (#29643)
The ngcc code now uses `AbsoluteFsPath` and `PathSegment` to do all its
path manipulation.

PR Close #29643
2019-04-29 12:37:21 -07:00
20898f9f4f test(ivy): ngcc - tighten up typings in Esm5ReflectionHost specs (#29643)
PR Close #29643
2019-04-29 12:37:21 -07:00
ef861958a9 refactor(ivy): ngcc - add MockFileSystem (#29643)
PR Close #29643
2019-04-29 12:37:21 -07:00
16d7dde2ad refactor(ivy): ngcc - implement abstract FileSystem (#29643)
This commit introduces a new interface, which abstracts access
to the underlying `FileSystem`. There is initially one concrete
implementation, `NodeJsFileSystem`, which is simply wrapping the
`fs` library of NodeJs.

Going forward, we can provide a `MockFileSystem` for test, which
should allow us to stop using `mock-fs` for most of the unit tests.
We could also implement a `CachedFileSystem` that may improve the
performance of ngcc.

PR Close #29643
2019-04-29 12:37:21 -07:00
1fd2cc6340 refactor(ivy): ngcc - move the dependency resolving stuff around (#29643)
For UMD/RequireJS support we will need to have multiple
`DependencyHost` implementations. This commit  prepares the
ground for that.

PR Close #29643
2019-04-29 12:37:21 -07:00
5ced8fbbd5 feat(ivy): ngcc - support additional paths to process (#29643)
By passing a `pathMappings` configuration (a subset of the
`ts.CompilerOptions` interface), we can instuct ngcc to process
additional paths outside the `node_modules` folder.

PR Close #29643
2019-04-29 12:37:21 -07:00
23152c37c8 feat(ivy): add helper methods to AbsoluteFsPath (#29643)
PR Close #29643
2019-04-29 12:37:21 -07:00
4a2405929c refactor(ivy): ngcc - implement new module resolver (#29643)
When working out the dependencies between entry-points
ngcc must parse the import statements and then resolve the
import path to the actual file.  This is complicated because module
resolution is not trivial.

Previously ngcc used the node.js `require.resolve`, with some
hacking to resolve modules. This change refactors the `DependencyHost`
to use a new custom `ModuleResolver`, which is optimized for this use
case.

Moreover, because we are in full control of the resolution,
we can support TS `paths` aliases, where not all imports come from
`node_modules`. This is the case in some CLI projects where there are
compiled libraries that are stored locally in a `dist` folder.
See //FW-1210.

PR Close #29643
2019-04-29 12:37:21 -07:00
eef4ca5dd3 refactor(ivy): ngcc - tidy up mainNgcc (#29643)
PR Close #29643
2019-04-29 12:37:20 -07:00
321da5cc83 refactor(compiler-cli): ngcc - track non-Angular entry-points (#29643)
Previously we completely ignored entry-points that had not been
compiled with Angular, since we do not need to compile them
with ngcc. But this makes it difficult to reason about dependencies
between entry-points that were compiled with Angular and those that
were not.

Now we do track these non-Angular compiled entry-points but they
are marked as `compiledByAngular: false`.

PR Close #29643
2019-04-29 12:37:20 -07:00
c2cf500da9 test(ivy): ngcc - check private dependency in integration test (#29643)
The test now attempts to compile an entry-point (@angular/common/http/testing)
that has a transient "private" dependency. A private dependency is one that is
only visible by looking at the compiled JS code, rather than the generated TS
typings files.

This proves that we can't rely on typings files alone for computing the
dependencies between entry-points.

PR Close #29643
2019-04-29 12:37:20 -07:00
4c03208537 refactor(ivy): ngcc - tidy up DependencyResolver helper method (#29643)
This method was poorly named for what it does, and did not have a
return type.

PR Close #29643
2019-04-29 12:37:20 -07:00
78b5bd5174 refactor(compiler-cli): ngcc - remove unnecessary sourcePath parameters (#29643)
The `Transformer` and `Renderer` classes do not
actually need a `sourcePath` value as by the time
they are doing their work we are only working directly
with full absolute paths.

PR Close #29643
2019-04-29 12:37:20 -07:00
1195dabb84 build(docs-infra): update the aio app to framework and cli 8.0.0-rc.1 (#30183)
I updated the payload size limits as well. There still seem to be size regressions in the framework,
but at least the polyfills now uses the evergreen build of zones so we shaved off a few KB there.

PR Close #30183
2019-04-29 12:30:25 -07:00
2945f47977 build: add size-tracking bazel test (#30070)
Introduces a new Bazel test that allows us to inspect
what source-files contribute to a given bundled file
and how much bytes they contribute to the bundle size.

Additionally the size-tracking rule groups the size
data by directories. This allows us to compare size
changes in the scope of directories. e.g. a lot of
files in a directory could increase slightly in size, but
in the directory scope the size change could be significant
and needs to be reported by the test target.

Resolves FW-1278

PR Close #30070
2019-04-29 12:29:25 -07:00
a44b510087 docs: release notes for the v8.0.0-rc.2 release 2019-04-29 12:25:07 -07:00
572b54967c fix: disable injectable-pipe migration (#30180)
Disables the injectable pipe migration until we can decide whether this is the right solution for Ivy. Rolling it out properly will involve a more detailed plan and more changes like updating the styleguide, scaffolding schematics etc.

Context for the new `test-migrations.json`: since we use the `migrations.json` both for the real migrations and for tests, it doesn't allow us to disable a schematic, but continue running its tests. This change adds the test-specific file so that we can continue running the `injectable-pipe` tests, even though the schematic itself is disabled.

PR Close #30180
2019-04-29 09:40:00 -07:00
6f433887e0 fix(ivy): injectable pipe schematic generating incorrect import statements (#30170)
Currently the injectable pipe schematic generates invalid imports like `import import { Pipe, PipeTransform, Injectable } from '@angular/core'; from '@angular/core';`. The issue wasn't caught by the unit tests, because the invalid import still contains the valid one.

Fixes #30159.

PR Close #30170
2019-04-29 09:39:11 -07:00
537502d685 docs: temporary disable aio_monitoring job due to a version skew (#30161)
It looks like `aio_monitoring` CircleCI job is still failing. Disabling it for now to keep master green.

PR Close #30161
2019-04-26 17:38:59 -07:00
e5c3695dbd Revert "refactor: use new Http library in playground (#29355)"
This reverts commit acfcf90528.
2019-04-26 16:49:50 -07:00
3cf318b498 refactor(ivy): move exports tests to acceptance (#30157)
PR Close #30157
2019-04-26 16:37:34 -07:00
54d4105264 docs: update readme. sentence correction. (#30136)
PR Close #30136
2019-04-26 16:36:53 -07:00
dd59b1d371 build: unable to accept new symbol-extractor golden on windows (#30127)
Currently when working on Windows, it's not possible to accept a new
golden for a `symbol-extractor` Bazel test. This is because the generated
executable output from the `nodejs_binary` rule (without a macro) misses
a Windows executable wrapper that sets up the proper environment
variables for the runfiles. Causing the following failure on Windows:

```
 >>>> FAIL: RUNFILES environment variable is not set. <<<<
```

PR Close #30127
2019-04-26 16:35:51 -07:00
124e49752f fix(language-service): Remove tsserverlibrary from rollup globals (#30123)
This PR removes `tsserverlibrary` from rollup globals since the symbol
should not appear by the time rollup is invoked. `tsserverlibrary` is
used for types only, so the import statement should not be emitted by
tsc.

PR Close #30123
2019-04-26 16:35:04 -07:00
fc2dd5482e ci: enable language service tests in codefresh (#30113)
PR Close #30113
2019-04-26 16:34:23 -07:00
e4b81a6957 test: fix language service tests in windows (#30113)
This PR parially addresses #29785 and fixes ` //packages/language-service/test:test`

PR Close #30113
2019-04-26 16:34:22 -07:00
3efdd39a18 ci(docs-infra): use the tests from the stable branch in aio_monitoring_stable CircleCI job (#30110)
Previously, the `aio_monitoring_stable` job (which runs tests against
https://angular.io/) was using the tests from the master branch. As a
result, if the master branch included changes in those tests that were
not yet backported to the stable branch (and thus deployed to
https://angular.io/), the tests would fail.

This commit fixes this by using the tests from the stable branch to test
against https://angular.io/.

Fixes #30101

PR Close #30110
2019-04-26 16:33:45 -07:00
582ef2e7b4 ci(docs-infra): split the aio_monitoring CircleCI job into two jobs (#30110)
Previously, the `aio_monitoring` job was testing both the stable
(https://angular.io/) and the @next (https://next.angular.io/) versions.

This commit splits the tests into two separate jobs (still run as part
of the same workflow). This speeds up the tests (since the two jobs can
now run in parallel) and makes it easier to isolate failures (e.g.
identify which branch is failing, disable one of the two, etc.).
(Credits to @petebacondarwin 😉)

PR Close #30110
2019-04-26 16:33:45 -07:00
214fef2ee4 ci(docs-infra): re-use setup CircleCI job in aio_monitoring (#30110)
PR Close #30110
2019-04-26 16:33:45 -07:00
531fcaa99a ci(docs-infra): re-enable aio_monitoring CircleCI job (#30110)
The job started failing for https://angular.io/, due to changes in tests
that only affected https://next.angular.io/, and was disabled in #30102.

This commit re-enables the job (since it does not block anything and it
will be fixed in a subsequent commit).

PR Close #30110
2019-04-26 16:33:45 -07:00
8a60239ae7 docs(docs-infra): fix typo in workspace-config.md file (#30108)
Fixed typo in 'Project asset configuration' section inside workdspace-config.md

PR Close #30108
2019-04-26 16:33:03 -07:00
10705684c8 test: fix api guardian tests on windows when node_modules are not installed (#30105)
When the workspace node_modules are not installed outside of bazel context the api guardian tests fails because the tree artifacts files are not symlinked in windows.

We need to pass the node module location in the node_path

PR Close #30105
2019-04-26 16:32:23 -07:00
bdc6818716 ci: add public_api_guard tests to codefresh config (#30105)
PR Close #30105
2019-04-26 16:32:22 -07:00
5f95796b61 test: fix ts api guardian and public guard tests on windows (#30105)
This change addresses several issues with ts-api-guardian and public api guards related tests in Windows

The fixes contain 3 main changes:
1) In `stripExportPattern` - replace `^` with `^^^^`  in RegExp due to a double escaping requirment under Windows. Note that under Linux this the extra character has no effect because it's still a valid RegExp in Js.

2. Force `*.patch` files to always be with a LF line sequence instead of CRLF in windows

3. When adding JSDoc comments consider the presence of a carriage return in a line new feed

Partially addresses #29785

PR Close #30105
2019-04-26 16:32:22 -07:00
f2709ac3f9 fix(ivy): correctly reflect undefined values (#30103)
Fixes Ivy reflecting properties with `undefined` values, rather than omitting them. Also fixes that Ivy doesn't clear the reflected values when property value changes from something that is defined to undefined.

This PR resolves FW-1277.

PR Close #30103
2019-04-26 16:31:49 -07:00
cce9b9912f docs: update redirect links and fix typo (#30092)
PR Close #30092
2019-04-26 16:31:04 -07:00
2ae26ce20b build: upgrade yargs package to 13.1.0 (#29722)
Update yargs, because the old version was transitively (via os-local) depending on a vulnerable version of the mem package: https://app.snyk.io/vuln/npm:mem:20180117

PR Close #29722
2019-04-26 16:29:29 -07:00
d47de60944 fix(ivy): @Component should support entry components from another module (#29566)
PR Close #29566
2019-04-26 16:27:19 -07:00
acfcf90528 refactor: use new Http library in playground (#29355)
PR Close #29355
2019-04-26 16:26:30 -07:00
c99d379cc8 refactor(ivy): move di tests for inject to acceptance (#29299)
PR Close #29299
2019-04-26 16:23:43 -07:00
0151ad432b refactor(ivy): move di tests for flags to acceptance (#29299)
Including tests for `@Optional`, `@Self`, `@SkipSelf` and `@Host`.

PR Close #29299
2019-04-26 16:23:43 -07:00
1b0be8d656 refactor(ivy): move di tests for directive injection to acceptance (#29299)
PR Close #29299
2019-04-26 16:23:43 -07:00
47244ba2b8 refactor(ivy): move di tests for DI tokens to acceptance (#29299)
Move tests for special tokens like `Injector`, `ElementRef`, `TemplateRef`, `ViewContainerRef`, `ChangeDectetorRef` and custom string tokens.

PR Close #29299
2019-04-26 16:23:43 -07:00
0d66844ad6 refactor(ivy): move di tests for Attribute to acceptance (#29299)
PR Close #29299
2019-04-26 16:23:42 -07:00
b945bc3a9e test(ivy): pin deps on hello world size tests (#30152)
We recently had an unexpected size regression in the hello world
tests because the CLI devkit released an RC that regressed us and
the dependencies were not pinned. This change ensures that we only
update dependencies like devkit deliberately, so we do not have
mysterious breakages caused by other packages.

PR Close #30152
2019-04-26 12:34:10 -07:00
4ae0ee86cb fix(bazel): update peerDep ranges (#30155)
PR Close #30155
2019-04-26 12:32:35 -07:00
6c86ae710a fix(ivy): output should not be subscribe twice when 2 listeners (#30144)
PR Close #30144
2019-04-26 11:11:09 -07:00
f3ce8eeb83 fix(ivy): property bindings use correct indices (#30129)
- Extracts and documents code that will be common to interpolation instructions
- Ensures that binding indices are updated at the proper time during compilation
- Adds additional tests

Related #30011

PR Close #30129
2019-04-26 11:09:51 -07:00
876ceb3688 docs: remove note about ivy being coupled to dynamic import (#30151)
PR Close #30151
2019-04-26 11:08:51 -07:00
ee12c45473 build: bazel ts-api-guardian usage fails on workspaces which don't depend on chalk (#30138)
When using the npm package in a workspace which doesn't depend on chalk, ts-api-guardian fails with an error `Error: Cannot find module 'chalk'`

PR Close #30138
2019-04-26 11:08:05 -07:00
1f4c380f58 fix(bazel): Exclude common/upgrade* in metadata.tsconfig.json (#30133)
It has a dependency on @angular/upgrade which is not part of the
dependencies in package.json, so postinstall would fail.

PR Close #30133
2019-04-26 11:07:34 -07:00
b9f0720c95 refactor(ivy): undeprecate inject (#30132)
PR Close #30132
2019-04-26 11:06:42 -07:00
71b8b355a6 fix(ivy): remove debug utilities from ivy production builds (#30130)
Prior to this commit, we were pulling DebugNode and DebugElement
into production builds because BrowserModule automatically pulled
in NgProbe and thus getDebugNode. In Ivy, this is not necessary
because Ivy has its own set of debug utilities. We should use these
existing tools instead of NgProbe.

This commit adds an Ivy switch so we do not pull in NgProbe utilities
when running with Ivy. This saves us ~8KB in prod builds.

PR Close #30130
2019-04-26 11:04:47 -07:00
1363 changed files with 109609 additions and 49090 deletions

View File

@ -1,3 +1,4 @@
.git
node_modules
dist
aio/content

View File

@ -1,14 +1,3 @@
###############################
# Typescript / Angular / Sass #
###############################
# Make compilation fast, by keeping a few copies of the compilers
# running as daemons, and cache SourceFile AST's to reduce parse time.
build --strategy=AngularTemplateCompile=worker
# TODO(alexeagle): re-enable after fixing worker instability with rxjs typings
# build --strategy=TypeScriptCompile=worker
build --strategy=TypeScriptCompile=standalone
# Enable debugging tests with --config=debug
test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test_strategy=exclusive --test_timeout=9999 --nocache_test_results
@ -85,12 +74,6 @@ query --output=label_kind
# By default, failing tests don't print any output, it goes to the log file
test --test_output=errors
# Show which actions are run under workers,
# and print all the actions running in parallel.
# Helps to demonstrate that bazel uses all the cores on the machine.
build --experimental_ui
test --experimental_ui
################################
# Settings for CircleCI #
################################
@ -154,6 +137,31 @@ build:remote --bes_results_url="https://source.cloud.google.com/results/invocati
# This allows us to avoid installing a second copy of node_modules
common --experimental_allow_incremental_repository_updates
# This option is changed to true in Bazel 0.27 and exposes a possible
# regression in Bazel 0.27.0.
# Error observed is in npm_package target `//packages/common/locales:package`:
# ```
# ERROR: /home/circleci/ng/packages/common/locales/BUILD.bazel:13:1: Assembling
# npm package packages/common/locales/package failed: No usable spawn strategy found
# for spawn with mnemonic SkylarkAction. Your --spawn_strategyor --strategy flags
# are probably too strict. Visit https://github.com/bazelbuild/bazel/issues/7480 for
# migration advises
# ```
# Suspect is https://github.com/bazelbuild/rules_nodejs/blob/master/internal/npm_package/npm_package.bzl#L75-L82:
# ```
# execution_requirements = {
# # Never schedule this action remotely because it's not computationally expensive.
# # It just copies files into a directory; it's not worth copying inputs and outputs to a remote worker.
# # Also don't run it in a sandbox, because it resolves an absolute path to the bazel-out directory
# # allowing the .pack and .publish runnables to work with no symlink_prefix
# # See https://github.com/bazelbuild/rules_nodejs/issues/187
# "local": "1",
# },
# ```
build --incompatible_list_based_execution_strategy_selection=false
test --incompatible_list_based_execution_strategy_selection=false
run --incompatible_list_based_execution_strategy_selection=false
####################################################
# User bazel configuration
# NOTE: This needs to be the *last* entry in the config.

View File

@ -1,42 +0,0 @@
# Heavily based on https://github.com/StefanScherer/dockerfiles-windows/ images.
# Combines the node windowsservercore image with the Bazel Prerequisites (https://docs.bazel.build/versions/master/install-windows.html).
# msys install taken from https://github.com/StefanScherer/dockerfiles-windows/issues/30
# VS redist install taken from https://github.com/StefanScherer/dockerfiles-windows/blob/master/apache/Dockerfile
# The nanoserver image won't work because MSYS2 does not run in it https://github.com/Alexpux/MSYS2-packages/issues/1493
# Before building this image, you must locally build node-windows:10.13.0-windowsservercore-1803.
# Clone https://github.com/StefanScherer/dockerfiles-windows/commit/4ce7101a766b9b880ac262479dd9126b64d656cf and build using
# docker build -t node-windows:10.13.0-windowsservercore-1803 --build-arg core=microsoft/windowsservercore:1803 --build-arg target=microsoft/windowsservercore:1803 .
FROM node-windows:10.13.0-windowsservercore-1803
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
# Install 7zip to extract msys2
RUN Invoke-WebRequest -UseBasicParsing 'https://www.7-zip.org/a/7z1805-x64.exe' -OutFile 7z.exe
# For some reason the last letter in the destination directory is lost. So '/D=C:\\7zip0' will extract to '/D=C:\\7zip'.
RUN Start-Process -FilePath 'C:\\7z.exe' -ArgumentList '/S', '/D=C:\\7zip0' -NoNewWindow -Wait
# Extract msys2
RUN Invoke-WebRequest -UseBasicParsing 'http://repo.msys2.org/distrib/x86_64/msys2-base-x86_64-20180531.tar.xz' -OutFile msys2.tar.xz
RUN Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'e', 'msys2.tar.xz' -Wait
RUN Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'x', 'msys2.tar', '-oC:\\' -Wait
RUN Remove-Item msys2.tar.xz
RUN Remove-Item msys2.tar
RUN Remove-Item 7z.exe
RUN Remove-Item -Recurse 7zip
# Add MSYS2 to PATH, and set BAZEL_SH
RUN [Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\msys64\usr\bin', [System.EnvironmentVariableTarget]::Machine)
RUN [Environment]::SetEnvironmentVariable('BAZEL_SH', 'C:\msys64\usr\bin\bash.exe', [System.EnvironmentVariableTarget]::Machine)
# Install Microsoft Visual C++ Redistributable for Visual Studio 2015
RUN Invoke-WebRequest -UseBasicParsing 'https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe' -OutFile vc_redist.x64.exe
RUN Start-Process 'c:\\vc_redist.x64.exe' -ArgumentList '/Install', '/Passive', '/NoRestart' -NoNewWindow -Wait
RUN Remove-Item vc_redist.x64.exe
# Add a fix for https://github.com/docker/for-win/issues/2920 as entry point to the container.
SHELL ["cmd", "/c"]
COPY "fix-msys64.cmd" "C:\\fix-msys64.cmd"
ENTRYPOINT cmd /C C:\\fix-msys64.cmd && cmd /c
CMD ["cmd.exe"]

View File

@ -1,96 +0,0 @@
# BuildKite configuration
This folder contains configuration for the [BuildKite](https://buildkite.com) based CI checks for
this repository.
BuildKite is a CI provider that provides build coordination and reports while we provide the
infrastructure.
CI runs are triggered by new PRs and will show up on the GitHub checks interface, along with the
other current CI solutions.
Currently it is only used for tests on Windows platforms.
## The build pipeline
BuildKite uses a pipeline for each repository. The `pipeline.yml` file defines pipeline
[build steps](https://buildkite.com/docs/pipelines/defining-steps) for this repository.
Run results can be seen in the GitHub checks interface and in the
[pipeline dashboard](https://buildkite.com/angular/angular).
Although most configuration is done via `pipeline.yml`, some options are only available
in the online [pipeline settings](https://buildkite.com/angular/angular/settings).
## Infrastructure
BuildKite does not provide the host machines where the builds runs, providing instead the
[BuildKite Agent](https://buildkite.com/docs/agent/v3) that should be run our own infrastructure.
### Agents
This agent polls the BuildKite API for builds, runs them, and reports back the results.
Agents are the unit of concurrency: each agent can run one build at any given time.
Adding agents allows more builds to be ran at the same time.
Individual agents can have tags, and pipeline steps can target only agents with certain tags via the
`agents` field in `pipeline.yml`.
For example: agents on Windows machines are tagged as `windows`, and the Windows specific build
steps list `windows: true` in their `agents` field.
You can see the current agent pool, along with their tags, in the
[agents list](https://buildkite.com/organizations/angular/agents).
### Our host machines
We use [Google Cloud](https://cloud.google.com/) as our cloud provider, under the
[Angular project](https://console.cloud.google.com/home/dashboard?project=internal-200822).
To access this project you need need to be logged in with a Google account that's a member of
team@angular.io.
For googlers this may be your google.com account, for others it is an angular.io account.
In this project we have a number of Windows VMs running, each of them with several agents.
The `provision-windows-buildkite.ps1` file contains instructions on how to create new host VMs that
are fully configured to run the BuildKite agents as services.
Our pipeline uses [docker-buildkite-plugin](https://github.com/buildkite-plugins/docker-buildkite-plugin)
to run build steps inside docker containers.
This way we achieve isolation and hermeticity.
The `Dockerfile` file describes a custom Docker image that includes NodeJs, Yarn, and the Bazel
pre-requisites on Windows.
To upload a new version of the docker image, follow any build instructions in `Dockerfile` and then
run `docker build -t angular/node-bazel-windows:NEW_VERSION`, followed by
`docker push angular/node-bazel-windows:NEW_VERSION`.
After being pushed it should be available online, and you can use the new version in `pipeline.yml`.
## Caretaker
BuildKite status can be found at https://www.buildkitestatus.com/.
Issues related to the BuildKite setup should be escalated to the Tools Team via the current
caretaker, followed by Alex Eagle and Filipe Silva.
Support requests should be submitted via email to support@buildkite.com and cc Igor, Misko, Alex,
Jeremy and Manu
## Rollout strategy
At the moment our BuildKite CI uses 1 host VM running 4 agents, thus being capable of 4 concurrent
builds.
The only test running is `bazel test //tools/ts-api-guardian:all`, and the PR check is not
mandatory.
In the future we should add cache support to speed up the initial `yarn` install, and also Bazel
remote caching to speed up Bazel builds.
After the current setup is verified as stable and reliable the GitHub PR check can become mandatory.
The tests ran should also be expanded to cover most, if not all, of the Bazel tests.

View File

@ -1,6 +0,0 @@
@echo off
REM Fix for https://github.com/docker/for-win/issues/2920
REM echo "Fixing msys64 folder..."
REM Touch all .dll files inside C:\msys64\
forfiles /p C:\msys64\ /s /m *.dll /c "cmd /c Copy /B @path+,, >NUL"
REM echo "Fixed msys64 folder."

View File

@ -1,10 +0,0 @@
steps:
- label: windows-test
commands:
- "yarn install --frozen-lockfile --non-interactive --network-timeout 100000"
- "yarn bazel test //tools/ts-api-guardian:all --noshow_progress"
plugins:
- docker#v2.1.0:
image: "filipesilva/node-bazel-windows:0.0.2"
agents:
windows: true

View File

@ -1,94 +0,0 @@
# PowerShell script to provision a Windows Server with BuildKite
# This script follows https://buildkite.com/docs/agent/v3/windows.
# Instructions
# VM creation:
# In Google Cloud Platform, create a Compute Engine instance.
# We recommend machine type n1-standard-16 (16 vCPUs, 60 GB memory).
# Use a recent windows boot disk with container support such as
# "Windows Server version 1803 Datacenter Core for Containers", and add a 128GB SSD disk.
# Give it a name, then click "Create".
# VM setup:
# In the Compute Engine menu, select "VM Instances". Click on the VM name you chose before.
# Click "Set Windows Password" to choose a username and password.
# Click RDP to open a remote desktop via browser, using the username and password.
# In the Windows command prompt start an elevated powershell by inputing
# "powershell -Command "Start-Process PowerShell -Verb RunAs" followed by Enter.
# Download and execute this script from GitHub, passing the token (mandatory), tags (optional)
# and number of agents (optional) as args:
# ```
# Invoke-WebRequest -Uri https://raw.githubusercontent.com/angular/angular/master/.buildkite/provision-windows-buildkite.ps1 -OutFile provision.ps1
# .\provision.ps1 -token "MY_TOKEN" -tags "windows=true,another_tag=true" -agents 4
# ```
# The VM should restart and be fully configured.
# Creating extra VMs
# You can create an image of the current VM by following the instructions below.
# https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image
# Then create a new VM and choose "Custom images".
# Script proper.
# Get the token and tags from arguments.
param (
[Parameter(Mandatory=$true)][string]$token,
[string]$tags = "",
[Int]$agents = 1
)
# Allow HTTPS
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
# Helper to add to PATH.
# Will take current PATH so avoid running it after anything to modifies only the powershell session path.
function Add-Path ([string]$newPathItem) {
$Env:Path+= ";" + $newPathItem + ";"
[Environment]::SetEnvironmentVariable("Path",$env:Path, [System.EnvironmentVariableTarget]::Machine)
}
# Install Git for Windows
Write-Host "Installing Git for Windows."
Invoke-WebRequest -Uri https://github.com/git-for-windows/git/releases/download/v2.19.1.windows.1/Git-2.19.1-64-bit.exe -OutFile git.exe
.\git.exe /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /COMPONENTS="icons,ext\reg\shellhere,assoc,assoc_sh" /DIR="C:\git"
Add-Path "C:\git\bin"
# Sleep for 15s while git is installed. Trying to remove the git.exe before it finishes install causes an error.
Start-Sleep -s 15
Remove-Item git.exe
# Download NSSM (https://nssm.cc/) to run the BuildKite agent as a service.
Write-Host "Downloading NSSM."
Invoke-WebRequest -Uri https://nssm.cc/ci/nssm-2.24-101-g897c7ad.zip -OutFile nssm.zip
Expand-Archive -Path nssm.zip -DestinationPath C:\nssm
Add-Path "C:\nssm\nssm-2.24-101-g897c7ad\win64"
Remove-Item nssm.zip
# Run the BuildKite agent install script
Write-Host "Installing BuildKite agent."
$env:buildkiteAgentToken = $token
$env:buildkiteAgentTags = $tags
Set-ExecutionPolicy Bypass -Scope Process -Force
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/buildkite/agent/master/install.ps1'))
# Configure the BuildKite agent clone and timestamp behavior
Add-Content C:\buildkite-agent\buildkite-agent.cfg "`ngit-clone-flags=--config core.autocrlf=input --config core.eol=lf --config core.longpaths=true --config core.symlinks=true`n"
Add-Content C:\buildkite-agent\buildkite-agent.cfg "`ntimestamp-lines=true`n"
# Register the BuildKite agent service using NSSM, so that it persists through restarts and is
# restarted if the process dies.
for ($i=1; $i -le $agents; $i++)
{
$agentName = "buildkite-agent-$i"
Write-Host "Registering $agentName as a service."
nssm.exe install $agentName "C:\buildkite-agent\bin\buildkite-agent.exe" "start"
nssm.exe set $agentName AppStdout "C:\buildkite-agent\$agentName.log"
nssm.exe set $agentName AppStderr "C:\buildkite-agent\$agentName.log"
nssm.exe status $agentName
nssm.exe start $agentName
nssm.exe status $agentName
}
# Restart the machine.
Restart-Computer

View File

@ -28,3 +28,14 @@ test --flaky_test_attempts=2
# More details on failures
build --verbose_failures=true
# We have seen some flakiness in using TS workers on CircleCI
# https://angular-team.slack.com/archives/C07DT5M6V/p1562693245183400
# > failures like `ERROR: /home/circleci/ng/packages/core/test/BUILD.bazel:5:1:
# > Compiling TypeScript (devmode) //packages/core/test:test_lib failed: Worker process did not return a WorkResponse:`
# > I saw that issue a couple times today.
# > Example job: https://circleci.com/gh/angular/angular/385517
# We expect that TypeScript compilations will parallelize wider than the number of local cores anyway
# so we should saturate remote workers with TS compilations
build --strategy=TypeScriptCompile=standalone
build --strategy=AngularTemplateCompile=standalone

View File

@ -58,17 +58,7 @@ var_5: &setup_bazel_remote_execution
# cause decryption failures based on the openssl version. https://stackoverflow.com/a/39641378/4317734
openssl aes-256-cbc -d -in .circleci/gcp_token -md md5 -k "$CI_REPO_NAME" -out /home/circleci/.gcp_credentials
echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/circleci/.gcp_credentials" >> $BASH_ENV
touch .bazelrc.user
sudo bash -c "echo -e 'build --config=remote\n' >> .bazelrc.user"
sudo bash -c "echo -e 'build:remote --remote_accept_cached=true\n' >> .bazelrc.user"
echo "Reading from remote cache for bazel remote jobs."
if [[ "$CI_PULL_REQUEST" == "false" ]]; then
sudo bash -c "echo -e 'build:remote --remote_upload_local_results=true\n' >> .bazelrc.user"
echo "Uploading local build results to remote cache."
else
sudo bash -c "echo -e 'build:remote --remote_upload_local_results=false\n' >> .bazelrc.user"
echo "Not uploading local build results to remote cache."
fi
./.circleci/setup-rbe.sh .bazelrc.user
# Settings common to each job
var_6: &job_defaults
@ -138,7 +128,7 @@ var_13: &notify_caretaker_on_fail
# `$SLACK_CARETAKER_WEBHOOK_URL` is a secret env var defined in CircleCI project settings.
# The URL comes from https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
command: |
notificationJson="{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}"
notificationJson="{\"text\":\":x: \`$CIRCLE_JOB\` job for $CIRCLE_BRANCH branch failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}"
curl --request POST --header "Content-Type: application/json" --data "$notificationJson" $SLACK_CARETAKER_WEBHOOK_URL
var_14: &notify_dev_infra_on_fail
@ -148,9 +138,14 @@ var_14: &notify_dev_infra_on_fail
# `$SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL` is a secret env var defined in CircleCI project settings.
# The URL comes from https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
command: |
notificationJson="{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}"
notificationJson="{\"text\":\":x: \`$CIRCLE_JOB\` job for $CIRCLE_BRANCH branch failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}"
curl --request POST --header "Content-Type: application/json" --data "$notificationJson" $SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
# Cache key for the Material unit tests job. **Note** when updating the SHA in the cache keys,
# also update the SHA for the "MATERIAL_REPO_COMMIT" environment variable.
var_15: &material_unit_tests_cache_key v4-angular-material-701302dc482d7e4b77990b24e3b5ab330bbf1aa5
var_16: &material_unit_tests_cache_key_short v4-angular-material
version: 2
jobs:
setup:
@ -203,6 +198,13 @@ jobs:
# Setup remote execution and run RBE-compatible tests.
- *setup_bazel_remote_execution
- run: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only
- run: mkdir ~/testlogs
- run: cp -Lr dist/testlogs/* ~/testlogs
- store_test_results:
# Bazel always writes test.xml files under this directory
path: ~/testlogs
- store_artifacts:
path: ~/testlogs
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_aot:
@ -238,6 +240,11 @@ jobs:
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js.br
destination: core/todo/bundle.br
# This job is currently a PoC for running tests on SauceLabs via bazel. It runs a subset of the
# tests in `legacy-unit-tests-saucelabs` (see
# [BUILD.bazel](https://github.com/angular/angular/blob/ef44f51d5/BUILD.bazel#L66-L92)).
#
# NOTE: This is currently limited to master builds only. See the `default_workflow` configuration.
test_saucelabs_bazel:
<<: *job_defaults
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
@ -286,6 +293,8 @@ jobs:
- run: yarn --cwd aio e2e --configuration=ci
# Run PWA-score tests
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Run accessibility tests
- run: yarn --cwd aio test-a11y-score-localhost
# Check the bundle sizes.
- run: yarn --cwd aio payload-size
# Run unit tests for Firebase redirects
@ -394,7 +403,7 @@ jobs:
# Run examples tests with ivy. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
# Since the parallelism is set to "3", there will be three parallel CircleCI containers
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
- run: yarn --cwd aio example-e2e --setup --local --ivy --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
- run: yarn --cwd aio example-e2e --setup --local --ivy --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
aio_preview:
@ -611,44 +620,55 @@ jobs:
resource_class: xlarge
docker:
- image: *browsers_docker_image
# The Material unit tests support splitting the browsers across multiple CircleCI
# instances. Since by default this job launches two browsers, we run each browser
# in its own container instance.
# https://github.com/angular/material2/blob/7baeaa797b19da2d2998f0d26f6fede3c8a13714/test/karma.conf.js#L107-L110
parallelism: 2
environment:
# The Material unit tests also support launching the same browser multiple times by
# sharding individual specs across the defined multiple instances.
# See: https://github.com/angular/material2/blob/7baeaa797b19da2d2998f0d26f6fede3c8a13714/test/karma.conf.js#L113-L116
KARMA_PARALLEL_BROWSERS: 3
steps:
- *attach_workspace
- *init_environment
- run:
name: "Cloning Material repository"
command: ./scripts/ci/clone_angular_material_repo.sh
# Although RBE is configured below for the Material repo, also setup RBE in the Angular repo
# to provision Angular's GCP token into the environment variables.
- *setup_bazel_remote_execution
# Restore the cache before cloning the repository because the clone script re-uses
# the restored repository if present. This reduces the amount of times the components
# repository needs to be cloned (this is slow and increases based on commits in the repo).
- restore_cache:
# Material directory must be kept in sync with the `$MATERIAL_REPO_TMP_DIR` env variable.
# It needs to be hardcoded here, because env variables interpolation is not supported.
keys:
- v2-angular-material-{{ checksum "/tmp/material2/yarn.lock" }}
- v2-angular-material-
- *material_unit_tests_cache_key
- *material_unit_tests_cache_key_short
- run:
name: "Fetching Material repository"
command: ./scripts/ci/clone_angular_material_repo.sh
- run:
# Run yarn install to fetch the Bazel binaries as used in the Material repo.
name: Installing Material dependencies.
command: yarn --cwd ${MATERIAL_REPO_TMP_DIR} install --frozen-lockfile --non-interactive
# Save the cache before we run the Material unit tests script. This is necessary
# because we don't want to cache the node modules which have been modified to contain
# the attached Ivy package output.
- save_cache:
# Material directory must be kept in sync with the `$MATERIAL_REPO_TMP_DIR` env variable.
# It needs to be hardcoded here, because env variables interpolation is not supported.
key: v2-angular-material-{{ checksum "/tmp/material2/yarn.lock" }}
key: *material_unit_tests_cache_key
paths:
- "/tmp/material2/node_modules"
# Material directory must be kept in sync with the `$MATERIAL_REPO_TMP_DIR` env variable.
# It needs to be hardcoded here, because env variables interpolation is not supported.
- "/tmp/material2"
- run:
name: "Setup Bazel RBE remote execution in Material repo"
command: |
./.circleci/setup-rbe.sh "${MATERIAL_REPO_TMP_DIR}/.bazelrc.user"
- run:
name: "Running Material unit tests"
command: ./scripts/ci/run_angular_material_unit_tests.sh
test_zonejs:
<<: *job_defaults
steps:
- *attach_workspace
- *init_environment
# Install
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
# Run zone.js tools tests
- run: yarn --cwd packages/zone.js promisetest
- run: yarn --cwd packages/zone.js promisefinallytest
- run: yarn bazel build //packages/zone.js:npm_package &&
cp dist/bin/packages/zone.js/npm_package/dist/zone-mix.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/dist/zone-patch-electron.js ./packages/zone.js/test/extra/ &&
yarn --cwd packages/zone.js electrontest
workflows:
version: 2
default_workflow:
@ -656,31 +676,41 @@ workflows:
- setup
- lint:
requires:
- setup
- setup
- test:
requires:
- setup
- setup
- test_ivy_aot:
requires:
- setup
- setup
- build-npm-packages:
requires:
- setup
- setup
- build-ivy-npm-packages:
requires:
- setup
- test_aio:
requires:
- setup
- legacy-unit-tests-saucelabs:
requires:
- setup
- deploy_aio:
requires:
- test_aio
- setup
- legacy-misc-tests:
requires:
- build-npm-packages
- legacy-unit-tests-saucelabs:
requires:
- setup
- test_saucelabs_bazel:
requires:
- setup
# This job is currently a PoC and a subset of `legacy-unit-tests-saucelabs`. Running on
# master only to avoid wasting resources.
#
# TODO: Run this job on all branches (including PRs) as soon as it is not a PoC.
filters:
branches:
only: master
- test_aio:
requires:
- setup
- deploy_aio:
requires:
- test_aio
- test_aio_local:
requires:
- build-npm-packages
@ -733,22 +763,9 @@ workflows:
- material-unit-tests:
requires:
- build-ivy-npm-packages
saucelabs_tests:
jobs:
- setup
- test_saucelabs_bazel:
- test_zonejs:
requires:
- setup
triggers:
- schedule:
# Runs the Saucelabs legacy tests every hour. We still want to run Saucelabs
# frequently as the caretaker needs up-to-date results when merging PRs or creating
# a new release. Also we primarily moved the Saucelabs job into a cronjob that doesn't
# run for PRs, in order to ensure that PRs are not affected by Saucelabs flakiness or
# incidents. This is still guaranteed (even if we run the job every hour).
cron: "0 * * * *"
filters: *publish_branches_filter
aio_monitoring:
jobs:

View File

@ -77,7 +77,9 @@ setPublicVar SAUCE_READY_FILE_TIMEOUT 120
# their separate build setups.
setPublicVar MATERIAL_REPO_TMP_DIR "/tmp/material2"
setPublicVar MATERIAL_REPO_URL "https://github.com/angular/material2.git"
setPublicVar MATERIAL_REPO_BRANCH "ivy-2019"
setPublicVar MATERIAL_REPO_BRANCH "master"
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI "config.yml".
setPublicVar MATERIAL_REPO_COMMIT "701302dc482d7e4b77990b24e3b5ab330bbf1aa5"
# Source `$BASH_ENV` to make the variables available immediately.
source $BASH_ENV;

Binary file not shown.

20
.circleci/setup-rbe.sh Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -u -e -o pipefail
# The path of the .bazelrc.user file to update should be passed as first parameter to this script.
# This allows to setup RBE for both the Angular repo and the Material repo.
bazelrc_user="$1"
echo "Writing RBE configuration to ${bazelrc_user}"
touch ${bazelrc_user}
echo -e 'build --config=remote\n' >> ${bazelrc_user}
echo -e 'build:remote --remote_accept_cached=true\n' >> ${bazelrc_user}
echo "Reading from remote cache for bazel remote jobs."
if [[ "$CI_PULL_REQUEST" == "false" ]]; then
echo -e 'build:remote --remote_upload_local_results=true\n' >> ${bazelrc_user}
echo "Uploading local build results to remote cache."
else
echo -e 'build:remote --remote_upload_local_results=false\n' >> ${bazelrc_user}
echo "Not uploading local build results to remote cache."
fi

View File

@ -1,3 +1,5 @@
# escape=`
ARG core=mcr.microsoft.com/windows/servercore:1809
ARG target=mcr.microsoft.com/powershell:windowsservercore-1809
@ -10,57 +12,57 @@ SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPref
ENV GPG_VERSION 2.3.4
RUN Invoke-WebRequest $('https://files.gpg4win.org/gpg4win-vanilla-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg4win.exe' -UseBasicParsing ; \
RUN Invoke-WebRequest $('https://files.gpg4win.org/gpg4win-vanilla-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg4win.exe' -UseBasicParsing ; `
Start-Process .\gpg4win.exe -ArgumentList '/S' -NoNewWindow -Wait
RUN @( \
'94AE36675C464D64BAFA68DD7434390BDBE9B9C5', \
'FD3A5288F042B6850C66B31F09FE44734EB7990E', \
'71DCFD284A79C3B38668286BC97EC7A07EDE3FC1', \
'DD8F2338BAE7501E3DD5AC78C273792F7D83545D', \
'C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8', \
'B9AE9905FFD7803F25714661B63B535A4C206CA9', \
'77984A986EBC2AA786BC0F66B01FBB92821C587A', \
'8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600', \
'4ED778F539E3634C779C87C6D7062848A1AB005C', \
'A48C2BEE680E841632CD4E44F07496B3EB3C1762', \
'B9E2F5981AA6E0CD28160D9FF13993A75599653C' \
) | foreach { \
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys $_ ; \
RUN @( `
'94AE36675C464D64BAFA68DD7434390BDBE9B9C5', `
'FD3A5288F042B6850C66B31F09FE44734EB7990E', `
'71DCFD284A79C3B38668286BC97EC7A07EDE3FC1', `
'DD8F2338BAE7501E3DD5AC78C273792F7D83545D', `
'C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8', `
'B9AE9905FFD7803F25714661B63B535A4C206CA9', `
'77984A986EBC2AA786BC0F66B01FBB92821C587A', `
'8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600', `
'4ED778F539E3634C779C87C6D7062848A1AB005C', `
'A48C2BEE680E841632CD4E44F07496B3EB3C1762', `
'B9E2F5981AA6E0CD28160D9FF13993A75599653C' `
) | foreach { `
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys $_ ; `
}
ENV NODE_VERSION=$node_version
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/SHASUMS256.txt.asc' -f $env:NODE_VERSION) -OutFile 'SHASUMS256.txt.asc' -UseBasicParsing ; \
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/SHASUMS256.txt.asc' -f $env:NODE_VERSION) -OutFile 'SHASUMS256.txt.asc' -UseBasicParsing ; `
gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION) -OutFile 'node.zip' -UseBasicParsing ; \
$sum = $(cat SHASUMS256.txt.asc | sls $(' node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; \
if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; \
Expand-Archive node.zip -DestinationPath C:\ ; \
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION) -OutFile 'node.zip' -UseBasicParsing ; `
$sum = $(cat SHASUMS256.txt.asc | sls $(' node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; `
if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; `
Expand-Archive node.zip -DestinationPath C:\ ; `
Rename-Item -Path $('C:\node-v{0}-win-x64' -f $env:NODE_VERSION) -NewName 'C:\nodejs'
ENV YARN_VERSION=$yarn_version
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \
Invoke-WebRequest $('https://yarnpkg.com/downloads/{0}/yarn-{0}.msi' -f $env:YARN_VERSION) -OutFile yarn.msi -UseBasicParsing ; \
$sig = Get-AuthenticodeSignature yarn.msi ; \
if ($sig.Status -ne 'Valid') { Write-Error 'Authenticode signature is not valid' } ; \
Write-Output $sig.SignerCertificate.Thumbprint ; \
if (@( \
'7E253367F8A102A91D04829E37F3410F14B68A5F', \
'AF764E1EA56C762617BDC757C8B0F3780A0CF5F9' \
) -notcontains $sig.SignerCertificate.Thumbprint) { Write-Error 'Unknown signer certificate' } ; \
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
Invoke-WebRequest $('https://yarnpkg.com/downloads/{0}/yarn-{0}.msi' -f $env:YARN_VERSION) -OutFile yarn.msi -UseBasicParsing ; `
$sig = Get-AuthenticodeSignature yarn.msi ; `
if ($sig.Status -ne 'Valid') { Write-Error 'Authenticode signature is not valid' } ; `
Write-Output $sig.SignerCertificate.Thumbprint ; `
if (@( `
'7E253367F8A102A91D04829E37F3410F14B68A5F', `
'AF764E1EA56C762617BDC757C8B0F3780A0CF5F9' `
) -notcontains $sig.SignerCertificate.Thumbprint) { Write-Error 'Unknown signer certificate' } ; `
Start-Process msiexec.exe -ArgumentList '/i', 'yarn.msi', '/quiet', '/norestart' -NoNewWindow -Wait
ENV GIT_VERSION 2.20.1
ENV GIT_DOWNLOAD_URL https://github.com/git-for-windows/git/releases/download/v${GIT_VERSION}.windows.1/MinGit-${GIT_VERSION}-busybox-64-bit.zip
ENV GIT_SHA256 9817ab455d9cbd0b09d8664b4afbe4bbf78d18b556b3541d09238501a749486c
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \
Invoke-WebRequest -UseBasicParsing $env:GIT_DOWNLOAD_URL -OutFile git.zip; \
if ((Get-FileHash git.zip -Algorithm sha256).Hash -ne $env:GIT_SHA256) {exit 1} ; \
Expand-Archive git.zip -DestinationPath C:\git; \
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
Invoke-WebRequest -UseBasicParsing $env:GIT_DOWNLOAD_URL -OutFile git.zip; `
if ((Get-FileHash git.zip -Algorithm sha256).Hash -ne $env:GIT_SHA256) {exit 1} ; `
Expand-Archive git.zip -DestinationPath C:\git; `
Remove-Item git.zip
FROM $target as baseimage
@ -74,30 +76,51 @@ COPY --from=download /git /git
ARG SETX=/M
RUN setx %SETX% PATH "%PATH%;C:\nodejs;C:\yarn\bin;C:\git\cmd;C:\git\mingw64\bin;C:\git\usr\bin"
CMD [ "node.exe" ]
CMD [ "node.exe" ]
FROM baseimage
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
RUN Invoke-WebRequest -UseBasicParsing 'https://www.7-zip.org/a/7z1805-x64.exe' -OutFile 7z.exe; \
Start-Process -FilePath 'C:\\7z.exe' -ArgumentList '/S', '/D=C:\\7zip0' -NoNewWindow -Wait; \
Invoke-WebRequest -UseBasicParsing 'http://repo.msys2.org/distrib/x86_64/msys2-base-x86_64-20180531.tar.xz' -OutFile msys2.tar.xz; \
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'e', 'msys2.tar.xz' -Wait; \
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'x', 'msys2.tar', '-oC:\\' -Wait; \
Remove-Item msys2.tar.xz; \
Remove-Item msys2.tar; \
Remove-Item 7z.exe; \
Remove-Item -Recurse 7zip; \
[Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\msys64\usr\bin', [System.EnvironmentVariableTarget]::Machine); \
[Environment]::SetEnvironmentVariable('BAZEL_SH', 'C:\msys64\usr\bin\bash.exe', [System.EnvironmentVariableTarget]::Machine); \
Invoke-WebRequest -UseBasicParsing 'https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe' -OutFile vc_redist.x64.exe; \
Start-Process 'c:\\vc_redist.x64.exe' -ArgumentList '/Install', '/Passive', '/NoRestart' -NoNewWindow -Wait; \
Remove-Item vc_redist.x64.exe
# Install Bazel prereqs on Windows (https://docs.bazel.build/versions/master/install-windows.html)
# Add a fix for https://github.com/docker/for-win/issues/2920 as entry point to the container.
SHELL ["cmd", "/c"]
COPY "fix-msys64.cmd" "C:\\fix-msys64.cmd"
ENTRYPOINT cmd /C C:\\fix-msys64.cmd && cmd /c
# Install MSYS2
RUN Invoke-WebRequest -UseBasicParsing 'https://www.7-zip.org/a/7z1805-x64.exe' -OutFile 7z.exe; `
Start-Process -FilePath 'C:\\7z.exe' -ArgumentList '/S', '/D=C:\\7zip0' -NoNewWindow -Wait; `
Invoke-WebRequest -UseBasicParsing 'http://repo.msys2.org/distrib/x86_64/msys2-base-x86_64-20180531.tar.xz' -OutFile msys2.tar.xz; `
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'e', 'msys2.tar.xz' -Wait; `
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'x', 'msys2.tar', '-oC:\\' -Wait; `
Remove-Item msys2.tar.xz; `
Remove-Item msys2.tar; `
Remove-Item 7z.exe; `
Remove-Item -Recurse 7zip; `
[Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\msys64\usr\bin', [System.EnvironmentVariableTarget]::Machine); `
[Environment]::SetEnvironmentVariable('BAZEL_SH', 'C:\msys64\usr\bin\bash.exe', [System.EnvironmentVariableTarget]::Machine)
CMD ["cmd.exe"]
# Install MSYS2 packages
RUN C:\msys64\usr\bin\bash.exe -l -c \"pacman --needed --noconfirm -S zip unzip patch diffutils git\"
# Install VS Build Tools (required to build C++ targets)
RUN Invoke-WebRequest -UseBasicParsing https://download.visualstudio.microsoft.com/download/pr/df649173-11e9-4af2-8eb7-0eb02ba8958a/cadb5bdac41e55bb8f6a6b7c45273370/vs_buildtools.exe -OutFile vs_BuildTools.exe; `
# Installer won't detect DOTNET_SKIP_FIRST_TIME_EXPERIENCE if ENV is used, must use setx /M
setx /M DOTNET_SKIP_FIRST_TIME_EXPERIENCE 1; `
Start-Process vs_BuildTools.exe `
-ArgumentList `
'--add', 'Microsoft.VisualStudio.Workload.VCTools', `
'--add', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64', `
'--add', 'Microsoft.Component.VC.Runtime.UCRTSDK', `
'--add', 'Microsoft.VisualStudio.Component.Windows10SDK.17763', `
'--quiet', '--norestart', '--nocache' `
-NoNewWindow -Wait; `
Remove-Item -Force vs_buildtools.exe; `
Remove-Item -Force -Recurse \"${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\"; `
Remove-Item -Force -Recurse ${Env:TEMP}\*; `
Remove-Item -Force -Recurse \"${Env:ProgramData}\Package Cache\"; `
[Environment]::SetEnvironmentVariable('BAZEL_VC', \"${Env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\BuildTools\VC\", [System.EnvironmentVariableTarget]::Machine)
# Install Python (required to build Python targets)
RUN Invoke-WebRequest -UseBasicParsing https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile python-3.5.1.exe; `
Start-Process python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait; `
Remove-Item -Force python-3.5.1.exe
CMD ["cmd.exe"]

View File

@ -2,11 +2,17 @@
# We do this by copying this file to /etc/bazel.bazelrc at the start of the build.
# See documentation in /docs/BAZEL.md
# Save downloaded repositories in a location that can be cached by CodeFresh and shared between
# builds. This helps speed up the analysis time significantly with Bazel managed node dependencies
# on the CI.
# Save built files and downloaded repositories in a location that can be cached by CodeFresh and
# shared between builds. This helps speed up the analysis time significantly with Bazel managed node
# dependencies on the CI.
# https://codefresh.io/docs/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#caching-the-artifacts-of-your-build-system
build --repository_cache=C:/codefresh/volume/bazel_repository_cache
# Setting the output_base to a Docker volume is currently broken because of a Docker bug on Windows:
# https://github.com/moby/moby/issues/37024
# This affects Bazel because bazel_output_base\external\bazel_tools is an absolute path junction.
# When its fixed we can uncomment this line, and use a different output_base for Ivy tests (they
# use a separate compiler and destructively replace the cache).
# startup --output_base=C:/codefresh/volume/bazel_output_base
# Don't be spammy in the logs
# TODO(gmagolan): Hide progress again once build performance improves
@ -23,20 +29,10 @@ build --announce_rc
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
# Limit Bazel to consuming resources that fit in CodeFresh VMs
# TODO(filipesilva): determine the correct memory limit
build --local_resources=8000,8.0,1.0
build --local_resources=10240,8.0,1.0
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
test --flaky_test_attempts=2
# More details on failures
build --verbose_failures=true
# Include PATH in Windows build/tests
# https://github.com/bazelbuild/rules_typescript/pull/356
build --action_env=PATH
test --action_env=PATH --test_env=PATH
# Exclude tests known to not work on Windows.
# Chrome web tests are currently broken.
test --test_tag_filters=-browser:chromium-local

View File

@ -2,6 +2,7 @@ version: '1.0'
steps:
BuildImage:
title: Build Docker image
type: build
image_name: node-bazel-windows
working_directory: ./.codefresh
@ -12,7 +13,7 @@ steps:
dockerfile: ./Dockerfile.win-1809
RunTests:
title: Run Example
title: Run Bazel tests
image: ${{BuildImage}}
commands:
# Install dependencies
@ -20,7 +21,8 @@ steps:
# Add Bazel CI config
- copy .codefresh\bazel.rc %ProgramData%\bazel.bazelrc
# Run tests
- yarn bazel test //tools/ts-api-guardian:all //packages/language-service/test //packages/compiler/test //packages/compiler-cli/test:ngc //packages/compiler-cli/test/ngtsc:ngtsc
- yarn test-ivy-aot //packages/animations/test //packages/common/test //packages/forms/test //packages/http/test //packages/platform-browser/test //packages/platform-browser-dynamic/test //packages/router/test
- yarn bazel test //tools/public_api_guard/...
- yarn bazel test //packages/compiler-cli/integrationtest:integrationtest //packages/compiler-cli/test/compliance:compliance
# At the moment 'browser:chromium-local' are broken in CI while locally they work
# VE
- yarn bazel test --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-browser:chromium-local //...
# Ivy
- yarn bazel test --define=compile=aot --build_tag_filters=-no-ivy-aot,-fixme-ivy-aot --test_tag_filters=-no-ivy-aot,-fixme-ivy-aot,-browser:chromium-local //...

View File

@ -1,6 +0,0 @@
@echo off
REM Fix for https://github.com/docker/for-win/issues/2920
REM echo "Fixing msys64 folder..."
REM Touch all .dll files inside C:\msys64\
forfiles /p C:\msys64\ /s /m *.dll /c "cmd /c Copy /B @path+,, >NUL"
REM echo "Fixed msys64 folder."

View File

@ -18,15 +18,15 @@ filegroup(
name = "web_test_bootstrap_scripts",
# do not sort
srcs = [
"@npm//node_modules/core-js:client/core.js",
"@npm//node_modules/zone.js:dist/zone.js",
"@npm//node_modules/zone.js:dist/zone-testing.js",
"@npm//node_modules/zone.js:dist/task-tracking.js",
"@npm//:node_modules/core-js/client/core.js",
"@npm//:node_modules/zone.js/dist/zone.js",
"@npm//:node_modules/zone.js/dist/zone-testing.js",
"@npm//:node_modules/zone.js/dist/task-tracking.js",
"//:test-events.js",
"//:shims_for_IE.js",
# Including systemjs because it defines `__eval`, which produces correct stack traces.
"@npm//node_modules/systemjs:dist/system.src.js",
"@npm//node_modules/reflect-metadata:Reflect.js",
"@npm//:node_modules/systemjs/dist/system.src.js",
"@npm//:node_modules/reflect-metadata/Reflect.js",
],
)
@ -35,15 +35,15 @@ filegroup(
srcs = [
# We also declare the unminfied AngularJS files since these can be used for
# local debugging (e.g. see: packages/upgrade/test/common/test_helpers.ts)
"@npm//node_modules/angular:angular.js",
"@npm//node_modules/angular:angular.min.js",
"@npm//node_modules/angular-1.5:angular.js",
"@npm//node_modules/angular-1.5:angular.min.js",
"@npm//node_modules/angular-1.6:angular.js",
"@npm//node_modules/angular-1.6:angular.min.js",
"@npm//node_modules/angular-mocks:angular-mocks.js",
"@npm//node_modules/angular-mocks-1.5:angular-mocks.js",
"@npm//node_modules/angular-mocks-1.6:angular-mocks.js",
"@npm//:node_modules/angular/angular.js",
"@npm//:node_modules/angular/angular.min.js",
"@npm//:node_modules/angular-1.5/angular.js",
"@npm//:node_modules/angular-1.5/angular.min.js",
"@npm//:node_modules/angular-1.6/angular.js",
"@npm//:node_modules/angular-1.6/angular.min.js",
"@npm//:node_modules/angular-mocks/angular-mocks.js",
"@npm//:node_modules/angular-mocks-1.5/angular-mocks.js",
"@npm//:node_modules/angular-mocks-1.6/angular-mocks.js",
],
)
@ -74,6 +74,7 @@ karma_web_test(
"//packages/core/test:test_lib",
"//packages/forms/test:test_lib",
"//packages/http/test:test_lib",
"//packages/zone.js/test:karma_jasmine_test_ci",
# "//packages/router/test:test_lib",
# //packages/router/test:test_lib fails with:
# IE 11.0.0 (Windows 8.1.0.0) bootstrap should restore the scrolling position FAILED

View File

@ -1,3 +1,140 @@
<a name="8.2.0-rc.0"></a>
# [8.2.0-rc.0](https://github.com/angular/angular/compare/8.2.0-next.2...8.2.0-rc.0) (2019-07-26)
### Bug Fixes
* **bazel:** increase memory limit of ngc under bazel from 2 to 4 GB ([#31784](https://github.com/angular/angular/issues/31784)) ([5a8eb92](https://github.com/angular/angular/commit/5a8eb92))
* **core:** allow Z variations of CSS transforms in sanitizer ([#29264](https://github.com/angular/angular/issues/29264)) ([78e7fdd](https://github.com/angular/angular/commit/78e7fdd))
* **elements:** handle falsy initial value ([#31604](https://github.com/angular/angular/issues/31604)) ([7151eae](https://github.com/angular/angular/commit/7151eae)), closes [angular/angular#30834](https://github.com/angular/angular/issues/30834)
* **platform-browser:** debug element query predicates not compatible with strictFunctionTypes ([#30993](https://github.com/angular/angular/issues/30993)) ([10a1e19](https://github.com/angular/angular/commit/10a1e19))
### Features
* **bazel:** compile targets used for indexing by Kythe with Ivy ([#31786](https://github.com/angular/angular/issues/31786)) ([82055b2](https://github.com/angular/angular/commit/82055b2))
* **upgrade:** support $element in upgraded component template/templateUrl functions ([#31637](https://github.com/angular/angular/issues/31637)) ([29e1c53](https://github.com/angular/angular/commit/29e1c53))
### Performance Improvements
* **compiler:** avoid copying from prototype while cloning an object ([#31638](https://github.com/angular/angular/issues/31638)) ([24ca582](https://github.com/angular/angular/commit/24ca582)), closes [#31627](https://github.com/angular/angular/issues/31627)
<a name="8.1.3"></a>
## [8.1.3](https://github.com/angular/angular/compare/8.1.2...8.1.3) (2019-07-26)
### Bug Fixes
* **elements:** handle falsy initial value ([#31604](https://github.com/angular/angular/issues/31604)) ([434b796](https://github.com/angular/angular/commit/434b796)), closes [angular/angular#30834](https://github.com/angular/angular/issues/30834)
### Performance Improvements
* **compiler:** avoid copying from prototype while cloning an object ([#31638](https://github.com/angular/angular/issues/31638)) ([1f3daa0](https://github.com/angular/angular/commit/1f3daa0)), closes [#31627](https://github.com/angular/angular/issues/31627)
<a name="8.2.0-next.2"></a>
# [8.2.0-next.2](https://github.com/angular/angular/compare/8.2.0-next.1...8.2.0-next.2) (2019-07-17)
### Bug Fixes
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([9204de9](https://github.com/angular/angular/commit/9204de9))
* **bazel:** pass custom bazel compiler host rather than rewriting one ([#31496](https://github.com/angular/angular/issues/31496)) ([0c61a35](https://github.com/angular/angular/commit/0c61a35))
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([3166cff](https://github.com/angular/angular/commit/3166cff)), closes [#22524](https://github.com/angular/angular/issues/22524)
* **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2))
<a name="8.1.2"></a>
## [8.1.2](https://github.com/angular/angular/compare/8.1.0...8.1.2) (2019-07-17)
### Bug Fixes
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([4aed480](https://github.com/angular/angular/commit/4aed480))
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([13dbb98](https://github.com/angular/angular/commit/13dbb98)), closes [#22524](https://github.com/angular/angular/issues/22524)
* **core:** export provider interfaces that are part of the public API types ([#31377](https://github.com/angular/angular/issues/31377)) ([bebf089](https://github.com/angular/angular/commit/bebf089)), closes [/github.com/angular/angular/pull/31377#discussion_r299254408](https://github.com//github.com/angular/angular/pull/31377/issues/discussion_r299254408) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L365-L366](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L365-L366) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L283-L284](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L283-L284) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts#L23](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts/issues/L23)
<a name="8.2.0-next.1"></a>
# [8.2.0-next.1](https://github.com/angular/angular/compare/8.2.0-next.0...8.2.0-next.1) (2019-07-10)
### Bug Fixes
* **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227))
* **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21))
### Features
* **core:** add automatic migration from Renderer to Renderer2 ([#30936](https://github.com/angular/angular/issues/30936)) ([c095597](https://github.com/angular/angular/commit/c095597))
<a name="8.1.1"></a>
## [8.1.1](https://github.com/angular/angular/compare/8.1.0...8.1.1) (2019-07-10)
### Bug Fixes
* **core:** export provider interfaces that are part of the public API types ([#31377](https://github.com/angular/angular/issues/31377)) ([bebf089](https://github.com/angular/angular/commit/bebf089)), closes [/github.com/angular/angular/pull/31377#discussion_r299254408](https://github.com//github.com/angular/angular/pull/31377/issues/discussion_r299254408) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L365-L366](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L365-L366) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L283-L284](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L283-L284) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts#L23](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts/issues/L23)
<a name="8.2.0-next.0"></a>
# [8.2.0-next.0](https://github.com/angular/angular/compare/8.1.0-rc.0...8.2.0-next.0) (2019-07-02)
### Bug Fixes
* **core:** handle `undefined` meta in `injectArgs` ([#31333](https://github.com/angular/angular/issues/31333)) ([80ccd6c](https://github.com/angular/angular/commit/80ccd6c)), closes [CLI #14888](https://github.com/angular/angular-cli/issues/14888)
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968)
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35))
### Features
* **bazel:** allow passing a custom bazel compiler host to ngc compile ([#31341](https://github.com/angular/angular/issues/31341)) ([a29dc96](https://github.com/angular/angular/commit/a29dc96))
* **bazel:** allow passing and rewriting an old bazel host ([#31381](https://github.com/angular/angular/issues/31381)) ([11a208f](https://github.com/angular/angular/commit/11a208f)), closes [#31341](https://github.com/angular/angular/issues/31341)
<a name="8.1.0"></a>
# [8.1.0](https://github.com/angular/angular/compare/8.1.0-rc.0...8.1.0) (2019-07-02)
### Bug Fixes
* **core:** handle `undefined` meta in `injectArgs` ([#31333](https://github.com/angular/angular/issues/31333)) ([80ccd6c](https://github.com/angular/angular/commit/80ccd6c)), closes [CLI #14888](https://github.com/angular/angular-cli/issues/14888)
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([b0c3453](https://github.com/angular/angular/commit/b0c3453)), closes [#30968](https://github.com/angular/angular/issues/30968)
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([a9038ef](https://github.com/angular/angular/commit/a9038ef))
<a name="8.1.0-rc.0"></a>
# [8.1.0-rc.0](https://github.com/angular/angular/compare/8.1.0-next.3...8.1.0-rc.0) (2019-06-26)
### Bug Fixes
* **bazel:** exclude all angular schematics folders from metadata build ([#31237](https://github.com/angular/angular/issues/31237)) ([16717fa](https://github.com/angular/angular/commit/16717fa)), closes [#31235](https://github.com/angular/angular/issues/31235)
* **bazel:** remove unsupported Css pre-processors from ng new ([#31234](https://github.com/angular/angular/issues/31234)) ([e83667a](https://github.com/angular/angular/commit/e83667a)), closes [#31209](https://github.com/angular/angular/issues/31209)
* **bazel:** update ng new schema to match the current ng new schema of [@schematics](https://github.com/schematics)/angular ([#31234](https://github.com/angular/angular/issues/31234)) ([805fc86](https://github.com/angular/angular/commit/805fc86)), closes [#31233](https://github.com/angular/angular/issues/31233)
* **compiler:** fix Elements not making a new ParseSourceSpan ([#31190](https://github.com/angular/angular/issues/31190)) ([7035f22](https://github.com/angular/angular/commit/7035f22))
* **compiler:** stringify `Object.create(null)` tokens ([#16848](https://github.com/angular/angular/issues/16848)) ([5e53956](https://github.com/angular/angular/commit/5e53956))
* **service-worker:** registration failed on Safari ([#31140](https://github.com/angular/angular/issues/31140)) ([a5dd4ed](https://github.com/angular/angular/commit/a5dd4ed)), closes [#31061](https://github.com/angular/angular/issues/31061)
### Features
* **upgrade:** provide unit test helpers for wiring up injectors ([#16848](https://github.com/angular/angular/issues/16848)) ([3fb78aa](https://github.com/angular/angular/commit/3fb78aa))
<a name="8.0.3"></a>
## [8.0.3](https://github.com/angular/angular/compare/8.0.2...8.0.3) (2019-06-26)
@ -11,6 +148,18 @@
<a name="8.1.0-next.3"></a>
# [8.1.0-next.3](https://github.com/angular/angular/compare/8.1.0-next.2...8.1.0-next.3) (2019-06-19)
### Bug Fixes
* **bazel:** builder workspace should use nodejs v10.16.0 ([#31088](https://github.com/angular/angular/issues/31088)) ([a1fc4de](https://github.com/angular/angular/commit/a1fc4de))
* **core:** temporarily remove [@deprecated](https://github.com/deprecated) jsdoc tag for a TextBedStatic.get overload ([#30714](https://github.com/angular/angular/issues/30714)) ([6bc9c78](https://github.com/angular/angular/commit/6bc9c78)), closes [#30514](https://github.com/angular/angular/issues/30514)
* **language-service:** Remove 'any' in getQuickInfoAtPosition ([#31014](https://github.com/angular/angular/issues/31014)) ([a4601ec](https://github.com/angular/angular/commit/a4601ec))
<a name="8.0.2"></a>
## [8.0.2](https://github.com/angular/angular/compare/8.0.1...8.0.2) (2019-06-19)
@ -23,6 +172,20 @@
<a name="8.1.0-next.2"></a>
# [8.1.0-next.2](https://github.com/angular/angular/compare/8.1.0-next.1...8.1.0-next.2) (2019-06-13)
### Bug Fixes
* **bazel:** do not modify tsconfig.json ([#30877](https://github.com/angular/angular/issues/30877)) ([b086676](https://github.com/angular/angular/commit/b086676))
* **bazel:** exclude components schematics from build ([#30825](https://github.com/angular/angular/issues/30825)) ([05a43ca](https://github.com/angular/angular/commit/05a43ca))
* **bazel:** Load global stylesheet in dev and prod ([#30879](https://github.com/angular/angular/issues/30879)) ([17bfedd](https://github.com/angular/angular/commit/17bfedd))
* **common:** expose the `HttpUploadProgressEvent` interface as public API ([#30852](https://github.com/angular/angular/issues/30852)) ([5c18f23](https://github.com/angular/angular/commit/5c18f23)), closes [#30814](https://github.com/angular/angular/issues/30814)
* **service-worker:** avoid uncaught rejection warning when registration fails ([#30876](https://github.com/angular/angular/issues/30876)) ([81c2a94](https://github.com/angular/angular/commit/81c2a94))
<a name="8.0.1"></a>
## [8.0.1](https://github.com/angular/angular/compare/8.0.0...8.0.1) (2019-06-13)
@ -37,24 +200,83 @@
<a name="8.1.0-next.1"></a>
# [8.1.0-next.1](https://github.com/angular/angular/compare/8.1.0-beta.0...8.1.0-next.1) (2019-06-05)
### Bug Fixes
* **core:** TypeScript related migrations should cater for BOM ([#30719](https://github.com/angular/angular/issues/30719)) ([80394ce](https://github.com/angular/angular/commit/80394ce)), closes [/github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts#L72](https://github.com//github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts/issues/L72) [#30713](https://github.com/angular/angular/issues/30713)
<a name="8.1.0-beta.0"></a>
# [8.1.0-beta.0](https://github.com/angular/angular/compare/8.0.0...8.1.0-beta.0) (2019-05-30)
### Bug Fixes
* **bazel:** allow ts_library interop with list-typed inputs ([#30600](https://github.com/angular/angular/issues/30600)) ([3125376](https://github.com/angular/angular/commit/3125376))
* **bazel:** Bump ibazel to 0.10.1 for windows fixes ([#30196](https://github.com/angular/angular/issues/30196)) ([1353bf0](https://github.com/angular/angular/commit/1353bf0))
* **bazel:** Directly spawn native Bazel binary ([#30306](https://github.com/angular/angular/issues/30306)) ([2a0f497](https://github.com/angular/angular/commit/2a0f497))
* **bazel:** Disable sandbox on Mac OS ([#30460](https://github.com/angular/angular/issues/30460)) ([b6b1aec](https://github.com/angular/angular/commit/b6b1aec))
* **bazel:** Exclude common/upgrade* in metadata.tsconfig.json ([#30133](https://github.com/angular/angular/issues/30133)) ([1f4c380](https://github.com/angular/angular/commit/1f4c380))
* **bazel:** ng test should run specific ts_web_test_suite ([#30526](https://github.com/angular/angular/issues/30526)) ([e688e02](https://github.com/angular/angular/commit/e688e02))
* **bazel:** pass correct arguments to http_server in Windows ([#30346](https://github.com/angular/angular/issues/30346)) ([3aff79c](https://github.com/angular/angular/commit/3aff79c)), closes [#29785](https://github.com/angular/angular/issues/29785)
* **bazel:** update peerDep ranges ([#30155](https://github.com/angular/angular/issues/30155)) ([4ae0ee8](https://github.com/angular/angular/commit/4ae0ee8))
* **bazel:** Use existing npm/yarn lock files ([#30438](https://github.com/angular/angular/issues/30438)) ([ff29ccc](https://github.com/angular/angular/commit/ff29ccc))
* **compiler-cli:** log ngcc skipping messages as debug instead of info ([#30232](https://github.com/angular/angular/issues/30232)) ([60a8888](https://github.com/angular/angular/commit/60a8888))
* **core:** consistently use ng:/// for sourcemap URLs ([#29826](https://github.com/angular/angular/issues/29826)) ([392473e](https://github.com/angular/angular/commit/392473e))
* **core:** CSS sanitizer now allows parens in file names ([#30322](https://github.com/angular/angular/issues/30322)) ([728db88](https://github.com/angular/angular/commit/728db88))
* **core:** fix interpolate identifier in AOT ([#30243](https://github.com/angular/angular/issues/30243)) ([30d1f29](https://github.com/angular/angular/commit/30d1f29))
* **core:** migrations not always migrating all files ([#30269](https://github.com/angular/angular/issues/30269)) ([349935a](https://github.com/angular/angular/commit/349935a))
* **core:** remove deprecated `TestBed.deprecatedOverrideProvider` API ([#30576](https://github.com/angular/angular/issues/30576)) ([a96976e](https://github.com/angular/angular/commit/a96976e))
* **core:** require 'static' flag on queries in typings ([#30639](https://github.com/angular/angular/issues/30639)) ([84dd267](https://github.com/angular/angular/commit/84dd267))
* **core:** static-query migration errors not printed properly ([#30458](https://github.com/angular/angular/issues/30458)) ([6ceb903](https://github.com/angular/angular/commit/6ceb903))
* **core:** static-query migration fails with default parameter values ([#30269](https://github.com/angular/angular/issues/30269)) ([6357d4a](https://github.com/angular/angular/commit/6357d4a))
* **core:** static-query migration should gracefully exit if AOT compiler throws ([#30269](https://github.com/angular/angular/issues/30269)) ([509352f](https://github.com/angular/angular/commit/509352f))
* **core:** static-query migration should handle queries on accessors ([#30327](https://github.com/angular/angular/issues/30327)) ([0ffdb48](https://github.com/angular/angular/commit/0ffdb48))
* **core:** static-query migration should not fallback to test strategy ([#30458](https://github.com/angular/angular/issues/30458)) ([0cdf598](https://github.com/angular/angular/commit/0cdf598))
* **core:** static-query migration should not prompt if no queries are used ([#30254](https://github.com/angular/angular/issues/30254)) ([4c12d74](https://github.com/angular/angular/commit/4c12d74))
* **core:** static-query usage migration strategy should detect ambiguous query usage ([#30215](https://github.com/angular/angular/issues/30215)) ([8d3365e](https://github.com/angular/angular/commit/8d3365e))
* **core:** temporarily remove [@deprecated](https://github.com/deprecated) jsdoc tag for a TextBed.get overload ([#30514](https://github.com/angular/angular/issues/30514)) ([f6bf892](https://github.com/angular/angular/commit/f6bf892)), closes [#29290](https://github.com/angular/angular/issues/29290) [#29905](https://github.com/angular/angular/issues/29905)
* **language-service:** Remove tsserverlibrary from rollup globals ([#30123](https://github.com/angular/angular/issues/30123)) ([124e497](https://github.com/angular/angular/commit/124e497))
* **router:** ensure `history.state` is set in `eager` update mode ([#30154](https://github.com/angular/angular/issues/30154)) ([b40f6f3](https://github.com/angular/angular/commit/b40f6f3))
* **router:** ensure navigations start with the current URL value incase redirect is skipped ([#30344](https://github.com/angular/angular/issues/30344)) ([0fd9d08](https://github.com/angular/angular/commit/0fd9d08)), closes [#30340](https://github.com/angular/angular/issues/30340) [#30160](https://github.com/angular/angular/issues/30160)
* **router:** fix a problem with router not responding to back button ([#30160](https://github.com/angular/angular/issues/30160)) ([3327bd8](https://github.com/angular/angular/commit/3327bd8))
* **router:** IE 11 bug can break URL unification when comparing objects ([#30393](https://github.com/angular/angular/issues/30393)) ([197584d](https://github.com/angular/angular/commit/197584d))
* **router:** type cast correctly for IE 11 bug breaking URL Unification when comparing objects ([#30464](https://github.com/angular/angular/issues/30464)) ([53f3564](https://github.com/angular/angular/commit/53f3564))
### Features
* **bazel:** use `rbe_autoconfig()` and new container. ([#29336](https://github.com/angular/angular/issues/29336)) ([9abf114](https://github.com/angular/angular/commit/9abf114))
* **common:** add ability to watch for AngularJS URL updates through `onUrlChange` hook ([#30466](https://github.com/angular/angular/issues/30466)) ([1aff524](https://github.com/angular/angular/commit/1aff524))
* **common:** stricter types for `SlicePipe` ([#30156](https://github.com/angular/angular/issues/30156)) ([95830ee](https://github.com/angular/angular/commit/95830ee))
* **core:** deprecate integration with the Web Tracing Framework (WTF) ([#30642](https://github.com/angular/angular/issues/30642)) ([f310a59](https://github.com/angular/angular/commit/f310a59))
* **language-service:** Implement `definitionAndBoundSpan` ([#30125](https://github.com/angular/angular/issues/30125)) ([f491673](https://github.com/angular/angular/commit/f491673))
* **platform-webworker:** deprecate platform-webworker ([#30642](https://github.com/angular/angular/issues/30642)) ([ccc76f7](https://github.com/angular/angular/commit/ccc76f7))
<a name="8.0.0"></a>
# [8.0.0](https://github.com/angular/angular/compare/8.0.0-rc.5...8.0.0) (2019-05-28)
### Features
* add support for TypeScript 3.3 (and drop older versions) ([#29004](https://github.com/angular/angular/issues/29004)) ([75748d6](https://github.com/angular/angular/commit/75748d6))
* add support for TypeScript 3.4 (and drop older versions) ([#29372](https://github.com/angular/angular/issues/29372)) ([ef85336](https://github.com/angular/angular/commit/ef85336))
* **common:** add ability to watch for AngularJS URL updates through `onUrlChange` hook ([#30466](https://github.com/angular/angular/issues/30466)) ([8022d36](https://github.com/angular/angular/commit/8022d36))
* **common:** stricter types for SlicePipe ([#30156](https://github.com/angular/angular/issues/30156)) ([722b2fa](https://github.com/angular/angular/commit/722b2fa))
* **bazel:** use rbe_autoconfig() and new container. ([#29336](https://github.com/angular/angular/issues/29336)) ([e562acc](https://github.com/angular/angular/commit/e562acc))
* **common:** add [@angular](https://github.com/angular)/common/upgrade package for $location-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
* **common:** add ability to retrieve the state from Location service ([#30055](https://github.com/angular/angular/issues/30055)) ([b44b143](https://github.com/angular/angular/commit/b44b143))
* **common:** stricter types for `SlicePipe` ([#30156](https://github.com/angular/angular/issues/30156)) ([722b2fa](https://github.com/angular/angular/commit/722b2fa))
* **bazel:** use `rbe_autoconfig()` and new container ([#29336](https://github.com/angular/angular/issues/29336)) ([e562acc](https://github.com/angular/angular/commit/e562acc))
* **common:** add @angular/common/upgrade package for `$location`-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
* **common:** add ability to retrieve the state from `Location` service ([#30055](https://github.com/angular/angular/issues/30055)) ([b44b143](https://github.com/angular/angular/commit/b44b143))
* **common:** add ability to track all location changes ([#30055](https://github.com/angular/angular/issues/30055)) ([3a9cf3f](https://github.com/angular/angular/commit/3a9cf3f))
* **common:** add APIs to read component pieces of URL ([#30055](https://github.com/angular/angular/issues/30055)) ([b635fe8](https://github.com/angular/angular/commit/b635fe8))
* **common:** add MockPlatformLocation to enable more robust testing of Location services ([#30055](https://github.com/angular/angular/issues/30055)) ([d0672c2](https://github.com/angular/angular/commit/d0672c2))
* **common:** add UrlCodec type for use with upgrade applications ([#30055](https://github.com/angular/angular/issues/30055)) ([ec455e1](https://github.com/angular/angular/commit/ec455e1))
* **common:** add `MockPlatformLocation` to enable more robust testing of `Location` services ([#30055](https://github.com/angular/angular/issues/30055)) ([d0672c2](https://github.com/angular/angular/commit/d0672c2))
* **common:** add `UrlCodec` type for use with upgrade applications ([#30055](https://github.com/angular/angular/issues/30055)) ([ec455e1](https://github.com/angular/angular/commit/ec455e1))
* **common:** provide replacement for AngularJS $location service ([#30055](https://github.com/angular/angular/issues/30055)) ([4277600](https://github.com/angular/angular/commit/4277600))
* remove deprecated DOCUMENT token from platform-browser ([#28117](https://github.com/angular/angular/issues/28117)) ([3a9d247](https://github.com/angular/angular/commit/3a9d247))
* remove deprecated `DOCUMENT` token from platform-browser ([#28117](https://github.com/angular/angular/issues/28117)) ([3a9d247](https://github.com/angular/angular/commit/3a9d247))
* **compiler:** support skipping leading trivia in template source-maps ([#30095](https://github.com/angular/angular/issues/30095)) ([304a12f](https://github.com/angular/angular/commit/304a12f))
* **core:** add missing ARIA attributes to html sanitizer ([#29685](https://github.com/angular/angular/issues/29685)) ([909557d](https://github.com/angular/angular/commit/909557d)), closes [#26815](https://github.com/angular/angular/issues/26815)
* **router:** deprecate loadChildren:string ([#30073](https://github.com/angular/angular/issues/30073)) ([c61df39](https://github.com/angular/angular/commit/c61df39))
@ -63,28 +285,28 @@
* **service-worker:** support bypassing SW with specific header/query param ([#30010](https://github.com/angular/angular/issues/30010)) ([6200732](https://github.com/angular/angular/commit/6200732)), closes [#21191](https://github.com/angular/angular/issues/21191)
* **compiler-cli:** export tooling definitions ([#29929](https://github.com/angular/angular/issues/29929)) ([e1f51ea](https://github.com/angular/angular/commit/e1f51ea))
* **compiler-cli:** lower some exported expressions ([#30038](https://github.com/angular/angular/issues/30038)) ([8e73f9b](https://github.com/angular/angular/commit/8e73f9b))
* **core:** add schematics to move deprecated DOCUMENT import ([#29950](https://github.com/angular/angular/issues/29950)) ([645e305](https://github.com/angular/angular/commit/645e305))
* **core:** add schematics to move deprecated `DOCUMENT` import ([#29950](https://github.com/angular/angular/issues/29950)) ([645e305](https://github.com/angular/angular/commit/645e305))
* **bazel:** update the build to use the new architect api ([#29720](https://github.com/angular/angular/issues/29720)) ([902a53a](https://github.com/angular/angular/commit/902a53a))
* remove [@angular](https://github.com/angular)/http dependency from [@angular](https://github.com/angular)/platform-server ([#29408](https://github.com/angular/angular/issues/29408)) ([9745f55](https://github.com/angular/angular/commit/9745f55))
* remove @angular/http dependency from @angular/platform-server ([#29408](https://github.com/angular/angular/issues/29408)) ([9745f55](https://github.com/angular/angular/commit/9745f55))
* **compiler-cli:** ngcc - make logging more configurable ([#29591](https://github.com/angular/angular/issues/29591)) ([8d3d75e](https://github.com/angular/angular/commit/8d3d75e))
* **core:** Add "AbstractType<T>" interface ([#29295](https://github.com/angular/angular/issues/29295)) ([afd4a4e](https://github.com/angular/angular/commit/afd4a4e)), closes [#26491](https://github.com/angular/angular/issues/26491)
* **core:** Add `AbstractType<T>` interface ([#29295](https://github.com/angular/angular/issues/29295)) ([afd4a4e](https://github.com/angular/angular/commit/afd4a4e)), closes [#26491](https://github.com/angular/angular/issues/26491)
* **core:** template-var-assignment update schematic ([#29608](https://github.com/angular/angular/issues/29608)) ([7c8f4e3](https://github.com/angular/angular/commit/7c8f4e3))
* **bazel:** Upgrade rules_nodejs and rules_sass ([#29388](https://github.com/angular/angular/issues/29388)) ([d6d081e](https://github.com/angular/angular/commit/d6d081e))
* **service-worker:** support multiple apps on different subpaths of a domain ([#27080](https://github.com/angular/angular/issues/27080)) ([e721c08](https://github.com/angular/angular/commit/e721c08)), closes [#21388](https://github.com/angular/angular/issues/21388)
* **bazel:** Eject Bazel ([#29167](https://github.com/angular/angular/issues/29167)) ([36a1550](https://github.com/angular/angular/commit/36a1550))
* **bazel:** Hide Bazel files in Bazel builder ([#29110](https://github.com/angular/angular/issues/29110)) ([7060d90](https://github.com/angular/angular/commit/7060d90))
* **forms:** clear (remove all) components from a FormArray ([#28918](https://github.com/angular/angular/issues/28918)) ([a68b1a1](https://github.com/angular/angular/commit/a68b1a1)), closes [#18531](https://github.com/angular/angular/issues/18531)
* **platform-server:** wait on returned BEFORE_APP_SERIALIZED promises ([#29120](https://github.com/angular/angular/issues/29120)) ([7102ea8](https://github.com/angular/angular/commit/7102ea8))
* **platform-server:** wait on returned `BEFORE_APP_SERIALIZED` promises ([#29120](https://github.com/angular/angular/issues/29120)) ([7102ea8](https://github.com/angular/angular/commit/7102ea8))
### Bug Fixes
* **bazel:** allow ts_library interop with list-typed inputs ([#30600](https://github.com/angular/angular/issues/30600)) ([bf38df4](https://github.com/angular/angular/commit/bf38df4))
* **bazel:** allow `ts_library` interop with list-typed inputs ([#30600](https://github.com/angular/angular/issues/30600)) ([bf38df4](https://github.com/angular/angular/commit/bf38df4))
* **bazel:** Disable sandbox on Mac OS ([#30460](https://github.com/angular/angular/issues/30460)) ([3de26a8](https://github.com/angular/angular/commit/3de26a8))
* **bazel:** ng test should run specific ts_web_test_suite ([#30526](https://github.com/angular/angular/issues/30526)) ([8bc4da8](https://github.com/angular/angular/commit/8bc4da8))
* **core:** remove deprecated `TestBed.deprecatedOverrideProvider` API ([#30576](https://github.com/angular/angular/issues/30576)) ([5a46f94](https://github.com/angular/angular/commit/5a46f94))
* **core:** require 'static' flag on queries in typings ([#30641](https://github.com/angular/angular/issues/30641)) ([c8af830](https://github.com/angular/angular/commit/c8af830))
* **core:** temporarily remove [@deprecated](https://github.com/deprecated) jsdoc tag for a TextBed.get overload ([#30514](https://github.com/angular/angular/issues/30514)) ([561e01d](https://github.com/angular/angular/commit/561e01d)), closes [#29290](https://github.com/angular/angular/issues/29290) [#29905](https://github.com/angular/angular/issues/29905)
* **core:** temporarily remove [@deprecated](https://github.com/deprecated) jsdoc tag for a `TextBed.get` overload ([#30514](https://github.com/angular/angular/issues/30514)) ([561e01d](https://github.com/angular/angular/commit/561e01d)), closes [#29290](https://github.com/angular/angular/issues/29290) [#29905](https://github.com/angular/angular/issues/29905)
* **router:** type cast correctly for IE 11 bug breaking URL Unification when comparing objects ([#30464](https://github.com/angular/angular/issues/30464)) ([32daa93](https://github.com/angular/angular/commit/32daa93))
* **bazel:** Directly spawn native Bazel binary ([#30306](https://github.com/angular/angular/issues/30306)) ([d1fcc2b](https://github.com/angular/angular/commit/d1fcc2b))
* **bazel:** pass correct arguments to http_server in Windows ([#30346](https://github.com/angular/angular/issues/30346)) ([71eba45](https://github.com/angular/angular/commit/71eba45)), closes [#29785](https://github.com/angular/angular/issues/29785)
@ -100,7 +322,7 @@
* **core:** static-query usage migration strategy should detect ambiguous query usage ([#30215](https://github.com/angular/angular/issues/30215)) ([e295c6a](https://github.com/angular/angular/commit/e295c6a))
* **router:** ensure navigations start with the current URL value incase redirect is skipped ([#30344](https://github.com/angular/angular/issues/30344)) ([9b88920](https://github.com/angular/angular/commit/9b88920)), closes [#30340](https://github.com/angular/angular/issues/30340) [#30160](https://github.com/angular/angular/issues/30160)
* **router:** IE 11 bug can break URL unification when comparing objects ([#30393](https://github.com/angular/angular/issues/30393)) ([c383491](https://github.com/angular/angular/commit/c383491))
* **bazel:** Bump ibazel to 0.10.1 for windows fixes ([#30196](https://github.com/angular/angular/issues/30196)) ([9f68c35](https://github.com/angular/angular/commit/9f68c35))
* **bazel:** Bump ibazel to 0.10.1 for Windows fixes ([#30196](https://github.com/angular/angular/issues/30196)) ([9f68c35](https://github.com/angular/angular/commit/9f68c35))
* **compiler-cli:** log ngcc skipping messages as debug instead of info ([#30232](https://github.com/angular/angular/issues/30232)) ([548b003](https://github.com/angular/angular/commit/548b003))
* **core:** fix interpolate identifier in AOT ([#30243](https://github.com/angular/angular/issues/30243)) ([3fe3a84](https://github.com/angular/angular/commit/3fe3a84))
* **router:** ensure `history.state` is set in `eager` update mode ([#30154](https://github.com/angular/angular/issues/30154)) ([9720227](https://github.com/angular/angular/commit/9720227))
@ -110,57 +332,54 @@
* **bazel:** Exclude common/upgrade* in metadata.tsconfig.json ([#30133](https://github.com/angular/angular/issues/30133)) ([6711f22](https://github.com/angular/angular/commit/6711f22))
* **bazel:** update peerDep ranges ([#30155](https://github.com/angular/angular/issues/30155)) ([6067583](https://github.com/angular/angular/commit/6067583))
* **bazel:** make name param in ng add optional ([#30074](https://github.com/angular/angular/issues/30074)) ([0b5f480](https://github.com/angular/angular/commit/0b5f480))
* **bazel:** Make sure only single copy of `[@angular](https://github.com/angular)/bazel` is installed ([#30072](https://github.com/angular/angular/issues/30072)) ([2905bf5](https://github.com/angular/angular/commit/2905bf5))
* **bazel:** Make sure only single copy of @angular/bazel is installed ([#30072](https://github.com/angular/angular/issues/30072)) ([2905bf5](https://github.com/angular/angular/commit/2905bf5))
* **bazel:** transitive npm deps in ng_module ([#30065](https://github.com/angular/angular/issues/30065)) ([61365a9](https://github.com/angular/angular/commit/61365a9))
* **common:** add upgrade sub-package to ng_package rule for [@angular](https://github.com/angular)/common ([#30117](https://github.com/angular/angular/issues/30117)) ([6de4cbd](https://github.com/angular/angular/commit/6de4cbd)), closes [#30055](https://github.com/angular/angular/issues/30055) [#30116](https://github.com/angular/angular/issues/30116)
* **common:** adjust MockPlatformLocation to set state to new object ([#30055](https://github.com/angular/angular/issues/30055)) ([825efa8](https://github.com/angular/angular/commit/825efa8))
* **common:** add upgrade sub-package to `ng_package` rule for @angular/common ([#30117](https://github.com/angular/angular/issues/30117)) ([6de4cbd](https://github.com/angular/angular/commit/6de4cbd)), closes [#30055](https://github.com/angular/angular/issues/30055) [#30116](https://github.com/angular/angular/issues/30116)
* **common:** adjust `MockPlatformLocation` to set state to new object ([#30055](https://github.com/angular/angular/issues/30055)) ([825efa8](https://github.com/angular/angular/commit/825efa8))
* **compiler:** Fix compiler crash due to isSkipSelf of null ([#30075](https://github.com/angular/angular/issues/30075)) ([28fd5ab](https://github.com/angular/angular/commit/28fd5ab))
* **upgrade:** do not break if `onMicrotaskEmpty` emits while a `$digest` is in progress ([#29794](https://github.com/angular/angular/issues/29794)) ([0ddf2e7](https://github.com/angular/angular/commit/0ddf2e7)), closes [#24680](https://github.com/angular/angular/issues/24680) [/github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts#L12](https://github.com//github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts/issues/L12) [#24680](https://github.com/angular/angular/issues/24680)
* **bazel:** do not typecheck core schematic files ([#29876](https://github.com/angular/angular/issues/29876)) ([2ba799d](https://github.com/angular/angular/commit/2ba799d))
* **bazel:** restore ng build --prod ([#30005](https://github.com/angular/angular/issues/30005)) ([96a8289](https://github.com/angular/angular/commit/96a8289))
* **common:** prevent repeated application of HttpParams mutations ([#29045](https://github.com/angular/angular/issues/29045)) ([8e8e89a](https://github.com/angular/angular/commit/8e8e89a)), closes [#20430](https://github.com/angular/angular/issues/20430)
* **common:** async pipe will properly check when it recieves an NaN value from an observable ([#22305](https://github.com/angular/angular/issues/22305)) ([3f6bf6d](https://github.com/angular/angular/commit/3f6bf6d)), closes [#15721](https://github.com/angular/angular/issues/15721)
* **core:** don't include a local `EventListener` in typings ([#29809](https://github.com/angular/angular/issues/29809)) ([4bde40f](https://github.com/angular/angular/commit/4bde40f)), closes [/github.com/angular/angular/blob/303eae918d997070a36b523ddc97e018f622c258/packages/core/src/debug/debug_node.ts#L32](https://github.com//github.com/angular/angular/blob/303eae918d997070a36b523ddc97e018f622c258/packages/core/src/debug/debug_node.ts/issues/L32) [#29806](https://github.com/angular/angular/issues/29806)
* **core:** use shakeable global definitions ([#29929](https://github.com/angular/angular/issues/29929)) ([e5905bb](https://github.com/angular/angular/commit/e5905bb)), closes [/github.com/angular/angular-cli/blob/5fc1f2499cbe57f9a95e4b0dfced130eb3a8046d/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts#L279-L282](https://github.com//github.com/angular/angular-cli/blob/5fc1f2499cbe57f9a95e4b0dfced130eb3a8046d/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts/issues/L279-L282)
* **bazel:** restore `ng build --prod` ([#30005](https://github.com/angular/angular/issues/30005)) ([96a8289](https://github.com/angular/angular/commit/96a8289))
* **common:** prevent repeated application of `HttpParams` mutations ([#29045](https://github.com/angular/angular/issues/29045)) ([8e8e89a](https://github.com/angular/angular/commit/8e8e89a)), closes [#20430](https://github.com/angular/angular/issues/20430)
* **common:** async pipe will properly check when it receives an NaN value from an observable ([#22305](https://github.com/angular/angular/issues/22305)) ([3f6bf6d](https://github.com/angular/angular/commit/3f6bf6d)), closes [#15721](https://github.com/angular/angular/issues/15721)
* **core:** don't include a local `EventListener` in typings ([#29809](https://github.com/angular/angular/issues/29809)) ([4bde40f](https://github.com/angular/angular/commit/4bde40f)), closes [#29806](https://github.com/angular/angular/issues/29806)
* **core:** use shakeable global definitions ([#29929](https://github.com/angular/angular/issues/29929)) ([e5905bb](https://github.com/angular/angular/commit/e5905bb))
* **language-service:** Use proper types instead of any ([#29942](https://github.com/angular/angular/issues/29942)) ([1a56cd5](https://github.com/angular/angular/commit/1a56cd5))
* **bazel:** Install packages after `ng add` when invoked independently ([#29852](https://github.com/angular/angular/issues/29852)) ([bd2ce9c](https://github.com/angular/angular/commit/bd2ce9c))
* **compiler-cli:** pass config path to ts.parseJsonConfigFileContent ([#29872](https://github.com/angular/angular/issues/29872)) ([86a3f90](https://github.com/angular/angular/commit/86a3f90)), closes [/github.com/Microsoft/TypeScript/blob/025d82633915b67003ea38ba40b9239a19721c13/src/compiler/emitter.ts#L56-L57](https://github.com//github.com/Microsoft/TypeScript/blob/025d82633915b67003ea38ba40b9239a19721c13/src/compiler/emitter.ts/issues/L56-L57)
* **compiler-cli:** pass config path to `ts.parseJsonConfigFileContent` ([#29872](https://github.com/angular/angular/issues/29872)) ([86a3f90](https://github.com/angular/angular/commit/86a3f90))
* **router:** support non-NgFactory promise in loadChildren typings ([#29832](https://github.com/angular/angular/issues/29832)) ([2bfb6a0](https://github.com/angular/angular/commit/2bfb6a0))
* **bazel:** add configuration_env_vars = ["compile"] to generated [@npm](https://github.com/npm)//[@angular](https://github.com/angular)/bazel/bin:ngc-wrapped nodejs_binary ([#29694](https://github.com/angular/angular/issues/29694)) ([2e66ddf](https://github.com/angular/angular/commit/2e66ddf))
* **bazel:** add `configuration_env_vars = ["compile"]` to generated `@npm//@angular/bazel/bin:ngc-wrapped` `nodejs_binary` ([#29694](https://github.com/angular/angular/issues/29694)) ([2e66ddf](https://github.com/angular/angular/commit/2e66ddf))
* **bazel:** docs formatting ([#29817](https://github.com/angular/angular/issues/29817)) ([cc2e4b6](https://github.com/angular/angular/commit/cc2e4b6))
* **bazel:** remove karma-jasmine from ts_web_test_suite ([#29695](https://github.com/angular/angular/issues/29695)) ([2bd9214](https://github.com/angular/angular/commit/2bd9214))
* **bazel:** remove karma-jasmine from `ts_web_test_suite` ([#29695](https://github.com/angular/angular/issues/29695)) ([2bd9214](https://github.com/angular/angular/commit/2bd9214))
* **bazel:** support running ng-add on minimal applications ([#29681](https://github.com/angular/angular/issues/29681)) ([9810c6c](https://github.com/angular/angular/commit/9810c6c)), closes [#29680](https://github.com/angular/angular/issues/29680)
* **common:** add `@Injectable()` to common pipes ([#29834](https://github.com/angular/angular/issues/29834)) ([387fbb8](https://github.com/angular/angular/commit/387fbb8))
* **compiler-cli:** ensure LogicalProjectPaths always start with a slash ([#29627](https://github.com/angular/angular/issues/29627)) ([e02684e](https://github.com/angular/angular/commit/e02684e))
* **compiler-cli:** ensure `LogicalProjectPaths` always start with a slash ([#29627](https://github.com/angular/angular/issues/29627)) ([e02684e](https://github.com/angular/angular/commit/e02684e))
* **core:** add missing migration to npm package ([#29705](https://github.com/angular/angular/issues/29705)) ([96b76dc](https://github.com/angular/angular/commit/96b76dc))
* **core:** call ngOnDestroy for tree-shakeable providers ([#28943](https://github.com/angular/angular/issues/28943)) ([30b0442](https://github.com/angular/angular/commit/30b0442)), closes [#28927](https://github.com/angular/angular/issues/28927)
* **core:** Deprecate TestBed.get(...):any ([#29290](https://github.com/angular/angular/issues/29290)) ([609024f](https://github.com/angular/angular/commit/609024f)), closes [#13785](https://github.com/angular/angular/issues/13785) [#26491](https://github.com/angular/angular/issues/26491)
* **core:** call `ngOnDestroy` for tree-shakeable providers ([#28943](https://github.com/angular/angular/issues/28943)) ([30b0442](https://github.com/angular/angular/commit/30b0442)), closes [#28927](https://github.com/angular/angular/issues/28927)
* **core:** Deprecate `TestBed.get(...):any` ([#29290](https://github.com/angular/angular/issues/29290)) ([609024f](https://github.com/angular/angular/commit/609024f)), closes [#13785](https://github.com/angular/angular/issues/13785) [#26491](https://github.com/angular/angular/issues/26491)
* **core:** resolve ts compile issues due to lenient tsconfig ([#29843](https://github.com/angular/angular/issues/29843)) ([54058ba](https://github.com/angular/angular/commit/54058ba))
* **platform-browser:** insert APP_ID in styles, contentAttr and hostAttr ([#17745](https://github.com/angular/angular/issues/17745)) ([712d60e](https://github.com/angular/angular/commit/712d60e))
* **bazel:** use //:tsconfig.json as the default for ng_module ([#29670](https://github.com/angular/angular/issues/29670)) ([#29711](https://github.com/angular/angular/issues/29711)) ([9e33dc3](https://github.com/angular/angular/commit/9e33dc3))
* **platform-browser:** insert APP_ID in styles, contentAttr and hostAttr ([#17745](https://github.com/angular/angular/issues/17745)) ([ca14509](https://github.com/angular/angular/commit/ca14509))
* **platform-browser:** insert `APP_ID` in styles, contentAttr and hostAttr ([#17745](https://github.com/angular/angular/issues/17745)) ([712d60e](https://github.com/angular/angular/commit/712d60e))
* **bazel:** Update schematics to support routing ([#29548](https://github.com/angular/angular/issues/29548)) ([401b8ee](https://github.com/angular/angular/commit/401b8ee))
* **bazel:** use //:tsconfig.json as the default for ng_module ([#29670](https://github.com/angular/angular/issues/29670)) ([b14537a](https://github.com/angular/angular/commit/b14537a))
* **bazel:** use `//:tsconfig.json` as the default for `ng_module` ([#29670](https://github.com/angular/angular/issues/29670)) ([b14537a](https://github.com/angular/angular/commit/b14537a))
* **compiler-cli:** ngcc - cope with processing entry-points multiple times ([#29657](https://github.com/angular/angular/issues/29657)) ([6b39c9c](https://github.com/angular/angular/commit/6b39c9c))
* **core:** static-query schematic should detect static queries in getters. ([#29609](https://github.com/angular/angular/issues/29609)) ([33016b8](https://github.com/angular/angular/commit/33016b8))
* **common:** escape query selector used when anchor scrolling ([#29577](https://github.com/angular/angular/issues/29577)) ([7671c73](https://github.com/angular/angular/commit/7671c73)), closes [#28193](https://github.com/angular/angular/issues/28193)
* **router:** adjust setting navigationTransition when a new navigation cancels an existing one ([#29636](https://github.com/angular/angular/issues/29636)) ([e884c0c](https://github.com/angular/angular/commit/e884c0c)), closes [#29389](https://github.com/angular/angular/issues/29389) [#29590](https://github.com/angular/angular/issues/29590)
* **bazel:** allow ng_module users to set createExternalSymbolFactoryReexports ([#29459](https://github.com/angular/angular/issues/29459)) ([21be0fb](https://github.com/angular/angular/commit/21be0fb))
* **bazel:** allow `ng_module` users to set `createExternalSymbolFactoryReexports` ([#29459](https://github.com/angular/angular/issues/29459)) ([21be0fb](https://github.com/angular/angular/commit/21be0fb))
* **bazel:** workaround problem reading summary files from node_modules ([#29459](https://github.com/angular/angular/issues/29459)) ([769d960](https://github.com/angular/angular/commit/769d960))
* **compiler:** inherit param types when class has a constructor which takes no declared parameters and delegates up ([#29232](https://github.com/angular/angular/issues/29232)) ([0007564](https://github.com/angular/angular/commit/0007564))
* **core:** parse incorrect ML open tag as text ([#29328](https://github.com/angular/angular/issues/29328)) ([dafbbf8](https://github.com/angular/angular/commit/dafbbf8)), closes [#29231](https://github.com/angular/angular/issues/29231)
* **core:** static-query schematic should detect queries in "ngDoCheck" and "ngOnChanges" ([#29492](https://github.com/angular/angular/issues/29492)) ([09fab58](https://github.com/angular/angular/commit/09fab58))
* **router:** support NgFactory promise in loadChildren typings ([#29392](https://github.com/angular/angular/issues/29392)) ([26a8c59](https://github.com/angular/angular/commit/26a8c59))
* **core:** static-query schematic should detect queries in `ngDoCheck` and `ngOnChanges` ([#29492](https://github.com/angular/angular/issues/29492)) ([09fab58](https://github.com/angular/angular/commit/09fab58))
* **router:** support `NgFactory` promise in loadChildren typings ([#29392](https://github.com/angular/angular/issues/29392)) ([26a8c59](https://github.com/angular/angular/commit/26a8c59))
* **bazel:** correct regexp test for self-references in metadata ([#29346](https://github.com/angular/angular/issues/29346)) ([9d090cb](https://github.com/angular/angular/commit/9d090cb))
* **bazel:** don't produce self-references in metadata ([#29317](https://github.com/angular/angular/issues/29317)) ([3facdeb](https://github.com/angular/angular/commit/3facdeb)), closes [#29315](https://github.com/angular/angular/issues/29315)
* **bazel:** fix strict null checks compile error in packages/bazel/src/schematics/ng-add/index.ts ([#29282](https://github.com/angular/angular/issues/29282)) ([9a7f560](https://github.com/angular/angular/commit/9a7f560))
* **bazel:** Remove [@angular](https://github.com/angular)/upgrade from dev dependencies ([#29319](https://github.com/angular/angular/issues/29319)) ([1db8bf3](https://github.com/angular/angular/commit/1db8bf3))
* **bazel:** fix strict null checks compile error in `packages/bazel/src/schematics/ng-add/index.ts` ([#29282](https://github.com/angular/angular/issues/29282)) ([9a7f560](https://github.com/angular/angular/commit/9a7f560))
* **bazel:** Remove @angular/upgrade from dev dependencies ([#29319](https://github.com/angular/angular/issues/29319)) ([1db8bf3](https://github.com/angular/angular/commit/1db8bf3))
* **bazel:** Support new e2e project layout ([#29318](https://github.com/angular/angular/issues/29318)) ([8ef690c](https://github.com/angular/angular/commit/8ef690c))
* **bazel:** turn off pure call tree shaking for ng_package ([#29210](https://github.com/angular/angular/issues/29210)) ([4990b93](https://github.com/angular/angular/commit/4990b93))
* **compiler-cli:** incorrect metadata bundle for multiple unnamed re-exports ([#29360](https://github.com/angular/angular/issues/29360)) ([105cfaf](https://github.com/angular/angular/commit/105cfaf)), closes [/github.com/angular/material2/blob/master/tools/package-tools/build-release.ts#L78-L85](https://github.com//github.com/angular/material2/blob/master/tools/package-tools/build-release.ts/issues/L78-L85)
* **compiler-cli:** incorrect metadata bundle for multiple unnamed re-exports ([#29360](https://github.com/angular/angular/issues/29360)) ([105cfaf](https://github.com/angular/angular/commit/105cfaf))
* **core:** don't wrap `<tr>` and `<col>` elements into a required parent ([#29219](https://github.com/angular/angular/issues/29219)) ([f2dc32e](https://github.com/angular/angular/commit/f2dc32e))
* **core:** parse incorrect ML open tag as text ([#29328](https://github.com/angular/angular/issues/29328)) ([4605df8](https://github.com/angular/angular/commit/4605df8)), closes [#29231](https://github.com/angular/angular/issues/29231)
* **compiler-cli:** incorrect metadata bundle for multiple unnamed re-exports ([#29360](https://github.com/angular/angular/issues/29360)) ([cf8d934](https://github.com/angular/angular/commit/cf8d934)), closes [github.com/angular/material2/blob/master/tools/package-tools/build-release.ts#L78-L85](https://github.com/angular/material2/blob/master/tools/package-tools/build-release.ts#L78-L85)
* **bazel:** add missing binary path for api-extractor ([#29202](https://github.com/angular/angular/issues/29202)) ([df354d1](https://github.com/angular/angular/commit/df354d1))
* **bazel:** ng build should produce prod bundle ([#29136](https://github.com/angular/angular/issues/29136)) ([14ce8a9](https://github.com/angular/angular/commit/14ce8a9))
* **compiler:** ensure template is updated if an output is transformed ([#29041](https://github.com/angular/angular/issues/29041)) ([c7e4931](https://github.com/angular/angular/commit/c7e4931))
@ -174,16 +393,16 @@
### BREAKING CHANGES
* **bazel:** @bazel/typescript is now a peerDependency of @angular/bazel so user's of @angular/bazel must add @bazel/typescript to their package.json
* **bazel:** ng_module now depends on a minimum of build_bazel_rules_nodejs 0.27.12
* **core:** In Angular version 8, it's required that all @ViewChild and @ContentChild
queries have a 'static' flag specifying whether the query is 'static' or
* **bazel:** @bazel/typescript is now a peerDependency of @angular/bazel so users of @angular/bazel must add @bazel/typescript to their package.json
* **bazel:** `ng_module` now depends on a minimum of build_bazel_rules_nodejs 0.27.12
* **core:** In Angular version 8, it's required that all `@ViewChild` and `@ContentChild`
queries have a `'static'` flag specifying whether the query is 'static' or
'dynamic'. The compiler previously sorted queries automatically, but in
8.0 developers are required to explicitly specify which behavior is wanted.
This is a temporary requirement as part of a migration; see
https://v8.angular.io/guide/static-query-migration for more details.
[static query migration guide](https://v8.angular.io/guide/static-query-migration) for more details.
@ViewChildren and @ContentChildren queries are always dynamic, and so are
`@ViewChildren` and `@ContentChildren` queries are always dynamic, and so are
unaffected.
* `TestBed.get()` has two signatures, one which is typed and another which accepts and returns `any`. The signature for `any` is deprecated; all usage of `TestBed.get()` should go through the typed API. This mainly affects string tokens
@ -217,8 +436,8 @@ https://v8.angular.io/guide/static-query-migration for more details.
- `<tr>` would be wrapped in `<tbody>` if not inside `<tbody>`, `<tfoot>` or `<thead>`;
- `<col>` would be wrapped in `<colgroup>` if not inside `<colgroup>`.
This meachanism of automatic wrapping / auto-correcting was problematic for several reasons:
- it is non-obvious and arbitrary (ex. there are more HTML elements that has rules for parent type);
This mechanism of automatic wrapping / auto-correcting was problematic for several reasons:
- it is non-obvious and arbitrary (ex. there are more HTML elements that have rules for parent type);
- it is incorrect for cases where `<tr>` / `<col>` are at the root of a component's content, ex.:
```html
@ -230,10 +449,13 @@ https://v8.angular.io/guide/static-query-migration for more details.
In the above example the `<projecting-tr-inside-tbody>` component could be "surprised" to see additional
`<tbody>` elements inserted by Angular HTML parser.
* **http:** The deprecated @angular/http package has been removed, the @angular/common/http package should be used instead.
For details on how to migrate, please refer to [the deprecations guide](https://angular.io/guide/deprecations#angularhttp).
* TypeScript 3.1 and 3.2 are no longer supported.
Please update your TypeScript version to 3.3
Please update your TypeScript version to 3.4, as version 3.3 is also not supported.
<a name="8.0.0-rc.5"></a>
@ -319,6 +541,17 @@ unaffected.
<a name="7.2.15"></a>
## [7.2.15](https://github.com/angular/angular/compare/7.2.14...7.2.15) (2019-05-07)
### Bug Fixes
* **upgrade:** do not break if `onMicrotaskEmpty` emits while a `$digest` is in progress ([#29794](https://github.com/angular/angular/issues/29794)) ([#30107](https://github.com/angular/angular/issues/30107)) ([1084c19](https://github.com/angular/angular/commit/1084c19)), closes [#24680](https://github.com/angular/angular/issues/24680) [/github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts#L12](https://github.com//github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts/issues/L12) [#24680](https://github.com/angular/angular/issues/24680)
<a name="8.0.0-rc.2"></a>
# [8.0.0-rc.2](https://github.com/angular/angular/compare/8.0.0-rc.1...8.0.0-rc.2) (2019-04-29)
@ -348,9 +581,9 @@ unaffected.
### Bug Fixes
* **bazel:** make name param in ng add optional ([#30074](https://github.com/angular/angular/issues/30074)) ([0b5f480](https://github.com/angular/angular/commit/0b5f480))
* **bazel:** Make sure only single copy of `[@angular](https://github.com/angular)/bazel` is installed ([#30072](https://github.com/angular/angular/issues/30072)) ([2905bf5](https://github.com/angular/angular/commit/2905bf5))
* **bazel:** Make sure only single copy of `@angular/bazel` is installed ([#30072](https://github.com/angular/angular/issues/30072)) ([2905bf5](https://github.com/angular/angular/commit/2905bf5))
* **bazel:** transitive npm deps in ng_module ([#30065](https://github.com/angular/angular/issues/30065)) ([61365a9](https://github.com/angular/angular/commit/61365a9))
* **common:** add upgrade sub-package to ng_package rule for [@angular](https://github.com/angular)/common ([#30117](https://github.com/angular/angular/issues/30117)) ([6de4cbd](https://github.com/angular/angular/commit/6de4cbd)), closes [#30055](https://github.com/angular/angular/issues/30055) [#30116](https://github.com/angular/angular/issues/30116)
* **common:** add upgrade sub-package to ng_package rule for @angular/common ([#30117](https://github.com/angular/angular/issues/30117)) ([6de4cbd](https://github.com/angular/angular/commit/6de4cbd)), closes [#30055](https://github.com/angular/angular/issues/30055) [#30116](https://github.com/angular/angular/issues/30116)
* **common:** adjust MockPlatformLocation to set state to new object ([#30055](https://github.com/angular/angular/issues/30055)) ([825efa8](https://github.com/angular/angular/commit/825efa8))
* **compiler:** Fix compiler crash due to isSkipSelf of null ([#30075](https://github.com/angular/angular/issues/30075)) ([28fd5ab](https://github.com/angular/angular/commit/28fd5ab))
* **upgrade:** do not break if `onMicrotaskEmpty` emits while a `$digest` is in progress ([#29794](https://github.com/angular/angular/issues/29794)) ([0ddf2e7](https://github.com/angular/angular/commit/0ddf2e7)), closes [#24680](https://github.com/angular/angular/issues/24680) [/github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts#L12](https://github.com//github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts/issues/L12) [#24680](https://github.com/angular/angular/issues/24680)
@ -358,7 +591,7 @@ unaffected.
### Features
* **common:** add [@angular](https://github.com/angular)/common/upgrade package for $location-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
* **common:** add @angular/common/upgrade package for $location-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
* **common:** add ability to retrieve the state from Location service ([#30055](https://github.com/angular/angular/issues/30055)) ([b44b143](https://github.com/angular/angular/commit/b44b143))
* **common:** add ability to track all location changes ([#30055](https://github.com/angular/angular/issues/30055)) ([3a9cf3f](https://github.com/angular/angular/commit/3a9cf3f))
* **common:** add APIs to read component pieces of URL ([#30055](https://github.com/angular/angular/issues/30055)) ([b635fe8](https://github.com/angular/angular/commit/b635fe8))
@ -421,7 +654,7 @@ unaffected.
### Bug Fixes
* **bazel:** add configuration_env_vars = ["compile"] to generated [@npm](https://github.com/npm)//[@angular](https://github.com/angular)/bazel/bin:ngc-wrapped nodejs_binary ([#29694](https://github.com/angular/angular/issues/29694)) ([2e66ddf](https://github.com/angular/angular/commit/2e66ddf))
* **bazel:** add configuration_env_vars = ["compile"] to generated [@npm](https://github.com/npm)//@angular/bazel/bin:ngc-wrapped nodejs_binary ([#29694](https://github.com/angular/angular/issues/29694)) ([2e66ddf](https://github.com/angular/angular/commit/2e66ddf))
* **bazel:** docs formatting ([#29817](https://github.com/angular/angular/issues/29817)) ([cc2e4b6](https://github.com/angular/angular/commit/cc2e4b6))
* **bazel:** remove karma-jasmine from ts_web_test_suite ([#29695](https://github.com/angular/angular/issues/29695)) ([2bd9214](https://github.com/angular/angular/commit/2bd9214))
* **bazel:** support running ng-add on minimal applications ([#29681](https://github.com/angular/angular/issues/29681)) ([9810c6c](https://github.com/angular/angular/commit/9810c6c)), closes [#29680](https://github.com/angular/angular/issues/29680)
@ -496,7 +729,7 @@ let service = TestBed.get(SERVICE_TOKEN); // type Service
### Features
* remove [@angular](https://github.com/angular)/http dependency from [@angular](https://github.com/angular)/platform-server ([#29408](https://github.com/angular/angular/issues/29408)) ([9745f55](https://github.com/angular/angular/commit/9745f55))
* remove @angular/http dependency from @angular/platform-server ([#29408](https://github.com/angular/angular/issues/29408)) ([9745f55](https://github.com/angular/angular/commit/9745f55))
* **compiler-cli:** ngcc - make logging more configurable ([#29591](https://github.com/angular/angular/issues/29591)) ([8d3d75e](https://github.com/angular/angular/commit/8d3d75e))
* **core:** Add "AbstractType<T>" interface ([#29295](https://github.com/angular/angular/issues/29295)) ([afd4a4e](https://github.com/angular/angular/commit/afd4a4e)), closes [#26491](https://github.com/angular/angular/issues/26491)
* **core:** template-var-assignment update schematic ([#29608](https://github.com/angular/angular/issues/29608)) ([7c8f4e3](https://github.com/angular/angular/commit/7c8f4e3))
@ -556,7 +789,7 @@ This release contains various API docs improvements.
* **bazel:** correct regexp test for self-references in metadata ([#29346](https://github.com/angular/angular/issues/29346)) ([9d090cb](https://github.com/angular/angular/commit/9d090cb))
* **bazel:** don't produce self-references in metadata ([#29317](https://github.com/angular/angular/issues/29317)) ([3facdeb](https://github.com/angular/angular/commit/3facdeb)), closes [#29315](https://github.com/angular/angular/issues/29315)
* **bazel:** fix strict null checks compile error in packages/bazel/src/schematics/ng-add/index.ts ([#29282](https://github.com/angular/angular/issues/29282)) ([9a7f560](https://github.com/angular/angular/commit/9a7f560))
* **bazel:** Remove [@angular](https://github.com/angular)/upgrade from dev dependencies ([#29319](https://github.com/angular/angular/issues/29319)) ([1db8bf3](https://github.com/angular/angular/commit/1db8bf3))
* **bazel:** Remove @angular/upgrade from dev dependencies ([#29319](https://github.com/angular/angular/issues/29319)) ([1db8bf3](https://github.com/angular/angular/commit/1db8bf3))
* **bazel:** Support new e2e project layout ([#29318](https://github.com/angular/angular/issues/29318)) ([8ef690c](https://github.com/angular/angular/commit/8ef690c))
* **bazel:** turn off pure call tree shaking for ng_package ([#29210](https://github.com/angular/angular/issues/29210)) ([4990b93](https://github.com/angular/angular/commit/4990b93))
* **compiler-cli:** incorrect metadata bundle for multiple unnamed re-exports ([#29360](https://github.com/angular/angular/issues/29360)) ([105cfaf](https://github.com/angular/angular/commit/105cfaf)), closes [/github.com/angular/material2/blob/master/tools/package-tools/build-release.ts#L78-L85](https://github.com//github.com/angular/material2/blob/master/tools/package-tools/build-release.ts/issues/L78-L85)
@ -577,8 +810,8 @@ This release contains various API docs improvements.
- `<tr>` would be wrapped in `<tbody>` if not inside `<tbody>`, `<tfoot>` or `<thead>`;
- `<col>` would be wrapped in `<colgroup>` if not inside `<colgroup>`.
This meachanism of automatic wrapping / auto-correcting was problematic for several reasons:
- it is non-obvious and arbitrary (ex. there are more HTML elements that has rules for parent type);
This mechanism of automatic wrapping / auto-correcting was problematic for several reasons:
- it is non-obvious and arbitrary (ex. there are more HTML elements that have rules for parent type);
- it is incorrect for cases where `<tr>` / `<col>` are at the root of a component's content, ex.:
```html
@ -979,7 +1212,7 @@ This release contains various API docs improvements.
* **bazel:** unable to launch protractor test on windows ([#27850](https://github.com/angular/angular/issues/27850)) ([1e6c9be](https://github.com/angular/angular/commit/1e6c9be))
* **bazel:** devserver entry_module should have underscore name ([#27719](https://github.com/angular/angular/issues/27719)) ([f57916c](https://github.com/angular/angular/commit/f57916c))
* **bazel:** emit full node stack traces when Angular compilation crashes ([#27678](https://github.com/angular/angular/issues/27678)) ([522919a](https://github.com/angular/angular/commit/522919a))
* **bazel:** fix major/minor semver check between [@angular](https://github.com/angular)/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([1cc08b4](https://github.com/angular/angular/commit/1cc08b4))
* **bazel:** fix major/minor semver check between @angular/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([1cc08b4](https://github.com/angular/angular/commit/1cc08b4))
* **bazel:** Load http_archive and rules_nodejs dependencies ([#27609](https://github.com/angular/angular/issues/27609)) ([8313ffc](https://github.com/angular/angular/commit/8313ffc))
* **bazel:** ng_package writes unrelevant definitions to bazel out ([#27519](https://github.com/angular/angular/issues/27519)) ([44dfa60](https://github.com/angular/angular/commit/44dfa60)), closes [/github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts#L105-L124](https://github.com//github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts/issues/L105-L124)
* **bazel:** Set module_name and enable ng test ([#27715](https://github.com/angular/angular/issues/27715)) ([85866de](https://github.com/angular/angular/commit/85866de))
@ -999,7 +1232,7 @@ This release contains various API docs improvements.
* **core:** export a value for InjectFlags ([#27279](https://github.com/angular/angular/issues/27279)) ([23b06af](https://github.com/angular/angular/commit/23b06af)), closes [#27251](https://github.com/angular/angular/issues/27251)
* **core:** More precise return type for `InjectableDecorator` ([#27360](https://github.com/angular/angular/issues/27360)) ([4b9948c](https://github.com/angular/angular/commit/4b9948c)), closes [#26942](https://github.com/angular/angular/issues/26942)
* **forms:** typed argument for FormBuilder group ([#26985](https://github.com/angular/angular/issues/26985)) ([b0c7561](https://github.com/angular/angular/commit/b0c7561))
* **platform-server:** add [@angular](https://github.com/angular)/http to the list of peerDependencies ([#27307](https://github.com/angular/angular/issues/27307)) ([32c5be9](https://github.com/angular/angular/commit/32c5be9)), closes [#26154](https://github.com/angular/angular/issues/26154)
* **platform-server:** add @angular/http to the list of peerDependencies ([#27307](https://github.com/angular/angular/issues/27307)) ([32c5be9](https://github.com/angular/angular/commit/32c5be9)), closes [#26154](https://github.com/angular/angular/issues/26154)
* **router:** ensure URL is updated after second redirect with UrlUpdateStrategy="eager" ([#27523](https://github.com/angular/angular/issues/27523)) ([ad26cd6](https://github.com/angular/angular/commit/ad26cd6)), closes [#27116](https://github.com/angular/angular/issues/27116)
* **router:** update URL after redirects when urlHandlingStrategy='eager' ([#27356](https://github.com/angular/angular/issues/27356)) ([11a8bd8](https://github.com/angular/angular/commit/11a8bd8)), closes [#27076](https://github.com/angular/angular/issues/27076)
* **upgrade:** allow nesting components from different downgraded modules ([#27217](https://github.com/angular/angular/issues/27217)) ([bc0ee01](https://github.com/angular/angular/commit/bc0ee01))
@ -1019,7 +1252,7 @@ This release contains various API docs improvements.
* **animations:** mark actual descendant node as disabled ([#26180](https://github.com/angular/angular/issues/26180)) ([453589f](https://github.com/angular/angular/commit/453589f))
* **bazel:** devserver entry_module should have underscore name ([#27719](https://github.com/angular/angular/issues/27719)) ([b108e9a](https://github.com/angular/angular/commit/b108e9a))
* **bazel:** emit full node stack traces when Angular compilation crashes ([#27678](https://github.com/angular/angular/issues/27678)) ([0d8528b](https://github.com/angular/angular/commit/0d8528b))
* **bazel:** fix major/minor semver check between [@angular](https://github.com/angular)/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([3ed1e84](https://github.com/angular/angular/commit/3ed1e84))
* **bazel:** fix major/minor semver check between @angular/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([3ed1e84](https://github.com/angular/angular/commit/3ed1e84))
* **bazel:** Load http_archive and rules_nodejs dependencies ([#27609](https://github.com/angular/angular/issues/27609)) ([89ace1a](https://github.com/angular/angular/commit/89ace1a))
* **bazel:** ng_package writes unrelevant definitions to bazel out ([#27519](https://github.com/angular/angular/issues/27519)) ([ef056c5](https://github.com/angular/angular/commit/ef056c5)), closes [/github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts#L105-L124](https://github.com//github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts/issues/L105-L124)
* **bazel:** Read latest versions from latest-versions.ts & use semver check ([#27591](https://github.com/angular/angular/issues/27591)) ([93078e3](https://github.com/angular/angular/commit/93078e3))
@ -1051,7 +1284,7 @@ This release contains various API docs improvements.
* **bazel:** ng_package should correctly map to source maps in secondary entry-points ([#27313](https://github.com/angular/angular/issues/27313)) ([fc2c23e](https://github.com/angular/angular/commit/fc2c23e)), closes [#25510](https://github.com/angular/angular/issues/25510)
* **compiler-cli:** flatModuleIndex files not generated on windows with multiple input files ([#27200](https://github.com/angular/angular/issues/27200)) ([8087b6b](https://github.com/angular/angular/commit/8087b6b))
* **compiler-cli:** ngtsc shim files not being generated on case-insensitive platforms ([#27466](https://github.com/angular/angular/issues/27466)) ([84f2928](https://github.com/angular/angular/commit/84f2928)), closes [/github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts#L681-L682](https://github.com//github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts/issues/L681-L682)
* **platform-server:** add [@angular](https://github.com/angular)/http to the list of peerDependencies ([#27307](https://github.com/angular/angular/issues/27307)) ([236ac06](https://github.com/angular/angular/commit/236ac06)), closes [#26154](https://github.com/angular/angular/issues/26154)
* **platform-server:** add @angular/http to the list of peerDependencies ([#27307](https://github.com/angular/angular/issues/27307)) ([236ac06](https://github.com/angular/angular/commit/236ac06)), closes [#26154](https://github.com/angular/angular/issues/26154)
@ -1078,7 +1311,7 @@ This release contains various API docs improvements.
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
* **core:** Remove static dependency from @angular/core to @angular/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
@ -1185,7 +1418,7 @@ This release contains various API docs improvements.
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
* **core:** Remove static dependency from @angular/core to @angular/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
@ -1197,7 +1430,7 @@ This release contains various API docs improvements.
### Bug Fixes
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([c01f340](https://github.com/angular/angular/commit/c01f340))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([#26879](https://github.com/angular/angular/issues/26879)) ([257ac83](https://github.com/angular/angular/commit/257ac83))
* **core:** Remove static dependency from @angular/core to @angular/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([#26879](https://github.com/angular/angular/issues/26879)) ([257ac83](https://github.com/angular/angular/commit/257ac83))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([b3c6409](https://github.com/angular/angular/commit/b3c6409))
@ -1274,7 +1507,7 @@ To learn about the release highlights and our new CLI-powered update workflow fo
* **compiler:** update compiler to flatten nested template fns ([#24943](https://github.com/angular/angular/issues/24943)) ([fe14f18](https://github.com/angular/angular/commit/fe14f18))
* **compiler:** update compiler to generate new slot allocations ([#25607](https://github.com/angular/angular/issues/25607)) ([27e2039](https://github.com/angular/angular/commit/27e2039))
* **core:** In Testability.whenStable update callback, pass more complete ([#25010](https://github.com/angular/angular/issues/25010)) ([16c03c0](https://github.com/angular/angular/commit/16c03c0))
* **core:** add missing `peerDependency ` to `[@angular](https://github.com/angular)/compiler` ([#26033](https://github.com/angular/angular/issues/26033)) ([549de1e](https://github.com/angular/angular/commit/549de1e)), closes [/github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e#diff-58563046c4439699f2e6a89187099a54](https://github.com//github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e/issues/diff-58563046c4439699f2e6a89187099a54)
* **core:** add missing `peerDependency ` to `@angular/compiler` ([#26033](https://github.com/angular/angular/issues/26033)) ([549de1e](https://github.com/angular/angular/commit/549de1e)), closes [/github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e#diff-58563046c4439699f2e6a89187099a54](https://github.com//github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e/issues/diff-58563046c4439699f2e6a89187099a54)
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
* **core:** do not clear element content when using shadow dom ([#24861](https://github.com/angular/angular/issues/24861)) ([6e828bb](https://github.com/angular/angular/commit/6e828bb))
* **core:** size regression with closure compiler ([#25531](https://github.com/angular/angular/issues/25531)) ([1f59f2f](https://github.com/angular/angular/commit/1f59f2f))
@ -1720,7 +1953,7 @@ To learn about the release highlights and our new CLI-powered update workflow fo
* **upgrade:** propagate return value of resumeBootstrap ([#22754](https://github.com/angular/angular/issues/22754)) ([a2330ff](https://github.com/angular/angular/commit/a2330ff)), closes [#22723](https://github.com/angular/angular/issues/22723)
* **upgrade:** two-way binding and listening for event ([#22772](https://github.com/angular/angular/issues/22772)) ([2b3de63](https://github.com/angular/angular/commit/2b3de63)), closes [#22734](https://github.com/angular/angular/issues/22734)
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([8a85888](https://github.com/angular/angular/commit/8a85888)), closes [#22392](https://github.com/angular/angular/issues/22392)
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([f089bf5](https://github.com/angular/angular/commit/f089bf5))
* **upgrade:** correctly handle `=` bindings in `@angular/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([f089bf5](https://github.com/angular/angular/commit/f089bf5))
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([13ab91e](https://github.com/angular/angular/commit/13ab91e)), closes [#22175](https://github.com/angular/angular/issues/22175)
@ -1855,7 +2088,7 @@ To learn about the release highlights and our new CLI-powered update workflow fo
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
* **upgrade:** correctly handle `=` bindings in `@angular/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
@ -1869,7 +2102,7 @@ To learn about the release highlights and our new CLI-powered update workflow fo
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
* **upgrade:** correctly handle `=` bindings in `@angular/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
@ -2316,7 +2549,7 @@ Note: Due to an animation fix back in 5.1.1 ([c2b3792](https://github.com/angula
* **platform-server:** provide a way to hook into renderModule* ([#19023](https://github.com/angular/angular/issues/19023)) ([8dfc3c3](https://github.com/angular/angular/commit/8dfc3c3))
* **router:** add ActivationStart/End events ([8f79150](https://github.com/angular/angular/commit/8f79150))
* **router:** add events tracking activation of individual routes ([49cd851](https://github.com/angular/angular/commit/49cd851))
* **service-worker:** introduce the [@angular](https://github.com/angular)/service-worker package ([#19274](https://github.com/angular/angular/issues/19274)) ([d442b68](https://github.com/angular/angular/commit/d442b68))
* **service-worker:** introduce the @angular/service-worker package ([#19274](https://github.com/angular/angular/issues/19274)) ([d442b68](https://github.com/angular/angular/commit/d442b68))
* **upgrade:** propagate touched state of NgModelController ([59c23c7](https://github.com/angular/angular/commit/59c23c7))
* **upgrade:** support lazy-loading Angular module into AngularJS app ([30e76fc](https://github.com/angular/angular/commit/30e76fc))
* update angular to support TypeScript 2.4 ([ca5aeba](https://github.com/angular/angular/commit/ca5aeba))
@ -2540,7 +2773,7 @@ Because of multiple bugs and browser inconsistencies, we have dropped the intl a
### Bug Fixes
* **animations:** do not leak DOM nodes/styling for host triggered animations ([#18853](https://github.com/angular/angular/issues/18853)) ([1cc3fe2](https://github.com/angular/angular/commit/1cc3fe2)), closes [#18606](https://github.com/angular/angular/issues/18606)
* **common:** fix improper packaging for [@angular](https://github.com/angular)/common/http ([#18613](https://github.com/angular/angular/issues/18613)) ([a203a95](https://github.com/angular/angular/commit/a203a95))
* **common:** fix improper packaging for @angular/common/http ([#18613](https://github.com/angular/angular/issues/18613)) ([a203a95](https://github.com/angular/angular/commit/a203a95))
* **common:** fix XSSI prefix stripping by using JSON.parse always ([#18466](https://github.com/angular/angular/issues/18466)) ([8821723](https://github.com/angular/angular/commit/8821723)), closes [#18396](https://github.com/angular/angular/issues/18396) [#18453](https://github.com/angular/angular/issues/18453)
* **compiler:** normalize the locale name ([#18963](https://github.com/angular/angular/issues/18963)) ([497e017](https://github.com/angular/angular/commit/497e017))
* **core:** complete EventEmitter in QueryList on component destroy ([#18902](https://github.com/angular/angular/issues/18902)) ([7d137d7](https://github.com/angular/angular/commit/7d137d7)), closes [#18741](https://github.com/angular/angular/issues/18741)
@ -2881,7 +3114,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **compiler-cli:** allow '==' to compare nullable types ([#16731](https://github.com/angular/angular/issues/16731)) ([d761059](https://github.com/angular/angular/commit/d761059))
* **core:** detach projected views when a parent view is destroyed ([#16592](https://github.com/angular/angular/issues/16592)) ([f0f6544](https://github.com/angular/angular/commit/f0f6544)), closes [#15578](https://github.com/angular/angular/issues/15578)
* **core:** projected views should be dirty checked when the declaring component is dirty checked. ([#16592](https://github.com/angular/angular/issues/16592)) ([fcc91d8](https://github.com/angular/angular/commit/fcc91d8)), closes [#14321](https://github.com/angular/angular/issues/14321)
* **http:** flatten metadata for [@angular](https://github.com/angular)/http/testing ([9da6340](https://github.com/angular/angular/commit/9da6340)), closes [#15521](https://github.com/angular/angular/issues/15521)
* **http:** flatten metadata for @angular/http/testing ([9da6340](https://github.com/angular/angular/commit/9da6340)), closes [#15521](https://github.com/angular/angular/issues/15521)
* **http:** honor RequestArgs.search and RequestArgs.params map type ([aef5245](https://github.com/angular/angular/commit/aef5245)), closes [#15761](https://github.com/angular/angular/issues/15761) [#16392](https://github.com/angular/angular/issues/16392)
* **http:** introduce encodingHint for text() for better ArrayBuffer support ([7ae7a84](https://github.com/angular/angular/commit/7ae7a84)), closes [#15932](https://github.com/angular/angular/issues/15932) [#16420](https://github.com/angular/angular/issues/16420)
* **router:** fix redirect to a URL with a param having multiple values ([#16376](https://github.com/angular/angular/issues/16376)) ([5d4b36f](https://github.com/angular/angular/commit/5d4b36f)), closes [#16310](https://github.com/angular/angular/issues/16310)
@ -2937,7 +3170,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **compiler:** avoid a `...null` spread in extraction ([#16547](https://github.com/angular/angular/issues/16547)) ([d0e1688](https://github.com/angular/angular/commit/d0e1688))
* **core:** detach projected views when a parent view is destroyed ([#16592](https://github.com/angular/angular/issues/16592)) ([ee6705a](https://github.com/angular/angular/commit/ee6705a)), closes [#15578](https://github.com/angular/angular/issues/15578)
* **core:** projected views should be dirty checked when the declaring component is dirty checked. ([#16592](https://github.com/angular/angular/issues/16592)) ([9218812](https://github.com/angular/angular/commit/9218812)), closes [#14321](https://github.com/angular/angular/issues/14321)
* **http:** flatten metadata for [@angular](https://github.com/angular)/http/testing ([9c70a3c](https://github.com/angular/angular/commit/9c70a3c)), closes [#15521](https://github.com/angular/angular/issues/15521)
* **http:** flatten metadata for @angular/http/testing ([9c70a3c](https://github.com/angular/angular/commit/9c70a3c)), closes [#15521](https://github.com/angular/angular/issues/15521)
* **http:** honor RequestArgs.search and RequestArgs.params map type ([63066f7](https://github.com/angular/angular/commit/63066f7)), closes [#15761](https://github.com/angular/angular/issues/15761) [#16392](https://github.com/angular/angular/issues/16392)
* **http:** introduce encodingHint for text() for better ArrayBuffer support ([ec3b6e9](https://github.com/angular/angular/commit/ec3b6e9)), closes [#15932](https://github.com/angular/angular/issues/15932) [#16420](https://github.com/angular/angular/issues/16420)
* **router:** fix redirect to a URL with a param having multiple values ([#16376](https://github.com/angular/angular/issues/16376)) ([915eae5](https://github.com/angular/angular/commit/915eae5)), closes [#16310](https://github.com/angular/angular/issues/16310)
@ -3567,7 +3800,7 @@ Note: the 4.0.0-rc.0 release on npm accidentally omitted one bug fix, so we cut
* **core:** add isStable Observable property to ApplicationRef to indicate when it's stable and unstable ([#14337](https://github.com/angular/angular/issues/14337)) ([c481798](https://github.com/angular/angular/commit/c481798))
* **platform-server:** add API to render Module and ModuleFactory to string ([#14381](https://github.com/angular/angular/issues/14381)) ([b4d444a](https://github.com/angular/angular/commit/b4d444a))
* **platform-server:** Implement PlatformLocation for platformServer() ([#14405](https://github.com/angular/angular/issues/14405)) ([9e28568](https://github.com/angular/angular/commit/9e28568))
* **platform-server:** support [@angular](https://github.com/angular)/http from [@angular](https://github.com/angular)/platform-server ([9559d3e](https://github.com/angular/angular/commit/9559d3e))
* **platform-server:** support @angular/http from @angular/platform-server ([9559d3e](https://github.com/angular/angular/commit/9559d3e))
* **tsc-wrapped:** add an option to `ngc` to bundle metadata ([#14509](https://github.com/angular/angular/issues/14509)) ([3b89670](https://github.com/angular/angular/commit/3b89670))
@ -4528,7 +4761,7 @@ Note: The 2.2.0-beta.0 release also contains all the changes present in the 2.1.
* **compiler:** properly shim `:host:before` and `:host(:before)` ([#12171](https://github.com/angular/angular/issues/12171)) ([aa92512](https://github.com/angular/angular/commit/aa92512)), closes [#12165](https://github.com/angular/angular/issues/12165)
* **compiler:** validate `@HostBinding` name ([#12139](https://github.com/angular/angular/issues/12139)) ([13ecc14](https://github.com/angular/angular/commit/13ecc14))
* **compiler-cli:** don't clone static symbols when simplifying annotation metadata ([#12158](https://github.com/angular/angular/issues/12158)) ([8c477b2](https://github.com/angular/angular/commit/8c477b2))
* **compiler-cli:** remove peerDependency on [@angular](https://github.com/angular)/platform-server ([#12122](https://github.com/angular/angular/issues/12122)) ([71b7654](https://github.com/angular/angular/commit/71b7654))
* **compiler-cli:** remove peerDependency on @angular/platform-server ([#12122](https://github.com/angular/angular/issues/12122)) ([71b7654](https://github.com/angular/angular/commit/71b7654))
* **compiler-cli:** remove unused parse5 dependency from package.json ([eaaec69](https://github.com/angular/angular/commit/eaaec69))
* **forms:** allow optional fields with pattern and minlength validators ([#12147](https://github.com/angular/angular/issues/12147)) ([d22eeb7](https://github.com/angular/angular/commit/d22eeb7))
* **forms:** properly validate blank strings with minlength ([#12091](https://github.com/angular/angular/issues/12091)) ([f50c1da](https://github.com/angular/angular/commit/f50c1da))

View File

@ -222,6 +222,7 @@ The following is the list of supported scopes:
* **router**
* **service-worker**
* **upgrade**
* **zone.js**
There are currently a few exceptions to the "use package name" rule:

View File

@ -18,8 +18,11 @@ 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 = "e04a82a72146bfbca2d0575947daa60fda1878c8d3a3afe868a8ec39a6b968bb",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.31.1/rules_nodejs-0.31.1.tar.gz"],
patch_args = ["-p1"],
# Patch https://github.com/bazelbuild/rules_nodejs/pull/903
patches = ["//tools:rollup_bundle_commonjs_ignoreGlobal.patch"],
sha256 = "6d4edbf28ff6720aedf5f97f9b9a7679401bf7fca9d14a0fff80f644a99992b4",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.32.2/rules_nodejs-0.32.2.tar.gz"],
)
# Check the bazel version and download npm dependencies
@ -27,6 +30,7 @@ load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "check_rules
# Bazel version must be at least the following version because:
# - 0.26.0 managed_directories feature added which is required for nodejs rules 0.30.0
# - 0.27.0 has a fix for managed_directories after `rm -rf node_modules`
check_bazel_version(
message = """
You no longer need to install Bazel on your machine.
@ -35,7 +39,7 @@ Try running `yarn bazel` instead.
(If you did run that, check that you've got a fresh `yarn install`)
""",
minimum_bazel_version = "0.26.0",
minimum_bazel_version = "0.27.0",
)
# The NodeJS rules version must be at least the following version because:
@ -46,7 +50,10 @@ Try running `yarn bazel` instead.
# - 0.27.12 Adds NodeModuleSources provider for transtive npm deps support
# - 0.30.0 yarn_install now uses symlinked node_modules with new managed directories Bazel 0.26.0 feature
# - 0.31.1 entry_point attribute of nodejs_binary & rollup_bundle is now a label
check_rules_nodejs_version(minimum_version_string = "0.31.1")
# - 0.32.0 yarn_install and npm_install no longer puts build files under symlinked node_modules
# - 0.32.1 remove override of @bazel/tsetse & exclude typescript lib declarations in node_module_library transitive_declarations
# - 0.32.2 resolves bug in @bazel/hide-bazel-files postinstall step
check_rules_nodejs_version(minimum_version_string = "0.32.2")
# Setup the Node.js toolchain
node_repositories(
@ -70,19 +77,7 @@ node_repositories(
yarn_install(
name = "npm",
data = [
"//:tools/npm/@angular_bazel/index.js",
"//:tools/npm/@angular_bazel/package.json",
"//:tools/postinstall-patches.js",
"//:tools/yarn/check-yarn.js",
],
package_json = "//:package.json",
# Don't install devDependencies, they are large and not used under Bazel
prod_only = True,
# Temporarily disable node_modules symlinking until the fix for
# https://github.com/bazelbuild/bazel/issues/8487 makes it into a
# future Bazel release
symlink_node_modules = False,
yarn_lock = "//:yarn.lock",
)

View File

@ -7,7 +7,7 @@ The Angular CLI is a command-line interface tool that you use to initialize, dev
Major versions of Angular CLI follow the supported major version of Angular, but minor versions can be released separately.
Install the CLI using the `npm` package manager:
<code-example format="." language="bash">
<code-example language="bash">
npm install -g @angular/cli
</code-example>
@ -20,14 +20,14 @@ Invoke the tool on the command line through the `ng` executable.
Online help is available on the command line.
Enter the following to list commands or options for a given command (such as [generate](cli/generate)) with a short description.
<code-example format="." language="bash">
<code-example language="bash">
ng help
ng generate --help
</code-example>
To create, build, and serve a new, basic Angular project on a development server, go to the parent directory of your new workspace use the following commands:
<code-example format="." language="bash">
<code-example language="bash">
ng new my-first-project
cd my-first-project
ng serve
@ -36,6 +36,14 @@ ng serve
In your browser, open http://localhost:4200/ to see the new app run.
When you use the [ng serve](cli/serve) command to build an app and serve it locally, the server automatically rebuilds the app and reloads the page when you change any of the source files.
<div class="alert is-helpful">
When you run `ng new my-first-project` a new folder, named `my-first-project`, will be created in the current working directory. Since you want to be able to create files inside that folder, make sure you have sufficient rights in the current working directory before running the command.
If the current working directory is not the right place for your project, you can change to a more appropriate directory by running `cd <path-to-other-directory>` first.
</div>
## Workspaces and project files
The [ng new](cli/new) command creates an *Angular workspace* folder and generates a new app skeleton.
@ -74,8 +82,8 @@ Command syntax is shown as follows:
* Option names are prefixed with a double dash (--).
Option aliases are prefixed with a single dash (-).
Arguments are not prefixed.
For example:
<code-example format="." language="bash">
For example:
<code-example language="bash">
ng build my-app -c production
</code-example>
@ -105,5 +113,5 @@ Schematic options are supplied to the command in the same format as immediate co
### Building with Bazel
Optionally, you can configure the Angular CLI to use [Bazel](https://docs.bazel.build) as the build tool. For more information, see [Building with Bazel](guide/bazel).
Optionally, you can configure the Angular CLI to use [Bazel](https://docs.bazel.build) as the build tool. For more information, see [Building with Bazel](guide/bazel).

View File

@ -25,8 +25,8 @@ describe('Attribute directives', () => {
greenRb.click();
browser.actions().mouseMove(highlightedEle).perform();
// Wait for up to 2s for the background color to be updated,
// Wait for up to 4s for the background color to be updated,
// to account for slow environments (e.g. CI).
browser.wait(() => highlightedEle.getCssValue('background-color').then(c => c === lightGreen), 2000);
browser.wait(() => highlightedEle.getCssValue('background-color').then(c => c === lightGreen), 4000);
});
});

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 32 KiB

View File

@ -18,7 +18,7 @@ export class AppComponent {
}
deleteItem(item: Item) {
alert(`Delete the ${item}.`);
alert(`Delete the ${item.name}.`);
}
onClickMe(event?: KeyboardEvent) {

View File

@ -16,16 +16,20 @@
<!-- #enddocregion checkout-form-1 -->
<div>
<label>Name</label>
<input type="text" formControlName="name">
<label for="name">
Name
</label>
<input id="name" type="text" formControlName="name">
</div>
<div>
<label>Address</label>
<input type="text" formControlName="address">
<label for="address">
Address
</label>
<input id="address" type="text" formControlName="address">
</div>
<button class="button" type="submit">Purchase</button>
<!-- #docregion checkout-form-1 -->
</form>

View File

@ -10,7 +10,6 @@ export class AppComponent {
gender = 'female';
fly = true;
logo = 'https://angular.io/assets/images/logos/angular/angular.png';
heroes: string[] = ['Magneta', 'Celeritas', 'Dynama'];
inc(i: number) {
this.minutes = Math.min(5, Math.max(0, this.minutes + i));
}

View File

@ -0,0 +1,14 @@
// imports
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
// @NgModule decorator with its metadata
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}

View File

@ -7,9 +7,9 @@ import { from } from 'rxjs';
const data = from(fetch('/api/endpoint'));
// Subscribe to begin listening for async result
data.subscribe({
next(response) { console.log(response); },
error(err) { console.error('Error: ' + err); },
complete() { console.log('Completed'); }
next(response) { console.log(response); },
error(err) { console.error('Error: ' + err); },
complete() { console.log('Completed'); }
});
// #enddocregion promise

View File

@ -2,42 +2,49 @@
import { browser, element, by } from 'protractor';
// Not yet complete
describe('Template Syntax', function () {
// TODO Not yet complete
describe('Template Syntax', () => {
beforeAll(function () {
beforeAll(() => {
browser.get('');
});
it('should be able to use interpolation with a hero', function () {
let heroInterEle = element.all(by.css('h2+p')).get(0);
it('should be able to use interpolation with a hero', () => {
const heroInterEle = element.all(by.css('h2+p')).get(0);
expect(heroInterEle.getText()).toEqual('My current hero is Hercules');
});
it('should be able to use interpolation with a calculation', function () {
let theSumEles = element.all(by.cssContainingText('h3~p', 'The sum of'));
it('should be able to use interpolation with a calculation', () => {
const theSumEles = element.all(by.cssContainingText('h3~p', 'The sum of'));
expect(theSumEles.count()).toBe(2);
expect(theSumEles.get(0).getText()).toEqual('The sum of 1 + 1 is 2');
expect(theSumEles.get(1).getText()).toEqual('The sum of 1 + 1 is not 4');
});
it('should be able to use class binding syntax', function () {
let specialEle = element(by.cssContainingText('div', 'Special'));
it('should be able to use class binding syntax', () => {
const specialEle = element(by.cssContainingText('div', 'Special'));
expect(specialEle.getAttribute('class')).toMatch('special');
});
it('should be able to use style binding syntax', function () {
let specialButtonEle = element(by.cssContainingText('div.special~button', 'button'));
it('should be able to use style binding syntax', () => {
const specialButtonEle = element(by.cssContainingText('div.special~button', 'button'));
expect(specialButtonEle.getAttribute('style')).toMatch('color: red');
});
it('should two-way bind to sizer', async () => {
let div = element(by.css('div#two-way-1'));
let incButton = div.element(by.buttonText('+'));
let input = div.element(by.css('input'));
let initSize = await input.getAttribute('value');
const div = element(by.css('div#two-way-1'));
const incButton = div.element(by.buttonText('+'));
const input = div.element(by.css('input'));
const initSize = await input.getAttribute('value');
incButton.click();
expect(input.getAttribute('value')).toEqual((+initSize + 1).toString());
});
});
it('should change SVG rectangle\'s fill color on click', async () => {
const div = element(by.css('app-svg'));
const colorSquare = div.element(by.css('rect'));
const initialColor = await colorSquare.getAttribute('fill');
colorSquare.click();
expect(colorSquare.getAttribute('fill')).not.toEqual(initialColor);
});
});

View File

@ -38,6 +38,7 @@
<a href="#safe-navigation-operator">Safe navigation operator <i>?.</i></a><br>
<a href="#non-null-assertion-operator">Non-null assertion operator <i>!.</i></a><br>
<a href="#enums">Enums</a><br>
<a href="#svg-templates">SVG Templates</a><br>
<!-- Interpolation and expressions -->
<hr><h2 id="interpolation">Interpolation</h2>
@ -442,7 +443,7 @@ button</button>
<!-- #docregion without-NgModel -->
<input [value]="currentHero.name"
(input)="currentHero.name=$event.target.value" >
(input)="updateCurrentHeroName($event)">
<!-- #enddocregion without-NgModel -->
without NgModel
<br>
@ -752,7 +753,7 @@ bindon-ngModel
<div>
<!-- pipe price to USD and display the $ symbol -->
<label>Price: </label>{{product.price | currency:'USD':true}}
<label>Price: </label>{{product.price | currency:'USD':'symbol'}}
</div>
<a class="to-toc" href="#toc">top</a>
@ -857,3 +858,9 @@ The null hero's name is {{nullHero && nullHero.name}}
</p>
<a class="to-toc" href="#toc">top</a>
<hr><h2 id="svg-templates">SVG Templates</h2>
<!-- #docregion svg-templates -->
<app-svg></app-svg>
<!-- #enddocregion svg-templates -->
<a class="to-toc" href="#toc">top</a>

View File

@ -5,7 +5,7 @@ import { AfterViewInit, Component, ElementRef, OnInit, QueryList, ViewChildren }
import { Hero } from './hero';
export enum Color {Red, Green, Blue};
export enum Color {Red, Green, Blue}
/**
* Giant grab bag of stuff to drive the chapter
@ -29,7 +29,7 @@ export class AppComponent implements AfterViewInit, OnInit {
trackChanges(this.heroesWithTrackBy, () => this.heroesWithTrackByCount++);
}
@ViewChildren('noTrackBy') heroesNoTrackBy: QueryList<ElementRef>;
@ViewChildren('noTrackBy') heroesNoTrackBy: QueryList<ElementRef>;
@ViewChildren('withTrackBy') heroesWithTrackBy: QueryList<ElementRef>;
actionName = 'Go for it';
@ -66,6 +66,10 @@ export class AppComponent implements AfterViewInit, OnInit {
currentHero: Hero;
updateCurrentHeroName(event: Event) {
this.currentHero.name = (event.target as any).value;
}
deleteHero(hero?: Hero) {
this.alert(`Delete ${hero ? hero.name : 'the hero'}.`);
}
@ -105,13 +109,13 @@ export class AppComponent implements AfterViewInit, OnInit {
get nullHero(): Hero { return null; }
onClickMe(event?: KeyboardEvent) {
let evtMsg = event ? ' Event target class is ' + (<HTMLElement>event.target).className : '';
onClickMe(event?: MouseEvent) {
const evtMsg = event ? ' Event target class is ' + (event.target as HTMLElement).className : '';
this.alert('Click me.' + evtMsg);
}
onSave(event?: KeyboardEvent) {
let evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).textContent : '';
onSave(event?: MouseEvent) {
const evtMsg = event ? ' Event target is ' + (event.target as HTMLElement).textContent : '';
this.alert('Saved.' + evtMsg);
if (event) { event.stopPropagation(); }
}
@ -140,9 +144,9 @@ export class AppComponent implements AfterViewInit, OnInit {
setCurrentClasses() {
// CSS classes: added/removed per current state of component properties
this.currentClasses = {
'saveable': this.canSave,
'modified': !this.isUnchanged,
'special': this.isSpecial
saveable: this.canSave,
modified: !this.isUnchanged,
special: this.isSpecial
};
}
// #enddocregion setClasses
@ -164,7 +168,7 @@ export class AppComponent implements AfterViewInit, OnInit {
// #enddocregion trackByHeroes
// #docregion trackById
trackById(index: number, item: any): number { return item['id']; }
trackById(index: number, item: any): number { return item.id; }
// #enddocregion trackById
}

View File

@ -1,13 +1,14 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { BigHeroDetailComponent, HeroDetailComponent } from './hero-detail.component';
import { ClickDirective, ClickDirective2 } from './click.directive';
import { HeroFormComponent } from './hero-form.component';
import { heroSwitchComponents } from './hero-switch.components';
import { SizerComponent } from './sizer.component';
import { HeroFormComponent } from './hero-form.component';
import { heroSwitchComponents } from './hero-switch.components';
import { SizerComponent } from './sizer.component';
import { SvgComponent } from './svg.component';
@NgModule({
imports: [
@ -22,7 +23,8 @@ import { SizerComponent } from './sizer.component';
heroSwitchComponents,
ClickDirective,
ClickDirective2,
SizerComponent
SizerComponent,
SvgComponent
],
bootstrap: [ AppComponent ]
})

View File

@ -1,4 +1,4 @@
/* tslint:disable use-output-property-decorator directive-class-suffix */
/* tslint:disable directive-selector directive-class-suffix */
// #docplaster
import { Directive, ElementRef, EventEmitter, Output } from '@angular/core';

View File

@ -1,5 +1,5 @@
import { Component, Input, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
import { NgForm } from '@angular/forms';
import { Hero } from './hero';
@ -15,10 +15,11 @@ export class HeroFormComponent {
@Input() hero: Hero;
@ViewChild('heroForm', {static: false}) form: NgForm;
// tslint:disable-next-line:variable-name
private _submitMessage = '';
get submitMessage() {
if (!this.form.valid) {
if (this.form && !this.form.valid) {
this._submitMessage = '';
}
return this._submitMessage;

View File

@ -0,0 +1,4 @@
svg {
display: block;
width: 100%;
}

View File

@ -0,0 +1,6 @@
<svg>
<g>
<rect x="0" y="0" width="100" height="100" [attr.fill]="fillColor" (click)="changeColor()" />
<text x="120" y="50">click the rectangle to change the fill color</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 201 B

View File

@ -0,0 +1,17 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-svg',
templateUrl: './svg.component.svg',
styleUrls: ['./svg.component.css']
})
export class SvgComponent {
fillColor = 'rgb(255, 0, 0)';
changeColor() {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
this.fillColor = `rgb(${r}, ${g}, ${b})`;
}
}

View File

@ -1,8 +1,4 @@
/* HeroesComponent's private CSS styles */
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
@ -19,18 +15,18 @@
height: 1.6em;
border-radius: 4px;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes .text {
position: relative;
top: -3px;
.heroes li.selected {
background-color: #CFD8DC;
color: white;
}
.heroes li.selected:hover {
background-color: #BBD8DC;
color: white;
}
.heroes .badge {
display: inline-block;

View File

@ -34,4 +34,7 @@ export class HeroesComponent implements OnInit {
this.selectedHero = hero;
}
// #enddocregion on-select
// #docregion component
}
// #enddocregion component

View File

@ -1,8 +1,4 @@
/* HeroesComponent's private CSS styles */
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
@ -19,18 +15,18 @@
height: 1.6em;
border-radius: 4px;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes .text {
position: relative;
top: -3px;
.heroes li.selected {
background-color: #CFD8DC;
color: white;
}
.heroes li.selected:hover {
background-color: #BBD8DC;
color: white;
}
.heroes .badge {
display: inline-block;

View File

@ -1,8 +1,4 @@
/* HeroesComponent's private CSS styles */
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
@ -19,18 +15,18 @@
height: 1.6em;
border-radius: 4px;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes .text {
position: relative;
top: -3px;
.heroes li.selected {
background-color: #CFD8DC;
color: white;
}
.heroes li.selected:hover {
background-color: #BBD8DC;
color: white;
}
.heroes .badge {
display: inline-block;
@ -43,8 +39,6 @@
left: -1px;
top: -4px;
height: 1.8em;
min-width: 16px;
text-align: right;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}

View File

@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HeroesComponent } from './heroes/heroes.component';
const routes: Routes = [
{ path: 'heroes', component: HeroesComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

View File

@ -7,9 +7,7 @@ import { RouterModule, Routes } from '@angular/router';
// #docregion import-dashboard
import { DashboardComponent } from './dashboard/dashboard.component';
// #enddocregion import-dashboard
// #docregion heroes-route
import { HeroesComponent } from './heroes/heroes.component';
// #enddocregion heroes-route
// #docregion import-herodetail
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
// #enddocregion import-herodetail
@ -39,7 +37,9 @@ const routes: Routes = [
imports: [ RouterModule.forRoot(routes) ],
// #enddocregion ngmodule-imports
// #docregion v1
// #docregion export-routermodule
exports: [ RouterModule ]
// #enddocregion export-routermodule
})
export class AppRoutingModule {}
// #enddocregion , v1

View File

@ -23,13 +23,17 @@ import { HeroSearchComponent } from './hero-search/hero-search.component';
// #docregion v1
import { MessagesComponent } from './messages/messages.component';
// #docregion import-httpclientmodule
@NgModule({
imports: [
// #enddocregion import-httpclientmodule
BrowserModule,
FormsModule,
AppRoutingModule,
// #docregion in-mem-web-api-imports
// #docregion import-httpclientmodule
HttpClientModule,
// #enddocregion import-httpclientmodule
// The HttpClientInMemoryWebApiModule module intercepts HTTP requests
// and returns simulated server responses.
@ -38,7 +42,9 @@ import { MessagesComponent } from './messages/messages.component';
InMemoryDataService, { dataEncapsulation: false }
)
// #enddocregion in-mem-web-api-imports
// #docregion import-httpclientmodule
],
// #enddocregion import-httpclientmodule
declarations: [
AppComponent,
DashboardComponent,
@ -50,6 +56,9 @@ import { MessagesComponent } from './messages/messages.component';
// #docregion v1
],
bootstrap: [ AppComponent ]
// #docregion import-httpclientmodule
})
// #enddocregion import-httpclientmodule
export class AppModule { }
// #enddocregion , v1

View File

@ -13,11 +13,6 @@ import { catchError, map, tap } from 'rxjs/operators';
import { Hero } from './hero';
import { MessageService } from './message.service';
// #docregion http-options
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
// #enddocregion http-options
@Injectable({ providedIn: 'root' })
export class HeroService {
@ -26,6 +21,12 @@ export class HeroService {
private heroesUrl = 'api/heroes'; // URL to web api
// #enddocregion heroesUrl
// #docregion http-options
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
// #enddocregion http-options
// #docregion ctor
constructor(
private http: HttpClient,
@ -96,7 +97,7 @@ export class HeroService {
// #docregion addHero
/** POST: add a new hero to the server */
addHero (hero: Hero): Observable<Hero> {
return this.http.post<Hero>(this.heroesUrl, hero, httpOptions).pipe(
return this.http.post<Hero>(this.heroesUrl, hero, this.httpOptions).pipe(
tap((newHero: Hero) => this.log(`added hero w/ id=${newHero.id}`)),
catchError(this.handleError<Hero>('addHero'))
);
@ -109,7 +110,7 @@ export class HeroService {
const id = typeof hero === 'number' ? hero : hero.id;
const url = `${this.heroesUrl}/${id}`;
return this.http.delete<Hero>(url, httpOptions).pipe(
return this.http.delete<Hero>(url, this.httpOptions).pipe(
tap(_ => this.log(`deleted hero id=${id}`)),
catchError(this.handleError<Hero>('deleteHero'))
);
@ -119,7 +120,7 @@ export class HeroService {
// #docregion updateHero
/** PUT: update the hero on the server */
updateHero (hero: Hero): Observable<any> {
return this.http.put(this.heroesUrl, hero, httpOptions).pipe(
return this.http.put(this.heroesUrl, hero, this.httpOptions).pipe(
tap(_ => this.log(`updated hero id=${hero.id}`)),
catchError(this.handleError<any>('updateHero'))
);

View File

@ -0,0 +1,79 @@
import { browser, element, by, ExpectedConditions } from 'protractor';
describe('Lazy Loading AngularJS Tests', function () {
const pageElements = {
homePageHref: element(by.cssContainingText('app-root nav a', 'Home')),
homePageParagraph: element(by.css('app-root app-home p')),
ajsUsersPageHref: element(by.cssContainingText('app-root nav a', 'Users')),
ajsUsersPageParagraph: element(by.css('app-root app-angular-js div p')),
notFoundPageHref: element(by.cssContainingText('app-root nav a', '404 Page')),
notFoundPageParagraph: element(by.css('app-root app-app404 p')),
};
beforeAll(async() => {
await browser.get('/');
});
it('should display \'Angular Home\' when visiting the home page', async() => {
await pageElements.homePageHref.click();
const paragraphText = await pageElements.homePageParagraph.getText();
expect(paragraphText).toEqual('Angular Home');
});
it('should display \'Users Page\' page when visiting the AngularJS page at /users', async() => {
await pageElements.ajsUsersPageHref.click();
await loadAngularJS();
const paragraphText = await pageElements.ajsUsersPageParagraph.getText();
expect(paragraphText).toEqual('Users Page');
});
it('should display \'Angular 404\' when visiting an invalid URL', async() => {
await pageElements.notFoundPageHref.click();
const paragraphText = await pageElements.notFoundPageParagraph.getText();
expect(paragraphText).toEqual('Angular 404');
});
// Workaround for https://github.com/angular/protractor/issues/4724
async function loadAngularJS() {
// Abort if `resumeBootstrap` has already occured
if (await browser.executeScript(`return '__TESTABILITY__NG1_APP_ROOT_INJECTOR__' in window;`)) {
return;
}
// Might have to re-insert the 'NG_DEFER_BOOTSTRAP!' if the name has been changed since protractor loaded the page
if (!await browser.executeScript('window.name.includes(\'NG_DEFER_BOOTSTRAP!\')')) {
await browser.executeScript('window.name = \'NG_DEFER_BOOTSTRAP!\' + name');
}
// Wait for the AngularJS bundle to download and initialize
await browser.wait(ExpectedConditions.presenceOf(element(by.css('app-root app-angular-js'))), 5000, 'AngularJS app');
// Run the protractor pre-bootstrap logic and resumeBootstrap
// Based on https://github.com/angular/protractor/blob/5.3.0/lib/browser.ts#L950-L969
{
let moduleNames = [];
for (const {name, script, args} of browser.mockModules_) {
moduleNames.push(name);
await browser.executeScriptWithDescription(script, 'add mock module ' + name, ...args);
}
await browser.executeScriptWithDescription(
// TODO: must manually assign __TESTABILITY__NG1_APP_ROOT_INJECTOR__ (https://github.com/angular/angular/issues/22723)
`window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__ = angular.resumeBootstrap(arguments[0]) `
+ `|| angular.element('app-angular-js').injector();`,
'resume bootstrap',
moduleNames
);
}
// Wait for the initial AngularJS page to finish loading
await browser.waitForAngular();
}
});

View File

@ -0,0 +1,3 @@
{
"projectType": "cli-ajs"
}

View File

@ -1,14 +1,22 @@
import { Component, OnInit, ElementRef } from '@angular/core';
import { Component, OnInit, OnDestroy, ElementRef } from '@angular/core';
import { LazyLoaderService } from '../lazy-loader.service';
@Component({
selector: 'app-angular-js',
template: '<div ng-view></div>'
})
export class AngularJSComponent implements OnInit {
constructor(private lazyLoader: LazyLoaderService, private elRef: ElementRef) {}
export class AngularJSComponent implements OnInit, OnDestroy {
constructor(
private lazyLoader: LazyLoaderService,
private elRef: ElementRef
) {}
ngOnInit() {
this.lazyLoader.load(this.elRef.nativeElement);
}
ngOnDestroy() {
this.lazyLoader.destroy();
}
}

View File

@ -19,7 +19,6 @@ import { App404Component } from './app404/app404.component';
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@ -1,23 +1,25 @@
import { Injectable } from '@angular/core';
import * as angular from 'angular';
@Injectable({
providedIn: 'root'
})
export class LazyLoaderService {
bootstrapped = false;
private app: angular.auto.IInjectorService;
load(el: HTMLElement): void {
if (this.bootstrapped) {
return;
}
import('./angularjs-app').then(app => {
try {
app.bootstrap(el);
this.bootstrapped = true;
this.app = app.bootstrap(el);
} catch (e) {
console.error(e);
}
});
}
destroy() {
if (this.app) {
this.app.get('$rootScope').$destroy();
}
}
}

View File

@ -0,0 +1,181 @@
# Accessibility in Angular
The web is used by a wide variety of people, including those who have visual or motor impairments.
A variety of assistive technologies are available that make it much easier for these groups to
interact with web-based software applications.
In addition, designing an application to be more accessible generally improves the user experience for all users.
For an in-depth introduction to issues and techniques for designing accessible applications, see the [Accessibility](https://developers.google.com/web/fundamentals/accessibility/#what_is_accessibility) section of the Google's [Web Fundamentals](https://developers.google.com/web/fundamentals/).
This page discusses best practices for designing Angular applications that
work well for all users, including those who rely on assistive technologies.
## Accessibility attributes
Building accessible web experience often involves setting [ARIA attributes](https://developers.google.com/web/fundamentals/accessibility/semantics-aria)
to provide semantic meaning where it might otherwise be missing.
Use [attribute binding](guide/template-syntax#attribute-binding) template syntax to control the values of accessibility-related attributes.
When binding to ARIA attributes in Angular, you must use the `attr.` prefix, as the ARIA
specification depends specifically on HTML attributes rather than properties on DOM elements.
```html
<!-- Use attr. when binding to an ARIA attribute -->
<button [attr.aria-label]="myActionLabel">...</button>
```
Note that this syntax is only necessary for attribute _bindings_.
Static ARIA attributes require no extra syntax.
```html
<!-- Static ARIA attributes require no extra syntax -->
<button aria-label="Save document">...</button>
```
NOTE:
<div class="alert is-helpful">
By convention, HTML attributes use lowercase names (`tabindex`), while properties use camelCase names (`tabIndex`).
See the [Template Syntax](https://angular.io/guide/template-syntax#html-attribute-vs-dom-property) guide for more background on the difference between attributes and properties.
</div>
## Angular UI components
The [Angular Material](https://material.angular.io/) library, which is maintained by the Angular team, is a suite of reusable UI components that aims to be fully accessible.
The [Component Development Kit (CDK)](https://material.angular.io/cdk/categories) includes the `a11y` package that provides tools to support various areas of accessibility.
For example:
* `LiveAnnouncer` is used to announce messages for screen-reader users using an `aria-live` region. See the W3C documentation for more information on [aria-live regions](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-live).
* The `cdkTrapFocus` directive traps Tab-key focus within an element. Use it to create accessible experience for components like modal dialogs, where focus must be constrained.
For full details of these and other tools, see the [Angular CDK accessibility overview](https://material.angular.io/cdk/a11y/overview).
### Augmenting native elements
Native HTML elements capture a number of standard interaction patterns that are important to accessibility.
When authoring Angular components, you should re-use these native elements directly when possible, rather than re-implementing well-supported behaviors.
For example, instead of creating a custom element for a new variety of button, you can create a component that uses an attribute selector with a native `<button>` element.
This most commonly applies to `<button>` and `<a>`, but can be used with many other types of element.
You can see examples of this pattern in Angular Material: [`MatButton`](https://github.com/angular/components/blob/master/src/material/button/button.ts#L66-L68), [`MatTabNav`](https://github.com/angular/components/blob/master/src/material/tabs/tab-nav-bar/tab-nav-bar.ts#L67), [`MatTable`](https://github.com/angular/components/blob/master/src/material/table/table.ts#L17).
### Using containers for native elements
Sometimes using the appropriate native element requires a container element.
For example, the native `<input>` element cannot have children, so any custom text entry components need
to wrap an `<input>` with additional elements.
While you might just include the `<input>` in your custom component's template,
this makes it impossible for users of the component to set arbitrary properties and attributes to the input element.
Instead, you can create a container component that uses content projection to include the native control in the
component's API.
You can see [`MatFormField`](https://material.angular.io/components/form-field/overview) as an example of this pattern.
## Case study: Building a custom progress bar
The following example shows how to make a simple progress bar accessible by using host binding to control accessibility-related attributes.
* The component defines an accessibility-enabled element with both the standard HTML attribute `role`, and ARIA attributes. The ARIA attribute `aria-valuenow` is bound to the user's input.
```ts
import { Component, Input } from '@angular/core';
/**
* Example progressbar component.
*/
@Component({
selector: 'example-progressbar',
template: `<div class="bar" [style.width.%]="value"></div>`,
styleUrls: ['./progress-bar.css'],
host: {
// Sets the role for this component to "progressbar"
role: 'progressbar',
// Sets the minimum and maximum values for the progressbar role.
'aria-valuemin': '0',
'aria-valuemax': '0',
// Binding that updates the current value of the progressbar.
'[attr.aria-valuenow]': 'value',
}
})
export class ExampleProgressbar {
/** Current value of the progressbar. */
@Input() value: number = 0;
}
```
* In the template, the `aria-label` attribute ensures that the control is accessible to screen readers.
```html
<label>
Enter an example progress value
<input type="number" min="0" max="100"
[value]="progress" (input)="progress = $event.target.value">
</label>
<!-- The user of the progressbar sets an aria-label to communicate what the progress means. -->
<example-progressbar [value]="progress" aria-label="Example of a progress bar">
</example-progressbar>
```
[See the full example in StackBlitz](https://stackblitz.com/edit/angular-kn5jdi?file=src%2Fapp%2Fapp.component.html).
## Routing and focus management
Tracking and controlling [focus](https://developers.google.com/web/fundamentals/accessibility/focus/) in a UI is an important consideration in designing for accessibility.
When using Angular routing, you should decide where page focus goes upon navigation.
To avoid relying solely on visual cues, you need to make sure your routing code updates focus after page navigation.
Use the `NavigationEnd` event from the `Router` service to know when to update
focus.
The following example shows how to find and focus the main content header in the DOM after navigation.
```ts
router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
const mainHeader = document.querySelector('#main-content-header')
if (mainHeader) {
mainHeader.focus();
}
});
```
In a real application, the element that receives focus will depend on your specific
application structure and layout.
The focused element should put users in a position to immediately move into the main content that has just been routed into view.
You should avoid situations where focus returns to the `body` element after a route change.
## Additional resources
* [Accessibility - Google Web Fundamentals](https://developers.google.com/web/fundamentals/accessibility)
* [ARIA specification and authoring practices](https://www.w3.org/TR/wai-aria/)
* [Material Design - Accessibility](https://material.io/design/usability/accessibility.html)
* [Smashing Magazine](https://www.smashingmagazine.com/search/?q=accessibility)
* [Inclusive Components](https://inclusive-components.design/)
* [Accessibility Resources and Code Examples](https://dequeuniversity.com/resources/)
* [W3C - Web Accessibility Initiative](https://www.w3.org/WAI/people-use-web/)
* [Rob Dodson A11ycasts](https://www.youtube.com/watch?v=HtTyRajRuyY)
* [Codelyzer](http://codelyzer.com/rules/) provides linting rules that can help you make sure your code meets accessibility standards.
Books
* "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery
* "Inclusive Design Patterns", Heydon Pickering

View File

@ -66,7 +66,7 @@ The following table lists some of the key AngularJS template features with their
### Bindings/interpolation
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="interpolation" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="interpolation"></code-example>
In Angular, a template expression in curly braces still denotes one-way binding.
@ -102,7 +102,7 @@ The following table lists some of the key AngularJS template features with their
### Pipes
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="uppercase" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="uppercase"></code-example>
In Angular you use similar syntax with the pipe (|) character to filter output, but now you call them **pipes**.
@ -136,7 +136,7 @@ The following table lists some of the key AngularJS template features with their
### Input variables
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="local" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="local"></code-example>
Angular has true template input variables that are explicitly defined using the `let` keyword.
@ -202,10 +202,10 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bootstrapping
<code-example hideCopy path="ajs-quick-reference/src/main.ts" header="main.ts" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/main.ts" header="main.ts"></code-example>
<br>
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts" header="app.module.ts" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts" header="app.module.ts"></code-example>
Angular doesn't have a bootstrap directive.
@ -245,7 +245,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ngClass
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngClass" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngClass"></code-example>
In Angular, the `ngClass` directive works similarly.
@ -291,7 +291,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bind to the `click` event
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="event-binding" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="event-binding"></code-example>
AngularJS event-based directives do not exist in Angular.
@ -338,7 +338,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### Component decorator
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component"></code-example>
In Angular, the template no longer specifies its associated controller.
@ -401,7 +401,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bind to the `href` property
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="href" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="href"></code-example>
Angular uses property binding; there is no built-in *href* directive.
@ -412,7 +412,7 @@ The following are some of the key AngularJS built-in directives and their equiva
In Angular, `href` is no longer used for routing. Routing uses `routerLink`, as shown in the following example.
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="router-link" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="router-link"></code-example>
For more information on routing, see the [RouterLink binding](guide/router#router-link)
@ -445,7 +445,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### *ngIf
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngIf" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngIf"></code-example>
The `*ngIf` directive in Angular works the same as the `ng-if` directive in AngularJS. It removes
@ -480,7 +480,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ngModel
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngModel" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngModel"></code-example>
In Angular, **two-way binding** is denoted by `[()]`, descriptively referred to as a "banana in a box". This syntax is a shortcut for defining both property binding (from the component to the view)
@ -516,7 +516,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### *ngFor
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngFor" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngFor"></code-example>
The `*ngFor` directive in Angular is similar to the `ng-repeat` directive in AngularJS. It repeats
@ -559,7 +559,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bind to the `hidden` property
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="hidden" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="hidden"></code-example>
Angular uses property binding; there is no built-in *show* directive.
@ -598,7 +598,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### Bind to the `src` property
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="src" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="src"></code-example>
Angular uses property binding; there is no built-in *src* directive.
@ -635,7 +635,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ngStyle
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngStyle" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="ngStyle"></code-example>
In Angular, the `ngStyle` directive works similarly. It sets a CSS style on an HTML element based on an expression.
@ -690,7 +690,7 @@ The following are some of the key AngularJS built-in directives and their equiva
### ngSwitch
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngSwitch" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.html" region="ngSwitch"></code-example>
In Angular, the `ngSwitch` directive works similarly.
@ -765,7 +765,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### currency
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="currency" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="currency"></code-example>
The Angular `currency` pipe is similar although some of the parameters have changed.
@ -793,7 +793,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### date
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="date" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="date"></code-example>
The Angular `date` pipe is similar.
@ -847,7 +847,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### json
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="json" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="json"></code-example>
The Angular `json` pipe does the same thing.
@ -876,7 +876,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### slice
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="slice" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="slice"></code-example>
The `SlicePipe` does the same thing but the *order of the parameters is reversed*, in keeping
@ -907,7 +907,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### lowercase
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="lowercase" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="lowercase"></code-example>
The Angular `lowercase` pipe does the same thing.
@ -935,7 +935,7 @@ For more information on pipes, see [Pipes](guide/pipes).
### number
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="number" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.component.html" region="number"></code-example>
The Angular `number` pipe is similar.
@ -1068,7 +1068,7 @@ The Angular code is shown using TypeScript.
### NgModules
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/app.module.1.ts"></code-example>
NgModules, defined with the `NgModule` decorator, serve the same purpose:
@ -1109,7 +1109,7 @@ The Angular code is shown using TypeScript.
### Component decorator
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="component"></code-example>
Angular adds a decorator to the component class to provide any required metadata.
@ -1145,7 +1145,7 @@ The Angular code is shown using TypeScript.
### Component class
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="class" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="class"></code-example>
In Angular, you create a component class.
@ -1184,7 +1184,7 @@ The Angular code is shown using TypeScript.
### Dependency injection
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="di" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="di"></code-example>
In Angular, you pass in dependencies as arguments to the component class constructor.
@ -1254,7 +1254,7 @@ also encapsulate a style sheet within a specific component.
### Styles configuration
<code-example hideCopy path="ajs-quick-reference/.angular-cli.1.json" region="styles" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/.angular-cli.1.json" region="styles"></code-example>
With the Angular CLI, you can configure your global styles in the `angular.json` file.
You can rename the extension to `.scss` to use sass.
@ -1263,7 +1263,7 @@ also encapsulate a style sheet within a specific component.
In Angular, you can use the `styles` or `styleUrls` property of the `@Component` metadata to define
a style sheet for a particular component.
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="style-url" linenums="false"></code-example>
<code-example hideCopy path="ajs-quick-reference/src/app/movie-list.component.ts" region="style-url"></code-example>
This allows you to set appropriate styles for individual components that wont leak into

View File

@ -37,8 +37,7 @@ To get started with adding Angular animations to your project, import the animat
Import `BrowserAnimationsModule`, which introduces the animation capabilities into your Angular root application module.
<code-example path="animations/src/app/app.module.1.ts" header="src/app/app.module.ts" language="typescript" linenums="false">
</code-example>
<code-example path="animations/src/app/app.module.1.ts" header="src/app/app.module.ts" language="typescript"></code-example>
<div class="alert is-helpful">
@ -180,9 +179,7 @@ In this example, we'll name the trigger `openClose`, and attach it to the `butto
Animations are defined in the metadata of the component that controls the HTML element to be animated. Put the code that defines your animations under the `animations:` property within the `@Component()` decorator.
<code-example path="animations/src/app/open-close.component.ts" header="src/app/open-close.component.ts" language="typescript"
region="component" linenums="false">
</code-example>
<code-example path="animations/src/app/open-close.component.ts" header="src/app/open-close.component.ts" language="typescript" region="component"></code-example>
When you've defined an animation trigger for a component, you can attach it to an element in that component's template by wrapping the trigger name in brackets and preceding it with an `@` symbol. Then, you can bind the trigger to a template expression using standard Angular property binding syntax as shown below, where `triggerName` is the name of the trigger, and `expression` evaluates to a defined animation state.

View File

@ -21,7 +21,7 @@ Angular offers two ways to compile your application:
1. **_Just-in-Time_ (JIT)**, which compiles your app in the browser at runtime.
1. **_Ahead-of-Time_ (AOT)**, which compiles your app at build time.
JIT compilation is the default when you run the [`ng build`](cli/build) (build only) or [`ng serve`](cli/serve) (build and serve locally) CLI commands:
JIT compilation is the default when you run the [`ng build`](cli/build) (build only) or [`ng serve`](cli/serve) (build and serve locally) CLI commands:
<code-example language="sh" class="code-shell">
ng build
@ -945,7 +945,7 @@ import { calculateValue } from './utilities';
To correct this error, export a function from the module and refer to the function in a `useFactory` provider instead.
<code-example linenums="false">
<code-example>
// CORRECTED
import { calculateValue } from './utilities';
@ -978,7 +978,7 @@ The compiler does not support references to variables assigned by [destructuring
For example, you cannot write something like this:
<code-example linenums="false">
<code-example>
// ERROR
import { configuration } from './configuration';
@ -994,7 +994,7 @@ const {foo, bar} = configuration;
To correct this error, refer to non-destructured values.
<code-example linenums="false">
<code-example>
// CORRECTED
import { configuration } from './configuration';
...
@ -1041,7 +1041,7 @@ you can finesse the problem in four steps:
Here's an illustrative example.
<code-example linenums="false">
<code-example>
// CORRECTED
import { Inject } from '@angular/core';
@ -1064,7 +1064,7 @@ uses the `@Inject(WINDOW)` to generate the injection code.
Angular does something similar with the `DOCUMENT` token so you can inject the browser's `document` object (or an abstraction of it, depending upon the platform in which the application runs).
<code-example linenums="false">
<code-example>
import { Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
@ -1101,7 +1101,7 @@ that you referenced in metadata.
The compiler can understand simple enum values but not complex values such as those derived from computed properties.
<code-example linenums="false">
<code-example>
// ERROR
enum Colors {
Red = 1,
@ -1311,7 +1311,7 @@ Chuck: After reviewing your PR comment I'm still at a loss. See [comment there](
{@a tsconfig-extends}
## Configuration inheritance with extends
Similar to TypeScript Compiler, Angular Compiler also supports `extends` in the `tsconfig.json` on `angularCompilerOptions`. A tsconfig file can inherit configurations from another file using the `extends` property.
The `extends` is a top level property parallel to `compilerOptions` and `angularCompilerOptions`.
The `extends` is a top level property parallel to `compilerOptions` and `angularCompilerOptions`.
The configuration from the base file are loaded first, then overridden by those in the inheriting config file.
Example:
```json

View File

@ -10,7 +10,7 @@ Learn more in [The App Shell Model](https://developers.google.com/web/fundamenta
## Step 1: Prepare the application
You can do this with the following CLI command:
<code-example format="." language="bash" linenums="false">
<code-example language="bash">
ng new my-app --routing
</code-example>
@ -20,7 +20,7 @@ For an existing application, you have to manually add the `RouterModule` and def
Use the CLI to automatically create the app shell.
<code-example format="." language="bash" linenums="false">
<code-example language="bash">
ng generate app-shell --client-project my-app --universal-project server-app
</code-example>
@ -29,7 +29,7 @@ ng generate app-shell --client-project my-app --universal-project server-app
After running this command you will notice that the `angular.json` configuration file has been updated to add two new targets, with a few other changes.
<code-example format="." language="none" linenums="false">
<code-example language="json">
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
@ -52,7 +52,7 @@ After running this command you will notice that the `angular.json` configuration
Use the CLI to build the `app-shell` target.
<code-example format="." language="bash" linenums="false">
<code-example language="bash">
ng run my-app:app-shell
</code-example>

View File

@ -10,12 +10,12 @@ For example, individual components define and control each of the following view
You define a component's application logic&mdash;what it does to support the view&mdash;inside a class.
The class interacts with the view through an API of properties and methods.
For example, `HeroListComponent` has a `heroes` property that holds an array of heroes.
Its `selectHero()` method sets a `selectedHero` property when the user clicks to choose a hero from that list.
The component acquires the heroes from a service, which is a TypeScript [parameter property](http://www.typescriptlang.org/docs/handbook/classes.html#parameter-properties) on the constructor.
For example, `HeroListComponent` has a `heroes` property that holds an array of heroes.
Its `selectHero()` method sets a `selectedHero` property when the user clicks to choose a hero from that list.
The component acquires the heroes from a service, which is a TypeScript [parameter property](http://www.typescriptlang.org/docs/handbook/classes.html#parameter-properties) on the constructor.
The service is provided to the component through the dependency injection system.
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" header="src/app/hero-list.component.ts (class)" region="class"></code-example>
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (class)" region="class"></code-example>
Angular creates, updates, and destroys components as the user moves through the application. Your app can take action at each moment in this lifecycle through optional [lifecycle hooks](guide/lifecycle-hooks), like `ngOnInit()`.
@ -31,7 +31,7 @@ In addition to containing or pointing to the template, the `@Component` metadata
Here's an example of basic metadata for `HeroListComponent`.
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" header="src/app/hero-list.component.ts (metadata)" region="metadata"></code-example>
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (metadata)" region="metadata"></code-example>
This example shows some of the most useful `@Component` configuration options:
@ -40,7 +40,7 @@ Angular inserts an instance of the `HeroListComponent` view between those tags.
* `templateUrl`: The module-relative address of this component's HTML template. Alternatively, you can provide the HTML template inline, as the value of the `template` property. This template defines the component's *host view*.
* `providers`: An array of [providers](guide/glossary#provider) for services that the component requires. In the example, this tells Angular how to provide the `HeroService` instance that the component's constructor uses to get the list of heroes to display.
* `providers`: An array of [providers](guide/glossary#provider) for services that the component requires. In the example, this tells Angular how to provide the `HeroService` instance that the component's constructor uses to get the list of heroes to display.
## Templates and views
@ -69,7 +69,7 @@ This template uses typical HTML elements like `<h2>` and `<p>`, and also includ
* The `*ngFor` directive tells Angular to iterate over a list.
* `{{hero.name}}`, `(click)`, and `[hero]` bind program data to and from the DOM, responding to user input. See more about [data binding](#data-binding) below.
* The `<app-hero-detail>` tag in the example is an element that represents a new component, `HeroDetailComponent`.
* The `<app-hero-detail>` tag in the example is an element that represents a new component, `HeroDetailComponent`.
`HeroDetailComponent` (code not shown) defines the hero-detail child view of `HeroListComponent`.
Notice how custom components like this mix seamlessly with native HTML in the same layouts.
@ -87,7 +87,7 @@ The following diagram shows the four forms of data binding markup. Each form has
This example from the `HeroListComponent` template uses three of these forms.
<code-example path="architecture/src/app/hero-list.component.1.html" linenums="false" header="src/app/hero-list.component.html (binding)" region="binding"></code-example>
<code-example path="architecture/src/app/hero-list.component.1.html" header="src/app/hero-list.component.html (binding)" region="binding"></code-example>
* The `{{hero.name}}` [*interpolation*](guide/displaying-data#interpolation)
displays the component's `hero.name` property value within the `<li>` element.
@ -97,11 +97,11 @@ displays the component's `hero.name` property value within the `<li>` element.
* The `(click)` [*event binding*](guide/user-input#binding-to-user-input-events) calls the component's `selectHero` method when the user clicks a hero's name.
Two-way data binding (used mainly in [template-driven forms](guide/forms))
combines property and event binding in a single notation.
Two-way data binding (used mainly in [template-driven forms](guide/forms))
combines property and event binding in a single notation.
Here's an example from the `HeroDetailComponent` template that uses two-way data binding with the `ngModel` directive.
<code-example path="architecture/src/app/hero-detail.component.html" linenums="false" header="src/app/hero-detail.component.html (ngModel)" region="ngModel"></code-example>
<code-example path="architecture/src/app/hero-detail.component.html" header="src/app/hero-detail.component.html (ngModel)" region="ngModel"></code-example>
In two-way binding, a data property value flows to the input box from the component as with property binding.
The user's changes also flow back to the component, resetting the property to the latest value,
@ -151,20 +151,20 @@ Angular templates are *dynamic*. When Angular renders them, it transforms the DO
A component is technically a directive.
However, components are so distinctive and central to Angular applications that Angular
defines the `@Component()` decorator, which extends the `@Directive()` decorator with
defines the `@Component()` decorator, which extends the `@Directive()` decorator with
template-oriented features.
In addition to components, there are two other kinds of directives: *structural* and *attribute*.
In addition to components, there are two other kinds of directives: *structural* and *attribute*.
Angular defines a number of directives of both kinds, and you can define your own using the `@Directive()` decorator.
Just as for components, the metadata for a directive associates the decorated class with a `selector` element that you use to insert it into HTML. In templates, directives typically appear within an element tag as attributes, either by name or as the target of an assignment or a binding.
#### Structural directives
*Structural directives* alter layout by adding, removing, and replacing elements in the DOM.
*Structural directives* alter layout by adding, removing, and replacing elements in the DOM.
The example template uses two built-in structural directives to add application logic to how the view is rendered.
<code-example path="architecture/src/app/hero-list.component.1.html" linenums="false" header="src/app/hero-list.component.html (structural)" region="structural"></code-example>
<code-example path="architecture/src/app/hero-list.component.1.html" header="src/app/hero-list.component.html (structural)" region="structural"></code-example>
* [`*ngFor`](guide/displaying-data#ngFor) is an iterative; it tells Angular to stamp out one `<li>` per hero in the `heroes` list.
* [`*ngIf`](guide/displaying-data#ngIf) is a conditional; it includes the `HeroDetail` component only if a selected hero exists.
@ -176,7 +176,7 @@ In templates they look like regular HTML attributes, hence the name.
The `ngModel` directive, which implements two-way data binding, is an example of an attribute directive. `ngModel` modifies the behavior of an existing element (typically `<input>`) by setting its display value property and responding to change events.
<code-example path="architecture/src/app/hero-detail.component.html" linenums="false" header="src/app/hero-detail.component.html (ngModel)" region="ngModel"></code-example>
<code-example path="architecture/src/app/hero-detail.component.html" header="src/app/hero-detail.component.html (ngModel)" region="ngModel"></code-example>
Angular has more pre-defined directives that either alter the layout structure
(for example, [ngSwitch](guide/template-syntax#ngSwitch))

View File

@ -23,7 +23,7 @@ An NgModule is defined by a class decorated with `@NgModule()`. The `@NgModule()
Here's a simple root NgModule definition.
<code-example path="architecture/src/app/mini-app.ts" region="module" header="src/app/app.module.ts" linenums="false"></code-example>
<code-example path="architecture/src/app/mini-app.ts" region="module" header="src/app/app.module.ts"></code-example>
<div class="alert is-helpful">
@ -69,9 +69,9 @@ In JavaScript each *file* is a module and all objects defined in the file belong
The module declares some objects to be public by marking them with the `export` key word.
Other JavaScript modules use *import statements* to access public objects from other modules.
<code-example path="architecture/src/app/app.module.ts" region="imports" linenums="false"></code-example>
<code-example path="architecture/src/app/app.module.ts" region="imports"></code-example>
<code-example path="architecture/src/app/app.module.ts" region="export" linenums="false"></code-example>
<code-example path="architecture/src/app/app.module.ts" region="export"></code-example>
<div class="alert is-helpful">
<a href="http://exploringjs.com/es6/ch_modules.html">Learn more about the JavaScript module system on the web.</a>
@ -87,17 +87,17 @@ Angular loads as a collection of JavaScript modules. You can think of them as li
For example, import Angular's `Component` decorator from the `@angular/core` library like this.
<code-example path="architecture/src/app/app.component.ts" region="import" linenums="false"></code-example>
<code-example path="architecture/src/app/app.component.ts" region="import"></code-example>
You also import NgModules from Angular *libraries* using JavaScript import statements.
For example, the following code imports the `BrowserModule` NgModule from the `platform-browser` library.
<code-example path="architecture/src/app/mini-app.ts" region="import-browser-module" linenums="false"></code-example>
<code-example path="architecture/src/app/mini-app.ts" region="import-browser-module"></code-example>
In the example of the simple root module above, the application module needs material from within
`BrowserModule`. To access that material, add it to the `@NgModule` metadata `imports` like this.
<code-example path="architecture/src/app/mini-app.ts" region="ngmodule-imports" linenums="false"></code-example>
<code-example path="architecture/src/app/mini-app.ts" region="ngmodule-imports"></code-example>
In this way you're using the Angular and JavaScript module systems *together*. Although it's easy to confuse the two systems, which share the common vocabulary of "imports" and "exports", you will become familiar with the different contexts in which they are used.

View File

@ -1,7 +1,7 @@
# Introduction to services and dependency injection
*Service* is a broad category encompassing any value, function, or feature that an app needs.
A service is typically a class with a narrow, well-defined purpose.
A service is typically a class with a narrow, well-defined purpose.
It should do something specific and do it well.
Angular distinguishes components from services to increase modularity and reusability.
@ -14,9 +14,9 @@ in order to mediate between the view (rendered by the template)
and the application logic (which often includes some notion of a *model*).
A component can delegate certain tasks to services, such as fetching data from the server,
validating user input, or logging directly to the console.
validating user input, or logging directly to the console.
By defining such processing tasks in an *injectable service class*, you make those tasks
available to any component.
available to any component.
You can also make your app more adaptable by injecting different providers of the same kind of service,
as appropriate in different circumstances.
@ -28,21 +28,21 @@ available to components through *dependency injection*.
Here's an example of a service class that logs to the browser console.
<code-example path="architecture/src/app/logger.service.ts" linenums="false" header="src/app/logger.service.ts (class)" region="class"></code-example>
<code-example path="architecture/src/app/logger.service.ts" header="src/app/logger.service.ts (class)" region="class"></code-example>
Services can depend on other services. For example, here's a `HeroService` that depends on the `Logger` service, and also uses `BackendService` to get heroes. That service in turn might depend on the `HttpClient` service to fetch heroes asynchronously from a server.
<code-example path="architecture/src/app/hero.service.ts" linenums="false" header="src/app/hero.service.ts (class)" region="class"></code-example>
<code-example path="architecture/src/app/hero.service.ts" header="src/app/hero.service.ts (class)" region="class"></code-example>
## Dependency injection (DI)
<img src="generated/images/guide/architecture/dependency-injection.png" alt="Service" class="left">
DI is wired into the Angular framework and used everywhere to provide new components with the services or other things they need.
Components consume services; that is, you can *inject* a service into a component, giving the component access to that service class.
Components consume services; that is, you can *inject* a service into a component, giving the component access to that service class.
To define a class as a service in Angular, use the `@Injectable()` decorator to provide the metadata that allows Angular to inject it into a component as a *dependency*.
Similarly, use the `@Injectable()` decorator to indicate that a component or other class (such as another service, a pipe, or an NgModule) *has* a dependency.
To define a class as a service in Angular, use the `@Injectable()` decorator to provide the metadata that allows Angular to inject it into a component as a *dependency*.
Similarly, use the `@Injectable()` decorator to indicate that a component or other class (such as another service, a pipe, or an NgModule) *has* a dependency.
* The *injector* is the main mechanism. Angular creates an application-wide injector for you during the bootstrap process, and additional injectors as needed. You don't have to create injectors.
@ -50,19 +50,19 @@ Similarly, use the `@Injectable()` decorator to indicate that a component or oth
* A *provider* is an object that tells an injector how to obtain or create a dependency.
For any dependency that you need in your app, you must register a provider with the app's injector,
so that the injector can use the provider to create new instances.
For any dependency that you need in your app, you must register a provider with the app's injector,
so that the injector can use the provider to create new instances.
For a service, the provider is typically the service class itself.
<div class="alert is-helpful">
A dependency doesn't have to be a service&mdash;it could be a function, for example, or a value.
A dependency doesn't have to be a service&mdash;it could be a function, for example, or a value.
</div>
When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the constructor parameter types. For example, the constructor of `HeroListComponent` needs `HeroService`.
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" header="src/app/hero-list.component.ts (constructor)" region="ctor"></code-example>
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (constructor)" region="ctor"></code-example>
When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector makes one using the registered provider, and adds it to the injector before returning the service to Angular.
@ -78,26 +78,26 @@ The process of `HeroService` injection looks something like this.
You must register at least one *provider* of any service you are going to use.
The provider can be part of the service's own metadata, making that service available everywhere,
or you can register providers with specific modules or components.
or you can register providers with specific modules or components.
You register providers in the metadata of the service (in the `@Injectable()` decorator),
or in the `@NgModule()` or `@Component()` metadata
or in the `@NgModule()` or `@Component()` metadata
* By default, the Angular CLI command [`ng generate service`](cli/generate) registers a provider with the root injector for your service by including provider metadata in the `@Injectable()` decorator. The tutorial uses this method to register the provider of HeroService class definition.
```
```
@Injectable({
providedIn: 'root',
})
```
```
When you provide the service at the root level, Angular creates a single, shared instance of `HeroService`
and injects it into any class that asks for it.
and injects it into any class that asks for it.
Registering the provider in the `@Injectable()` metadata also allows Angular to optimize an app
by removing the service from the compiled app if it isn't used.
by removing the service from the compiled app if it isn't used.
* When you register a provider with a [specific NgModule](guide/architecture-modules), the same instance of a service is available to all components in that NgModule. To register at this level, use the `providers` property of the `@NgModule()` decorator,
```
```
@NgModule({
providers: [
BackendService,
@ -105,12 +105,12 @@ or in the `@NgModule()` or `@Component()` metadata
],
...
})
```
```
* When you register a provider at the component level, you get a new instance of the
service with each new instance of that component.
service with each new instance of that component.
At the component level, register a service provider in the `providers` property of the `@Component()` metadata.
<code-example path="architecture/src/app/hero-list.component.ts" linenums="false" header="src/app/hero-list.component.ts (component providers)" region="providers"></code-example>
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (component providers)" region="providers"></code-example>
For more detailed information, see the [Dependency Injection](guide/dependency-injection) section.

View File

@ -37,13 +37,13 @@ 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" linenums="false" header="src/app/app.component.html (applied)" region="applied"></code-example>
<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" linenums="false" header="src/app/app.component.avoid.html (unsupported)" region="unsupported"></code-example>
<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
@ -101,7 +101,7 @@ Now edit the generated `src/app/highlight.directive.ts` to look as follows:
The `import` statement specifies an additional `ElementRef` symbol from the Angular `core` library:
You use the `ElementRef` in the directive's constructor
to [inject](guide/dependency-injection) a reference to the host DOM element,
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
@ -140,12 +140,12 @@ and respond by setting or clearing the highlight color.
Begin by adding `HostListener` to the list of imported symbols.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" 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 eventhandlers that respond when the mouse enters or leaves,
each adorned by the `HostListener` decorator.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" 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.
@ -166,7 +166,7 @@ The handlers delegate to a helper method that sets the color on the host DOM ele
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" linenums="false" header="src/app/highlight.directive.ts (constructor)" region="ctor"></code-example>
<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:
@ -187,11 +187,11 @@ Currently the highlight color is hard-coded _within_ the directive. That's infle
In this section, you give the developer the power to set the highlight color while applying the directive.
Begin by adding `Input` to the list of symbols imported from `@angular/core`.
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" 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:
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" 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 (highlightColor)" region="color"></code-example>
{@a input}
@ -204,19 +204,19 @@ Without that input metadata, Angular rejects the binding; see [below](guide/attr
Try it by adding the following directive binding variations to the `AppComponent` template:
<code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html (excerpt)" region="color-1"></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>
Add a `color` property to the `AppComponent`.
<code-example path="attribute-directives/src/app/app.component.1.ts" linenums="false" header="src/app/app.component.ts (class)" region="class"></code-example>
<code-example path="attribute-directives/src/app/app.component.1.ts" header="src/app/app.component.ts (class)" region="class"></code-example>
Let it control the highlight color with a property binding.
<code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html (excerpt)" region="color-2"></code-example>
<code-example path="attribute-directives/src/app/app.component.1.html" header="src/app/app.component.html (excerpt)" region="color-2"></code-example>
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" linenums="false" header="src/app/app.component.html (color)" region="color"></code-example>
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (color)" region="color"></code-example>
The `[appHighlight]` attribute binding both applies the highlighting directive to the `<p>` element
and sets the directive's highlight color with a property binding.
@ -225,7 +225,7 @@ That's a crisp, compact syntax.
You'll have to rename the directive's `highlightColor` property to `appHighlight` because that's now the color property binding name.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (renamed to match directive selector)" region="color-2"></code-example>
<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.
@ -237,23 +237,23 @@ Fortunately you can name the directive property whatever you want _and_ **_alias
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" linenums="false" header="src/app/highlight.directive.ts (color property with alias)" region="color"></code-example>
<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" linenums="false" header="src/app/app.component.html (color)" region="color"></code-example>
<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 `appHighlightColor`, highlight the host element in red:
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" header="src/app/highlight.directive.ts (mouse enter)" region="mouse-enter"></code-example>
<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" linenums="false" header="src/app/highlight.directive.ts (excerpt)"></code-example>
<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
@ -263,11 +263,11 @@ lets you pick the highlight color with a radio button and bind your color choice
Update <code>app.component.html</code> as follows:
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" 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 (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" linenums="false" header="src/app/app.component.ts (class)" region="class"></code-example>
<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.
@ -287,12 +287,12 @@ Let the template developer set the default color.
Add a second **input** property to `HighlightDirective` called `defaultColor`:
<code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" 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>
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" linenums="false" 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>
How do you bind to a second property when you're already binding to the `appHighlight` attribute name?
@ -300,7 +300,7 @@ As with components, you can add as many directive property bindings as you need
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.
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (defaultColor)" region="defaultColor"></code-example>
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (defaultColor)" region="defaultColor"></code-example>
Angular knows that the `defaultColor` binding belongs to the `HighlightDirective`
because you made it _public_ with the `@Input` decorator.
@ -342,11 +342,11 @@ You can also experience and download the <live-example title="Attribute Directiv
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" linenums="false" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
<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" linenums="false" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
<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.
@ -378,7 +378,7 @@ You can tell if `@Input` is needed by the position of the property name in a bin
Now apply that reasoning to the following example:
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (color)" region="color"></code-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.

View File

@ -106,19 +106,16 @@ To use a directive, component, or pipe in a module, you must do a few things:
Those three steps look like the following. In the file where you create your directive, export it.
The following example, named `ItemDirective` is the default directive structure that the CLI generates in its own file, `item.directive.ts`:
<code-example path="bootstrapping/src/app/item.directive.ts" region="directive" header="src/app/item.directive.ts" linenums="false">
</code-example>
<code-example path="bootstrapping/src/app/item.directive.ts" region="directive" header="src/app/item.directive.ts"></code-example>
The key point here is that you have to export it so you can import it elsewhere. Next, import it
into the NgModule, in this example `app.module.ts`, with a JavaScript import statement:
<code-example path="bootstrapping/src/app/app.module.ts" region="directive-import" header="src/app/app.module.ts" linenums="false">
</code-example>
<code-example path="bootstrapping/src/app/app.module.ts" region="directive-import" header="src/app/app.module.ts"></code-example>
And in the same file, add it to the `@NgModule` `declarations` array:
<code-example path="bootstrapping/src/app/app.module.ts" region="declarations" header="src/app/app.module.ts" linenums="false">
</code-example>
<code-example path="bootstrapping/src/app/app.module.ts" region="declarations" header="src/app/app.module.ts"></code-example>
Now you could use your `ItemDirective` in a component. This example uses `AppModule`, but you'd do it the same way for a feature module. For more about directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives). You'd also use the same technique for [pipes](guide/pipes) and components.

View File

@ -53,7 +53,7 @@ Angular supports most recent browsers. This includes the following specific vers
IE
</td>
<td>
11<br>10<br>9
11, 10, 9
</td>
</tr>
<tr>
@ -89,7 +89,7 @@ Angular supports most recent browsers. This includes the following specific vers
</td>
<td>
Nougat (7.0)<br>Marshmallow (6.0)<br>Lollipop (5.0, 5.1)<br>KitKat (4.4)
Nougat (7.0), Marshmallow (6.0), Lollipop (5.0, 5.1), KitKat (4.4)
</td>
</tr>
@ -127,25 +127,27 @@ In Angular CLI version 8 and higher, applications are built using *differential
This strategy allows you to continue to build your web application to support multiple browsers, but only load the necessary code that the browser needs.
For more information about how this works, see [Differential Loading](guide/deployment#differential-loading) in the [Deployment guide](guide/deployment).
## Enabling polyfills
## Enabling polyfills with CLI projects
[Angular CLI](cli) users enable polyfills through the `src/polyfills.ts` file that
the CLI created with your project.
The [Angular CLI](cli) provides support for polyfills.
If you are not using the CLI to create your projects, see [Polyfill instructions for non-CLI users](#non-cli).
When you create a project with the `ng new` command, a `src/polyfills.ts` configuration file is created as part of your project folder.
This file incorporates the mandatory and many of the optional polyfills as JavaScript `import` statements.
The npm packages for the _mandatory_ polyfills (such as `zone.js`) were installed automatically for you when you created your project and their corresponding `import` statements are ready to go. You probably won't touch these.
* The npm packages for the [_mandatory_ polyfills](#polyfill-libs) (such as `zone.js`) are installed automatically for you when you create your project with `ng new`, and their corresponding `import` statements are already enabled in the `src/polyfills.ts` configuration file.
But if you need an optional polyfill, you'll have to install its npm package.
For example, [if you need the web animations polyfill](http://caniuse.com/#feat=web-animation), you could install it with `npm`, using the following command (or the `yarn` equivalent):
* If you need an _optional_ polyfill, you must install its npm package, then uncomment or create the corresponding import statement in the `src/polyfills.ts` configuration file.
For example, if you need the optional [web animations polyfill](http://caniuse.com/#feat=web-animation), you could install it with `npm`, using the following command (or the `yarn` equivalent):
<code-example language="sh" class="code-shell">
# note that the web-animations-js polyfill is only here as an example
# it isn't a strict requirement of Angular anymore (more below)
# install the optional web animations polyfill
npm install --save web-animations-js
</code-example>
Then open the `polyfills.ts` file and un-comment the corresponding `import` statement as in the following example:
You can then add the import statement in the `src/polyfills.ts` file.
For many polyfills, you can simply un-comment the corresponding `import` statement in the file, as in the following example.
<code-example header="src/polyfills.ts">
/**
@ -155,23 +157,14 @@ Then open the `polyfills.ts` file and un-comment the corresponding `import` stat
import 'web-animations-js'; // Run `npm install --save web-animations-js`.
</code-example>
If you can't find the polyfill you want in `polyfills.ts`,
add it yourself, following the same pattern:
If the polyfill you want is not already in `polyfills.ts` file, add the `import` statement by hand.
1. install the npm package
1. `import` the file in `polyfills.ts`
<div class="alert is-helpful">
Non-CLI users should follow the instructions [below](#non-cli).
</div>
{@a polyfill-libs}
### Mandatory polyfills
These are the polyfills required to run an Angular application on each supported browser:
<table>
<tr style="vertical-align: top">
@ -189,26 +182,13 @@ These are the polyfills required to run an Angular application on each supported
<tr style="vertical-align: top">
<td>
Chrome, Firefox, Edge, Safari 9+
Chrome, Firefox, Edge, <br>
Safari, Android, IE10+
</td>
<td>
[ES7/reflect](guide/browser-support#core-es7-reflect) (JIT only)
</td>
</tr>
<tr style="vertical-align: top">
<td>
Safari 7 & 8, IE10 & 11, Android 4.1+
</td>
<td>
[ES6](guide/browser-support#core-es6)
[ES2015](guide/browser-support#core-es6)
</td>
@ -222,7 +202,7 @@ These are the polyfills required to run an Angular application on each supported
<td>
[ES6<br>classList](guide/browser-support#classlist)
ES2015<br>[classList](guide/browser-support#classlist)
</td>
@ -235,12 +215,6 @@ These are the polyfills required to run an Angular application on each supported
Some features of Angular may require additional polyfills.
For example, the animations library relies on the standard web animation API, which is only available in Chrome and Firefox today.
(note that the dependency of web-animations-js in Angular is only necessary if `AnimationBuilder` is used.)
Here are the features which may require additional polyfills:
<table>
<tr style="vertical-align: top">
@ -263,31 +237,8 @@ Here are the features which may require additional polyfills:
<td>
[JIT compilation](guide/aot-compiler).
Required to reflect for metadata.
</td>
<td>
[ES7/reflect](guide/browser-support#core-es7-reflect)
</td>
<td>
All current browsers. Enabled by default.
Can remove if you always use AOT and only use Angular decorators.
</td>
</tr>
<tr style="vertical-align: top">
<td>
[Animations](guide/animations)
<br>Only if `Animation Builder` is used within the application--standard
animation support in Angular doesn't require any polyfills (as of NG6).
[AnimationBuilder](api/animations/AnimationBuilder).
(Standard animation support does not require polyfills.)
</td>
@ -298,8 +249,9 @@ Here are the features which may require additional polyfills:
</td>
<td>
<p>If AnimationBuilder is used then the polyfill will enable scrubbing
support for IE/Edge and Safari (Chrome and Firefox support this natively).</p>
<p>If AnimationBuilder is used, enables scrubbing
support for IE/Edge and Safari.
(Chrome and Firefox support this natively).</p>
</td>
</tr>
@ -308,15 +260,10 @@ Here are the features which may require additional polyfills:
<td>
If you use the following deprecated i18n pipes:
If you use the following deprecated i18n pipes:
[date](api/common/DeprecatedDatePipe),
[currency](api/common/DeprecatedCurrencyPipe),
[decimal](api/common/DeprecatedDecimalPipe),
[percent](api/common/DeprecatedPercentPipe)
</td>
@ -337,9 +284,7 @@ Here are the features which may require additional polyfills:
<td>
[NgClass](api/common/NgClass)
on SVG elements
[NgClass](api/common/NgClass) on SVG elements
</td>
<td>
@ -358,9 +303,7 @@ Here are the features which may require additional polyfills:
<td>
[Http](guide/http)
when sending and receiving binary data
[Http](guide/http) when sending and receiving binary data
</td>
<td>
@ -383,9 +326,8 @@ Here are the features which may require additional polyfills:
<td>
[Router](guide/router)
when using [hash-based routing](guide/router#appendix-locationstrategy-and-browser-url-styles)
[Router](guide/router) when using
[hash-based routing](guide/router#appendix-locationstrategy-and-browser-url-styles)
</td>
<td>
@ -404,8 +346,9 @@ Here are the features which may require additional polyfills:
### Suggested polyfills ##
Below are the polyfills which are used to test the framework itself. They are a good starting point for an application.
### Suggested polyfills
The following polyfills are used to test the framework itself. They are a good starting point for an application.
<table>
@ -426,24 +369,6 @@ Below are the polyfills which are used to test the framework itself. They are a
</tr>
<tr>
<td>
<a id='core-es7-reflect' href="https://github.com/zloirock/core-js/tree/v2/fn/reflect">ES7/reflect</a>
</td>
<td>
MIT
</td>
<td>
0.5KB
</td>
</tr>
<tr>
<td>
@ -466,7 +391,7 @@ Below are the polyfills which are used to test the framework itself. They are a
<td>
<a id='core-es6' href="https://github.com/zloirock/core-js">ES6</a>
<a id='core-es6' href="https://github.com/zloirock/core-js">ES2015</a>
</td>
@ -595,11 +520,14 @@ Below are the polyfills which are used to test the framework itself. They are a
computed with the <a href="http://closure-compiler.appspot.com/home">closure compiler</a>.
{@a non-cli}
## Polyfills for non-CLI users
If you are not using the CLI, you should add your polyfill scripts directly to the host web page (`index.html`), perhaps like this.
If you are not using the CLI, add your polyfill scripts directly to the host web page (`index.html`).
<code-example header="src/index.html">
For example:
<code-example header="src/index.html" language="html">
&lt;!-- pre-zone polyfills -->
&lt;script src="node_modules/core-js/client/shim.min.js">&lt;/script>
&lt;script src="node_modules/web-animations-js/web-animations.min.js">&lt;/script>

View File

@ -185,8 +185,7 @@ is available to <code>declarations</code> of this module.</p>
</td>
</tr><tr>
<td><code><b>@Injectable()</b><br>class MyService() {}</code></td>
<td><p>Declares that a class has dependencies that should be injected into the constructor when the dependency injector is creating an instance of this class.
</p>
<td><p>Declares that a class can be provided and injected by other classes. Without this decorator, the compiler won't generate enough metadata to allow the class to be created properly when it's injected somewhere.</p>
</td>
</tr>
</tbody></table>

View File

@ -191,7 +191,7 @@ For our example builder, we expect the `options` value to be a `JsonObject` with
We can provide the following schema for type validation of these values.
<code-example format="." language="json" linenums="false">
<code-example language="json">
{
"$schema": "http://json-schema.org/schema",
@ -222,7 +222,7 @@ To link our builder implementation with its schema and name, we need to create a
Create a file named `builders.json` file that looks like this.
<code-example format="." language="json" linenums="false">
<code-example language="json">
{
"builders": {
@ -238,7 +238,7 @@ Create a file named `builders.json` file that looks like this.
In the `package.json` file, add a `builders` key that tells the Architect tool where to find our builder definition file.
<code-example format="." language="json" linenums="false">
<code-example language="json">
{
"name": "@example/command-runner",
@ -257,7 +257,7 @@ The first part of this is the package name (resolved using node resolution), an
Using one of our `options` is very straightforward, we did this in the previous section when we accessed `options.command`.
<code-example format="." language="typescript" linenums="false">
<code-example language="typescript">
context.reportStatus(`Executing "${options.command}"...`);
const child = childProcess.spawn(options.command, options.args, { stdio: 'pipe' });
@ -274,7 +274,7 @@ The Architect tool uses the target definition to resolve input options for a giv
The `angular.json` file has a section for each project, and the "architect" section of each project configures targets for builders used by CLI commands such as 'build', 'test', and 'lint'.
By default, for example, the `build` command runs the builder `@angular-devkit/build-angular:browser` to perform the build task, and passes in default option values as specified for the `build` target in `angular.json`.
<code-example format="." language="json" linenums="false">
<code-example language="json">
{
"myApp": {
...
@ -361,7 +361,7 @@ npm install @example/command-runner
If we create a new project with `ng new builder-test`, the generated `angular.json` file looks something like this, with only default builder configurations.
<code-example format="." language="json" linenums="false">
<code-example language="json">
{
// ...
@ -413,7 +413,7 @@ We need to update the `angular.json` file to add a target for this builder to th
* The configurations key is optional, we'll leave it out for now.
<code-example format="." language="json" linenums="false">
<code-example language="json">
{
"projects": {
@ -495,7 +495,7 @@ Use integration testing for your builder, so that you can use the Architect sche
Heres an example of a test that runs the command builder.
The test uses the builder to run the `ls` command, then validates that it ran successfully and listed the proper files.
<code-example format="." language="typescript" linenums="false">
<code-example language="typescript">
import { Architect, ArchitectHost } from '@angular-devkit/architect';
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
@ -592,4 +592,4 @@ The CLI Builder API provides a new way of changing the behavior of the Angular C
* We recommend that you use integration tests to test Architect builders. You can use unit tests to validate the logic that the builder executes.
* If your builder returns an Observable, it should clean up in the teardown logic of that Observable.
* If your builder returns an Observable, it should clean up in the teardown logic of that Observable.

View File

@ -38,7 +38,7 @@ The following example demonstrates how to use `query()` and `stagger()` function
* Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it.
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="page-animations" language="typescript" linenums="false"></code-example>
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="page-animations" language="typescript"></code-example>
## Parallel animation using group() function
@ -51,7 +51,7 @@ You've seen how to add a delay between each successive animation. But you may al
In the following example, using groups on both `:enter` and `:leave` allow for two different timing configurations. They're applied to the same element in parallel, but run independently.
<code-example path="animations/src/app/hero-list-groups.component.ts" region="animationdef" header="src/app/hero-list-groups.component.ts (excerpt)" language="typescript" linenums="false"></code-example>
<code-example path="animations/src/app/hero-list-groups.component.ts" region="animationdef" header="src/app/hero-list-groups.component.ts (excerpt)" language="typescript"></code-example>
## Sequential vs. parallel animations
@ -74,7 +74,7 @@ The HTML template contains a trigger called `filterAnimation`.
The component file contains three transitions.
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="filter-animations" language="typescript" linenums="false"></code-example>
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="filter-animations" language="typescript"></code-example>
The animation does the following:
@ -101,4 +101,4 @@ You may also be interested in the following:
* [Introduction to Angular animations](guide/animations)
* [Transition and triggers](guide/transition-and-triggers)
* [Reusable animations](guide/reusable-animations)
* [Route transition animations](guide/route-animations)
* [Route transition animations](guide/route-animations)

View File

@ -21,8 +21,7 @@ One way to do this is to set the `styles` property in the component metadata.
The `styles` property takes an array of strings that contain CSS code.
Usually you give it one string, as in the following example:
<code-example path="component-styles/src/app/hero-app.component.ts" header="src/app/hero-app.component.ts" linenums="false">
</code-example>
<code-example path="component-styles/src/app/hero-app.component.ts" header="src/app/hero-app.component.ts"></code-example>
## Style scope
@ -71,8 +70,7 @@ Use the `:host` pseudo-class selector to target styles in the element that *host
targeting elements *inside* the component's template).
<code-example path="component-styles/src/app/hero-details.component.css" region="host" header="src/app/hero-details.component.css" linenums="false">
</code-example>
<code-example path="component-styles/src/app/hero-details.component.css" region="host" header="src/app/hero-details.component.css"></code-example>
The `:host` selector is the only way to target the host element. You can't reach
the host element from inside the component with other selectors because it's not part of the
@ -83,8 +81,7 @@ including another selector inside parentheses after `:host`.
The next example targets the host element again, but only when it also has the `active` CSS class.
<code-example path="component-styles/src/app/hero-details.component.css" region="hostfunction" header="src/app/hero-details.component.css" linenums="false">
</code-example>
<code-example path="component-styles/src/app/hero-details.component.css" region="hostfunction" header="src/app/hero-details.component.css"></code-example>
### :host-context
@ -99,8 +96,7 @@ up to the document root. The `:host-context()` selector is useful when combined
The following example applies a `background-color` style to all `<h2>` elements *inside* the component, only
if some ancestor element has the CSS class `theme-light`.
<code-example path="component-styles/src/app/hero-details.component.css" region="hostcontext" header="src/app/hero-details.component.css" linenums="false">
</code-example>
<code-example path="component-styles/src/app/hero-details.component.css" region="hostcontext" header="src/app/hero-details.component.css"></code-example>
### (deprecated) `/deep/`, `>>>`, and `::ng-deep`
@ -115,9 +111,7 @@ can bleed into other components.
The following example targets all `<h3>` elements, from the host element down
through this component to all of its child elements in the DOM.
<code-example path="component-styles/src/app/hero-details.component.css" region="deep" header="src/app/hero-details.component.css" linenums="false">
</code-example>
<code-example path="component-styles/src/app/hero-details.component.css" region="deep" header="src/app/hero-details.component.css"></code-example>
The `/deep/` combinator also has the aliases `>>>`, and `::ng-deep`.
@ -304,8 +298,7 @@ Choose from the following modes:
To set the components encapsulation mode, use the `encapsulation` property in the component metadata:
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.native" header="src/app/quest-summary.component.ts" linenums="false">
</code-example>
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.native" header="src/app/quest-summary.component.ts"></code-example>
`ShadowDom` view encapsulation only works on browsers that have native support
for shadow DOM (see [Shadow DOM v1](https://caniuse.com/#feat=shadowdomv1) on the

View File

@ -12,7 +12,7 @@ A simple example might be a button that sends users to your company website, tha
Use the Angular CLI to generate a new library skeleton with the following command:
<code-example format="." language="bash">
<code-example language="bash">
ng generate library my-lib
</code-example>
@ -35,7 +35,7 @@ The workspace configuration file, `angular.json`, is updated with a project of t
You can build, test, and lint the project with CLI commands:
<code-example format="." language="bash">
<code-example language="bash">
ng build my-lib
ng test my-lib
ng lint my-lib
@ -106,7 +106,7 @@ To learn more, see [Schematics Overview](guide/schematics) and [Schematicsfor
Use the Angular CLI and the npm package manager to build and publish your library as an npm package.
Libraries are built in [AoT mode](guide/aot-compiler) by default, so you do not need to specify the `-prod` flag when building for publication.
<code-example format="." language="bash">
<code-example language="bash">
ng build my-lib
cd dist/my-lib
npm publish
@ -158,7 +158,7 @@ You don't have to publish your library to the npm package manager in order to us
To use your own library in an app:
* Build the library. You cannot use a library before it is built.
<code-example format="." language="bash">
<code-example language="bash">
ng build my-lib
</code-example>
@ -190,6 +190,6 @@ Every time a file is changed a partial build is performed that emits the amended
Incremental builds can be run as a backround process in your dev environment. To take advantage of this feature add the `--watch` flag to the build command:
<code-example format="." language="bash">
<code-example language="bash">
ng build my-lib --watch
</code-example>

View File

@ -21,18 +21,14 @@ constructor, and lets the framework provide them.
The following example shows that `AppComponent` declares its dependence on `LoggerService` and `UserContext`.
<code-example path="dependency-injection-in-action/src/app/app.component.ts" region="ctor" header="src/app/app.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/app.component.ts" region="ctor" header="src/app/app.component.ts"></code-example>
`UserContext` in turn depends on both `LoggerService` and
`UserService`, another service that gathers information about a particular user.
<code-example path="dependency-injection-in-action/src/app/user-context.service.ts" region="injectables" header="user-context.service.ts (injection)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/user-context.service.ts" region="injectables" header="user-context.service.ts (injection)"></code-example>
When Angular creates `AppComponent`, the DI framework creates an instance of `LoggerService` and starts to create `UserContextService`.
@ -185,17 +181,13 @@ This `HeroBiosAndContactsComponent` is a revision of `HeroBiosComponent` which y
Focus on the template:
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="template" header="dependency-injection-in-action/src/app/hero-bios.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="template" header="dependency-injection-in-action/src/app/hero-bios.component.ts"></code-example>
Now there's a new `<hero-contact>` element between the `<hero-bio>` tags.
Angular *projects*, or *transcludes*, the corresponding `HeroContactComponent` into the `HeroBioComponent` view,
placing it in the `<ng-content>` slot of the `HeroBioComponent` template.
<code-example path="dependency-injection-in-action/src/app/hero-bio.component.ts" region="template" header="src/app/hero-bio.component.ts (template)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/hero-bio.component.ts" region="template" header="src/app/hero-bio.component.ts (template)"></code-example>
The result is shown below, with the hero's telephone number from `HeroContactComponent` projected above the hero description.
@ -212,9 +204,7 @@ Here's `HeroContactComponent`, which demonstrates the qualifying decorators.
Focus on the constructor parameters.
<code-example path="dependency-injection-in-action/src/app/hero-contact.component.ts" region="ctor-params" header="src/app/hero-contact.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/hero-contact.component.ts" region="ctor-params" header="src/app/hero-contact.component.ts"></code-example>
The `@Host()` function decorating the `heroCache` constructor property ensures that
you get a reference to the cache service from the parent `HeroBioComponent`.
@ -299,9 +289,7 @@ whose `nativeElement` property exposes the DOM element for the directive to mani
The sample code applies the directive's `myHighlight` attribute to two `<div>` tags,
first without a value (yielding the default color) and then with an assigned color value.
<code-example path="dependency-injection-in-action/src/app/app.component.html" region="highlight" header="src/app/app.component.html (highlight)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/app.component.html" region="highlight" header="src/app/app.component.html (highlight)"></code-example>
The following image shows the effect of mousing over the `<hero-bios-and-contacts>` tag.
@ -325,9 +313,7 @@ Angular passes this token to the injector and assigns the result to the paramete
The following is a typical example.
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="ctor" header="src/app/hero-bios.component.ts (component constructor injection)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/hero-bios.component.ts" region="ctor" header="src/app/hero-bios.component.ts (component constructor injection)"></code-example>
Angular asks the injector for the service associated with `LoggerService`
@ -386,9 +372,7 @@ You can also use a value provider in a unit test to provide mock data in place o
The `HeroOfTheMonthComponent` example has two value providers.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-value" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-value" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts"></code-example>
* The first provides an existing instance of the `Hero` class to use for the `Hero` token, rather than
requiring the injector to create a new instance with `new` or use its own cached instance.
@ -427,9 +411,7 @@ extend the default class, or emulate the behavior of the real class in a test ca
The following code shows two examples in `HeroOfTheMonthComponent`.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-class" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="use-class" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts"></code-example>
The first provider is the *de-sugared*, expanded form of the most typical case in which the
class to be created (`HeroService`) is also the provider's dependency injection token.
@ -448,9 +430,7 @@ Components outside the tree continue to receive the original `LoggerService` ins
`DateLoggerService` inherits from `LoggerService`; it appends the current date/time to each message:
<code-example path="dependency-injection-in-action/src/app/date-logger.service.ts" region="date-logger-service" header="src/app/date-logger.service.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/date-logger.service.ts" region="date-logger-service" header="src/app/date-logger.service.ts"></code-example>
{@a useexisting}
@ -472,15 +452,11 @@ You might want to shrink that API surface to just the members you actually need.
In this example, the `MinimalLogger` [class-interface](#class-interface) reduces the API to two members:
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" header="src/app/minimal-logger.service.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" header="src/app/minimal-logger.service.ts"></code-example>
The following example puts `MinimalLogger` to use in a simplified version of `HeroOfTheMonthComponent`.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.1.ts" header="src/app/hero-of-the-month.component.ts (minimal version)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.1.ts" header="src/app/hero-of-the-month.component.ts (minimal version)"></code-example>
The `HeroOfTheMonthComponent` constructor's `logger` parameter is typed as `MinimalLogger`, so only the `logs` and `logInfo` members are visible in a TypeScript-aware editor.
@ -532,9 +508,7 @@ The `runnersUpFactory()` returns the *provider factory function*, which can use
the passed-in state value and the injected services `Hero` and `HeroService`.
<code-example path="dependency-injection-in-action/src/app/runners-up.ts" region="factory-synopsis" header="runners-up.ts (excerpt)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/runners-up.ts" region="factory-synopsis" header="runners-up.ts (excerpt)"></code-example>
The provider factory function (returned by `runnersUpFactory()`) returns the actual dependency object,
the string of names.
@ -578,9 +552,7 @@ as the token for a provider of `LoggerService`.
`MinimalLogger` is an abstract class.
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" header="dependency-injection-in-action/src/app/minimal-logger.service.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" header="dependency-injection-in-action/src/app/minimal-logger.service.ts"></code-example>
An abstract class is usually a base class that you can extend.
In this app, however there is no class that inherits from `MinimalLogger`.
@ -606,9 +578,7 @@ Using a class as an interface gives you the characteristics of an interface in a
To minimize memory cost, however, the class should have *no implementation*.
The `MinimalLogger` transpiles to this unoptimized, pre-minified JavaScript for a constructor function.
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" region="minimal-logger-transpiled" header="dependency-injection-in-action/src/app/minimal-logger.service.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/minimal-logger.service.ts" region="minimal-logger-transpiled" header="dependency-injection-in-action/src/app/minimal-logger.service.ts"></code-example>
Notice that it doesn't have any members. It never grows no matter how many members you add to the class,
as long as those members are typed but not implemented.
@ -635,15 +605,11 @@ another token that happens to have the same name.
You encountered them twice in the *Hero of the Month* example,
in the *title* value provider and in the *runnersUp* factory provider.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="provide-injection-token" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="provide-injection-token" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts"></code-example>
You created the `TITLE` token like this:
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="injection-token" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="injection-token" header="dependency-injection-in-action/src/app/hero-of-the-month.component.ts"></code-example>
The type parameter, while optional, conveys the dependency's type to developers and tooling.
The token description is another developer aid.
@ -733,9 +699,7 @@ appear *above* the class definition.
Break the circularity with `forwardRef`.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" header="parent-finder.component.ts (AlexComponent providers)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" header="parent-finder.component.ts (AlexComponent providers)"></code-example>
<!--- Waiting for good examples

View File

@ -2,16 +2,16 @@
Application components often need to share information.
You can often use loosely coupled techniques for sharing information,
such as data binding and service sharing,
but sometimes it makes sense for one component to have a direct reference to another component.
such as data binding and service sharing,
but sometimes it makes sense for one component to have a direct reference to another component.
You need a direct reference, for instance, to access values or call methods on that component.
Obtaining a component reference is a bit tricky in Angular.
Angular components themselves do not have a tree that you can
Angular components themselves do not have a tree that you can
inspect or navigate programmatically. The parent-child relationship is indirect,
established through the components' [view objects](guide/glossary#view).
Each component has a *host view*, and can have additional *embedded views*.
Each component has a *host view*, and can have additional *embedded views*.
An embedded view in component A is the
host view of component B, which can in turn have embedded view.
This means that there is a [view hierarchy](guide/glossary#view-hierarchy) for each component,
@ -40,18 +40,14 @@ In the following example, the parent `AlexComponent` has several children includ
{@a alex}
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-1" header="parent-finder.component.ts (AlexComponent v.1)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-1" header="parent-finder.component.ts (AlexComponent v.1)"></code-example>
*Cathy* reports whether or not she has access to *Alex*
after injecting an `AlexComponent` into her constructor:
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="cathy" header="parent-finder.component.ts (CathyComponent)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="cathy" header="parent-finder.component.ts (CathyComponent)"></code-example>
@ -98,17 +94,13 @@ inject its parent via the parent's base class*.
The sample's `CraigComponent` explores this question. [Looking back](#alex),
you see that the `Alex` component *extends* (*inherits*) from a class named `Base`.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-class-signature" header="parent-finder.component.ts (Alex class signature)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-class-signature" header="parent-finder.component.ts (Alex class signature)"></code-example>
The `CraigComponent` tries to inject `Base` into its `alex` constructor parameter and reports if it succeeded.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="craig" header="parent-finder.component.ts (CraigComponent)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="craig" header="parent-finder.component.ts (CraigComponent)"></code-example>
@ -138,9 +130,7 @@ and add that provider to the `providers` array of the `@Component()` metadata fo
{@a alex-providers}
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" header="parent-finder.component.ts (AlexComponent providers)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" header="parent-finder.component.ts (AlexComponent providers)"></code-example>
[Parent](#parent-token) is the provider's class interface token.
@ -149,9 +139,7 @@ The [*forwardRef*](guide/dependency-injection-in-action#forwardref) breaks the c
*Carol*, the third of *Alex*'s child components, injects the parent into its `parent` parameter,
the same way you've done it before.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="carol-class" header="parent-finder.component.ts (CarolComponent class)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="carol-class" header="parent-finder.component.ts (CarolComponent class)"></code-example>
@ -177,9 +165,7 @@ That means he must both *inject* the `Parent` class interface to get *Alice* and
Here's *Barry*.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="barry" header="parent-finder.component.ts (BarryComponent)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="barry" header="parent-finder.component.ts (BarryComponent)"></code-example>
@ -229,9 +215,7 @@ You [learned earlier](guide/dependency-injection-in-action#class-interface) that
The example defines a `Parent` class interface.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="parent" header="parent-finder.component.ts (Parent class-interface)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="parent" header="parent-finder.component.ts (Parent class-interface)"></code-example>
@ -241,9 +225,7 @@ Such a narrow interface helps decouple the child component class from its parent
A component that could serve as a parent *should* implement the class interface as the `AliceComponent` does.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alice-class-signature" header="parent-finder.component.ts (AliceComponent class signature)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alice-class-signature" header="parent-finder.component.ts (AliceComponent class signature)"></code-example>
@ -251,9 +233,7 @@ Doing so adds clarity to the code. But it's not technically necessary.
Although `AlexComponent` has a `name` property, as required by its `Base` class,
its class signature doesn't mention `Parent`.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-class-signature" header="parent-finder.component.ts (AlexComponent class signature)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-class-signature" header="parent-finder.component.ts (AlexComponent class signature)"></code-example>
@ -277,21 +257,15 @@ It doesn't in this example *only* to demonstrate that the code will compile and
Writing variations of the same parent *alias provider* gets old quickly,
especially this awful mouthful with a [*forwardRef*](guide/dependency-injection-in-action#forwardref).
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alex-providers" header="dependency-injection-in-action/src/app/parent-finder.component.ts"></code-example>
You can extract that logic into a helper function like the following.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="provide-the-parent" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="provide-the-parent" header="dependency-injection-in-action/src/app/parent-finder.component.ts"></code-example>
Now you can add a simpler, more meaningful parent provider to your components.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alice-providers" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="alice-providers" header="dependency-injection-in-action/src/app/parent-finder.component.ts"></code-example>
You can do better. The current version of the helper function can only alias the `Parent` class interface.
@ -299,14 +273,10 @@ The application might have a variety of parent types, each with its own class in
Here's a revised version that defaults to `parent` but also accepts an optional second parameter for a different parent class interface.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="provide-parent" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="provide-parent" header="dependency-injection-in-action/src/app/parent-finder.component.ts"></code-example>
And here's how you could use it with a different parent type.
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="beth-providers" header="dependency-injection-in-action/src/app/parent-finder.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/parent-finder.component.ts" region="beth-providers" header="dependency-injection-in-action/src/app/parent-finder.component.ts"></code-example>

View File

@ -68,13 +68,11 @@ using the `Logger` token.
Another class, `EvenBetterLogger`, might display the user name in the log message.
This logger gets the user from an injected `UserService` instance.
<code-example path="dependency-injection/src/app/providers.component.ts" region="EvenBetterLogger" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="EvenBetterLogger"></code-example>
The injector needs providers for both this new logging service and its dependent `UserService`. Configure this alternative logger with the `useClass` provider-definition key, like `BetterLogger`. The following array specifies both providers in the `providers` metadata option of the parent module or component.
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-5" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-5"></code-example>
{@a aliased-class-providers}
@ -92,13 +90,11 @@ when a component asks for either the new or the old logger.
If you try to alias `OldLogger` to `NewLogger` with `useClass`, you end up with two different `NewLogger` instances in your app.
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-6a" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-6a"></code-example>
To make sure there is only one instance of `NewLogger`, alias `OldLogger` with the `useExisting` option.
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-6b" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-6b"></code-example>
{@a value-provider}
@ -110,13 +106,11 @@ configure the injector with the `useValue` option
The following code defines a variable that creates such an object to play the logger role.
<code-example path="dependency-injection/src/app/providers.component.ts" region="silent-logger" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="silent-logger"></code-example>
The following provider object uses the `useValue` key to associate the variable with the `Logger` token.
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-7" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-7"></code-example>
{@a non-class-dependencies}
@ -130,8 +124,7 @@ like the title of the application or the address of a web API endpoint.
These configuration objects aren't always instances of a class.
They can be object literals, as shown in the following example.
<code-example path="dependency-injection/src/app/app.config.ts" region="config" header="src/app/app.config.ts (excerpt)" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/app.config.ts" region="config" header="src/app/app.config.ts (excerpt)"></code-example>
{@a interface-not-valid-token}
@ -141,11 +134,9 @@ The `HERO_DI_CONFIG` constant conforms to the `AppConfig` interface.
Unfortunately, you cannot use a TypeScript interface as a token.
In TypeScript, an interface is a design-time artifact, and doesn't have a runtime representation (token) that the DI framework can use.
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-9-interface" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-9-interface"></code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="provider-9-ctor-interface" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="provider-9-ctor-interface"></code-example>
<div class="alert is-helpful">
@ -163,22 +154,19 @@ Another solution to choosing a provider token for non-class dependencies is
to define and use an `InjectionToken` object.
The following example shows how to define such a token.
<code-example path="dependency-injection/src/app/app.config.ts" region="token" header="src/app/app.config.ts" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/app.config.ts" region="token" header="src/app/app.config.ts"></code-example>
The type parameter, while optional, conveys the dependency's type to developers and tooling.
The token description is another developer aid.
Register the dependency provider using the `InjectionToken` object:
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-9" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-9"></code-example>
Now you can inject the configuration object into any constructor that needs it, with
the help of an `@Inject()` parameter decorator.
<code-example path="dependency-injection/src/app/app.component.2.ts" region="ctor" header="src/app/app.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/app.component.2.ts" region="ctor" header="src/app/app.component.ts"></code-example>
<div class="alert is-helpful">
@ -215,22 +203,19 @@ who is authorized and who isn't.
To resolve this, we give the `HeroService` constructor a boolean flag to control display of secret heroes.
<code-example path="dependency-injection/src/app/heroes/hero.service.ts" region="internals" header="src/app/heroes/hero.service.ts (excerpt)" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/heroes/hero.service.ts" region="internals" header="src/app/heroes/hero.service.ts (excerpt)"></code-example>
You can inject `Logger`, but you can't inject the `isAuthorized` flag. Instead, you can use a factory provider to create a new logger instance for `HeroService`.
A factory provider needs a factory function.
<code-example path="dependency-injection/src/app/heroes/hero.service.provider.ts" region="factory" header="src/app/heroes/hero.service.provider.ts (excerpt)" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/heroes/hero.service.provider.ts" region="factory" header="src/app/heroes/hero.service.provider.ts (excerpt)"></code-example>
Although `HeroService` has no access to `UserService`, the factory function does.
You inject both `Logger` and `UserService` into the factory provider
and let the injector pass them along to the factory function.
<code-example path="dependency-injection/src/app/heroes/hero.service.provider.ts" region="provider" header="src/app/heroes/hero.service.provider.ts (excerpt)" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/heroes/hero.service.provider.ts" region="provider" header="src/app/heroes/hero.service.provider.ts (excerpt)"></code-example>
* The `useFactory` field tells Angular that the provider is a factory function whose implementation is `heroServiceFactory`.
@ -322,13 +307,13 @@ Thus, services in the NgModule `providers` array or at component level are not t
The following example of non-tree-shakable providers in Angular configures a service provider for the injector of an NgModule.
<code-example path="dependency-injection/src/app/tree-shaking/service-and-module.ts" header="src/app/tree-shaking/service-and-modules.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/tree-shaking/service-and-module.ts" header="src/app/tree-shaking/service-and-modules.ts"></code-example>
You can then import this module into your application module
to make the service available for injection in your app,
as in the following example.
<code-example path="dependency-injection/src/app/tree-shaking/app.module.ts" header="src/app/tree-shaking/app.modules.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/tree-shaking/app.module.ts" header="src/app/tree-shaking/app.modules.ts"></code-example>
When `ngc` runs, it compiles `AppModule` into a module factory, which contains definitions for all the providers declared in all the modules it includes. At runtime, this factory becomes an injector that instantiates these services.
@ -340,11 +325,11 @@ You can make a provider tree-shakable by specifying it in the `@Injectable()` de
The following example shows the tree-shakable equivalent to the `ServiceModule` example above.
<code-example path="dependency-injection/src/app/tree-shaking/service.ts" header="src/app/tree-shaking/service.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/tree-shaking/service.ts" header="src/app/tree-shaking/service.ts"></code-example>
The service can be instantiated by configuring a factory function, as in the following example.
<code-example path="dependency-injection/src/app/tree-shaking/service.0.ts" header="src/app/tree-shaking/service.0.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/tree-shaking/service.0.ts" header="src/app/tree-shaking/service.0.ts"></code-example>
<div class="alert is-helpful">

View File

@ -196,8 +196,7 @@ Listing dependencies as constructor parameters may be all you need to test appli
For example, you can create a new `HeroListComponent` with a mock service that you can manipulate
under test.
<code-example path="dependency-injection/src/app/test.component.ts" region="spec" header="src/app/test.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/test.component.ts" region="spec" header="src/app/test.component.ts"></code-example>
<div class="alert is-helpful">
@ -259,8 +258,7 @@ In simple examples, the dependency value is an *instance*, and
the class *type* serves as its own lookup key.
Here you get a `HeroService` directly from the injector by supplying the `HeroService` type as the token:
<code-example path="dependency-injection/src/app/injector.component.ts" region="get-hero-service" header="src/app/injector.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/injector.component.ts" region="get-hero-service" header="src/app/injector.component.ts"></code-example>
The behavior is similar when you write a constructor that requires an injected class-based dependency.
When you define a constructor parameter with the `HeroService` class type,
@ -287,8 +285,7 @@ constructor parameter with `@Optional()`.
<code-example path="dependency-injection/src/app/providers.component.ts" region="import-optional">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="provider-10-ctor" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/providers.component.ts" region="provider-10-ctor"></code-example>
When using `@Optional()`, your code must be prepared for a null value. If you
don't register a logger provider anywhere, the injector sets the

View File

@ -152,17 +152,14 @@ The list is by no means exhaustive, but should provide you with a good starting
[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to the `.htaccess` file as shown
(https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):
<code-example format=".">
<code-example>
RewriteEngine On
&#35 If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ - [L]<br>
&#35 If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
</code-example>
@ -170,18 +167,15 @@ The list is by no means exhaustive, but should provide you with a good starting
[Front Controller Pattern Web Apps](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#front-controller-pattern-web-apps),
modified to serve `index.html`:
<code-example format=".">
try_files $uri $uri/ /index.html;
</code-example>
```
try_files $uri $uri/ /index.html;
```
* [IIS](https://www.iis.net/): add a rewrite rule to `web.config`, similar to the one shown
[here](http://stackoverflow.com/a/26152011/2116927):
<code-example format='.' linenums="false">
<code-example format='.' language="xml">
&lt;system.webServer&gt;
&lt;rewrite&gt;
&lt;rules&gt;
@ -196,7 +190,6 @@ modified to serve `index.html`:
&lt;/rules&gt;
&lt;/rewrite&gt;
&lt;/system.webServer&gt;
</code-example>
@ -214,13 +207,11 @@ and to
* [Firebase hosting](https://firebase.google.com/docs/hosting/): add a
[rewrite rule](https://firebase.google.com/docs/hosting/url-redirects-rewrites#section-rewrites).
<code-example format=".">
<code-example language="json">
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
</code-example>
{@a cors}
@ -412,7 +403,7 @@ Differential loading, which is supported by default in Angular CLI version 8 and
Differential loading is a strategy where the CLI builds two separate bundles as part of your deployed application.
* The first bundle contains modern ES1015 syntax, takes advantage of built-in support in modern browsers, ships less polyfills, and results in a smaller bundle size.
* The first bundle contains modern ES2015 syntax, takes advantage of built-in support in modern browsers, ships less polyfills, and results in a smaller bundle size.
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This results in a larger bundle size, but supports older browsers.
@ -445,24 +436,20 @@ When you create a production build using [`ng build --prod`](cli/build), the CLI
The `index.html` file is also modified during the build process to include script tags that enable differential loading. See the sample output below from the `index.html` file produced during a build using `ng build`.
<code-example language="html" format="." linenums="false">
<!-- ... -->
<body>
<app-root></app-root>
<script src="runtime-es2015.js" type="module"></script>
<script src="runtime-es5.js" nomodule></script>
<script src="polyfills-es2015.js" type="module"></script>
<script src="polyfills-es5.js" nomodule></script>
<script src="styles-es2015.js" type="module"></script>
<script src="styles-es5.js" nomodule></script>
<script src="vendor-es2015.js" type="module"></script>
<script src="vendor-es5.js" nomodule></script>
<script src="main-es2015.js" type="module"></script>
<script src="main-es5.js" nomodule></script>
</body>
<!-- ... -->
<code-example language="html">
&lt;body>
&lt;app-root>&lt;/app-root>
&lt;script src="runtime-es2015.js" type="module">&lt;/script>
&lt;script src="runtime-es5.js" nomodule>&lt;/script>
&lt;script src="polyfills-es2015.js" type="module">&lt;/script>
&lt;script src="polyfills-es5.js" nomodule>&lt;/script>
&lt;script src="styles-es2015.js" type="module">&lt;/script>
&lt;script src="styles-es5.js" nomodule>&lt;/script>
&lt;script src="vendor-es2015.js" type="module">&lt;/script>
&lt;script src="vendor-es5.js" nomodule>&lt;/script>
&lt;script src="main-es2015.js" type="module">&lt;/script>
&lt;script src="main-es5.js" nomodule>&lt;/script>
&lt;/body>
</code-example>
Each script tag has a `type="module"` or `nomodule` attribute. Browsers with native support for ES modules only load the scripts with the `module` type attribute and ignore scripts with the `nomodule` attribute. Legacy browsers only load the scripts with the `nomodule` attribute, and ignore the script tags with the `module` type that load ES modules.
@ -492,7 +479,7 @@ not IE 9-11 # For IE 9-11 support, remove 'not'.
The `tsconfig.json` looks like this:
<code-example language="json" format="." linenums="false">
<code-example language="json">
{
"compileOnSave": false,
@ -523,7 +510,7 @@ By default, legacy browsers such as IE 9-11 are ignored, and the compilation tar
<div class="alert is-important">
To see which browsers are supported with the above configuration, see which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+Chrome+41%2C+not+dead%2C+not+IE+9-11).
To see which browsers are supported with the above configuration, see which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
</div>
@ -563,7 +550,7 @@ To maintain the benefits of differential loading, however, a better option is to
To do this for `ng serve`, create a new file, `tsconfig-es5.app.json` next to `tsconfig.app.json` with the following content.
<code-example language="json" format="." linenums="false">
<code-example language="json">
{
"extends": "./tsconfig.app.json",
@ -576,7 +563,7 @@ To do this for `ng serve`, create a new file, `tsconfig-es5.app.json` next to `t
In `angular.json` add two new configuration sections under the `build` and `serve` targets to point to the new TypeScript configuration.
<code-example language="json" format="." linenums="false">
<code-example language="json">
"build": {
"builder": "@angular-devkit/build-angular:browser",
@ -623,7 +610,7 @@ ng serve --configuration es5
Create a new file, `tsconfig-es5.spec.json` next to `tsconfig.spec.json` with the following content.
<code-example language="json" format="." linenums="false">
<code-example language="json">
{
"extends": "./tsconfig.spec.json",
@ -634,7 +621,7 @@ Create a new file, `tsconfig-es5.spec.json` next to `tsconfig.spec.json` with th
</code-example>
<code-example language="json" format="." linenums="false">
<code-example language="json">
"test": {
"builder": "@angular-devkit/build-angular:karma",
@ -660,9 +647,9 @@ ng test --configuration es5
### Configuring the e2e command
Create an ES5 serve configuration as explained above (link to the above serve section), and configuration an ES5 configuration for the E2E target.
Create an [ES5 serve configuration](guide/deployment#configuring-serve-for-es5) as explained above, and configuration an ES5 configuration for the E2E target.
<code-example language="json" format="." linenums="false">
<code-example language="json">
"test": {
"builder": "@angular-devkit/build-angular:protractor",

View File

@ -368,7 +368,7 @@ These two properties have subtle differences, so switching to `textContent` unde
All of the `wtf*` APIs are deprecated and will be removed in a future version.
{@a webworker-apps}
### Running Angular applications in platform-webworker
### Running Angular applications in platform-webworker
The `@angular/platform-*` packages enable Angular to be run in different contexts. For examples,
`@angular/platform-server` enables Angular to be run on the server, and `@angular/platform-browser`
@ -382,7 +382,7 @@ worker is not the best strategy for most applications.
Going forward, we will focus our efforts related to web workers around their primary use case of
offloading CPU-intensive, non-critical work needed for initial rendering (such as in-memory search
and image processing). Learn more in the
and image processing). Learn more in the
[guide to Using Web Workers with the Angular CLI](guide/web-worker).
As of Angular version 8, all `platform-webworker` APIs are deprecated.
@ -465,3 +465,99 @@ For more information about using `@angular/common/http`, see the [HttpClient gui
| `MockBackend` | [`HttpTestingController`](/api/common/http/testing/HttpTestingController) |
| `MockConnection` | [`HttpTestingController`](/api/common/http/testing/HttpTestingController) |
## Renderer to Renderer2 migration
### Migration Overview
The `Renderer` class has been marked as deprecated since Angular version 4. This section provides guidance on migrating from this deprecated API to the newer `Renderer2` API and what it means for your app.
### Why should I migrate to Renderer2?
The deprecated `Renderer` class has been removed in version 9 of Angular, so it's necessary to migrate to a supported API. Using `Renderer2` is the recommended strategy because it supports a similar set of functionality to `Renderer`. The API surface is quite large (with 19 methods), but the schematic should simplify this process for your applications.
### Is there action required on my end?
No. The schematic should handle most cases with the exception of `Renderer.animate()` and `Renderer.setDebugInfo()`, which already arent supported.
### What are the `__ngRendererX` methods? Why are they necessary?
Some methods either don't have exact equivalents in `Renderer2`, or they correspond to more than one expression. For example, both renderers have a `createElement()` method, but they're not equal because a call such as `renderer.createElement(parentNode, namespaceAndName)` in the `Renderer` corresponds to the following block of code in `Renderer2`:
```ts
const [namespace, name] = splitNamespace(namespaceAndName);
const el = renderer.createElement(name, namespace);
if (parentNode) {
renderer.appendChild(parentNode, el);
}
return el;
```
Migration has to guarantee that the return values of functions and types of variables stay the same. To handle the majority of cases safely, the schematic declares helper functions at the bottom of the user's file. These helpers encapsulate your own logic and keep the replacements inside your code down to a single function call. Here's an example of how the `createElement()` migration looks:
**Before:**
```ts
public createAndAppendElement() {
const el = this.renderer.createElement('span');
el.textContent = 'hello world';
return el;
}
```
**After:**
<code-example>
public createAndAppendElement() {
const el = __ngRendererCreateElement(this.renderer, this.element, 'span');
el.textContent = 'hello world';
return el;
}
// Generated code at the bottom of the file
__ngRendererCreateElement(renderer: any, parentNode: any, nameAndNamespace: any) {
const [namespace, name] = __ngRendererSplitNamespace(namespaceAndName);
const el = renderer.createElement(name, namespace);
if (parentNode) {
renderer.appendChild(parentNode, el);
}
return el;
}
__ngRendererSplitNamespace(nameAndNamespace: any) {
// returns the split name and namespace
}
</code-example>
When implementing these helper functions, the schematic ensures that they're only declared once per file and that their names are unique enough that there's a small chance of colliding with pre-existing functions in your code. The schematic also keeps their parameter types as `any` so that it doesn't have to insert extra logic that ensures that their values have the correct type.
### Im a library author. Should I run this migration?
**Library authors should definitely use this migration to move away from the `Renderer`. Otherwise, the libraries won't work with applications built with version 9.**
### Full list of method migrations
The following table shows all methods that the migration maps from `Renderer` to `Renderer2`.
|Renderer|Renderer2|
|---|---|
|`listen(renderElement, name, callback)`|`listen(renderElement, name, callback)`|
|`setElementProperty(renderElement, propertyName, propertyValue)`|`setProperty(renderElement, propertyName, propertyValue)`|
|`setText(renderNode, text)`|`setValue(renderNode, text)`|
|`listenGlobal(target, name, callback)`|`listen(target, name, callback)`|
|`selectRootElement(selectorOrNode, debugInfo?)`|`selectRootElement(selectorOrNode)`|
|`createElement(parentElement, name, debugInfo?)`|`appendChild(parentElement, createElement(name))`|
|`setElementStyle(el, style, value?)`|`value == null ? removeStyle(el, style) : setStyle(el, style, value)`
|`setElementAttribute(el, name, value?)`|`attributeValue == null ? removeAttribute(el, name) : setAttribute(el, name, value)`
|`createText(parentElement, value, debugInfo?)`|`appendChild(parentElement, createText(value))`|
|`createTemplateAnchor(parentElement)`|`appendChild(parentElement, createComment(''))`|
|`setElementClass(renderElement, className, isAdd)`|`isAdd ? addClass(renderElement, className) : removeClass(renderElement, className)`|
|`projectNodes(parentElement, nodes)`|`for (let i = 0; i < nodes.length; i<ins></ins>) { appendChild(parentElement, nodes<i>); }`|
|`attachViewAfter(node, viewRootNodes)`|`const parentElement = parentNode(node); const nextSibling = nextSibling(node); for (let i = 0; i < viewRootNodes.length; i<ins></ins>) { insertBefore(parentElement, viewRootNodes<i>, nextSibling);}`|
|`detachView(viewRootNodes)`|`for (let i = 0; i < viewRootNodes.length; i<ins></ins>) {const node = viewRootNodes<i>; const parentElement = parentNode(node); removeChild(parentElement, node);}`|
|`destroyView(hostElement, viewAllNodes)`|`for (let i = 0; i < viewAllNodes.length; i<ins></ins>) { destroyNode(viewAllNodes<i>); }`|
|`setBindingDebugInfo()`|This function is a noop in `Renderer2`.|
|`createViewRoot(hostElement)`|Should be replaced with a reference to `hostElement`|
|`invokeElementMethod(renderElement, methodName, args?)`|`(renderElement as any)<methodName>.apply(renderElement, args);`|
|`animate(element, startingStyles, keyframes, duration, delay, easing, previousPlayers?)`|Throws an error (same behavior as `Renderer.animate()`)|

View File

@ -31,7 +31,7 @@ The easiest way to display a component property
is to bind the property name through interpolation.
With interpolation, you put the property name in the view template, enclosed in double curly braces: `{{myHero}}`.
Use the CLI command [`ng new displaying-data`](cli/new) to create a workspace and app named `displaying-data`.
Use the CLI command [`ng new displaying-data`](cli/new) to create a workspace and app named `displaying-data`.
Delete the <code>app.component.html</code> file. It is not needed for this example.
@ -41,9 +41,7 @@ changing the template and the body of the component.
When you're done, it should look like this:
<code-example path="displaying-data/src/app/app.component.1.ts" header="src/app/app.component.ts">
</code-example>
<code-example path="displaying-data/src/app/app.component.1.ts" header="src/app/app.component.ts"></code-example>
@ -53,9 +51,7 @@ The template displays the two component properties using double curly brace
interpolation:
<code-example path="displaying-data/src/app/app.component.1.ts" linenums="false" header="src/app/app.component.ts (template)" region="template">
</code-example>
<code-example path="displaying-data/src/app/app.component.1.ts" header="src/app/app.component.ts (template)" region="template"></code-example>
@ -97,9 +93,7 @@ The CSS `selector` in the `@Component` decorator specifies an element named `<ap
That element is a placeholder in the body of your `index.html` file:
<code-example path="displaying-data/src/index.html" linenums="false" header="src/index.html (body)" region="body">
</code-example>
<code-example path="displaying-data/src/index.html" header="src/index.html (body)" region="body"></code-example>
@ -133,7 +127,7 @@ is simpler without the additional HTML file.
In either style, the template data bindings have the same access to the component's properties.
<div class="alert is-helpful">
By default, the Angular CLI command [`ng generate component`](cli/generate) generates components with a template file. You can override that with:
<code-example hideCopy language="sh" class="code-shell">
@ -148,9 +142,7 @@ In either style, the template data bindings have the same access to the componen
Although this example uses variable assignment to initialize the components, you could instead declare and initialize the properties using a constructor:
<code-example path="displaying-data/src/app/app-ctor.component.1.ts" linenums="false" region="class">
</code-example>
<code-example path="displaying-data/src/app/app-ctor.component.1.ts" region="class"></code-example>
@ -163,9 +155,7 @@ This app uses more terse "variable assignment" style simply for brevity.
To display a list of heroes, begin by adding an array of hero names to the component and redefine `myHero` to be the first name in the array.
<code-example path="displaying-data/src/app/app.component.2.ts" linenums="false" header="src/app/app.component.ts (class)" region="class">
</code-example>
<code-example path="displaying-data/src/app/app.component.2.ts" header="src/app/app.component.ts (class)" region="class"></code-example>
@ -173,9 +163,7 @@ Now use the Angular `ngFor` directive in the template to display
each item in the `heroes` list.
<code-example path="displaying-data/src/app/app.component.2.ts" linenums="false" header="src/app/app.component.ts (template)" region="template">
</code-example>
<code-example path="displaying-data/src/app/app.component.2.ts" header="src/app/app.component.ts (template)" region="template"></code-example>
@ -184,9 +172,7 @@ in the `<li>` element is the Angular "repeater" directive.
It marks that `<li>` element (and its children) as the "repeater template":
<code-example path="displaying-data/src/app/app.component.2.ts" linenums="false" header="src/app/app.component.ts (li)" region="li">
</code-example>
<code-example path="displaying-data/src/app/app.component.2.ts" header="src/app/app.component.ts (li)" region="li"></code-example>
@ -251,9 +237,7 @@ of hero names into an array of `Hero` objects. For that you'll need a `Hero` cla
With the following code:
<code-example path="displaying-data/src/app/hero.ts" linenums="false" header="src/app/hero.ts">
</code-example>
<code-example path="displaying-data/src/app/hero.ts" header="src/app/hero.ts"></code-example>
@ -265,9 +249,7 @@ The declaration of the constructor parameters takes advantage of a TypeScript sh
Consider the first parameter:
<code-example path="displaying-data/src/app/hero.ts" linenums="false" header="src/app/hero.ts (id)" region="id">
</code-example>
<code-example path="displaying-data/src/app/hero.ts" header="src/app/hero.ts (id)" region="id"></code-example>
@ -285,9 +267,7 @@ After importing the `Hero` class, the `AppComponent.heroes` property can return
of `Hero` objects:
<code-example path="displaying-data/src/app/app.component.3.ts" linenums="false" header="src/app/app.component.ts (heroes)" region="heroes">
</code-example>
<code-example path="displaying-data/src/app/app.component.3.ts" header="src/app/app.component.ts (heroes)" region="heroes"></code-example>
@ -296,9 +276,7 @@ At the moment it displays the hero's `id` and `name`.
Fix that to display only the hero's `name` property.
<code-example path="displaying-data/src/app/app.component.3.ts" linenums="false" header="src/app/app.component.ts (template)" region="template">
</code-example>
<code-example path="displaying-data/src/app/app.component.3.ts" header="src/app/app.component.ts (template)" region="template"></code-example>
@ -316,9 +294,7 @@ The Angular `ngIf` directive inserts or removes an element based on a _truthy/fa
To see it in action, add the following paragraph at the bottom of the template:
<code-example path="displaying-data/src/app/app.component.ts" linenums="false" header="src/app/app.component.ts (message)" region="message">
</code-example>
<code-example path="displaying-data/src/app/app.component.ts" header="src/app/app.component.ts (message)" region="message"></code-example>

View File

@ -428,7 +428,7 @@ You control the _code-example_ output by setting one or more of its attributes:
* `region`- displays the source file fragment with that region name; regions are identified by _docregion_ markup in the source file, as explained [below](#region "Displaying a code fragment").
* `linenums`- value may be `true`, `false`, or a `number`. When not specified, line numbers are automatically displayed when there are greater than 10 lines of code. The rarely used `number` option starts line numbering at the given value. `linenums=4` sets the starting line number to 4.
* `linenums`- value may be `true`, `false`, or a `number`. When not specified, line numbers default to `false` (i.e. no line numbers are displayed). The rarely used `number` option starts line numbering at the given value. `linenums=4` sets the starting line number to 4.
* `class`- code snippets can be styled with the CSS classes `no-box`, `code-shell`, and `avoid`.
@ -465,8 +465,6 @@ A couple of observations:
1. Omitting the `header` is fine when the source of the fragment is obvious. We just said that this is a fragment of the `app.module.ts` file which was displayed immediately above, in full, with a header.
There's no need to repeat the header.
1. The line numbers disappeared. By default, the doc viewer omits line numbers when there are fewer than 10 lines of code; it adds line numbers after that. You can turn line numbers on or off explicitly by setting the `linenums` attribute.
#### Example of bad code
Sometimes you want to display an example of bad code or bad design.
@ -496,18 +494,18 @@ Code tabs display code much like _code examples_ do. The added advantage is tha
#### Code-tabs attributes
* `linenums`: The value can be `true`, `false` or a number indicating the starting line number. If not specified, line numbers are enabled only when code for a tab pane has greater than 10 lines of code.
* `linenums`: The value can be `true`, `false` or a number indicating the starting line number. If not specified, it defaults to `false`.
#### Code-pane attributes
* `path` - a file in the content/examples folder
* `header` - seen in the header of a tab
* `linenums` - overrides the `linenums` property at the `code-tabs` level for this particular pane. The value can be `true`, `false` or a number indicating the starting line number. If not specified, line numbers are enabled only when the number of lines of code are greater than 10.
* `linenums` - overrides the `linenums` property at the `code-tabs` level for this particular pane. The value can be `true`, `false` or a number indicating the starting line number. If not specified, it defaults to `false`.
The next example displays multiple code tabs, each with its own header.
It demonstrates control over display of line numbers at both the `<code-tabs>` and `<code-pane>` levels.
<code-tabs linenums="false">
<code-tabs linenums="true">
<code-pane
header="app.component.html"
path="docs-style-guide/src/app/app.component.html">
@ -515,7 +513,7 @@ It demonstrates control over display of line numbers at both the `<code-tabs>` a
<code-pane
header="app.component.ts"
path="docs-style-guide/src/app/app.component.ts"
linenums="true">
linenums="false">
</code-pane>
<code-pane
header="app.component.css (heroes)"
@ -530,11 +528,11 @@ It demonstrates control over display of line numbers at both the `<code-tabs>` a
Here's the markup for that example.
Note how the `linenums` attribute in the `<code-tabs>` explicitly disables numbering for all panes.
The `linenums` attribute in the second pane restores line numbering for _itself only_.
Note how the `linenums` attribute in the `<code-tabs>` explicitly enables numbering for all panes.
The `linenums` attribute in the second pane disables line numbering for _itself only_.
```html
<code-tabs linenums="false">
<code-tabs linenums="true">
<code-pane
header="app.component.html"
path="docs-style-guide/src/app/app.component.html">
@ -542,7 +540,7 @@ The `linenums` attribute in the second pane restores line numbering for _itself
<code-pane
header="app.component.ts"
path="docs-style-guide/src/app/app.component.ts"
linenums="true">
linenums="false">
</code-pane>
<code-pane
header="app.component.css (heroes)"
@ -667,7 +665,7 @@ Examine the `src/app/app.component.ts` file which defines two nested _#docregion
The inner, `class-skeleton` region appears twice, once to capture the code that opens the class definition and once to capture the code that closes the class definition.
<code-example linenums="false">
<code-example>
// #docplaster
...
// #docregion class, class-skeleton

View File

@ -35,9 +35,7 @@ The ad banner uses a helper directive called `AdDirective` to
mark valid insertion points in the template.
<code-example path="dynamic-component-loader/src/app/ad.directive.ts" header="src/app/ad.directive.ts" linenums="false">
</code-example>
<code-example path="dynamic-component-loader/src/app/ad.directive.ts" header="src/app/ad.directive.ts"></code-example>
@ -62,9 +60,7 @@ To apply the `AdDirective`, recall the selector from `ad.directive.ts`,
where to dynamically load components.
<code-example path="dynamic-component-loader/src/app/ad-banner.component.ts" region="ad-host" header="src/app/ad-banner.component.ts (template)" linenums="false">
</code-example>
<code-example path="dynamic-component-loader/src/app/ad-banner.component.ts" region="ad-host" header="src/app/ad-banner.component.ts (template)"></code-example>
@ -91,9 +87,7 @@ With its `getAds()` method, `AdBannerComponent` cycles through the array of `AdI
and loads a new component every 3 seconds by calling `loadComponent()`.
<code-example path="dynamic-component-loader/src/app/ad-banner.component.ts" region="class" header="src/app/ad-banner.component.ts (excerpt)" linenums="false">
</code-example>
<code-example path="dynamic-component-loader/src/app/ad-banner.component.ts" region="class" header="src/app/ad-banner.component.ts (excerpt)"></code-example>
@ -150,9 +144,7 @@ dynamically loaded components since they load at runtime.
To ensure that the compiler still generates a factory,
add dynamically loaded components to the `NgModule`'s `entryComponents` array:
<code-example path="dynamic-component-loader/src/app/app.module.ts" region="entry-components" header="src/app/app.module.ts (entry components)" linenums="false">
</code-example>
<code-example path="dynamic-component-loader/src/app/app.module.ts" region="entry-components" header="src/app/app.module.ts (entry components)"></code-example>

View File

@ -77,18 +77,14 @@ appropriate controls dynamically.
via the `type` property.
<code-example path="dynamic-form/src/app/question-textbox.ts" header="src/app/question-textbox.ts" linenums="false">
</code-example>
<code-example path="dynamic-form/src/app/question-textbox.ts" header="src/app/question-textbox.ts"></code-example>
`DropdownQuestion` presents a list of choices in a select box.
<code-example path="dynamic-form/src/app/question-dropdown.ts" header="src/app/question-dropdown.ts" linenums="false">
</code-example>
<code-example path="dynamic-form/src/app/question-dropdown.ts" header="src/app/question-dropdown.ts"></code-example>
@ -97,9 +93,7 @@ In a nutshell, the form group consumes the metadata from the question model and
allows you to specify default values and validation rules.
<code-example path="dynamic-form/src/app/question-control.service.ts" header="src/app/question-control.service.ts" linenums="false">
</code-example>
<code-example path="dynamic-form/src/app/question-control.service.ts" header="src/app/question-control.service.ts"></code-example>
{@a form-component}

View File

@ -1,12 +1,5 @@
# Entry Components
#### Prerequisites:
A basic understanding of the following concepts:
* [Bootstrapping](guide/bootstrapping).
<hr />
An entry component is any component that Angular loads imperatively, (which means youre not referencing it in the template), by type. You specify an entry component by bootstrapping it in an NgModule, or including it in a routing definition.
<div class="alert is-helpful">

View File

@ -1,12 +1,6 @@
# Feature Modules
Feature modules are NgModules for the purpose of organizing code.
#### Prerequisites
A basic understanding of the following:
* [Bootstrapping](guide/bootstrapping).
* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
* [Frequently Used Modules](guide/frequent-ngmodules).
Feature modules are NgModules for the purpose of organizing code.
For the final sample app with a feature module that this page describes,
see the <live-example></live-example>.
@ -72,8 +66,7 @@ ng generate component customer-dashboard/CustomerDashboard
This generates a folder for the new component within the customer-dashboard folder and updates the feature module with the `CustomerDashboardComponent` info:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" header="src/app/customer-dashboard/customer-dashboard.module.ts" linenums="false">
</code-example>
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
@ -83,8 +76,7 @@ The `CustomerDashboardComponent` is now in the JavaScript import list at the top
To incorporate the feature module into your app, you have to let the root module, `app.module.ts`, know about it. Notice the `CustomerDashboardModule` export at the bottom of `customer-dashboard.module.ts`. This exposes it so that other modules can get to it. To import it into the `AppModule`, add it to the imports in `app.module.ts` and to the `imports` array:
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts" linenums="false">
</code-example>
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example>
Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules dont expose their components.
@ -94,21 +86,18 @@ Now the `AppModule` knows about the feature module. If you were to add any servi
When the CLI generated the `CustomerDashboardComponent` for the feature module, it included a template, `customer-dashboard.component.html`, with the following markup:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" region="feature-template" header="src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" linenums="false">
</code-example>
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" region="feature-template" header="src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html"></code-example>
To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardComponent`:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts" linenums="false">
</code-example>
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
Next, in the `AppComponent`, `app.component.html`, add the tag `<app-customer-dashboard>`:
<code-example path="feature-modules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="feature-modules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too:

View File

@ -4,7 +4,7 @@ You develop applications in the context of an Angular [workspace](guide/glossary
The Angular CLI `ng new` command creates a workspace.
<code-example language="bash" linenums="false">
<code-example language="bash">
ng new &lt;my-project&gt;
</code-example>
@ -111,7 +111,7 @@ An `e2e/` folder at the top level contains source files for a set of end-to-end
For a multi-project workspace, application-specific end-to-end tests are in the project root, under `projects/project-name/e2e/`.
<code-example language="none" linenums="false">
<code-example language="none">
e2e/
src/ (end-to-end tests for my-app)
app.e2e-spec.ts
@ -131,13 +131,13 @@ A multi-project workspace is suitable for an enterprise that uses a single repos
If you intend to have multiple projects in a workspace, you can skip the initial application generation when you create the workspace, and give the workspace a unique name.
The following command creates a workspace with all of the workspace-wide configuration files, but no root-level application.
<code-example language="bash" linenums="false">
<code-example language="bash">
ng new my-workspace --createApplication="false"
</code-example>
You can then generate apps and libraries with names that are unique within the workspace.
<code-example language="bash" linenums="false">
<code-example language="bash">
cd my-workspace
ng generate application my-first-app
</code-example>
@ -148,7 +148,7 @@ The first explicitly generated application goes into the `projects/` folder alon
Newly generated libraries are also added under `projects/`.
When you create projects this way, the file structure of the workspace is entirely consistent with the structure of the [workspace configuration file](guide/workspace-config), `angular.json`.
<code-example language="none" linenums="false">
<code-example language="none">
my-workspace/
... (workspace-wide config files)
projects/ (generated applications and libraries)

View File

@ -29,9 +29,7 @@ either a list of validation errors, which results in an INVALID status, or null,
You can then inspect the control's state by exporting `ngModel` to a local template variable.
The following example exports `NgModel` into a variable called `name`:
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="name-with-error-msg" header="template/hero-form-template.component.html (name)" linenums="false">
</code-example>
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="name-with-error-msg" header="template/hero-form-template.component.html (name)"></code-example>
Note the following:
@ -92,8 +90,7 @@ built-in validators&mdash;this time, in function form. See below:
{@a reactive-component-class}
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="form-group" header="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
</code-example>
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="form-group" header="reactive/hero-form-reactive.component.ts (validator functions)"></code-example>
Note that:
@ -106,8 +103,7 @@ for the template.
If you look at the template for the name input again, it is fairly similar to the template-driven example.
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="name-with-error-msg" header="reactive/hero-form-reactive.component.html (name with error msg)" linenums="false">
</code-example>
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="name-with-error-msg" header="reactive/hero-form-reactive.component.html (name with error msg)"></code-example>
Key takeaways:
@ -125,8 +121,7 @@ Consider the `forbiddenNameValidator` function from previous
[examples](guide/form-validation#reactive-component-class) in
this guide. Here's what the definition of that function looks like:
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="custom-validator" header="shared/forbidden-name.directive.ts (forbiddenNameValidator)" linenums="false">
</code-example>
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="custom-validator" header="shared/forbidden-name.directive.ts (forbiddenNameValidator)"></code-example>
The function is actually a factory that takes a regular expression to detect a _specific_ forbidden name and returns a validator function.
@ -148,8 +143,7 @@ at which point the form uses the last value emitted for validation.
In reactive forms, custom validators are fairly simple to add. All you have to do is pass the function directly
to the `FormControl`.
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="custom-validator" header="reactive/hero-form-reactive.component.ts (validator functions)" linenums="false">
</code-example>
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.1.ts" region="custom-validator" header="reactive/hero-form-reactive.component.ts (validator functions)"></code-example>
### Adding to template-driven forms
@ -161,8 +155,7 @@ The corresponding `ForbiddenValidatorDirective` serves as a wrapper around the `
Angular recognizes the directive's role in the validation process because the directive registers itself
with the `NG_VALIDATORS` provider, a provider with an extensible collection of validators.
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="directive-providers" header="shared/forbidden-name.directive.ts (providers)" linenums="false">
</code-example>
<code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="directive-providers" header="shared/forbidden-name.directive.ts (providers)"></code-example>
The directive class then implements the `Validator` interface, so that it can easily integrate
with Angular forms. Here is the rest of the directive to help you get an idea of how it all
@ -173,9 +166,7 @@ comes together:
Once the `ForbiddenValidatorDirective` is ready, you can simply add its selector, `appForbiddenName`, to any input element to activate it. For example:
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="name-input" header="template/hero-form-template.component.html (forbidden-name-input)" linenums="false">
</code-example>
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="name-input" header="template/hero-form-template.component.html (forbidden-name-input)"></code-example>
<div class="alert is-helpful">
@ -245,8 +236,7 @@ const heroForm = new FormGroup({
The validator code is as follows:
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-validator" header="shared/identity-revealed.directive.ts" linenums="false">
</code-example>
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-validator" header="shared/identity-revealed.directive.ts"></code-example>
The identity validator implements the `ValidatorFn` interface. It takes an Angular control object as an argument and returns either null if the form is valid, or `ValidationErrors` otherwise.
@ -255,8 +245,7 @@ First we retrieve the child controls by calling the `FormGroup`'s [get](api/form
If the values do not match, the hero's identity remains secret, and we can safely return null. Otherwise, the hero's identity is revealed and we must mark the form as invalid by returning an error object.
Next, to provide better user experience, we show an appropriate error message when the form is invalid.
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="cross-validation-error-message" header="reactive/hero-form-template.component.html" linenums="false">
</code-example>
<code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="cross-validation-error-message" header="reactive/hero-form-template.component.html"></code-example>
Note that we check if:
- the `FormGroup` has the cross validation error returned by the `identityRevealed` validator,
@ -265,16 +254,13 @@ Note that we check if:
### Adding to template driven forms
First we must create a directive that will wrap the validator function. We provide it as the validator using the `NG_VALIDATORS` token. If you are not sure why, or you do not fully understand the syntax, revisit the previous [section](guide/form-validation#adding-to-template-driven-forms).
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-directive" header="shared/identity-revealed.directive.ts" linenums="false">
</code-example>
<code-example path="form-validation/src/app/shared/identity-revealed.directive.ts" region="cross-validation-directive" header="shared/identity-revealed.directive.ts"></code-example>
Next, we have to add the directive to the html template. Since the validator must be registered at the highest level in the form, we put the directive on the `form` tag.
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-register-validator" header="template/hero-form-template.component.html" linenums="false">
</code-example>
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-register-validator" header="template/hero-form-template.component.html"></code-example>
To provide better user experience, we show an appropriate error message when the form is invalid.
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-error-message" header="template/hero-form-template.component.html" linenums="false">
</code-example>
<code-example path="form-validation/src/app/template/hero-form-template.component.html" region="cross-validation-error-message" header="template/hero-form-template.component.html"></code-example>
Note that we check if:
- the form has the cross validation error returned by the `identityRevealed` validator,
@ -313,7 +299,7 @@ To validate the potential alter ego, we need to consult a central database of al
Let's start by creating the validator class.
<code-example path="form-validation/src/app/shared/alter-ego.directive.ts" region="async-validator" linenums="false"></code-example>
<code-example path="form-validation/src/app/shared/alter-ego.directive.ts" region="async-validator"></code-example>
As you can see, the `UniqueAlterEgoValidator` class implements the `AsyncValidator` interface. In the constructor, we inject the `HeroesService` that has the following interface:

View File

@ -109,9 +109,7 @@ Using the Angular CLI command [`ng generate class`](cli/generate), generate a ne
With this content:
<code-example path="forms/src/app/hero.ts" header="src/app/hero.ts">
</code-example>
<code-example path="forms/src/app/hero.ts" header="src/app/hero.ts"></code-example>
It's an anemic model with few requirements and no behavior. Perfect for the demo.
@ -122,9 +120,7 @@ The `alterEgo` is optional, so the constructor lets you omit it; note the questi
You can create a new hero like this:
<code-example path="forms/src/app/hero-form/hero-form.component.ts" linenums="false" region="SkyDog">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.ts" region="SkyDog"></code-example>
## Create a form component
@ -142,9 +138,7 @@ Using the Angular CLI command [`ng generate component`](cli/generate), generate
With this content:
<code-example path="forms/src/app/hero-form/hero-form.component.ts" linenums="false" header="src/app/hero-form/hero-form.component.ts (v1)" region="v1">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.ts" header="src/app/hero-form/hero-form.component.ts (v1)" region="v1"></code-example>
Theres nothing special about this component, nothing form-specific,
nothing to distinguish it from any component you've written before.
@ -176,9 +170,7 @@ Because template-driven forms are in their own module, you need to add the `Form
Update it with the following:
<code-example path="forms/src/app/app.module.ts" header="src/app/app.module.ts">
</code-example>
<code-example path="forms/src/app/app.module.ts" header="src/app/app.module.ts"></code-example>
<div class="alert is-helpful">
@ -204,9 +196,7 @@ Update it with the following:
Replace the contents of its template with the following:
<code-example path="forms/src/app/app.component.html" header="src/app/app.component.html">
</code-example>
<code-example path="forms/src/app/app.component.html" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
@ -221,9 +211,7 @@ Replace the contents of its template with the following:
Update the template file with the following contents:
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="start" header="src/app/hero-form/hero-form.component.html">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="start" header="src/app/hero-form/hero-form.component.html"></code-example>
The language is simply HTML5. You're presenting two of the `Hero` fields, `name` and `alterEgo`, and
opening them up for user input in input boxes.
@ -259,9 +247,7 @@ Bootstrap gives the form a little style.
To add the stylesheet, open `styles.css` and add the following import line at the top:
<code-example path="forms/src/styles.1.css" linenums="false" header="src/styles.css">
</code-example>
<code-example path="forms/src/styles.1.css" header="src/styles.css"></code-example>
## Add powers with _*ngFor_
@ -274,9 +260,7 @@ a technique seen previously in the [Displaying Data](guide/displaying-data) page
Add the following HTML *immediately below* the *Alter Ego* group:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (powers)" region="powers">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (powers)" region="powers"></code-example>
This code repeats the `<option>` tag for each power in the list of powers.
The `pow` template input variable is a different power in each iteration;
@ -307,9 +291,7 @@ makes binding the form to the model easy.
Find the `<input>` tag for *Name* and update it like this:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-1">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-1"></code-example>
<div class="alert is-helpful">
@ -325,9 +307,7 @@ You need one more addition to display the data. Declare
a template variable for the form. Update the `<form>` tag with
`#heroForm="ngForm"` as follows:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="template-variable">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="template-variable"></code-example>
The variable `heroForm` is now a reference to the `NgForm` directive that governs the form as a whole.
@ -391,9 +371,7 @@ Then you can confirm that two-way data binding works *for the entire hero model*
After revision, the core of the form should look like this:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModel-2">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModel-2"></code-example>
<div class="alert is-helpful">
@ -493,9 +471,7 @@ You can leverage those class names to change the appearance of the control.
Temporarily add a [template reference variable](guide/template-syntax#ref-vars) named `spy`
to the _Name_ `<input>` tag and use it to display the input's CSS classes.
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-2">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="ngModelName-2"></code-example>
Now run the app and look at the _Name_ input box.
Follow these steps *precisely*:
@ -535,15 +511,11 @@ on the left of the input box:
You achieve this effect by adding these class definitions to a new `forms.css` file
that you add to the project as a sibling to `index.html`:
<code-example path="forms/src/assets/forms.css" header="src/assets/forms.css">
</code-example>
<code-example path="forms/src/assets/forms.css" header="src/assets/forms.css"></code-example>
Update the `<head>` of `index.html` to include this style sheet:
<code-example path="forms/src/index.html" linenums="false" header="src/index.html (styles)" region="styles">
</code-example>
<code-example path="forms/src/index.html" header="src/index.html (styles)" region="styles"></code-example>
## Show and hide validation error messages
@ -564,9 +536,7 @@ To achieve this effect, extend the `<input>` tag with the following:
Here's an example of an error message added to the _name_ input box:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="name-with-error-msg">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="name-with-error-msg"></code-example>
You need a template reference variable to access the input box's Angular control from within the template.
Here you created a variable called `name` and gave it the value "ngModel".
@ -583,9 +553,7 @@ Here you created a variable called `name` and gave it the value "ngModel".
You control visibility of the name error message by binding properties of the `name`
control to the message `<div>` element's `hidden` property.
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (hidden-error-msg)" region="hidden-error-msg">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (hidden-error-msg)" region="hidden-error-msg"></code-example>
In this example, you hide the message when the control is valid or pristine;
"pristine" means the user hasn't changed the value since it was displayed in this form.
@ -609,13 +577,9 @@ power to valid values.
Now you'll add a new hero in this form.
Place a *New Hero* button at the bottom of the form and bind its click event to a `newHero` component method.
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-no-reset" header="src/app/hero-form/hero-form.component.html (New Hero button)">
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-no-reset" header="src/app/hero-form/hero-form.component.html (New Hero button)"></code-example>
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.ts" region="new-hero" header="src/app/hero-form/hero-form.component.ts (New Hero method)" linenums="false">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.ts" region="new-hero" header="src/app/hero-form/hero-form.component.ts (New Hero method)"></code-example>
Run the application again, click the *New Hero* button, and the form clears.
The *required* bars to the left of the input box are red, indicating invalid `name` and `power` properties.
@ -634,9 +598,7 @@ Replacing the hero object *did not restore the pristine state* of the form contr
You have to clear all of the flags imperatively, which you can do
by calling the form's `reset()` method after calling the `newHero()` method.
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-form-reset" header="src/app/hero-form/hero-form.component.html (Reset the form)">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" region="new-hero-button-form-reset" header="src/app/hero-form/hero-form.component.html (Reset the form)"></code-example>
Now clicking "New Hero" resets both the form and its control flags.
@ -651,9 +613,7 @@ A "form submit" is useless at the moment.
To make it useful, bind the form's `ngSubmit` event property
to the hero form component's `onSubmit()` method:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (ngSubmit)" region="ngSubmit">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (ngSubmit)" region="ngSubmit"></code-example>
You'd already defined a template reference variable,
`#heroForm`, and initialized it with the value "ngForm".
@ -664,9 +624,7 @@ You'll bind the form's overall validity via
the `heroForm` variable to the button's `disabled` property
using an event binding. Here's the code:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (submit-button)" region="submit-button">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (submit-button)" region="submit-button"></code-example>
If you run the application now, you find that the button is enabled&mdash;although
it doesn't do anything useful yet.
@ -703,17 +661,13 @@ hide the data entry area and display something else.
Wrap the form in a `<div>` and bind
its `hidden` property to the `HeroFormComponent.submitted` property.
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="edit-div">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="edit-div"></code-example>
The main form is visible from the start because the
`submitted` property is false until you submit the form,
as this fragment from the `HeroFormComponent` shows:
<code-example path="forms/src/app/hero-form/hero-form.component.ts" linenums="false" header="src/app/hero-form/hero-form.component.ts (submitted)" region="submitted">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.ts" header="src/app/hero-form/hero-form.component.ts (submitted)" region="submitted"></code-example>
When you click the *Submit* button, the `submitted` flag becomes true and the form disappears
as planned.
@ -721,9 +675,7 @@ as planned.
Now the app needs to show something else while the form is in the submitted state.
Add the following HTML below the `<div>` wrapper you just wrote:
<code-example path="forms/src/app/hero-form/hero-form.component.html" linenums="false" header="src/app/hero-form/hero-form.component.html (excerpt)" region="submitted">
</code-example>
<code-example path="forms/src/app/hero-form/hero-form.component.html" header="src/app/hero-form/hero-form.component.html (excerpt)" region="submitted"></code-example>
There's the hero again, displayed read-only with interpolation bindings.
This `<div>` appears only while the component is in the submitted state.

View File

@ -1,12 +1,5 @@
# Frequently Used Modules
#### Prerequisites
A basic understanding of [Bootstrapping](guide/bootstrapping).
<hr>
An Angular app needs at least one module that serves as the root module.
As you add features to your app, you can add them in modules.
The following are frequently used Angular modules with examples

View File

@ -454,10 +454,9 @@ A form of property [data binding](#data-binding) in which a [template expression
That text can be concatenated with neighboring text before it is assigned to an element property
or displayed between element tags, as in this example.
<code-example language="html" escape="html">
<label>My current hero is {{hero.name}}</label>
</code-example>
```html
<label>My current hero is {{hero.name}}</label>
```
Read more about [interpolation](guide/template-syntax#interpolation) in [Template Syntax](guide/template-syntax).
@ -749,7 +748,7 @@ For more information, see [Schematics](guide/schematics) and [Integrating Librar
Schematics come with their own command-line tool.
Using Node 6.9 or above, install the Schematics CLI globally:
<code-example format="." language="bash">
<code-example language="bash">
npm install -g @angular-devkit/schematics-cli
</code-example>
@ -764,7 +763,7 @@ NgModules are delivered within scoped packages whose names begin with the Angula
Import a scoped package in the same way that you import a normal package.
<code-example path="architecture/src/app/app.component.ts" linenums="false" header="architecture/src/app/app.component.ts (import)" region="import">
<code-example path="architecture/src/app/app.component.ts" header="architecture/src/app/app.component.ts (import)" region="import">
</code-example>

View File

@ -19,7 +19,7 @@ an NgModule, directive-level injectors follow the structure of the component hie
The choices you make about where to configure providers lead to differences in the final bundle size, service _scope_, and service _lifetime_.
When you specify providers in the `@Injectable()` decorator of the service itself (typically at the app root level), optimization tools such as those used by the CLI's production builds can perform *tree shaking*, which removes services that aren't used by your app. Tree shaking results in smaller bundle sizes.
When you specify providers in the `@Injectable()` decorator of the service itself (typically at the app root level), optimization tools such as those used by the CLI's production builds can perform *tree shaking*, which removes services that aren't used by your app. Tree shaking results in smaller bundle sizes.
* Learn more about [tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
@ -29,12 +29,12 @@ You're likely to inject `UserService` in many places throughout the app and will
<header>Platform injector</header>
When you use `providedIn:'root'`, you are configuring the root injector for the _app_, which is the injector for `AppModule`.
The actual root of the entire injector hierarchy is a _platform injector_ that is the parent of app-root injectors.
The actual root of the entire injector hierarchy is a _platform injector_ that is the parent of app-root injectors.
This allows multiple apps to share a platform configuration. For example, a browser has only one URL bar, no matter how many apps you have running.
The platform injector is used internally during bootstrap, to configure platform-specific dependencies. You can configure additional platform-specific providers at the platform level by supplying `extraProviders` using the `platformBrowser()` function.
The platform injector is used internally during bootstrap, to configure platform-specific dependencies. You can configure additional platform-specific providers at the platform level by supplying `extraProviders` using the `platformBrowser()` function.
Learn more about dependency resolution through the injector hierarchy:
Learn more about dependency resolution through the injector hierarchy:
[What you always wanted to know about Angular Dependency Injection tree](https://blog.angularindepth.com/angular-dependency-injection-and-tree-shakeable-tokens-4588a8f70d5d)
@ -42,24 +42,24 @@ Learn more about dependency resolution through the injector hierarchy:
*NgModule-level* providers can be specified with `@NgModule()` `providers` metadata option, or in the `@Injectable()` `providedIn` option (with some module other than the root `AppModule`).
Use the `@NgModule()` `providers` option if a module is [lazy loaded](guide/lazy-loading-ngmodules). The module's own injector is configured with the provider when that module is loaded, and Angular can inject the corresponding services in any class it creates in that module. If you use the `@Injectable()` option `providedIn: MyLazyloadModule`, the provider could be shaken out at compile time, if it is not used anywhere else in the app.
Use the `@NgModule()` `providers` option if a module is [lazy loaded](guide/lazy-loading-ngmodules). The module's own injector is configured with the provider when that module is loaded, and Angular can inject the corresponding services in any class it creates in that module. If you use the `@Injectable()` option `providedIn: MyLazyloadModule`, the provider could be shaken out at compile time, if it is not used anywhere else in the app.
* Learn more about [tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
For both root-level and module-level injectors, a service instance lives for the life of the app or module, and Angular injects this one service instance in every class that needs it.
*Component-level* providers configure each component instance's own injector.
Angular can only inject the corresponding services in that component instance or one of its descendant component instances.
Angular can't inject the same service instance anywhere else.
*Component-level* providers configure each component instance's own injector.
Angular can only inject the corresponding services in that component instance or one of its descendant component instances.
Angular can't inject the same service instance anywhere else.
A component-provided service may have a limited lifetime.
Each new instance of the component gets its own instance of the service.
A component-provided service may have a limited lifetime.
Each new instance of the component gets its own instance of the service.
When the component instance is destroyed, so is that service instance.
In our sample app, `HeroComponent` is created when the application starts
In our sample app, `HeroComponent` is created when the application starts
and is never destroyed,
so the `HeroService` instance created for `HeroComponent` lives for the life of the app.
If you want to restrict `HeroService` access to `HeroComponent` and its nested
so the `HeroService` instance created for `HeroComponent` lives for the life of the app.
If you want to restrict `HeroService` access to `HeroComponent` and its nested
`HeroListComponent`, provide `HeroService` at the component level, in `HeroComponent` metadata.
* See more [examples of component-level injection](#component-injectors) below.
@ -67,32 +67,32 @@ If you want to restrict `HeroService` access to `HeroComponent` and its nested
{@a register-providers-injectable}
### @Injectable-level configuration
### @Injectable-level configuration
The `@Injectable()` decorator identifies every service class. The `providedIn` metadata option for a service class configures a specific injector (typically `root`)
to use the decorated class as a provider of the service.
When an injectable class provides its own service to the `root` injector, the service is available anywhere the class is imported.
to use the decorated class as a provider of the service.
When an injectable class provides its own service to the `root` injector, the service is available anywhere the class is imported.
The following example configures a provider for `HeroService` using the `@Injectable()` decorator on the class.
<code-example path="dependency-injection/src/app/heroes/hero.service.0.ts" header="src/app/heroes/heroes.service.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/heroes/hero.service.0.ts" header="src/app/heroes/heroes.service.ts"></code-example>
This configuration tells Angular that the app's root injector is responsible for creating an
This configuration tells Angular that the app's root injector is responsible for creating an
instance of `HeroService` by invoking its constructor,
and for making that instance available across the application.
and for making that instance available across the application.
Providing a service with the app's root injector is a typical case,
and the CLI sets up this kind of a provider automatically for you
when generating a new service.
when generating a new service.
However, you might not always want to provide your service at the root level.
You might, for instance, want users to explicitly opt-in to using the service.
Instead of specifying the `root` injector, you can set `providedIn` to a specific NgModule.
Instead of specifying the `root` injector, you can set `providedIn` to a specific NgModule.
For example, in the following excerpt, the `@Injectable()` decorator configures a provider
that is available in any injector that includes the `HeroModule`.
<code-example path="dependency-injection/src/app/heroes/hero.service.4.ts" header="src/app/heroes/hero.service.ts" linenums="false"> </code-example>
<code-example path="dependency-injection/src/app/heroes/hero.service.4.ts" header="src/app/heroes/hero.service.ts"></code-example>
This is generally no different from configuring the injector of the NgModule itself,
except that the service is tree-shakable if the NgModule doesn't use it.
@ -108,18 +108,16 @@ and leave it up to the app whether to provide the service.
You can configure a provider at the module level using the `providers` metadata option for a non-root NgModule, in order to limit the scope of the provider to that module.
This is the equivalent of specifying the non-root module in the `@Injectable()` metadata, except that the service provided via `providers` is not tree-shakable.
You generally don't need to specify `AppModule` with `providedIn`, because the app's `root` injector is the `AppModule` injector.
You generally don't need to specify `AppModule` with `providedIn`, because the app's `root` injector is the `AppModule` injector.
However, if you configure a app-wide provider in the `@NgModule()` metadata for `AppModule`,
it overrides one configured for `root` in the `@Injectable()` metadata.
You can do this to configure a non-default provider of a service that is shared with multiple apps.
it overrides one configured for `root` in the `@Injectable()` metadata.
You can do this to configure a non-default provider of a service that is shared with multiple apps.
Here is an example of the case where the component router configuration includes
a non-default [location strategy](guide/router#location-strategy) by listing its provider
in the `providers` list of the `AppModule`.
<code-example path="dependency-injection-in-action/src/app/app.module.ts" region="providers" header="src/app/app.module.ts (providers)" linenums="false">
</code-example>
<code-example path="dependency-injection-in-action/src/app/app.module.ts" region="providers" header="src/app/app.module.ts (providers)"></code-example>
{@a register-providers-component}
@ -130,19 +128,18 @@ Individual components within an NgModule have their own injectors.
You can limit the scope of a provider to a component and its children
by configuring the provider at the component level using the `@Component` metadata.
The following example is a revised `HeroesComponent` that specifies `HeroService` in its `providers` array. `HeroService` can provide heroes to instances of this component, or to any child component instances.
The following example is a revised `HeroesComponent` that specifies `HeroService` in its `providers` array. `HeroService` can provide heroes to instances of this component, or to any child component instances.
<code-example path="dependency-injection/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts" linenums="false">
</code-example>
<code-example path="dependency-injection/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts"></code-example>
### Element injectors
An injector does not actually belong to a component, but rather to the component instance's anchor element in the DOM. A different component instance on a different DOM element uses a different injector.
Components are a special type of directive, and the `providers` property of
`@Component()` is inherited from `@Directive()`.
`@Component()` is inherited from `@Directive()`.
Directives can also have dependencies, and you can configure providers
in their `@Directive()` metadata.
in their `@Directive()` metadata.
When you configure a provider for a component or directive using the `providers` property, that provider belongs to the injector for the anchor DOM element. Components and directives on the same element share an injector.
<!--- TBD with examples
@ -168,16 +165,16 @@ When a component requests a dependency, Angular tries to satisfy that dependency
If the component's injector lacks the provider, it passes the request up to its parent component's injector.
If that injector can't satisfy the request, it passes the request along to the next parent injector up the tree.
The requests keep bubbling up until Angular finds an injector that can handle the request or runs out of ancestor injectors.
If it runs out of ancestors, Angular throws an error.
If it runs out of ancestors, Angular throws an error.
If you have registered a provider for the same DI token at different levels, the first one Angular encounters is the one it uses to provide the dependency. If, for example, a provider is registered locally in the component that needs a service, Angular doesn't look for another provider of the same service.
If you have registered a provider for the same DI token at different levels, the first one Angular encounters is the one it uses to provide the dependency. If, for example, a provider is registered locally in the component that needs a service, Angular doesn't look for another provider of the same service.
<div class="alert is-helpful">
You can cap the bubbling by adding the `@Host()` parameter decorator on the dependant-service parameter
in a component's constructor.
The hunt for providers stops at the injector for the host element of the component.
in a component's constructor.
The hunt for providers stops at the injector for the host element of the component.
* See an [example](guide/dependency-injection-in-action#qualify-dependency-lookup) of using `@Host` together with `@Optional`, another parameter decorator that lets you handle the null case if no provider is found.
@ -197,7 +194,7 @@ The guide sample offers some scenarios where you might want to do so.
### Scenario: service isolation
Architectural reasons may lead you to restrict access to a service to the application domain where it belongs.
Architectural reasons may lead you to restrict access to a service to the application domain where it belongs.
For example, the guide sample includes a `VillainsListComponent` that displays a list of villains.
It gets those villains from a `VillainsService`.
@ -207,9 +204,7 @@ that would make the `VillainsService` available everywhere in the application, i
Instead, you can provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:
<code-example path="hierarchical-dependency-injection/src/app/villains-list.component.ts" linenums="false" header="src/app/villains-list.component.ts (metadata)" region="metadata">
</code-example>
<code-example path="hierarchical-dependency-injection/src/app/villains-list.component.ts" header="src/app/villains-list.component.ts (metadata)" region="metadata"></code-example>
By providing `VillainsService` in the `VillainsListComponent` metadata and nowhere else,
the service becomes available only in the `VillainsListComponent` and its sub-component tree.
@ -273,9 +268,7 @@ Every component would share the same service instance, and each component would
To prevent this, we configure the component-level injector of `HeroTaxReturnComponent` to provide the service, using the `providers` property in the component metadata.
<code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" linenums="false" header="src/app/hero-tax-return.component.ts (providers)" region="providers">
</code-example>
<code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" header="src/app/hero-tax-return.component.ts (providers)" region="providers"></code-example>
The `HeroTaxReturnComponent` has its own provider of the `HeroTaxReturnService`.
Recall that every component _instance_ has its own injector.

View File

@ -11,7 +11,7 @@ You can run the <live-example></live-example> that accompanies this guide.
<div class="alert is-helpful">
The sample app does not require a data server.
It relies on the
It relies on the
[Angular _in-memory-web-api_](https://github.com/angular/in-memory-web-api/blob/master/README.md),
which replaces the _HttpClient_ module's `HttpBackend`.
The replacement service simulates the behavior of a REST-like backend.
@ -22,50 +22,50 @@ Look at the `AppModule` _imports_ to see how it is configured.
## Setup
Before you can use the `HttpClient`, you need to import the Angular `HttpClientModule`.
Before you can use the `HttpClient`, you need to import the Angular `HttpClientModule`.
Most apps do so in the root `AppModule`.
<code-example
<code-example
path="http/src/app/app.module.ts"
region="sketch"
header="app/app.module.ts (excerpt)" linenums="false">
header="app/app.module.ts (excerpt)">
</code-example>
Having imported `HttpClientModule` into the `AppModule`, you can inject the `HttpClient`
into an application class as shown in the following `ConfigService` example.
<code-example
<code-example
path="http/src/app/config/config.service.ts"
region="proto"
header="app/config/config.service.ts (excerpt)" linenums="false">
header="app/config/config.service.ts (excerpt)">
</code-example>
## Getting JSON data
Applications often request JSON data from the server.
For example, the app might need a configuration file on the server, `config.json`,
Applications often request JSON data from the server.
For example, the app might need a configuration file on the server, `config.json`,
that specifies resource URLs.
<code-example
<code-example
path="http/src/assets/config.json"
header="assets/config.json" linenums="false">
header="assets/config.json">
</code-example>
The `ConfigService` fetches this file with a `get()` method on `HttpClient`.
<code-example
<code-example
path="http/src/app/config/config.service.ts"
region="getConfig_1"
header="app/config/config.service.ts (getConfig v.1)" linenums="false">
header="app/config/config.service.ts (getConfig v.1)">
</code-example>
A component, such as `ConfigComponent`, injects the `ConfigService` and calls
the `getConfig` service method.
<code-example
<code-example
path="http/src/app/config/config.component.ts"
region="v1"
header="app/config/config.component.ts (showConfig v.1)" linenums="false">
header="app/config/config.component.ts (showConfig v.1)">
</code-example>
Because the service method returns an `Observable` of configuration data,
@ -93,12 +93,12 @@ the component, even in simple cases like this one.
The subscribe callback above requires bracket notation to extract the data values.
<code-example
<code-example
path="http/src/app/config/config.component.ts"
region="v1_callback" linenums="false">
region="v1_callback">
</code-example>
You can't write `data.heroesUrl` because TypeScript correctly complains that the `data` object from the service does not have a `heroesUrl` property.
You can't write `data.heroesUrl` because TypeScript correctly complains that the `data` object from the service does not have a `heroesUrl` property.
The `HttpClient.get()` method parsed the JSON server response into the anonymous `Object` type. It doesn't know what the shape of that object is.
@ -106,48 +106,48 @@ You can tell `HttpClient` the type of the response to make consuming the output
First, define an interface with the correct shape:
<code-example
<code-example
path="http/src/app/config/config.service.ts"
region="config-interface" linenums="false">
region="config-interface">
</code-example>
Then, specify that interface as the `HttpClient.get()` call's type parameter in the service:
<code-example
<code-example
path="http/src/app/config/config.service.ts"
region="getConfig_2"
header="app/config/config.service.ts (getConfig v.2)" linenums="false">
region="getConfig_2"
header="app/config/config.service.ts (getConfig v.2)">
</code-example>
The callback in the updated component method receives a typed data object, which is
easier and safer to consume:
<code-example
<code-example
path="http/src/app/config/config.component.ts"
region="v2"
header="app/config/config.component.ts (showConfig v.2)" linenums="false">
header="app/config/config.component.ts (showConfig v.2)">
</code-example>
### Reading the full response
The response body doesn't return all the data you may need. Sometimes servers return special headers or status codes to indicate certain conditions that are important to the application workflow.
The response body doesn't return all the data you may need. Sometimes servers return special headers or status codes to indicate certain conditions that are important to the application workflow.
Tell `HttpClient` that you want the full response with the `observe` option:
<code-example
<code-example
path="http/src/app/config/config.service.ts"
region="getConfigResponse" linenums="false">
region="getConfigResponse">
</code-example>
Now `HttpClient.get()` returns an `Observable` of typed `HttpResponse` rather than just the JSON data.
The component's `showConfigResponse()` method displays the response headers as well as the configuration:
<code-example
<code-example
path="http/src/app/config/config.component.ts"
region="showConfigResponse"
region="showConfigResponse"
header="app/config/config.component.ts (showConfigResponse)"
linenums="false">
>
</code-example>
As you can see, the response object has a `body` property of the correct type.
@ -158,11 +158,11 @@ What happens if the request fails on the server, or if a poor network connection
You _could_ handle in the component by adding a second callback to the `.subscribe()`:
<code-example
<code-example
path="http/src/app/config/config.component.ts"
region="v3"
region="v3"
header="app/config/config.component.ts (showConfig v.3 with error handling)"
linenums="false">
>
</code-example>
It's certainly a good idea to give the user some kind of feedback when data access fails.
@ -180,15 +180,15 @@ Or something could go wrong on the client-side such as a network error that prev
The `HttpClient` captures both kinds of errors in its `HttpErrorResponse` and you can inspect that response to figure out what really happened.
Error inspection, interpretation, and resolution is something you want to do in the _service_,
not in the _component_.
Error inspection, interpretation, and resolution is something you want to do in the _service_,
not in the _component_.
You might first devise an error handler like this one:
<code-example
<code-example
path="http/src/app/config/config.service.ts"
region="handleError"
header="app/config/config.service.ts (handleError)" linenums="false">
region="handleError"
header="app/config/config.service.ts (handleError)">
</code-example>
Notice that this handler returns an RxJS [`ErrorObservable`](#rxjs) with a user-friendly error message.
@ -198,10 +198,10 @@ even a "bad" one.
Now you take the `Observables` returned by the `HttpClient` methods
and _pipe them through_ to the error handler.
<code-example
<code-example
path="http/src/app/config/config.service.ts"
region="getConfig_3"
header="app/config/config.service.ts (getConfig v.3 with error handler)" linenums="false">
region="getConfig_3"
header="app/config/config.service.ts (getConfig v.3 with error handler)">
</code-example>
### `retry()`
@ -215,10 +215,10 @@ The simplest is called `retry()` and it automatically re-subscribes to a failed
_Pipe_ it onto the `HttpClient` method result just before the error handler.
<code-example
<code-example
path="http/src/app/config/config.service.ts"
region="getConfig"
header="app/config/config.service.ts (getConfig with retry)" linenums="false">
region="getConfig"
header="app/config/config.service.ts (getConfig with retry)">
</code-example>
{@a rxjs}
@ -229,17 +229,17 @@ You will encounter more RxJS artifacts as you continue below.
[RxJS](http://reactivex.io/rxjs/) is a library for composing asynchronous and callback-based code
in a _functional, reactive style_.
Many Angular APIs, including `HttpClient`, produce and consume RxJS `Observables`.
Many Angular APIs, including `HttpClient`, produce and consume RxJS `Observables`.
RxJS itself is out-of-scope for this guide. You will find many learning resources on the web.
While you can get by with a minimum of RxJS knowledge, you'll want to grow your RxJS skills over time in order to use `HttpClient` effectively.
If you're following along with these code snippets, note that you must import the RxJS observable and operator symbols that appear in those snippets. These `ConfigService` imports are typical.
<code-example
<code-example
path="http/src/app/config/config.service.ts"
region="rxjs-imports"
header="app/config/config.service.ts (RxJS imports)" linenums="false">
region="rxjs-imports"
header="app/config/config.service.ts (RxJS imports)">
</code-example>
## Requesting non-JSON data
@ -247,24 +247,24 @@ If you're following along with these code snippets, note that you must import th
Not all APIs return JSON data. In this next example,
a `DownloaderService` method reads a text file from the server
and logs the file contents, before returning those contents to the caller
as an `Observable<string>`.
as an `Observable<string>`.
<code-example
<code-example
path="http/src/app/downloader/downloader.service.ts"
region="getTextFile"
header="app/downloader/downloader.service.ts (getTextFile)" linenums="false">
region="getTextFile"
header="app/downloader/downloader.service.ts (getTextFile)">
</code-example>
`HttpClient.get()` returns a string rather than the default JSON because of the `responseType` option.
The RxJS `tap` operator (as in "wiretap") lets the code inspect good and error values passing through the observable without disturbing them.
The RxJS `tap` operator (as in "wiretap") lets the code inspect good and error values passing through the observable without disturbing them.
A `download()` method in the `DownloaderComponent` initiates the request by subscribing to the service method.
<code-example
<code-example
path="http/src/app/downloader/downloader.component.ts"
region="download"
header="app/downloader/downloader.component.ts (download)" linenums="false">
region="download"
header="app/downloader/downloader.component.ts (download)">
</code-example>
## Sending data to the server
@ -279,28 +279,28 @@ The following sections excerpt methods of the sample's `HeroesService`.
### Adding headers
Many servers require extra headers for save operations.
For example, they may require a "Content-Type" header to explicitly declare
For example, they may require a "Content-Type" header to explicitly declare
the MIME type of the request body.
Or perhaps the server requires an authorization token.
The `HeroesService` defines such headers in an `httpOptions` object that will be passed
to every `HttpClient` save method.
<code-example
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="http-options"
header="app/heroes/heroes.service.ts (httpOptions)" linenums="false">
region="http-options"
header="app/heroes/heroes.service.ts (httpOptions)">
</code-example>
### Making a POST request
Apps often POST data to a server. They POST when submitting a form.
Apps often POST data to a server. They POST when submitting a form.
In the following example, the `HeroesService` posts when adding a hero to the database.
<code-example
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="addHero"
header="app/heroes/heroes.service.ts (addHero)" linenums="false">
region="addHero"
header="app/heroes/heroes.service.ts (addHero)">
</code-example>
The `HttpClient.post()` method is similar to `get()` in that it has a type parameter
@ -314,13 +314,13 @@ It takes two more parameters:
Of course it catches errors in much the same manner [described above](#error-details).
The `HeroesComponent` initiates the actual POST operation by subscribing to
The `HeroesComponent` initiates the actual POST operation by subscribing to
the `Observable` returned by this service method.
<code-example
<code-example
path="http/src/app/heroes/heroes.component.ts"
region="add-hero-subscribe"
header="app/heroes/heroes.component.ts (addHero)" linenums="false">
region="add-hero-subscribe"
header="app/heroes/heroes.component.ts (addHero)">
</code-example>
When the server responds successfully with the newly added hero, the component adds
@ -331,22 +331,22 @@ that hero to the displayed `heroes` list.
This application deletes a hero with the `HttpClient.delete` method by passing the hero's id
in the request URL.
<code-example
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="deleteHero"
header="app/heroes/heroes.service.ts (deleteHero)" linenums="false">
region="deleteHero"
header="app/heroes/heroes.service.ts (deleteHero)">
</code-example>
The `HeroesComponent` initiates the actual DELETE operation by subscribing to
The `HeroesComponent` initiates the actual DELETE operation by subscribing to
the `Observable` returned by this service method.
<code-example
<code-example
path="http/src/app/heroes/heroes.component.ts"
region="delete-hero-subscribe"
header="app/heroes/heroes.component.ts (deleteHero)" linenums="false">
region="delete-hero-subscribe"
header="app/heroes/heroes.component.ts (deleteHero)">
</code-example>
The component isn't expecting a result from the delete operation, so it subscribes without a callback. Even though you are not using the result, you still have to subscribe. Calling the `subscribe()` method _executes_ the observable, which is what initiates the DELETE request.
The component isn't expecting a result from the delete operation, so it subscribes without a callback. Even though you are not using the result, you still have to subscribe. Calling the `subscribe()` method _executes_ the observable, which is what initiates the DELETE request.
<div class="alert is-important">
@ -355,9 +355,9 @@ You must call _subscribe()_ or nothing happens. Just calling `HeroesService.dele
</div>
<code-example
<code-example
path="http/src/app/heroes/heroes.component.ts"
region="delete-hero-no-subscribe" linenums="false">
region="delete-hero-no-subscribe">
</code-example>
{@a always-subscribe}
@ -400,10 +400,10 @@ req.subscribe();
An app will send a PUT request to completely replace a resource with updated data.
The following `HeroesService` example is just like the POST example.
<code-example
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="updateHero"
header="app/heroes/heroes.service.ts (updateHero)" linenums="false">
region="updateHero"
header="app/heroes/heroes.service.ts (updateHero)">
</code-example>
For the reasons [explained above](#always-subscribe), the caller (`HeroesComponent.update()` in this case) must `subscribe()` to the observable returned from the `HttpClient.put()`
@ -427,15 +427,15 @@ You can do more.
You can't directly modify the existing headers within the previous options
object because instances of the `HttpHeaders` class are immutable.
Use the `set()` method instead.
Use the `set()` method instead.
It returns a clone of the current instance with the new changes applied.
Here's how you might update the authorization header (after the old token expired)
Here's how you might update the authorization header (after the old token expired)
before making the next request.
<code-example
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="update-headers" linenums="false">
region="update-headers">
</code-example>
#### URL Parameters
@ -443,9 +443,9 @@ before making the next request.
Adding URL search parameters works a similar way.
Here is a `searchHeroes` method that queries for heroes whose names contain the search term.
<code-example
<code-example
path="http/src/app/heroes/heroes.service.ts"
region="searchHeroes" linenums="false">
region="searchHeroes">
</code-example>
If there is a search term, the code constructs an options object with an HTML URL-encoded search parameter. If the term were "foo", the GET request URL would be `api/heroes/?name=foo`.
@ -461,9 +461,9 @@ a search request for a package with that name to the NPM web API.
Here's a pertinent excerpt from the template:
<code-example
<code-example
path="http/src/app/package-search/package-search.component.html"
region="search"
region="search"
header="app/package-search/package-search.component.html (search)">
</code-example>
@ -473,9 +473,9 @@ Sending a request for every keystroke could be expensive.
It's better to wait until the user stops typing and then send a request.
That's easy to implement with RxJS operators, as shown in this excerpt.
<code-example
<code-example
path="http/src/app/package-search/package-search.component.ts"
region="debounce"
region="debounce"
header="app/package-search/package-search.component.ts (excerpt)">
</code-example>
@ -514,7 +514,7 @@ The `switchMap()` operator has three important characteristics.
it cancels that request and sends a new one.
3. It returns service responses in their original request order, even if the
server returns them out of order.
server returns them out of order.
<div class="alert is-helpful">
@ -526,14 +526,14 @@ consider moving it to a utility function or into the `PackageSearchService` itse
### Intercepting requests and responses
_HTTP Interception_ is a major feature of `@angular/common/http`.
_HTTP Interception_ is a major feature of `@angular/common/http`.
With interception, you declare _interceptors_ that inspect and transform HTTP requests from your application to the server.
The same interceptors may also inspect and transform the server's responses on their way back to the application.
Multiple interceptors form a _forward-and-backward_ chain of request/response handlers.
Interceptors can perform a variety of _implicit_ tasks, from authentication to logging, in a routine, standard way, for every HTTP request/response.
Interceptors can perform a variety of _implicit_ tasks, from authentication to logging, in a routine, standard way, for every HTTP request/response.
Without interception, developers would have to implement these tasks _explicitly_
Without interception, developers would have to implement these tasks _explicitly_
for each `HttpClient` method call.
#### Write an interceptor
@ -541,13 +541,12 @@ for each `HttpClient` method call.
To implement an interceptor, declare a class that implements the `intercept()` method of the `HttpInterceptor` interface.
Here is a do-nothing _noop_ interceptor that simply passes the request through without touching it:
<code-example
<code-example
path="http/src/app/http-interceptors/noop-interceptor.ts"
header="app/http-interceptors/noop-interceptor.ts"
linenums="false">
header="app/http-interceptors/noop-interceptor.ts">
</code-example>
The `intercept` method transforms a request into an `Observable` that eventually returns the HTTP response.
The `intercept` method transforms a request into an `Observable` that eventually returns the HTTP response.
In this sense, each interceptor is fully capable of handling the request entirely by itself.
Most interceptors inspect the request on the way in and forward the (perhaps altered) request to the `handle()` method of the `next` object which implements the [`HttpHandler`](api/common/http/HttpHandler) interface.
@ -564,22 +563,22 @@ This _no-op_ interceptor simply calls `next.handle()` with the original request
#### The _next_ object
The `next` object represents the next interceptor in the chain of interceptors.
The `next` object represents the next interceptor in the chain of interceptors.
The final `next` in the chain is the `HttpClient` backend handler that sends the request to the server and receives the server's response.
Most interceptors call `next.handle()` so that the request flows through to the next interceptor and, eventually, the backend handler.
An interceptor _could_ skip calling `next.handle()`, short-circuit the chain, and [return its own `Observable`](#caching) with an artificial server response.
An interceptor _could_ skip calling `next.handle()`, short-circuit the chain, and [return its own `Observable`](#caching) with an artificial server response.
This is a common middleware pattern found in frameworks such as Express.js.
#### Provide the interceptor
The `NoopInterceptor` is a service managed by Angular's [dependency injection (DI)](guide/dependency-injection) system.
The `NoopInterceptor` is a service managed by Angular's [dependency injection (DI)](guide/dependency-injection) system.
Like other services, you must provide the interceptor class before the app can use it.
Because interceptors are (optional) dependencies of the `HttpClient` service,
you must provide them in the same injector (or a parent of the injector) that provides `HttpClient`.
Because interceptors are (optional) dependencies of the `HttpClient` service,
you must provide them in the same injector (or a parent of the injector) that provides `HttpClient`.
Interceptors provided _after_ DI creates the `HttpClient` are ignored.
This app provides `HttpClient` in the app's root injector, as a side-effect of importing the `HttpClientModule` in `AppModule`.
@ -588,35 +587,35 @@ You should provide interceptors in `AppModule` as well.
After importing the `HTTP_INTERCEPTORS` injection token from `@angular/common/http`,
write the `NoopInterceptor` provider like this:
<code-example
<code-example
path="http/src/app/http-interceptors/index.ts"
region="noop-provider" linenums="false">
region="noop-provider">
</code-example>
Note the `multi: true` option.
This required setting tells Angular that `HTTP_INTERCEPTORS` is a token for a _multiprovider_
Note the `multi: true` option.
This required setting tells Angular that `HTTP_INTERCEPTORS` is a token for a _multiprovider_
that injects an array of values, rather than a single value.
You _could_ add this provider directly to the providers array of the `AppModule`.
However, it's rather verbose and there's a good chance that
However, it's rather verbose and there's a good chance that
you'll create more interceptors and provide them in the same way.
You must also pay [close attention to the order](#interceptor-order)
You must also pay [close attention to the order](#interceptor-order)
in which you provide these interceptors.
Consider creating a "barrel" file that gathers all the interceptor providers into an `httpInterceptorProviders` array, starting with this first one, the `NoopInterceptor`.
<code-example
<code-example
path="http/src/app/http-interceptors/index.ts"
region="interceptor-providers"
header="app/http-interceptors/index.ts" linenums="false">
header="app/http-interceptors/index.ts">
</code-example>
Then import and add it to the `AppModule` _providers array_ like this:
<code-example
<code-example
path="http/src/app/app.module.ts"
region="interceptor-providers"
header="app/app.module.ts (interceptor providers)" linenums="false">
header="app/app.module.ts (interceptor providers)">
</code-example>
As you create new interceptors, add them to the `httpInterceptorProviders` array and
@ -647,8 +646,8 @@ That's because interceptors work at a lower level than those `HttpClient` method
Many interceptors are only concerned with the outgoing request and simply return the event stream from `next.handle()` without modifying it.
But interceptors that examine and modify the response from `next.handle()`
will see all of these events.
But interceptors that examine and modify the response from `next.handle()`
will see all of these events.
Your interceptor should return _every event untouched_ unless it has a _compelling reason to do otherwise_.
#### Immutability
@ -660,39 +659,39 @@ rendering them largely immutable.
They are immutable for a good reason: the app may retry a request several times before it succeeds, which means that the interceptor chain may re-process the same request multiple times.
If an interceptor could modify the original request object, the re-tried operation would start from the modified request rather than the original. Immutability ensures that interceptors see the same request for each try.
TypeScript will prevent you from setting `HttpRequest` readonly properties.
TypeScript will prevent you from setting `HttpRequest` readonly properties.
```javascript
// Typescript disallows the following assignment because req.url is readonly
req.url = req.url.replace('http://', 'https://');
```
To alter the request, clone it first and modify the clone before passing it to `next.handle()`.
To alter the request, clone it first and modify the clone before passing it to `next.handle()`.
You can clone and modify the request in a single step as in this example.
<code-example
<code-example
path="http/src/app/http-interceptors/ensure-https-interceptor.ts"
region="excerpt"
header="app/http-interceptors/ensure-https-interceptor.ts (excerpt)" linenums="false">
region="excerpt"
header="app/http-interceptors/ensure-https-interceptor.ts (excerpt)">
</code-example>
The `clone()` method's hash argument allows you to mutate specific properties of the request while copying the others.
##### The request body
The `readonly` assignment guard can't prevent deep updates and, in particular,
The `readonly` assignment guard can't prevent deep updates and, in particular,
it can't prevent you from modifying a property of a request body object.
```javascript
req.body.name = req.body.name.trim(); // bad idea!
```
If you must mutate the request body, copy it first, change the copy,
If you must mutate the request body, copy it first, change the copy,
`clone()` the request, and set the clone's body with the new body, as in the following example.
<code-example
<code-example
path="http/src/app/http-interceptors/trim-name-interceptor.ts"
region="excerpt"
header="app/http-interceptors/trim-name-interceptor.ts (excerpt)" linenums="false">
region="excerpt"
header="app/http-interceptors/trim-name-interceptor.ts (excerpt)">
</code-example>
##### Clearing the request body
@ -710,21 +709,21 @@ If you set the cloned request body to `null`, Angular knows you intend to clear
#### Set default headers
Apps often use an interceptor to set default headers on outgoing requests.
Apps often use an interceptor to set default headers on outgoing requests.
The sample app has an `AuthService` that produces an authorization token.
Here is its `AuthInterceptor` that injects that service to get the token and
adds an authorization header with that token to every outgoing request:
<code-example
<code-example
path="http/src/app/http-interceptors/auth-interceptor.ts"
header="app/http-interceptors/auth-interceptor.ts">
</code-example>
The practice of cloning a request to set new headers is so common that
The practice of cloning a request to set new headers is so common that
there's a `setHeaders` shortcut for it:
<code-example
<code-example
path="http/src/app/http-interceptors/auth-interceptor.ts"
region="set-header-shortcut">
</code-example>
@ -737,16 +736,16 @@ An interceptor that alters headers can be used for a number of different operati
#### Logging
Because interceptors can process the request and response _together_, they can do things like time and log
an entire HTTP operation.
Because interceptors can process the request and response _together_, they can do things like time and log
an entire HTTP operation.
Consider the following `LoggingInterceptor`, which captures the time of the request,
the time of the response, and logs the outcome with the elapsed time
with the injected `MessageService`.
<code-example
<code-example
path="http/src/app/http-interceptors/logging-interceptor.ts"
region="excerpt"
region="excerpt"
header="app/http-interceptors/logging-interceptor.ts)">
</code-example>
@ -761,20 +760,20 @@ Neither `tap` nor `finalize` touch the values of the observable stream returned
Interceptors can handle requests by themselves, without forwarding to `next.handle()`.
For example, you might decide to cache certain requests and responses to improve performance.
You can delegate caching to an interceptor without disturbing your existing data services.
You can delegate caching to an interceptor without disturbing your existing data services.
The `CachingInterceptor` demonstrates this approach.
<code-example
<code-example
path="http/src/app/http-interceptors/caching-interceptor.ts"
region="v1"
header="app/http-interceptors/caching-interceptor.ts)" linenums="false">
region="v1"
header="app/http-interceptors/caching-interceptor.ts)">
</code-example>
The `isCachable()` function determines if the request is cachable.
In this sample, only GET requests to the npm package search api are cachable.
If the request is not cachable, the interceptor simply forwards the request
If the request is not cachable, the interceptor simply forwards the request
to the next handler in the chain.
If a cachable request is found in the cache, the interceptor returns an `of()` _observable_ with
@ -783,7 +782,7 @@ the cached response, by-passing the `next` handler (and all other interceptors d
If a cachable request is not in cache, the code calls `sendRequest`.
{@a send-request}
<code-example
<code-example
path="http/src/app/http-interceptors/caching-interceptor.ts"
region="send-request">
</code-example>
@ -799,16 +798,16 @@ It _pipes_ the response through the `tap()` operator,
whose callback adds the response to the cache.
The original response continues untouched back up through the chain of interceptors
to the application caller.
to the application caller.
Data services, such as `PackageSearchService`, are unaware that
Data services, such as `PackageSearchService`, are unaware that
some of their `HttpClient` requests actually return cached responses.
{@a cache-refresh}
#### Return a multi-valued _Observable_
The `HttpClient.get()` method normally returns an _observable_
that either emits the data or an error.
The `HttpClient.get()` method normally returns an _observable_
that either emits the data or an error.
Some folks describe it as a "_one and done_" observable.
But an interceptor can change this to an _observable_ that emits more than once.
@ -817,7 +816,7 @@ A revised version of the `CachingInterceptor` optionally returns an _observable_
immediately emits the cached response, sends the request to the NPM web API anyway,
and emits again later with the updated search results.
<code-example
<code-example
path="http/src/app/http-interceptors/caching-interceptor.ts"
region="intercept-refresh">
</code-example>
@ -833,8 +832,8 @@ and adds it to the request before calling `HttpClient.get()`.
</div>
The revised `CachingInterceptor` sets up a server request
whether there's a cached value or not,
The revised `CachingInterceptor` sets up a server request
whether there's a cached value or not,
using the same `sendRequest()` method described [above](#send-request).
The `results$` observable will make the request when subscribed.
@ -849,15 +848,15 @@ Subscribers see a sequence of _two_ responses.
### Listening to progress events
Sometimes applications transfer large amounts of data and those transfers can take a long time.
File uploads are a typical example.
File uploads are a typical example.
Give the users a better experience by providing feedback on the progress of such transfers.
To make a request with progress events enabled, you can create an instance of `HttpRequest`
To make a request with progress events enabled, you can create an instance of `HttpRequest`
with the `reportProgress` option set true to enable tracking of progress events.
<code-example
<code-example
path="http/src/app/uploader/uploader.service.ts"
region="upload-request"
region="upload-request"
header="app/uploader/uploader.service.ts (upload request)">
</code-example>
@ -873,24 +872,24 @@ When using [`HttpClient#request()`](api/common/http/HttpClient#request) with an
Next, pass this request object to the `HttpClient.request()` method, which
returns an `Observable` of `HttpEvents`, the same events processed by interceptors:
<code-example
<code-example
path="http/src/app/uploader/uploader.service.ts"
region="upload-body"
header="app/uploader/uploader.service.ts (upload body)" linenums="false">
region="upload-body"
header="app/uploader/uploader.service.ts (upload body)">
</code-example>
The `getEventMessage` method interprets each type of `HttpEvent` in the event stream.
<code-example
<code-example
path="http/src/app/uploader/uploader.service.ts"
region="getEventMessage"
header="app/uploader/uploader.service.ts (getEventMessage)" linenums="false">
region="getEventMessage"
header="app/uploader/uploader.service.ts (getEventMessage)">
</code-example>
<div class="alert is-helpful">
The sample app for this guide doesn't have a server that accepts uploaded files.
The `UploadInterceptor` in `app/http-interceptors/upload-interceptor.ts`
The `UploadInterceptor` in `app/http-interceptors/upload-interceptor.ts`
intercepts and short-circuits upload requests
by returning an observable of simulated events.
@ -911,45 +910,44 @@ In order to prevent collisions in environments where multiple Angular apps share
<div class="alert is-important">
*Note that `HttpClient` supports only the client half of the XSRF protection scheme.*
Your backend service must be configured to set the cookie for your page, and to verify that
the header is present on all eligible requests.
*Note that `HttpClient` supports only the client half of the XSRF protection scheme.*
Your backend service must be configured to set the cookie for your page, and to verify that
the header is present on all eligible requests.
If not, Angular's default protection will be ineffective.
</div>
### Configuring custom cookie/header names
If your backend service uses different names for the XSRF token cookie or header,
If your backend service uses different names for the XSRF token cookie or header,
use `HttpClientXsrfModule.withOptions()` to override the defaults.
<code-example
<code-example
path="http/src/app/app.module.ts"
region="xsrf"
linenums="false">
region="xsrf">
</code-example>
## Testing HTTP requests
Like any external dependency, the HTTP backend needs to be mocked
so your tests can simulate interaction with a remote server.
The `@angular/common/http/testing` library makes
so your tests can simulate interaction with a remote server.
The `@angular/common/http/testing` library makes
setting up such mocking straightforward.
### Mocking philosophy
Angular's HTTP testing library is designed for a pattern of testing wherein
Angular's HTTP testing library is designed for a pattern of testing wherein
the app executes code and makes requests first.
Then a test expects that certain requests have or have not been made,
performs assertions against those requests,
Then a test expects that certain requests have or have not been made,
performs assertions against those requests,
and finally provide responses by "flushing" each expected request.
At the end, tests may verify that the app has made no unexpected requests.
<div class="alert is-helpful">
You can run <live-example stackblitz="specs">these sample tests</live-example>
You can run <live-example stackblitz="specs">these sample tests</live-example>
in a live coding environment.
The tests described in this guide are in `src/testing/http-client.spec.ts`.
@ -960,23 +958,23 @@ There are also tests of an application data service that call `HttpClient` in
### Setup
To begin testing calls to `HttpClient`,
To begin testing calls to `HttpClient`,
import the `HttpClientTestingModule` and the mocking controller, `HttpTestingController`,
along with the other symbols your tests require.
<code-example
<code-example
path="http/src/testing/http-client.spec.ts"
region="imports"
header="app/testing/http-client.spec.ts (imports)" linenums="false">
region="imports"
header="app/testing/http-client.spec.ts (imports)">
</code-example>
Then add the `HttpClientTestingModule` to the `TestBed` and continue with
the setup of the _service-under-test_.
<code-example
<code-example
path="http/src/testing/http-client.spec.ts"
region="setup"
header="app/testing/http-client.spec.ts(setup)" linenums="false">
region="setup"
header="app/testing/http-client.spec.ts(setup)">
</code-example>
Now requests made in the course of your tests will hit the testing backend instead of the normal backend.
@ -986,47 +984,44 @@ so they can be referenced during the tests.
### Expecting and answering requests
Now you can write a test that expects a GET Request to occur and provides a mock response.
Now you can write a test that expects a GET Request to occur and provides a mock response.
<code-example
<code-example
path="http/src/testing/http-client.spec.ts"
region="get-test"
header="app/testing/http-client.spec.ts(httpClient.get)" linenums="false">
region="get-test"
header="app/testing/http-client.spec.ts(httpClient.get)">
</code-example>
The last step, verifying that no requests remain outstanding, is common enough for you to move it into an `afterEach()` step:
<code-example
<code-example
path="http/src/testing/http-client.spec.ts"
region="afterEach"
linenums="false">
region="afterEach">
</code-example>
#### Custom request expectations
If matching by URL isn't sufficient, it's possible to implement your own matching function.
If matching by URL isn't sufficient, it's possible to implement your own matching function.
For example, you could look for an outgoing request that has an authorization header:
<code-example
<code-example
path="http/src/testing/http-client.spec.ts"
region="predicate"
linenums="false">
region="predicate">
</code-example>
As with the previous `expectOne()`,
As with the previous `expectOne()`,
the test will fail if 0 or 2+ requests satisfy this predicate.
#### Handling more than one request
If you need to respond to duplicate requests in your test, use the `match()` API instead of `expectOne()`.
It takes the same arguments but returns an array of matching requests.
Once returned, these requests are removed from future matching and
It takes the same arguments but returns an array of matching requests.
Once returned, these requests are removed from future matching and
you are responsible for flushing and verifying them.
<code-example
<code-example
path="http/src/testing/http-client.spec.ts"
region="multi-request"
linenums="false">
region="multi-request">
</code-example>
### Testing for errors
@ -1035,16 +1030,14 @@ You should test the app's defenses against HTTP requests that fail.
Call `request.flush()` with an error message, as seen in the following example.
<code-example
<code-example
path="http/src/testing/http-client.spec.ts"
region="404"
linenums="false">
region="404">
</code-example>
Alternatively, you can call `request.error()` with an `ErrorEvent`.
<code-example
path="http/src/testing/http-client.spec.ts"
region="network-error"
linenums="false">
region="network-error">
</code-example>

View File

@ -10,8 +10,8 @@ an AOT-compiled app, translated into French.
{@a angular-i18n}
## Angular and i18n
*Internationalization* is the process of designing and preparing your app to be usable in different languages.
*Localization* is the process of translating your internationalized app into specific languages for particular locales.
*Internationalization* is the process of designing and preparing your app to be usable in different languages.
*Localization* is the process of translating your internationalized app into specific languages for particular locales.
Angular simplifies the following aspects of internationalization:
* Displaying dates, number, percentages, and currencies in a local format.
@ -19,7 +19,7 @@ Angular simplifies the following aspects of internationalization:
* Handling plural forms of words.
* Handling alternative text.
For localization, you can use the [Angular CLI](cli) to generate most of the boilerplate necessary to create files for translators, and to publish your app in multiple languages.
For localization, you can use the [Angular CLI](cli) to generate most of the boilerplate necessary to create files for translators, and to publish your app in multiple languages.
After you have set up your app to use i18n, the CLI can help you with the following steps:
* Extracting localizable text into a file that you can send out to be translated.
* Building and serving the app for a given locale, using the translated text.
@ -85,8 +85,7 @@ The CLI imports the locale data for you when you use the parameter `--configurat
If you want to import locale data for other languages, you can do it manually:
<code-example path="i18n/doc-files/app.locale_data.ts" region="import-locale" header="src/app/app.module.ts" linenums="false">
</code-example>
<code-example path="i18n/doc-files/app.locale_data.ts" region="import-locale" header="src/app/app.module.ts"></code-example>
The first parameter is an object containing the locale data imported from `@angular/common/locales`.
By default, the imported locale data is registered with the locale id that is defined in the Angular
@ -100,8 +99,7 @@ The files in `@angular/common/locales` contain most of the locale data that you
need, but some advanced formatting options might only be available in the extra dataset that you can
import from `@angular/common/locales/extra`. An error message informs you when this is the case.
<code-example path="i18n/doc-files/app.locale_data_extra.ts" region="import-locale-extra" header="src/app/app.module.ts" linenums="false">
</code-example>
<code-example path="i18n/doc-files/app.locale_data_extra.ts" region="import-locale-extra" header="src/app/app.module.ts"></code-example>
<div class="alert is-helpful">
@ -132,9 +130,9 @@ The i18n template translation process has four phases:
* `--i18nFile`=*path to the translation file*
* `--i18nFormat`=*format of the translation file*
* `--i18nLocale`= *locale id*
* `--i18nLocale`= *locale id*
The command replaces the original messages with translated text, and generates a new version of the app in the target language.
The command replaces the original messages with translated text, and generates a new version of the app in the target language.
You need to build and deploy a separate version of the app for each supported language.
@ -146,13 +144,11 @@ text is to be translated.
In the example below, an `<h1>` tag displays a simple English language greeting, "Hello i18n!"
<code-example path="i18n/doc-files/app.component.html" region="greeting" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/doc-files/app.component.html" region="greeting" header="src/app/app.component.html"></code-example>
To mark the greeting for translation, add the `i18n` attribute to the `<h1>` tag.
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute" header="src/app/app.component.html"></code-example>
<div class="alert is-helpful">
@ -171,8 +167,7 @@ To translate a text message accurately, the translator may need additional infor
You can add a description of the text message as the value of the `i18n` attribute, as shown in the
example below:
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute-desc" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute-desc" header="src/app/app.component.html"></code-example>
The translator may also need to know the meaning or intent of the text message within this particular
app context.
@ -180,8 +175,7 @@ app context.
You add context by beginning the `i18n` attribute value with the _meaning_ and
separating it from the _description_ with the `|` character: `<meaning>|<description>`
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute-meaning" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/doc-files/app.component.html" region="i18n-attribute-meaning" header="src/app/app.component.html"></code-example>
All occurrences of a text message that have the same meaning will have the same translation.
A text message that is associated with different meanings can have different translations.
@ -199,8 +193,7 @@ text messages with different descriptions (not different meanings), then they ar
The angular i18n extractor tool generates a file with a translation unit entry for each `i18n`
attribute in a template. By default, it assigns each translation unit a unique id such as this one:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="generated-id" linenums="false">
</code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="generated-id"></code-example>
When you change the translatable text, the extractor tool generates a new id for that translation unit.
You must then update the translation file with the new id.
@ -208,14 +201,12 @@ You must then update the translation file with the new id.
Alternatively, you can specify a custom id in the `i18n` attribute by using the prefix `@@`.
The example below defines the custom id `introductionHeader`:
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-solo-id' header='app/app.component.html' linenums="false">
</code-example>
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-solo-id' header='app/app.component.html'></code-example>
When you specify a custom id, the extractor tool and compiler generate a translation unit with that
custom id.
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="custom-id" linenums="false">
</code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="custom-id"></code-example>
The custom id is persistent. The extractor tool does not change it when the translatable text changes.
Therefore, you do not need to update the translation. This approach makes maintenance easier.
@ -226,13 +217,11 @@ You can use a custom id in combination with a description by including both in t
`i18n` attribute. In the example below, the `i18n` attribute value includes a description, followed
by the custom `id`:
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-id' header='app/app.component.html' linenums="false">
</code-example>
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-id' header='app/app.component.html'></code-example>
You also can add a meaning, as shown in this example:
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-meaning-and-id' header='app/app.component.html' linenums="false">
</code-example>
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-meaning-and-id' header='app/app.component.html'></code-example>
#### Define unique custom ids
@ -275,8 +264,7 @@ However, if you don't want to create a new DOM element merely to facilitate tran
you can wrap the text in an `<ng-container>` element.
The `<ng-container>` is transformed into an html comment:
<code-example path="i18n/src/app/app.component.html" region="i18n-ng-container" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/src/app/app.component.html" region="i18n-ng-container" header="src/app/app.component.html"></code-example>
{@a translate-attributes}
### Translate attributes
@ -284,15 +272,13 @@ The `<ng-container>` is transformed into an html comment:
Displayed text is sometimes supplied as the value of an attribute, rather than the content of tag.
For example, if your template has an image with a `title` attribute, the text value of the `title` attribute needs to be translated.
<code-example path="i18n/doc-files/app.component.html" region="i18n-title" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/doc-files/app.component.html" region="i18n-title" header="src/app/app.component.html"></code-example>
To mark an attribute for translation, add an attribute in the form of `i18n-x`,
where `x` is the name of the attribute to translate. The following example shows how to mark the
`title` attribute for translation by adding the `i18n-title` attribute on the `img` tag:
<code-example path="i18n/src/app/app.component.html" region="i18n-title-translate" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/src/app/app.component.html" region="i18n-title-translate" header="src/app/app.component.html"></code-example>
This technique works for any attribute of any element.
@ -301,8 +287,8 @@ syntax.
## Regular expressions for plurals and selections
Different languages have different pluralization rules and grammatical constructions that add
complexity to the translation task.
Different languages have different pluralization rules and grammatical constructions that add
complexity to the translation task.
You can use regular expressions with the `plural` and `select` clauses to provide patterns that aid translation in these cases.
{@a plural-ICU}
@ -316,8 +302,7 @@ Other languages might express the cardinality differently.
The example below shows how to use a `plural` ICU expression to display one of those three options
based on when the update occurred:
<code-example path="i18n/src/app/app.component.html" region="i18n-plural" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/src/app/app.component.html" region="i18n-plural" header="src/app/app.component.html"></code-example>
* The first parameter is the key. It is bound to the component property (`minutes`), which determines
the number of minutes.
@ -372,8 +357,7 @@ The following format message in the component template binds to the component's
which outputs one of the following string values: "male", "female" or "other".
The message maps those values to the appropriate translations:
<code-example path="i18n/src/app/app.component.html" region="i18n-select" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/src/app/app.component.html" region="i18n-select" header="src/app/app.component.html"></code-example>
{@a nesting-ICUS}
### Nesting plural and select ICU expressions
@ -395,7 +379,7 @@ Open a terminal window at the root of the app project and run the CLI command `x
ng xi18n
</code-example>
By default, the command creates a file named `messages.xlf` in your `src/` folder.
By default, the command creates a file named `messages.xlf` in your `src/` folder.
<div class="alert is-helpful">
@ -411,7 +395,7 @@ For more information, see the [Angular Ahead-of-Time Webpack Plugin documentatio
{@a other-formats}
### Output options
You can supply command options to change the format, the name, the location, and the source locale of the extracted file.
You can supply command options to change the format, the name, the location, and the source locale of the extracted file.
For example, to create a file in the `src/locale` folder, specify the output path:
<code-example language="sh" class="code-shell">
@ -472,7 +456,7 @@ file. This information is not used by Angular, but external translation tools ma
The `ng xi18n` command generates a translation source file named `messages.xlf` in the project `src`
folder.
The next step is to translate the display strings in this source file into language-specific
The next step is to translate the display strings in this source file into language-specific
translation files. The example in this guide creates a French translation file.
{@a localization-folder}
@ -518,8 +502,7 @@ This sample file is easy to translate without a special editor or knowledge of F
1. Open `messages.fr.xlf` and find the first `<trans-unit>` section:
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello-before" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello-before" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)"></code-example>
> This XML element represents the translation of the `<h1>` greeting tag that you marked with the
`i18n` attribute earlier in this guide.
@ -534,13 +517,11 @@ This sample file is easy to translate without a special editor or knowledge of F
and context provided by the source, description, and meaning elements to guide your selection of
the appropriate French translation.
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;, after translation)" linenums="false">
</code-example>
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;, after translation)"></code-example>
3. Translate the other text nodes the same way:
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-other-nodes" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-other-nodes" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)"></code-example>
<div class="alert is-important">
@ -566,8 +547,7 @@ must be just below the translation unit for the logo.
To translate a `plural`, translate its ICU format match values:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-plural" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-plural" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)"></code-example>
You can add or remove plural cases, with each language having its own cardinality. (See
[CLDR plural rules](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html).)
@ -577,8 +557,7 @@ You can add or remove plural cases, with each language having its own cardinalit
Below is the content of our example `select` ICU expression in the component template:
<code-example path="i18n/src/app/app.component.html" region="i18n-select" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="i18n/src/app/app.component.html" region="i18n-select" header="src/app/app.component.html"></code-example>
The extraction tool broke that into two translation units because ICU expressions are extracted
separately.
@ -588,19 +567,16 @@ In place of the `select` is a placeholder, `<x id="ICU">`, that represents the `
Translate the text and move around the placeholder if necessary, but don't remove it. If you remove
the placeholder, the ICU expression will not be present in your translated app.
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-select-1" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-select-1" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)"></code-example>
The second translation unit, immediately below the first one, contains the `select` message.
Translate that as well.
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-select-2" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-select-2" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)"></code-example>
Here they are together, after translation:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-select" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-select" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)"></code-example>
{@a translate-nested}
### Translate a nested expression
@ -608,18 +584,15 @@ Here they are together, after translation:
A nested expression is similar to the previous examples. As in the previous example, there are
two translation units. The first one contains the text outside of the nested expression:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested-1" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested-1" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)"></code-example>
The second unit contains the complete nested expression:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested-2" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested-2" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)"></code-example>
And both together:
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)" linenums="false">
</code-example>
<code-example path="i18n/doc-files/messages.fr.xlf.html" region="translate-nested" header="src/locale/messages.fr.xlf (&lt;trans-unit&gt;)"></code-example>
The entire template translation is complete. The next section describes how to load that translation
into the app.
@ -783,8 +756,7 @@ behavior of the compiler. You can use it to specify the translation providers:
Then provide the `LOCALE_ID` in the main module:
<code-example path="i18n/doc-files/app.module.ts" header="src/app/app.module.ts" linenums="false">
</code-example>
<code-example path="i18n/doc-files/app.module.ts" header="src/app/app.module.ts"></code-example>
{@a missing-translation}
@ -837,4 +809,4 @@ For example, if the French version of your application is served from https://my
}
```
For more details about how to create scripts to generate an app in multiple languages and how to set up Apache 2 to serve them from different subdirectories, read [this tutorial by Philippe Martin](https://medium.com/@feloy/deploying-an-i18n-angular-app-with-angular-cli-fc788f17e358#.1xq4iy6fp).
For more details about how to create scripts to generate an app in multiple languages and how to set up Apache 2 and NGINX to serve them from different subdirectories, read [this tutorial by Philippe Martin](https://dev.to/angular/deploying-an-i18n-angular-app-with-angular-cli-2fb9).

View File

@ -1,23 +1,13 @@
# Lazy Loading Feature Modules
#### Prerequisites
A basic understanding of the following:
* [Feature Modules](guide/feature-modules).
* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
* [Frequently Used Modules](guide/frequent-ngmodules).
* [Types of Feature Modules](guide/module-types).
* [Routing and Navigation](guide/router).
For the final sample app with two lazy loaded modules that this page describes, see the
<live-example></live-example>.
<hr>
## High level view
By default, NgModules are eagerly loaded, which means that as soon as the app loads, so do all the NgModules, whether or not they are immediately necessary. For large apps with lots of routes, consider lazy loading&mdash;a design pattern that loads NgModules as needed. Lazy loading helps keep initial
bundle sizes smaller, which in turn helps decrease load times.
For the final sample app with two lazy loaded modules that this page describes, see the
<live-example></live-example>.
There are three main steps to setting up a lazy loaded feature module:
1. Create the feature module.
@ -98,9 +88,7 @@ placeholder markup in `app.component.html` with a custom nav
so you can easily navigate to your modules in the browser:
<code-example path="lazy-loading-ngmodules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="lazy-loading-ngmodules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
@ -138,9 +126,7 @@ Each feature module acts as a doorway via the router. In the `AppRoutingModule`,
In `AppRoutingModule`, update the `routes` array with the following:
<code-example path="lazy-loading-ngmodules/src/app/app-routing.module.ts" region="const-routes" header="src/app/app-routing.module.ts" linenums="false">
</code-example>
<code-example path="lazy-loading-ngmodules/src/app/app-routing.module.ts" region="const-routes" header="src/app/app-routing.module.ts"></code-example>
The import statements stay the same. The first two paths are the routes to the `CustomersModule` and the `OrdersModule` respectively. Notice that the lazy loading syntax uses `loadChildren` followed by a function that uses the browser's built-in `import('...')` syntax for dynamic imports. The import path is the relative path to the module.
@ -150,9 +136,7 @@ The import statements stay the same. The first two paths are the routes to the `
Next, take a look at `customers.module.ts`. If youre using the CLI and following the steps outlined in this page, you dont have to do anything here. The feature module is like a connector between the `AppRoutingModule` and the feature routing module. The `AppRoutingModule` imports the feature module, `CustomersModule`, and `CustomersModule` in turn imports the `CustomersRoutingModule`.
<code-example path="lazy-loading-ngmodules/src/app/customers/customers.module.ts" region="customers-module" header="src/app/customers/customers.module.ts" linenums="false">
</code-example>
<code-example path="lazy-loading-ngmodules/src/app/customers/customers.module.ts" region="customers-module" header="src/app/customers/customers.module.ts"></code-example>
@ -163,18 +147,14 @@ The `customers.module.ts` file imports the `CustomersRoutingModule` and `Custome
The next step is in `customers-routing.module.ts`. First, import the component at the top of the file with the other JavaScript import statements. Then, add the route to `CustomerListComponent`.
<code-example path="lazy-loading-ngmodules/src/app/customers/customers-routing.module.ts" region="customers-routing-module" header="src/app/customers/customers-routing.module.ts" linenums="false">
</code-example>
<code-example path="lazy-loading-ngmodules/src/app/customers/customers-routing.module.ts" region="customers-routing-module" header="src/app/customers/customers-routing.module.ts"></code-example>
Notice that the `path` is set to an empty string. This is because the path in `AppRoutingModule` is already set to `customers`, so this route in the `CustomersRoutingModule`, is already within the `customers` context. Every route in this routing module is a child route.
Repeat this last step of importing the `OrdersListComponent` and configuring the Routes array for the `orders-routing.module.ts`:
<code-example path="lazy-loading-ngmodules/src/app/orders/orders-routing.module.ts" region="orders-routing-module-detail" header="src/app/orders/orders-routing.module.ts (excerpt)" linenums="false">
</code-example>
<code-example path="lazy-loading-ngmodules/src/app/orders/orders-routing.module.ts" region="orders-routing-module-detail" header="src/app/orders/orders-routing.module.ts (excerpt)"></code-example>
Now, if you view the app in the browser, the three buttons take you to each module.

View File

@ -23,7 +23,7 @@ Each interface has a single hook method whose name is the interface name prefixe
For example, the `OnInit` interface has a hook method named `ngOnInit()`
that Angular calls shortly after creating the component:
<code-example path="lifecycle-hooks/src/app/peek-a-boo.component.ts" region="ngOnInit" header="peek-a-boo.component.ts (excerpt)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/peek-a-boo.component.ts" region="ngOnInit" header="peek-a-boo.component.ts (excerpt)"></code-example>
No directive or component will implement all of the lifecycle hooks.
Angular only calls a directive/component hook method *if it is defined*.
@ -339,13 +339,13 @@ The heroes will never know they're being watched.
The sneaky spy directive is simple, consisting almost entirely of `ngOnInit()` and `ngOnDestroy()` hooks
that log messages to the parent via an injected `LoggerService`.
<code-example path="lifecycle-hooks/src/app/spy.directive.ts" region="spy-directive" header="src/app/spy.directive.ts" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/spy.directive.ts" region="spy-directive" header="src/app/spy.directive.ts"></code-example>
You can apply the spy to any native or component element and it'll be initialized and destroyed
at the same time as that element.
Here it is attached to the repeated hero `<div>`:
<code-example path="lifecycle-hooks/src/app/spy.component.html" region="template" header="src/app/spy.component.html" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/spy.component.html" region="template" header="src/app/spy.component.html"></code-example>
Each spy's birth and death marks the birth and death of the attached hero `<div>`
with an entry in the *Hook Log* as seen here:
@ -425,7 +425,7 @@ You risk memory leaks if you neglect to do so.
Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive).
This example monitors the `OnChanges` hook.
<code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="ng-on-changes" header="on-changes.component.ts (excerpt)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="ng-on-changes" header="on-changes.component.ts (excerpt)"></code-example>
The `ngOnChanges()` method takes an object that maps each changed property name to a
[SimpleChange](api/core/SimpleChange) object holding the current and previous property values.
@ -433,7 +433,7 @@ This hook iterates over the changed properties and logs them.
The example component, `OnChangesComponent`, has two input properties: `hero` and `power`.
<code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="inputs" header="src/app/on-changes.component.ts" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="inputs" header="src/app/on-changes.component.ts"></code-example>
The host `OnChangesParentComponent` binds to them like this:
@ -468,7 +468,7 @@ Use the `DoCheck` hook to detect and act upon changes that Angular doesn't catch
The *DoCheck* sample extends the *OnChanges* sample with the following `ngDoCheck()` hook:
<code-example path="lifecycle-hooks/src/app/do-check.component.ts" region="ng-do-check" header="DoCheckComponent (ngDoCheck)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/do-check.component.ts" region="ng-do-check" header="DoCheckComponent (ngDoCheck)"></code-example>
This code inspects certain _values of interest_, capturing and comparing their current state against previous values.
It writes a special message to the log when there are no substantive changes to the `hero` or the `power`
@ -497,25 +497,25 @@ The *AfterView* sample explores the `AfterViewInit()` and `AfterViewChecked()` h
Here's a child view that displays a hero's name in an `<input>`:
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="child-view" header="ChildComponent" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="child-view" header="ChildComponent"></code-example>
The `AfterViewComponent` displays this child view *within its template*:
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="template" header="AfterViewComponent (template)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="template" header="AfterViewComponent (template)"></code-example>
The following hooks take action based on changing values *within the child view*,
which can only be reached by querying for the child view via the property decorated with
[@ViewChild](api/core/ViewChild).
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="hooks" header="AfterViewComponent (class excerpts)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="hooks" header="AfterViewComponent (class excerpts)"></code-example>
{@a wait-a-tick}
### Abide by the unidirectional data flow rule
The `doSomething()` method updates the screen when the hero name exceeds 10 characters.
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="do-something" header="AfterViewComponent (doSomething)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="do-something" header="AfterViewComponent (doSomething)"></code-example>
Why does the `doSomething()` method wait a tick before updating `comment`?
@ -559,7 +559,7 @@ Consider this variation on the [previous _AfterView_](guide/lifecycle-hooks#afte
This time, instead of including the child view within the template, it imports the content from
the `AfterContentComponent`'s parent. Here's the parent's template:
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="parent-template" header="AfterContentParentComponent (template excerpt)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="parent-template" header="AfterContentParentComponent (template excerpt)"></code-example>
Notice that the `<app-child>` tag is tucked between the `<after-content>` tags.
Never put content between a component's element tags *unless you intend to project that content
@ -567,7 +567,7 @@ into the component*.
Now look at the component's template:
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="template" header="AfterContentComponent (template)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="template" header="AfterContentComponent (template)"></code-example>
The `<ng-content>` tag is a *placeholder* for the external content.
It tells Angular where to insert that content.
@ -603,7 +603,7 @@ The following *AfterContent* hooks take action based on changing values in a *co
which can only be reached by querying for them via the property decorated with
[@ContentChild](api/core/ContentChild).
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="hooks" header="AfterContentComponent (class excerpts)" linenums="false"></code-example>
<code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="hooks" header="AfterContentComponent (class excerpts)"></code-example>
{@a no-unidirectional-flow-worries}

View File

@ -1,16 +1,5 @@
# Types of Feature Modules
#### Prerequisites
A basic understanding of the following concepts:
* [Feature Modules](guide/feature-modules).
* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
* [Frequently Used Modules](guide/frequent-ngmodules).
<hr>
There are five general categories of feature modules which
tend to fall into the following groups:

View File

@ -1,15 +1,5 @@
# NgModule API
#### Prerequisites
A basic understanding of the following concepts:
* [Bootstrapping](guide/bootstrapping).
* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
<hr />
## Purpose of `@NgModule`
At a high level, NgModules are a way to organize Angular apps
and they accomplish this through the metadata in the `@NgModule`
decorator.

View File

@ -1,13 +1,5 @@
# NgModule FAQs
#### Prerequisites:
A basic understanding of the following concepts:
* [NgModules](guide/ngmodules).
<hr />
NgModules help organize an application into cohesive blocks of functionality.
This page answers the questions many developers ask about NgModule design and implementation.
@ -478,8 +470,7 @@ You can throw an error or take other remedial action.
Certain NgModules, such as `BrowserModule`, implement such a guard.
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)" linenums="false">
</code-example>
<code-example path="ngmodules/src/app/greeting/greeting.module.ts" region="ctor" header="src/app/greeting/greeting.module.ts (Constructor)"></code-example>
<hr/>

View File

@ -1,13 +1,9 @@
# JavaScript Modules vs. NgModules
#### Prerequisites
A basic understanding of [JavaScript/ECMAScript modules](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/).
<hr>
JavaScript and Angular use modules to organize code, and
though they organize it differently, Angular apps rely on both.
## JavaScript modules
In JavaScript, modules are individual files with JavaScript code in them. To make whats in them available, you write an export statement, usually after the relevant code, like this:
@ -24,6 +20,8 @@ import { AppComponent } from './app.component';
JavaScript modules help you namespace, preventing accidental global variables.
For more information on JavaScript modules, see [JavaScript/ECMAScript modules](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/).
## NgModules
<!-- KW-- perMisko: let's discuss. This does not answer the question why it is different. Also, last sentence is confusing.-->

View File

@ -1,13 +1,5 @@
# NgModules
#### Prerequisites
A basic understanding of the following concepts:
* [Bootstrapping](guide/bootstrapping).
* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
<hr>
**NgModules** configure the injector and the compiler and help organize related things together.
An NgModule is a class marked by the `@NgModule` decorator.
@ -20,7 +12,6 @@ For an example app showcasing all the techniques that NgModules related pages
cover, see the <live-example></live-example>. For explanations on the individual techniques, visit the relevant NgModule pages under the NgModules
section.
## Angular modularity
Modules are a great way to organize an application and extend it with capabilities from external libraries.
@ -57,12 +48,14 @@ You then import these modules into the root module.
## The basic NgModule
The [Angular CLI](cli) generates the following basic app module when creating a new app.
The [Angular CLI](cli) generates the following basic `AppModule` when creating a new app.
<code-example path="bootstrapping/src/app/app.module.ts" region="whole-ngmodule" header="src/app/app.module.ts" linenums="false">
<code-example path="ngmodules/src/app/app.module.1.ts" header="src/app/app.module.ts (default AppModule)">
// @NgModule decorator with its metadata
</code-example>
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`). This page builds on [Bootstrapping](guide/bootstrapping), which covers the structure of an NgModule in detail. If you need more information on the structure of an `@NgModule`, be sure to read [Bootstrapping](guide/bootstrapping).
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 />

View File

@ -26,18 +26,14 @@ In this page, you'll use pipes to transform a component's birthday property into
a human-friendly date.
<code-example path="pipes/src/app/hero-birthday1.component.ts" header="src/app/hero-birthday1.component.ts" linenums="false">
</code-example>
<code-example path="pipes/src/app/hero-birthday1.component.ts" header="src/app/hero-birthday1.component.ts"></code-example>
Focus on the component's template.
<code-example path="pipes/src/app/app.component.html" region="hero-birthday-template" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="pipes/src/app/app.component.html" region="hero-birthday-template" header="src/app/app.component.html"></code-example>
@ -79,9 +75,7 @@ Modify the birthday template to give the date pipe a format parameter.
After formatting the hero's April 15th birthday, it renders as **<samp>04/15/88</samp>**:
<code-example path="pipes/src/app/app.component.html" region="format-birthday" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="pipes/src/app/app.component.html" region="format-birthday" header="src/app/app.component.html"></code-example>
@ -95,9 +89,7 @@ Write a second component that *binds* the pipe's format parameter
to the component's `format` property. Here's the template for that component:
<code-example path="pipes/src/app/hero-birthday2.component.ts" region="template" header="src/app/hero-birthday2.component.ts (template)" linenums="false">
</code-example>
<code-example path="pipes/src/app/hero-birthday2.component.ts" region="template" header="src/app/hero-birthday2.component.ts (template)"></code-example>
@ -106,9 +98,7 @@ That method toggles the component's `format` property between a short form
(`'shortDate'`) and a longer form (`'fullDate'`).
<code-example path="pipes/src/app/hero-birthday2.component.ts" region="class" header="src/app/hero-birthday2.component.ts (class)" linenums="false">
</code-example>
<code-example path="pipes/src/app/hero-birthday2.component.ts" region="class" header="src/app/hero-birthday2.component.ts (class)"></code-example>
@ -143,9 +133,7 @@ the birthday is chained to the `DatePipe` and on to the `UpperCasePipe`.
The birthday displays as **<samp>APR 15, 1988</samp>**.
<code-example path="pipes/src/app/app.component.html" region="chained-birthday" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="pipes/src/app/app.component.html" region="chained-birthday" header="src/app/app.component.html"></code-example>
@ -153,9 +141,7 @@ This example&mdash;which displays **<samp>FRIDAY, APRIL 15, 1988</samp>**&mdash;
the same pipes as above, but passes in a parameter to `date` as well.
<code-example path="pipes/src/app/app.component.html" region="chained-parameter-birthday" header="src/app/app.component.html" linenums="false">
</code-example>
<code-example path="pipes/src/app/app.component.html" region="chained-parameter-birthday" header="src/app/app.component.html"></code-example>
@ -166,9 +152,7 @@ You can write your own custom pipes.
Here's a custom pipe named `ExponentialStrengthPipe` that can boost a hero's powers:
<code-example path="pipes/src/app/exponential-strength.pipe.ts" header="src/app/exponential-strength.pipe.ts" linenums="false">
</code-example>
<code-example path="pipes/src/app/exponential-strength.pipe.ts" header="src/app/exponential-strength.pipe.ts"></code-example>
@ -200,8 +184,7 @@ Technically, it's optional; Angular looks for and executes the `transform` metho
Now you need a component to demonstrate the pipe.
<code-example path="pipes/src/app/power-booster.component.ts" header="src/app/power-booster.component.ts" linenums="false">
</code-example>
<code-example path="pipes/src/app/power-booster.component.ts" header="src/app/power-booster.component.ts"></code-example>
<figure>
<img src='generated/images/guide/pipes/power-booster.png' alt="Power Booster">
@ -271,17 +254,13 @@ In the next example, the component uses the default, aggressive change detection
its display of every hero in the `heroes` array. Here's the template:
<code-example path="pipes/src/app/flying-heroes.component.html" region="template-1" header="src/app/flying-heroes.component.html (v1)" linenums="false">
</code-example>
<code-example path="pipes/src/app/flying-heroes.component.html" region="template-1" header="src/app/flying-heroes.component.html (v1)"></code-example>
The companion component class provides heroes, adds heroes into the array, and can reset the array.
<code-example path="pipes/src/app/flying-heroes.component.ts" region="v1" header="src/app/flying-heroes.component.ts (v1)" linenums="false">
</code-example>
<code-example path="pipes/src/app/flying-heroes.component.ts" region="v1" header="src/app/flying-heroes.component.ts (v1)"></code-example>
@ -293,17 +272,13 @@ If you added the ability to remove or change a hero, Angular would detect those
Add a `FlyingHeroesPipe` to the `*ngFor` repeater that filters the list of heroes to just those heroes who can fly.
<code-example path="pipes/src/app/flying-heroes.component.html" region="template-flying-heroes" header="src/app/flying-heroes.component.html (flyers)" linenums="false">
</code-example>
<code-example path="pipes/src/app/flying-heroes.component.html" region="template-flying-heroes" header="src/app/flying-heroes.component.html (flyers)"></code-example>
Here's the `FlyingHeroesPipe` implementation, which follows the pattern for custom pipes described earlier.
<code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pure" header="src/app/flying-heroes.pipe.ts" linenums="false">
</code-example>
<code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pure" header="src/app/flying-heroes.pipe.ts"></code-example>
@ -315,9 +290,7 @@ It's just using a different change-detection algorithm that ignores changes to t
Notice how a hero is added:
<code-example path="pipes/src/app/flying-heroes.component.ts" region="push" header="src/app/flying-heroes.component.ts" linenums="false">
</code-example>
<code-example path="pipes/src/app/flying-heroes.component.ts" region="push" header="src/app/flying-heroes.component.ts"></code-example>
@ -365,9 +338,7 @@ You make a pipe impure by setting its pure flag to false. You could make the `Fl
impure like this:
<code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pipe-decorator" header="src/app/flying-heroes.pipe.ts" linenums="false">
</code-example>
<code-example path="pipes/src/app/flying-heroes.pipe.ts" region="pipe-decorator" header="src/app/flying-heroes.pipe.ts"></code-example>
@ -441,18 +412,14 @@ The only difference is the `pure` flag in the pipe metadata.
This is a good candidate for an impure pipe because the `transform` function is trivial and fast.
<code-example path="pipes/src/app/flying-heroes.pipe.ts" linenums="false" header="src/app/flying-heroes.pipe.ts (filter)" region="filter">
</code-example>
<code-example path="pipes/src/app/flying-heroes.pipe.ts" header="src/app/flying-heroes.pipe.ts (filter)" region="filter"></code-example>
You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`.
<code-example path="pipes/src/app/flying-heroes-impure.component.html" linenums="false" header="src/app/flying-heroes-impure.component.html (excerpt)" region="template-flying-heroes">
</code-example>
<code-example path="pipes/src/app/flying-heroes-impure.component.html" header="src/app/flying-heroes-impure.component.html (excerpt)" region="template-flying-heroes"></code-example>

View File

@ -1,16 +1,10 @@
# Providers
#### Prerequisites:
* A basic understanding of [Bootstrapping](guide/bootstrapping).
* Familiarity with [Frequently Used Modules](guide/frequent-ngmodules).
A provider is an instruction to the DI system on how to obtain a value for a dependency. Most of the time, these dependencies are services that you create and provide.
For the final sample app using the provider that this page describes,
see the <live-example></live-example>.
<hr>
A provider is an instruction to the DI system on how to obtain a value for a dependency. Most of the time, these dependencies are services that you create and provide.
## Providing a service
If you already have an app that was created with the [Angular CLI](cli), you can create a service using the [`ng generate`](cli/generate) CLI command in the root project directory. Replace _User_ with the name of your service.
@ -21,7 +15,7 @@ ng generate service User
This command creates the following `UserService` skeleton:
<code-example path="providers/src/app/user.service.0.ts" header="src/app/user.service.ts" linenums="false"> </code-example>
<code-example path="providers/src/app/user.service.0.ts" header="src/app/user.service.ts"></code-example>
You can now inject `UserService` anywhere in your application.
@ -38,11 +32,11 @@ You should always provide your service in the root injector unless there is a ca
It's also possible to specify that a service should be provided in a particular `@NgModule`. For example, if you don't want `UserService` to be available to applications unless they import a `UserModule` you've created, you can specify that the service should be provided in the module:
<code-example path="providers/src/app/user.service.1.ts" header="src/app/user.service.ts" linenums="false"> </code-example>
<code-example path="providers/src/app/user.service.1.ts" header="src/app/user.service.ts"></code-example>
The example above shows the preferred way to provide a service in a module. This method is preferred because it enables tree-shaking of the service if nothing injects it. If it's not possible to specify in the service which module should provide it, you can also declare a provider for the service within the module:
<code-example path="providers/src/app/user.module.ts" header="src/app/user.module.ts" linenums="false"> </code-example>
<code-example path="providers/src/app/user.module.ts" header="src/app/user.module.ts"></code-example>
## Limiting provider scope by lazy loading modules
@ -67,8 +61,7 @@ method is helpful for when you want to eagerly load a module that needs a servic
Providing a service in the component limits the service only to that component (other components in
the same module cant access it.)
<code-example path="providers/src/app/app.component.ts" region="component-providers" header="src/app/app.component.ts" linenums="false">
</code-example>
<code-example path="providers/src/app/app.component.ts" region="component-providers" header="src/app/app.component.ts"></code-example>
## Providing services in modules vs. components

View File

@ -12,7 +12,7 @@ Try the <live-example title="Reactive Forms in Stackblitz">Reactive Forms live-e
## Introduction to reactive forms
Reactive forms use an explicit and immutable approach to managing the state of a form at a given point in time. Each change to the form state returns a new state, which maintains the integrity of the model between changes. Reactive forms are built around observable streams, where form inputs and values are provided as streams of input values, which can be accessed synchronously.
Reactive forms use an explicit and immutable approach to managing the state of a form at a given point in time. Each change to the form state returns a new state, which maintains the integrity of the model between changes. Reactive forms are built around observable streams, where form inputs and values are provided as streams of input values, which can be accessed synchronously.
Reactive forms also provide a straightforward path to testing because you are assured that your data is consistent and predictable when requested. Any consumers of the streams have access to manipulate that data safely.
@ -26,11 +26,9 @@ This section describes how to add a single form control. In the example, the use
To use reactive forms, import `ReactiveFormsModule` from the `@angular/forms` package and add it to your NgModule's `imports` array.
<code-example path="reactive-forms/src/app/app.module.ts" region="imports" header="src/app/app.module.ts (excerpt)">
<code-example path="reactive-forms/src/app/app.module.ts" region="imports" header="src/app/app.module.ts (excerpt)"></code-example>
</code-example>
### Step 2: Generating and importing a new form control
### Step 2: Generating and importing a new form control
Generate a component for the control.
@ -42,19 +40,15 @@ Generate a component for the control.
The `FormControl` class is the basic building block when using reactive forms. To register a single form control, import the `FormControl` class into your component and create a new instance of the form control to save as a class property.
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.ts" region="create-control" header="src/app/name-editor/name-editor.component.ts">
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.ts" region="create-control" header="src/app/name-editor/name-editor.component.ts"></code-example>
</code-example>
Use the constructor of `FormControl` to set its initial value, which in this case is an empty string. By creating these controls in your component class, you get immediate access to listen for, update, and validate the state of the form input.
Use the constructor of `FormControl` to set its initial value, which in this case is an empty string. By creating these controls in your component class, you get immediate access to listen for, update, and validate the state of the form input.
### Step 3: Registering the control in the template
After you create the control in the component class, you must associate it with a form control element in the template. Update the template with the form control using the `formControl` binding provided by `FormControlDirective` included in `ReactiveFormsModule`.
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="control-binding" linenums="false" header="src/app/name-editor/name-editor.component.html">
</code-example>
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="control-binding" header="src/app/name-editor/name-editor.component.html"></code-example>
<div class="alert is-helpful">
@ -66,11 +60,9 @@ Using the template binding syntax, the form control is now registered to the `na
#### Displaying the component
The form control assigned to `name` is displayed when the component is added to a template.
The form control assigned to `name` is displayed when the component is added to a template.
<code-example path="reactive-forms/src/app/app.component.1.html" region="app-name-editor" linenums="false" header="src/app/app.component.html (name editor)">
</code-example>
<code-example path="reactive-forms/src/app/app.component.1.html" region="app-name-editor" header="src/app/app.component.html (name editor)"></code-example>
<figure>
<img src="generated/images/guide/reactive-forms/name-editor-1.png" alt="Name Editor">
@ -78,23 +70,21 @@ The form control assigned to `name` is displayed when the component is added to
## Managing control values
Reactive forms give you access to the form control state and value at a point in time. You can manipulate
Reactive forms give you access to the form control state and value at a point in time. You can manipulate
the current state and value through the component class or the component template. The following examples display the value of the form control instance and change it.
{@a display-value}
### Displaying a form control value
You can display the value in these ways:
You can display the value in these ways:
* Through the `valueChanges` observable where you can listen for changes in the form's value in the template using `AsyncPipe` or in the component class using the `subscribe()` method.
* With the `value` property. which gives you a snapshot of the current value.
* Through the `valueChanges` observable where you can listen for changes in the form's value in the template using `AsyncPipe` or in the component class using the `subscribe()` method.
* With the `value` property. which gives you a snapshot of the current value.
The following example shows you how to display the current value using interpolation in the template.
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="display-value" linenums="false" header="src/app/name-editor/name-editor.component.html (control value)">
</code-example>
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="display-value" header="src/app/name-editor/name-editor.component.html (control value)"></code-example>
The displayed value changes as you update the form control element.
@ -104,7 +94,7 @@ Read about other `FormControl` properties and methods in the [Reactive forms API
### Replacing a form control value
Reactive forms have methods to change a control's value programmatically, which gives you the flexibility to update the value without user interaction. A form control instance provides a `setValue()` method that updates the value of the form control and validates the structure of the value provided against the control's structure. For example, when retrieving form data from a backend API or service, use the `setValue()` method to update the control to its new value, replacing the old value entirely.
Reactive forms have methods to change a control's value programmatically, which gives you the flexibility to update the value without user interaction. A form control instance provides a `setValue()` method that updates the value of the form control and validates the structure of the value provided against the control's structure. For example, when retrieving form data from a backend API or service, use the `setValue()` method to update the control to its new value, replacing the old value entirely.
The following example adds a method to the component class to update the value of the control to *Nancy* using the `setValue()` method.
@ -112,11 +102,9 @@ The following example adds a method to the component class to update the value o
</code-example>
Update the template with a button to simulate a name update. When you click the **Update Name** button, the value entered in the form control element is reflected as its current value.
Update the template with a button to simulate a name update. When you click the **Update Name** button, the value entered in the form control element is reflected as its current value.
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="update-value" linenums="false" header="src/app/name-editor/name-editor.component.html (update value)">
</code-example>
<code-example path="reactive-forms/src/app/name-editor/name-editor.component.html" region="update-value" header="src/app/name-editor/name-editor.component.html (update value)"></code-example>
The form model is the source of truth for the control, so when you click the button, the value of the input is changed within the component class, overriding its current value.
@ -162,21 +150,17 @@ The individual form controls are now collected within a group. A `FormGroup` ins
A form group tracks the status and changes for each of its controls, so if one of the controls changes, the parent control also emits a new status or value change. The model for the group is maintained from its members. After you define the model, you must update the template to reflect the model in the view.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="formgroup" linenums="false" header="src/app/profile-editor/profile-editor.component.html (template form group)">
</code-example>
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="formgroup" header="src/app/profile-editor/profile-editor.component.html (template form group)"></code-example>
Note that just as a form group contains a group of controls, the *profile form* `FormGroup` is bound to the `form` element with the `FormGroup` directive, creating a communication layer between the model and the form containing the inputs. The `formControlName` input provided by the `FormControlName` directive binds each individual input to the form control defined in `FormGroup`. The form controls communicate with their respective elements. They also communicate changes to the form group instance, which provides the source of truth for the model value.
### Saving form data
The `ProfileEditor` component accepts input from the user, but in a real scenario you want to capture the form value and make available for further processing outside the component. The `FormGroup` directive listens for the `submit` event emitted by the `form` element and emits an `ngSubmit` event that you can bind to a callback function.
The `ProfileEditor` component accepts input from the user, but in a real scenario you want to capture the form value and make available for further processing outside the component. The `FormGroup` directive listens for the `submit` event emitted by the `form` element and emits an `ngSubmit` event that you can bind to a callback function.
Add an `ngSubmit` event listener to the `form` tag with the `onSubmit()` callback method.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="ng-submit" linenums="false" header="src/app/profile-editor/profile-editor.component.html (submit event)">
</code-example>
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="ng-submit" header="src/app/profile-editor/profile-editor.component.html (submit event)"></code-example>
The `onSubmit()` method in the `ProfileEditor` component captures the current value of `profileForm`. Use `EventEmitter` to keep the form encapsulated and to provide the form value outside the component. The following example uses `console.warn` to log a message to the browser console.
@ -184,13 +168,11 @@ The `onSubmit()` method in the `ProfileEditor` component captures the current va
</code-example>
The `submit` event is emitted by the `form` tag using the native DOM event. You trigger the event by clicking a button with `submit` type. This allows the user to press the **Enter** key to submit the completed form.
The `submit` event is emitted by the `form` tag using the native DOM event. You trigger the event by clicking a button with `submit` type. This allows the user to press the **Enter** key to submit the completed form.
Use a `button` element to add a button to the bottom of the form to trigger the form submission.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="submit-button" linenums="false" header="src/app/profile-editor/profile-editor.component.html (submit button)">
</code-example>
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="submit-button" header="src/app/profile-editor/profile-editor.component.html (submit button)"></code-example>
<div class="alert is-helpful">
@ -202,9 +184,7 @@ Use a `button` element to add a button to the bottom of the form to trigger the
To display the `ProfileEditor` component that contains the form, add it to a component template.
<code-example path="reactive-forms/src/app/app.component.1.html" region="app-profile-editor" linenums="false" header="src/app/app.component.html (profile editor)">
</code-example>
<code-example path="reactive-forms/src/app/app.component.1.html" region="app-profile-editor" header="src/app/app.component.html (profile editor)"></code-example>
`ProfileEditor` allows you to manage the form control instances for the `firstName` and `lastName` controls within the form group instance.
@ -220,9 +200,7 @@ When building complex forms, managing the different areas of information is easi
An address is a good example of information that can be grouped together. Form groups can accept both form control and form group instances as children. This makes composing complex form models easier to maintain and logically group together. To create a nested group in `profileForm`, add a nested `address` element to the form group instance.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="nested-formgroup" linenums="false" header="src/app/profile-editor/profile-editor.component.ts (nested form group)">
</code-example>
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="nested-formgroup" header="src/app/profile-editor/profile-editor.component.ts (nested form group)"></code-example>
In this example, `address group` combines the current `firstName` and `lastName` controls with the new `street`, `city`, `state`, and `zip` controls. Even though the `address` element in the form group is a child of the overall `profileForm` element in the form group, the same rules apply with value and status changes. Changes in status and value from the nested form group propagate to the parent form group, maintaining consistency with the overall model.
@ -232,9 +210,7 @@ After you update the model in the component class, update the template to connec
Add the `address` form group containing the `street`, `city`, `state`, and `zip` fields to the `ProfileEditor` template.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="formgroupname" linenums="false" header="src/app/profile-editor/profile-editor.component.html (template nested form group)">
</code-example>
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="formgroupname" header="src/app/profile-editor/profile-editor.component.html (template nested form group)"></code-example>
The `ProfileEditor` form is displayed as one group, but the model is broken down further to represent the logical grouping areas.
@ -254,11 +230,11 @@ When updating the value for a form group instance that contains multiple control
### Patching the model value
There are two ways to update the model value:
There are two ways to update the model value:
* Use the `setValue()` method to set a new value for an individual control. The `setValue()` method strictly adheres to the structure of the form group and replaces the entire value for the control.
* Use the `setValue()` method to set a new value for an individual control. The `setValue()` method strictly adheres to the structure of the form group and replaces the entire value for the control.
* Use the `patchValue()` method to replace any properties defined in the object that have changed in the form model.
* Use the `patchValue()` method to replace any properties defined in the object that have changed in the form model.
The strict checks of the `setValue()` method help catch nesting errors in complex forms, while `patchValue()` fails silently on those errors.
@ -270,15 +246,13 @@ In `ProfileEditorComponent`, use the `updateProfile` method with the example bel
Simulate an update by adding a button to the template to update the user profile on demand.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="patch-value" linenums="false" header="src/app/profile-editor/profile-editor.component.html (update value)">
</code-example>
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="patch-value" header="src/app/profile-editor/profile-editor.component.html (update value)"></code-example>
When a user clicks the button, the `profileForm` model is updated with new values for `firstName` and `street`. Notice that `street` is provided in an object inside the `address` property. This is necessary because the `patchValue()` method applies the update against the model structure. `PatchValue()` only updates properties that the form model defines.
## Generating form controls with FormBuilder
Creating form control instances manually can become repetitive when dealing with multiple forms. The `FormBuilder` service provides convenient methods for generating controls.
Creating form control instances manually can become repetitive when dealing with multiple forms. The `FormBuilder` service provides convenient methods for generating controls.
The following section refactors the `ProfileEditor` component to use the form builder service to create form control and form group instances.
@ -300,7 +274,7 @@ The `FormBuilder` service is an injectable provider that is provided with the re
### Step 3: Generating form controls
The `FormBuilder` service has three methods: `control()`, `group()`, and `array()`. These are factory methods for generating instances in your component classes including form controls, form groups, and form arrays.
The `FormBuilder` service has three methods: `control()`, `group()`, and `array()`. These are factory methods for generating instances in your component classes including form controls, form groups, and form arrays.
Use the `group` method to create the `profileForm` controls.
@ -321,7 +295,7 @@ Compare using the form builder to creating the instances manually.
<code-tabs>
<code-pane path="reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" region="formgroup-compare" header="src/app/profile-editor/profile-editor.component.ts (instances)">
</code-pane>
<code-pane path="reactive-forms/src/app/profile-editor/profile-editor.component.2.ts" region="formgroup-compare" header="src/app/profile-editor/profile-editor.component.ts (form builder)">
@ -356,9 +330,7 @@ In the `ProfileEditor` component, add the `Validators.required` static method as
HTML5 has a set of built-in attributes that you can use for native validation, including `required`, `minlength`, and `maxlength`. You can take advantage of these optional attributes on your form input elements. Add the `required` attribute to the `firstName` input element.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="required-attribute" linenums="false" header="src/app/profile-editor/profile-editor.component.html (required attribute)">
</code-example>
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="required-attribute" header="src/app/profile-editor/profile-editor.component.html (required attribute)"></code-example>
<div class="alert is-important">
@ -372,9 +344,7 @@ When you add a required field to the form control, its initial status is invalid
Display the current status of `profileForm` using interpolation.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="display-status" linenums="false" header="src/app/profile-editor/profile-editor.component.html (display status)">
</code-example>
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="display-status" header="src/app/profile-editor/profile-editor.component.html (display status)"></code-example>
<figure>
<img src="generated/images/guide/reactive-forms/profile-editor-3.png" alt="Profile Editor Validation">
@ -410,7 +380,7 @@ The aliases control in the form group instance is now populated with a single co
### Step 3: Accessing the FormArray control
A getter provides easy access to the aliases in the form array instance compared to repeating the `profileForm.get()` method to get each instance. The form array instance represents an undefined number of controls in an array. It's convenient to access a control through a getter, and this approach is easy to repeat for additional controls.
A getter provides easy access to the aliases in the form array instance compared to repeating the `profileForm.get()` method to get each instance. The form array instance represents an undefined number of controls in an array. It's convenient to access a control through a getter, and this approach is easy to repeat for additional controls.
Use the getter syntax to create an `aliases` class property to retrieve the alias's form array control from the parent form group.
@ -434,15 +404,13 @@ In the template, each control is displayed as a separate input field.
### Step 4: Displaying the form array in the template
To attach the aliases from your form model, you must add it to the template. Similar to the `formGroupName` input provided by `FormGroupNameDirective`, `formArrayName` binds communication from the form array instance to the template with `FormArrayNameDirective`.
To attach the aliases from your form model, you must add it to the template. Similar to the `formGroupName` input provided by `FormGroupNameDirective`, `formArrayName` binds communication from the form array instance to the template with `FormArrayNameDirective`.
Add the template HTML below after the `<div>` closing the `formGroupName` element.
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="formarrayname" linenums="false" header="src/app/profile-editor/profile-editor.component.html (aliases form array template)">
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.html" region="formarrayname" header="src/app/profile-editor/profile-editor.component.html (aliases form array template)"></code-example>
</code-example>
The `*ngFor` directive iterates over each form control instance provided by the aliases form array instance. Because form array elements are unnamed, you assign the index to the `i` variable and pass it to each control to bind it to the `formControlName` input.
The `*ngFor` directive iterates over each form control instance provided by the aliases form array instance. Because form array elements are unnamed, you assign the index to the `i` variable and pass it to each control to bind it to the `formControlName` input.
<figure>
<img src="generated/images/guide/reactive-forms/profile-editor-4.png" alt="Profile Editor Aliases">
@ -554,7 +522,7 @@ Listed below are the base classes and services used to create and manage form co
</td>
</tr>
</tr>
</table>

View File

@ -15,8 +15,7 @@ The [AnimationOptions](https://angular.io/api/animations/AnimationOptions) inter
To create a reusable animation, use the [`animation()`](https://angular.io/api/animations/animation) method to define an animation in a separate `.ts` file and declare this animation definition as a `const` export variable. You can then import and reuse this animation in any of your app components using the [`useAnimation()`](https://angular.io/api/animations/useAnimation) API.
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="reusable" language="typescript" linenums="false">
</code-example>
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="reusable" language="typescript"></code-example>
In the above code snippet, `transAnimation` is made reusable by declaring it as an export variable.
@ -27,8 +26,7 @@ In the above code snippet, `transAnimation` is made reusable by declaring it as
You can import the reusable `transAnimation` variable in your component class and reuse it using the `useAnimation()` method as shown below.
<code-example path="animations/src/app/open-close.component.3.ts" header="src/app/open-close.component.ts" region="reusable" language="typescript" linenums="false">
</code-example>
<code-example path="animations/src/app/open-close.component.3.ts" header="src/app/open-close.component.ts" region="reusable" language="typescript"></code-example>
## More on Angular animations
@ -37,4 +35,4 @@ You may also be interested in the following:
* [Introduction to Angular animations](guide/animations)
* [Transition and triggers](guide/transition-and-triggers)
* [Complex animation Sequences](guide/complex-animation-sequences)
* [Route transition animations](guide/route-animations)
* [Route transition animations](guide/route-animations)

View File

@ -43,8 +43,7 @@ Use the `RouterModule.forRoot` method to define a set of routes. Also, import th
The following configuration defines the possible routes for the application.
<code-example path="animations/src/app/app.module.ts" linenums="false" header="src/app/app.module.ts" region="route-animation-data" language="typescript">
</code-example>
<code-example path="animations/src/app/app.module.ts" header="src/app/app.module.ts" region="route-animation-data" language="typescript"></code-example>
The `home` and `about` paths are associated with the `HomeComponent` and `AboutComponent` views. The route configuration tells the Angular router to instantiate the `HomeComponent` and `AboutComponent` views when the navigation matches the corresponding path.
@ -62,13 +61,11 @@ After configuring the routes, tell the Angular router where to render the views
The `<router-outlet>` container has an attribute directive that contains data about active routes and their states, based on the `data` property that we set in the route configuration.
<code-example path="animations/src/app/app.component.html" header="src/app/app.component.html" region="route-animations-outlet">
</code-example>
<code-example path="animations/src/app/app.component.html" header="src/app/app.component.html" region="route-animations-outlet"></code-example>
`AppComponent` defines a method that can detect when a view changes. The method assigns an animation state value to the animation trigger (`@routeAnimation`) based on the route configuration `data` property value. Here's an example of an `AppComponent` method that detects when a route change happens.
<code-example path="animations/src/app/app.component.ts" linenums="false" header="src/app/app.component.ts" region="prepare-router-outlet" language="typescript">
</code-example>
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="prepare-router-outlet" language="typescript"></code-example>
Here, the `prepareRoute()` method takes the value of the output directive (established through `#outlet="outlet"`) and returns a string value representing the state of the animation based on the custom data of the current active route. You can use this data to control which transition to execute for each route.
@ -79,8 +76,7 @@ Animations can be defined directly inside your components. For this example we a
The following code snippet defines a reusable animation named `slideInAnimation`.
<code-example path="animations/src/app/animations.ts" linenums="false" header="src/app/animations.ts" region="route-animations" language="typescript">
</code-example>
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="route-animations" language="typescript"></code-example>
The animation definition does several things:
@ -97,15 +93,13 @@ A route change activates the animation trigger, and a transition matching the st
Make the animation definition available in your application by adding the reusable animation (`slideInAnimation`) to the `animations` metadata of the `AppComponent`.
<code-example path="animations/src/app/app.component.ts" linenums="false" header="src/app/app.component.ts" region="define" language="typescript">
</code-example>
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="define" language="typescript"></code-example>
### Styling the host and child components
During a transition, a new view is inserted directly after the old one and both elements appear on screen at the same time. To prevent this, apply additional styling to the host view, and to the removed and inserted child views. The host view must use relative positioning, and the child views must use absolute positioning. Adding styling to the views animates the containers in place, without the DOM moving things around.
<code-example path="animations/src/app/animations.ts" linenums="false" header="src/app/animations.ts" region="style-view" language="typescript">
</code-example>
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="style-view" language="typescript"></code-example>
### Querying the view containers
@ -113,8 +107,7 @@ Use the `query()` method to find and animate elements within the current host co
Let's assume that we are routing from the *Home => About*.
<code-example path="animations/src/app/animations.ts" linenums="false" header="src/app/animations.ts" region="query" language="typescript" linenums="false">
</code-example>
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="query" language="typescript"></code-example>
The animation code does the following after styling the views:

View File

@ -53,9 +53,7 @@ If the `app` folder is the application root, as it is for the sample application
set the `href` value *exactly* as shown here.
<code-example path="router/src/index.html" linenums="false" header="src/index.html (base-href)" region="base-href">
</code-example>
<code-example path="router/src/index.html" header="src/index.html (base-href)" region="base-href"></code-example>
@ -69,9 +67,7 @@ It is not part of the Angular core. It is in its own library package, `@angular/
Import what you need from it as you would from any other Angular package.
<code-example path="router/src/app/app.module.1.ts" linenums="false" header="src/app/app.module.ts (import)" region="import-router">
</code-example>
<code-example path="router/src/app/app.module.1.ts" header="src/app/app.module.ts (import)" region="import-router"></code-example>
@ -100,9 +96,7 @@ The following example creates five route definitions, configures the router via
and adds the result to the `AppModule`'s `imports` array.
<code-example path="router/src/app/app.module.0.ts" linenums="false" header="src/app/app.module.ts (excerpt)">
</code-example>
<code-example path="router/src/app/app.module.0.ts" header="src/app/app.module.ts (excerpt)"></code-example>
@ -177,9 +171,7 @@ an anchor tag.
Consider the following template:
<code-example path="router/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html">
</code-example>
<code-example path="router/src/app/app.component.1.html" header="src/app/app.component.html"></code-example>
The `RouterLink` directives on the anchor tags give the router control over those elements.
The navigation paths are fixed, so you can assign a string to the `routerLink` (a "one-time" binding).
@ -917,9 +909,7 @@ In order to use the Router, you must first register the `RouterModule` from the
</div>
<code-example path="router/src/app/app.module.1.ts" linenums="false" header="src/app/app.module.ts (first-config)" region="first-config">
</code-example>
<code-example path="router/src/app/app.module.1.ts" header="src/app/app.module.ts (first-config)" region="first-config"></code-example>
<div class="alert is-helpful">
@ -947,9 +937,7 @@ The router outlet serves as a placeholder when the routed components will be ren
The corresponding component template looks like this:
<code-example path="router/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html">
</code-example>
<code-example path="router/src/app/app.component.1.html" header="src/app/app.component.html"></code-example>
{@a wildcard}
@ -973,17 +961,13 @@ Be sure it is the _last_ route in the configuration.
To test this feature, add a button with a `RouterLink` to the `HeroListComponent` template and set the link to `"/sidekicks"`.
<code-example path="router/src/app/hero-list/hero-list.component.1.html" linenums="false" header="src/app/hero-list/hero-list.component.html (excerpt)">
</code-example>
<code-example path="router/src/app/hero-list/hero-list.component.1.html" header="src/app/hero-list/hero-list.component.html (excerpt)"></code-example>
The application will fail if the user clicks that button because you haven't defined a `"/sidekicks"` route yet.
Instead of adding the `"/sidekicks"` route, define a `wildcard` route instead and have it navigate to a simple `PageNotFoundComponent`.
<code-example path="router/src/app/app.module.1.ts" linenums="false" header="src/app/app.module.ts (wildcard)" region="wildcard">
</code-example>
<code-example path="router/src/app/app.module.1.ts" header="src/app/app.module.ts (wildcard)" region="wildcard"></code-example>
Create the `PageNotFoundComponent` to display when users visit invalid URLs.
@ -991,9 +975,7 @@ Create the `PageNotFoundComponent` to display when users visit invalid URLs.
ng generate component page-not-found
</code-example>
<code-example path="router/src/app/page-not-found/page-not-found.component.html" linenums="false" header="src/app/page-not-found.component.html (404 component)">
</code-example>
<code-example path="router/src/app/page-not-found/page-not-found.component.html" header="src/app/page-not-found.component.html (404 component)"></code-example>
Now when the user visits `/sidekicks`, or any other invalid URL, the browser displays "Page not found".
The browser address bar continues to point to the invalid URL.
@ -1022,8 +1004,7 @@ Add the default route somewhere _above_ the wildcard route.
It's just above the wildcard route in the following excerpt showing the complete `appRoutes` for this milestone.
<code-example path="router/src/app/app-routing.module.1.ts" linenums="false" header="src/app/app-routing.module.ts (appRoutes)" region="appRoutes">
</code-example>
<code-example path="router/src/app/app-routing.module.1.ts" header="src/app/app-routing.module.ts (appRoutes)" region="appRoutes"></code-example>
A redirect route requires a `pathMatch` property to tell the router how to match a URL to the path of a route.
@ -1314,16 +1295,12 @@ By re-exporting the `RouterModule` here the components declared in `AppModule` w
After these steps, the file should look like this.
<code-example path="router/src/app/app-routing.module.1.ts" header="src/app/app-routing.module.ts">
</code-example>
<code-example path="router/src/app/app-routing.module.1.ts" header="src/app/app-routing.module.ts"></code-example>
Next, update the `app.module.ts` file, removing `RouterModule.forRoot` in
the `imports` array.
<code-example path="router/src/app/app.module.2.ts" header="src/app/app.module.ts">
</code-example>
<code-example path="router/src/app/app.module.2.ts" header="src/app/app.module.ts"></code-example>
@ -1442,9 +1419,7 @@ Next, you'll update the `HeroesModule` metadata.
* Import and add the `HeroDetailComponent` and `HeroListComponent` to the `declarations` array in the `HeroesModule`.
<code-example path="router/src/app/heroes/heroes.module.ts" header="src/app/heroes/heroes.module.ts">
</code-example>
<code-example path="router/src/app/heroes/heroes.module.ts" header="src/app/heroes/heroes.module.ts"></code-example>
@ -1568,9 +1543,7 @@ In any other module, you must call the **`RouterModule.forChild`** method to reg
The updated `HeroesRoutingModule` looks like this:
<code-example path="router/src/app/heroes/heroes-routing.module.1.ts" header="src/app/heroes/heroes-routing.module.ts">
</code-example>
<code-example path="router/src/app/heroes/heroes-routing.module.1.ts" header="src/app/heroes/heroes-routing.module.ts"></code-example>
@ -1602,9 +1575,7 @@ Remove the `HeroListComponent` import and the `/heroes` route from the `app-rout
These are concerns at the top level of the application itself.
<code-example path="router/src/app/app-routing.module.2.ts" linenums="false" header="src/app/app-routing.module.ts (v2)">
</code-example>
<code-example path="router/src/app/app-routing.module.2.ts" header="src/app/app-routing.module.ts (v2)"></code-example>
@ -1618,9 +1589,7 @@ Remove the `HeroListComponent` from the `AppModule`'s `declarations` because it'
After these steps, the `AppModule` should look like this:
<code-example path="router/src/app/app.module.3.ts" header="src/app/app.module.ts">
</code-example>
<code-example path="router/src/app/app.module.3.ts" header="src/app/app.module.ts"></code-example>
@ -1632,9 +1601,7 @@ After these steps, the `AppModule` should look like this:
Look at the module `imports` array. Notice that the `AppRoutingModule` is _last_.
Most importantly, it comes _after_ the `HeroesModule`.
<code-example path="router/src/app/app.module.3.ts" region="module-imports" header="src/app/app.module.ts (module-imports)" linenums="false">
</code-example>
<code-example path="router/src/app/app.module.3.ts" region="module-imports" header="src/app/app.module.ts (module-imports)"></code-example>
@ -1678,9 +1645,7 @@ Return to the `HeroesRoutingModule` and look at the route definitions again.
The route to `HeroDetailComponent` has a twist.
<code-example path="router/src/app/heroes/heroes-routing.module.1.ts" linenums="false" header="src/app/heroes/heroes-routing.module.ts (excerpt)" region="hero-detail-route">
</code-example>
<code-example path="router/src/app/heroes/heroes-routing.module.1.ts" header="src/app/heroes/heroes-routing.module.ts (excerpt)" region="hero-detail-route"></code-example>
@ -1734,9 +1699,7 @@ Accordingly, the _link parameters array_ has *two* items: the routing _path_ an
`id` of the selected hero.
<code-example path="router/src/app/heroes/hero-list/hero-list.component.1.html" linenums="false" header="src/app/heroes/hero-list/hero-list.component.html (link-parameters-array)" region="link-parameters-array">
</code-example>
<code-example path="router/src/app/heroes/hero-list/hero-list.component.1.html" header="src/app/heroes/hero-list/hero-list.component.html (link-parameters-array)" region="link-parameters-array"></code-example>
@ -1765,18 +1728,14 @@ the `HeroDetailComponent` via the `ActivatedRoute` service.
Import the `Router`, `ActivatedRoute`, and `ParamMap` tokens from the router package.
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.1.ts" linenums="false" header="src/app/heroes/hero-detail/hero-detail.component.ts (activated route)" region="imports">
</code-example>
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.1.ts" header="src/app/heroes/hero-detail/hero-detail.component.ts (activated route)" region="imports"></code-example>
Import the `switchMap` operator because you need it later to process the `Observable` route parameters.
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.3.ts" linenums="false" header="src/app/heroes/hero-detail/hero-detail.component.ts (switchMap operator import)" region="rxjs-operator-import">
</code-example>
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.3.ts" header="src/app/heroes/hero-detail/hero-detail.component.ts (switchMap operator import)" region="rxjs-operator-import"></code-example>
@ -1787,17 +1746,13 @@ As usual, you write a constructor that asks Angular to inject services
that the component requires and reference them as private variables.
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.3.ts" linenums="false" header="src/app/heroes/hero-detail/hero-detail.component.ts (constructor)" region="ctor">
</code-example>
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.3.ts" header="src/app/heroes/hero-detail/hero-detail.component.ts (constructor)" region="ctor"></code-example>
Later, in the `ngOnInit` method, you use the `ActivatedRoute` service to retrieve the parameters for the route,
pull the hero `id` from the parameters and retrieve the hero to display.
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.3.ts" linenums="false" header="src/app/heroes/hero-detail/hero-detail.component.ts (ngOnInit)" region="ngOnInit">
</code-example>
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.3.ts" header="src/app/heroes/hero-detail/hero-detail.component.ts (ngOnInit)" region="ngOnInit"></code-example>
The `paramMap` processing is a bit tricky. When the map changes, you `get()`
the `id` parameter from the changed parameters.
@ -1934,9 +1889,7 @@ You can access the parameters directly without subscribing or adding observable
It's much simpler to write and read:
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.2.ts" linenums="false" header="src/app/heroes/hero-detail/hero-detail.component.ts (ngOnInit snapshot)" region="snapshot">
</code-example>
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.2.ts" header="src/app/heroes/hero-detail/hero-detail.component.ts (ngOnInit snapshot)" region="snapshot"></code-example>
@ -1967,9 +1920,7 @@ that you can bind to a `[routerLink]` directive.
It holds the _path to the `HeroListComponent`_:
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.1.ts" linenums="false" header="src/app/heroes/hero-detail/hero-detail.component.ts (excerpt)" region="gotoHeroes">
</code-example>
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.1.ts" header="src/app/heroes/hero-detail/hero-detail.component.ts (excerpt)" region="gotoHeroes"></code-example>
{@a optional-route-parameters}
@ -2029,9 +1980,7 @@ When navigating to the `HeroDetailComponent` you specified the _required_ `id` o
*route parameter* and made it the second item of the [_link parameters array_](#link-parameters-array).
<code-example path="router/src/app/heroes/hero-list/hero-list.component.1.html" linenums="false" header="src/app/heroes/hero-list/hero-list.component.html (link-parameters-array)" region="link-parameters-array">
</code-example>
<code-example path="router/src/app/heroes/hero-list/hero-list.component.1.html" header="src/app/heroes/hero-list/hero-list.component.html (link-parameters-array)" region="link-parameters-array"></code-example>
@ -2039,9 +1988,7 @@ The router embedded the `id` value in the navigation URL because you had defined
as a route parameter with an `:id` placeholder token in the route `path`:
<code-example path="router/src/app/heroes/heroes-routing.module.1.ts" linenums="false" header="src/app/heroes/heroes-routing.module.ts (hero-detail-route)" region="hero-detail-route">
</code-example>
<code-example path="router/src/app/heroes/heroes-routing.module.1.ts" header="src/app/heroes/heroes-routing.module.ts (hero-detail-route)" region="hero-detail-route"></code-example>
@ -2049,9 +1996,7 @@ When the user clicks the back button, the `HeroDetailComponent` constructs anoth
which it uses to navigate back to the `HeroListComponent`.
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.1.ts" linenums="false" header="src/app/heroes/hero-detail/hero-detail.component.ts (gotoHeroes)" region="gotoHeroes">
</code-example>
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.1.ts" header="src/app/heroes/hero-detail/hero-detail.component.ts (gotoHeroes)" region="gotoHeroes"></code-example>
@ -2066,9 +2011,7 @@ For demonstration purposes, there's an extra junk parameter (`foo`) in the objec
Here's the revised navigation statement:
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.3.ts" linenums="false" header="src/app/heroes/hero-detail/hero-detail.component.ts (go to heroes)" region="gotoHeroes">
</code-example>
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.3.ts" header="src/app/heroes/hero-detail/hero-detail.component.ts (go to heroes)" region="gotoHeroes"></code-example>
@ -2148,27 +2091,21 @@ This time you'll be navigating in the opposite direction, from the `HeroDetailCo
First you extend the router import statement to include the `ActivatedRoute` service symbol:
<code-example path="router/src/app/heroes/hero-list/hero-list.component.ts" linenums="false" header="src/app/heroes/hero-list/hero-list.component.ts (import)" region="import-router">
</code-example>
<code-example path="router/src/app/heroes/hero-list/hero-list.component.ts" header="src/app/heroes/hero-list/hero-list.component.ts (import)" region="import-router"></code-example>
Import the `switchMap` operator to perform an operation on the `Observable` of route parameter map.
<code-example path="router/src/app/heroes/hero-list/hero-list.component.ts" linenums="false" header="src/app/heroes/hero-list/hero-list.component.ts (rxjs imports)" region="rxjs-imports">
</code-example>
<code-example path="router/src/app/heroes/hero-list/hero-list.component.ts" header="src/app/heroes/hero-list/hero-list.component.ts (rxjs imports)" region="rxjs-imports"></code-example>
Then you inject the `ActivatedRoute` in the `HeroListComponent` constructor.
<code-example path="router/src/app/heroes/hero-list/hero-list.component.ts" linenums="false" header="src/app/heroes/hero-list/hero-list.component.ts (constructor and ngOnInit)" region="ctor">
</code-example>
<code-example path="router/src/app/heroes/hero-list/hero-list.component.ts" header="src/app/heroes/hero-list/hero-list.component.ts (constructor and ngOnInit)" region="ctor"></code-example>
@ -2181,15 +2118,11 @@ The binding adds the `selected` CSS class when the comparison returns `true` and
Look for it within the repeated `<li>` tag as shown here:
<code-example path="router/src/app/heroes/hero-list/hero-list.component.html" linenums="false" header="src/app/heroes/hero-list/hero-list.component.html">
</code-example>
<code-example path="router/src/app/heroes/hero-list/hero-list.component.html" header="src/app/heroes/hero-list/hero-list.component.html"></code-example>
Add some styles to apply when the list item is selected.
<code-example path="router/src/app/heroes/hero-list/hero-list.component.css" linenums="false" region="selected" header="src/app/heroes/hero-list/hero-list.component.css">
</code-example>
<code-example path="router/src/app/heroes/hero-list/hero-list.component.css" region="selected" header="src/app/heroes/hero-list/hero-list.component.css"></code-example>
@ -2215,22 +2148,16 @@ This section shows you how to add some [animations](guide/animations) to the `He
First import the `BrowserAnimationsModule` and add it to the `imports` array:
<code-example path="router/src/app/app.module.ts" linenums="false" header="src/app/app.module.ts (animations-module)" region="animations-module">
</code-example>
<code-example path="router/src/app/app.module.ts" header="src/app/app.module.ts (animations-module)" region="animations-module"></code-example>
Next, add a `data` object to the routes for `HeroListComponent` and `HeroDetailComponent`. Transitions are based on `states` and you'll use the `animation` data from the route to provide a named animation `state` for the transitions.
<code-example path="router/src/app/heroes/heroes-routing.module.2.ts" header="src/app/heroes/heroes-routing.module.ts (animation data)">
</code-example>
<code-example path="router/src/app/heroes/heroes-routing.module.2.ts" header="src/app/heroes/heroes-routing.module.ts (animation data)"></code-example>
Create an `animations.ts` file in the root `src/app/` folder. The contents look like this:
<code-example path="router/src/app/animations.ts" linenums="false" header="src/app/animations.ts (excerpt)">
</code-example>
<code-example path="router/src/app/animations.ts" header="src/app/animations.ts (excerpt)"></code-example>
This file does the following:
@ -2248,24 +2175,18 @@ Back in the `AppComponent`, import the `RouterOutlet` token from the `@angular/r
Add an `animations` array to the `@Component` metadata's that contains the `slideInAnimation`.
<code-example path="router/src/app/app.component.2.ts" linenums="false" header="src/app/app.component.ts (animations)" region="animation-imports">
</code-example>
<code-example path="router/src/app/app.component.2.ts" header="src/app/app.component.ts (animations)" region="animation-imports"></code-example>
In order to use the routable animations, you'll need to wrap the `RouterOutlet` inside an element. You'll
use the `@routeAnimation` trigger and bind it to the element.
For the `@routeAnimation` transitions to key off states, you'll need to provide it with the `data` from the `ActivatedRoute`. The `RouterOutlet` is exposed as an `outlet` template variable, so you bind a reference to the router outlet. A variable of `routerOutlet` is an ideal choice.
<code-example path="router/src/app/app.component.2.html" linenums="false" header="src/app/app.component.html (router outlet)">
</code-example>
<code-example path="router/src/app/app.component.2.html" header="src/app/app.component.html (router outlet)"></code-example>
The `@routeAnimation` property is bound to the `getAnimationData` with the provided `routerOutlet` reference, so you'll need to define that function in the `AppComponent`. The `getAnimationData` function returns the animation property from the `data` provided through the `ActivatedRoute`. The `animation` property matches the `transition` names you used in the `slideInAnimation` defined in `animations.ts`.
<code-example path="router/src/app/app.component.2.ts" linenums="false" header="src/app/app.component.ts (router outlet)" region="function-binding">
</code-example>
<code-example path="router/src/app/app.component.2.ts" header="src/app/app.component.ts (router outlet)" region="function-binding"></code-example>
When switching between the two routes, the `HeroDetailComponent` and `HeroListComponent` will ease in from the left when routed to and will slide to the right when navigating away.
@ -2563,9 +2484,7 @@ Begin by imitating the heroes feature:
You'll use mock crises instead of mock heroes:
<code-example path="router/src/app/crisis-center/mock-crises.ts" header="src/app/crisis-center/mock-crises.ts">
</code-example>
<code-example path="router/src/app/crisis-center/mock-crises.ts" header="src/app/crisis-center/mock-crises.ts"></code-example>
The resulting crisis center is a foundation for introducing a new concept&mdash;**child routing**.
@ -2622,8 +2541,7 @@ Generate a `CrisisCenter` component in the `crisis-center` folder:
Update the component template to look like this:
<code-example path="router/src/app/crisis-center/crisis-center/crisis-center.component.html" linenums="false" header="src/app/crisis-center/crisis-center/crisis-center.component.html">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-center/crisis-center.component.html" header="src/app/crisis-center/crisis-center/crisis-center.component.html"></code-example>
The `CrisisCenterComponent` has the following in common with the `AppComponent`:
@ -2650,14 +2568,12 @@ As a host page for the "Crisis Center" feature, generate a `CrisisCenterHome` co
Update the template with a welcome message to the `Crisis Center`.
<code-example path="router/src/app/crisis-center/crisis-center-home/crisis-center-home.component.html" linenums="false" header="src/app/crisis-center/crisis-center-home/crisis-center-home.component.html">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-center-home/crisis-center-home.component.html" header="src/app/crisis-center/crisis-center-home/crisis-center-home.component.html"></code-example>
Update the `crisis-center-routing.module.ts` you renamed after copying it from `heroes-routing.module.ts` file.
This time, you define **child routes** *within* the parent `crisis-center` route.
<code-example path="router/src/app/crisis-center/crisis-center-routing.module.1.ts" linenums="false" header="src/app/crisis-center/crisis-center-routing.module.ts (Routes)" region="routes">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-center-routing.module.1.ts" header="src/app/crisis-center/crisis-center-routing.module.ts (Routes)" region="routes"></code-example>
Notice that the parent `crisis-center` route has a `children` property
@ -2703,9 +2619,7 @@ The absolute URL for the latter example, including the `localhost` origin, is
Here's the complete `crisis-center-routing.module.ts` file with its imports.
<code-example path="router/src/app/crisis-center/crisis-center-routing.module.1.ts" linenums="false" header="src/app/crisis-center/crisis-center-routing.module.ts (excerpt)">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-center-routing.module.1.ts" header="src/app/crisis-center/crisis-center-routing.module.ts (excerpt)"></code-example>
@ -2723,7 +2637,7 @@ _before_ the `AppRoutingModule`:
</code-pane>
<code-pane path="router/src/app/app.module.4.ts" linenums="false" header="src/app/app.module.ts (import CrisisCenterModule)" region="crisis-center-module">
<code-pane path="router/src/app/app.module.4.ts" header="src/app/app.module.ts (import CrisisCenterModule)" region="crisis-center-module">
</code-pane>
@ -2735,9 +2649,7 @@ The feature routes are now provided by the `HeroesModule` and the `CrisisCenter`
The `app-routing.module.ts` file retains the top-level application routes such as the default and wildcard routes.
<code-example path="router/src/app/app-routing.module.3.ts" linenums="false" header="src/app/app-routing.module.ts (v3)" region="v3">
</code-example>
<code-example path="router/src/app/app-routing.module.3.ts" header="src/app/app-routing.module.ts (v3)" region="v3"></code-example>
@ -2814,9 +2726,7 @@ The `ActivatedRoute` is implicit in a `RouterLink` directive.
Update the `gotoCrises` method of the `CrisisDetailComponent` to navigate back to the *Crisis Center* list using relative path navigation.
<code-example path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts" linenums="false" header="src/app/crisis-center/crisis-detail/crisis-detail.component.ts (relative navigation)" region="gotoCrises-navigate">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts" header="src/app/crisis-center/crisis-detail/crisis-detail.component.ts (relative navigation)" region="gotoCrises-navigate"></code-example>
Notice that the path goes up a level using the `../` syntax.
@ -2847,9 +2757,7 @@ Multiple outlets can be displaying different content, determined by different ro
Add an outlet named "popup" in the `AppComponent`, directly below the unnamed outlet.
<code-example path="router/src/app/app.component.4.html" linenums="false" header="src/app/app.component.html (outlets)" region="outlets">
</code-example>
<code-example path="router/src/app/app.component.4.html" header="src/app/app.component.html (outlets)" region="outlets"></code-example>
@ -2923,9 +2831,7 @@ That's a peculiarity covered [below](#clear-secondary-routes).
Open the `AppRoutingModule` and add a new `compose` route to the `appRoutes`.
<code-example path="router/src/app/app-routing.module.3.ts" linenums="false" header="src/app/app-routing.module.ts (compose route)" region="compose">
</code-example>
<code-example path="router/src/app/app-routing.module.3.ts" header="src/app/app-routing.module.ts (compose route)" region="compose"></code-example>
@ -2936,9 +2842,7 @@ This route now targets the popup outlet and the `ComposeMessageComponent` will d
The user needs a way to open the popup.
Open the `AppComponent` and add a "Contact" link.
<code-example path="router/src/app/app.component.4.html" linenums="false" header="src/app/app.component.html (contact-link)" region="contact-link">
</code-example>
<code-example path="router/src/app/app.component.4.html" header="src/app/app.component.html (contact-link)" region="contact-link"></code-example>
@ -3031,9 +2935,7 @@ That's why the popup stays visible as you navigate among the crises and heroes.
Clicking the "send" or "cancel" buttons _does_ clear the popup view.
To see how, look at the `closePopup()` method again:
<code-example path="router/src/app/compose-message/compose-message.component.ts" linenums="false" header="src/app/compose-message/compose-message.component.ts (closePopup)" region="closePopup">
</code-example>
<code-example path="router/src/app/compose-message/compose-message.component.ts" header="src/app/compose-message/compose-message.component.ts (closePopup)" region="closePopup"></code-example>
@ -3266,11 +3168,11 @@ feature module, a dashboard route and two unfinished components to manage crises
<code-tabs>
<code-pane header="src/app/admin/admin/admin.component.html" linenums="false" path="router/src/app/admin/admin/admin.component.html">
<code-pane header="src/app/admin/admin/admin.component.html" path="router/src/app/admin/admin/admin.component.html">
</code-pane>
<code-pane header="src/app/admin/admin-dashboard/admin-dashboard.component.html" linenums="false" path="router/src/app/admin/admin-dashboard/admin-dashboard.component.1.html">
<code-pane header="src/app/admin/admin-dashboard/admin-dashboard.component.html" path="router/src/app/admin/admin-dashboard/admin-dashboard.component.1.html">
</code-pane>
@ -3278,11 +3180,11 @@ feature module, a dashboard route and two unfinished components to manage crises
</code-pane>
<code-pane header="src/app/admin/manage-crises/manage-crises.component.html" linenums="false" path="router/src/app/admin/manage-crises/manage-crises.component.html">
<code-pane header="src/app/admin/manage-crises/manage-crises.component.html" path="router/src/app/admin/manage-crises/manage-crises.component.html">
</code-pane>
<code-pane header="src/app/admin/manage-heroes/manage-heroes.component.html" linenums="false" path="router/src/app/admin/manage-heroes/manage-heroes.component.html">
<code-pane header="src/app/admin/manage-heroes/manage-heroes.component.html" path="router/src/app/admin/manage-heroes/manage-heroes.component.html">
</code-pane>
@ -3309,9 +3211,7 @@ is considered a match to any route within the admin feature area. You only want
The initial admin routing configuration:
<code-example path="router/src/app/admin/admin-routing.module.1.ts" linenums="false" header="src/app/admin/admin-routing.module.ts (admin routing)" region="admin-routes">
</code-example>
<code-example path="router/src/app/admin/admin-routing.module.1.ts" header="src/app/admin/admin-routing.module.ts (admin routing)" region="admin-routes"></code-example>
Looking at the child route under the `AdminComponent`, there is a `path` and a `children`
property but it's not using a `component`.
@ -3327,18 +3227,14 @@ Next, import the `AdminModule` into `app.module.ts` and add it to the `imports`
to register the admin routes.
<code-example path="router/src/app/app.module.4.ts" linenums="false" header="src/app/app.module.ts (admin module)" region="admin-module">
</code-example>
<code-example path="router/src/app/app.module.4.ts" header="src/app/app.module.ts (admin module)" region="admin-module"></code-example>
Add an "Admin" link to the `AppComponent` shell so that users can get to this feature.
<code-example path="router/src/app/app.component.5.html" linenums="false" header="src/app/app.component.html (template)">
</code-example>
<code-example path="router/src/app/app.component.5.html" header="src/app/app.component.html (template)"></code-example>
@ -3367,9 +3263,7 @@ At the moment you're interested in seeing how guards work so the first version d
It simply logs to console and `returns` true immediately, allowing navigation to proceed:
<code-example path="router/src/app/auth/auth.guard.1.ts" linenums="false" header="src/app/auth/auth.guard.ts (excerpt)">
</code-example>
<code-example path="router/src/app/auth/auth.guard.1.ts" header="src/app/auth/auth.guard.ts (excerpt)"></code-example>
@ -3377,9 +3271,7 @@ Next, open `admin-routing.module.ts `, import the `AuthGuard` class, and
update the admin route with a `canActivate` guard property that references it:
<code-example path="router/src/app/admin/admin-routing.module.2.ts" linenums="false" header="src/app/admin/admin-routing.module.ts (guarded admin route)" region="admin-route">
</code-example>
<code-example path="router/src/app/admin/admin-routing.module.2.ts" header="src/app/admin/admin-routing.module.ts (guarded admin route)" region="admin-route"></code-example>
@ -3401,9 +3293,7 @@ The `AuthGuard` should call an application service that can login a user and ret
Update the `AuthService` to log in the user:
<code-example path="router/src/app/auth/auth.service.ts" linenums="false" header="src/app/auth/auth.service.ts (excerpt)">
</code-example>
<code-example path="router/src/app/auth/auth.service.ts" header="src/app/auth/auth.service.ts (excerpt)"></code-example>
@ -3416,9 +3306,7 @@ The `redirectUrl` property will store the attempted URL so you can navigate to i
Revise the `AuthGuard` to call it.
<code-example path="router/src/app/auth/auth.guard.2.ts" linenums="false" header="src/app/auth/auth.guard.ts (v2)">
</code-example>
<code-example path="router/src/app/auth/auth.guard.2.ts" header="src/app/auth/auth.guard.ts (v2)"></code-example>
@ -3496,9 +3384,7 @@ async checks and a `boolean` for sync checks.
This one returns a `boolean`:
<code-example path="router/src/app/auth/auth.guard.3.ts" linenums="false" header="src/app/auth/auth.guard.ts (excerpt)" region="can-activate-child">
</code-example>
<code-example path="router/src/app/auth/auth.guard.3.ts" header="src/app/auth/auth.guard.ts (excerpt)" region="can-activate-child"></code-example>
@ -3506,9 +3392,7 @@ Add the same `AuthGuard` to the `component-less` admin route to protect all othe
instead of adding the `AuthGuard` to each route individually.
<code-example path="router/src/app/admin/admin-routing.module.3.ts" linenums="false" header="src/app/admin/admin-routing.module.ts (excerpt)" region="can-activate-child">
</code-example>
<code-example path="router/src/app/admin/admin-routing.module.3.ts" header="src/app/admin/admin-routing.module.ts (excerpt)" region="can-activate-child"></code-example>
@ -3557,9 +3441,7 @@ discards the changes when the user presses the *Cancel* button.
Both buttons navigate back to the crisis list after save or cancel.
<code-example path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts" linenums="false" header="src/app/crisis-center/crisis-detail/crisis-detail.component.ts (cancel and save methods)" region="cancel-save">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts" header="src/app/crisis-center/crisis-detail/crisis-detail.component.ts (cancel and save methods)" region="cancel-save"></code-example>
@ -3593,9 +3475,7 @@ Generate a `Dialog` service to handle user confirmation.
Add a `confirm()` method to the `DialogService` to prompt the user to confirm their intent. The `window.confirm` is a _blocking_ action that displays a modal dialog and waits for user interaction.
<code-example path="router/src/app/dialog.service.ts" header="src/app/dialog.service.ts">
</code-example>
<code-example path="router/src/app/dialog.service.ts" header="src/app/dialog.service.ts"></code-example>
It returns an `Observable` that *resolves* when the user eventually decides what to do: either
to discard changes and navigate away (`true`) or to preserve the pending changes and stay in the crisis editor (`false`).
@ -3617,9 +3497,7 @@ It need only detect that the component has a `canDeactivate()` method and call i
This approach makes the guard reusable.
<code-example path="router/src/app/can-deactivate.guard.ts" header="src/app/can-deactivate.guard.ts">
</code-example>
<code-example path="router/src/app/can-deactivate.guard.ts" header="src/app/can-deactivate.guard.ts"></code-example>
@ -3632,18 +3510,14 @@ wanted to use this guard for this component and needed to get
the component's properties or confirm whether the router should allow navigation away from it.
<code-example path="router/src/app/can-deactivate.guard.1.ts" linenums="false" header="src/app/can-deactivate.guard.ts (component-specific)">
</code-example>
<code-example path="router/src/app/can-deactivate.guard.1.ts" header="src/app/can-deactivate.guard.ts (component-specific)"></code-example>
Looking back at the `CrisisDetailComponent`, it implements the confirmation workflow for unsaved changes.
<code-example path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts" linenums="false" header="src/app/crisis-center/crisis-detail/crisis-detail.component.ts (excerpt)" region="canDeactivate">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts" header="src/app/crisis-center/crisis-detail/crisis-detail.component.ts (excerpt)" region="canDeactivate"></code-example>
@ -3656,9 +3530,7 @@ to resolve to truthy (navigate) or falsy (stay put).
Add the `Guard` to the crisis detail route in `crisis-center-routing.module.ts` using the `canDeactivate` array property.
<code-example path="router/src/app/crisis-center/crisis-center-routing.module.3.ts" linenums="false" header="src/app/crisis-center/crisis-center-routing.module.ts (can deactivate guard)">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-center-routing.module.3.ts" header="src/app/crisis-center/crisis-center-routing.module.ts (can deactivate guard)"></code-example>
Now you have given the user a safeguard against unsaved changes.
@ -3704,9 +3576,7 @@ Generate a `CrisisDetailResolver` service file within the `Crisis Center` featur
</code-example>
<code-example path="router/src/app/crisis-center/crisis-detail-resolver.service.1.ts" header="src/app/crisis-center/crisis-detail-resolver.service.ts (generated)">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-detail-resolver.service.1.ts" header="src/app/crisis-center/crisis-detail-resolver.service.ts (generated)"></code-example>
@ -3728,17 +3598,13 @@ Observable completes after retrieving the first value from the Observable return
If it doesn't return a valid `Crisis`, return an empty `Observable`, canceling the previous in-flight navigation to the `CrisisDetailComponent` and navigate the user back to the `CrisisListComponent`. The update resolver service looks like this:
<code-example path="router/src/app/crisis-center/crisis-detail-resolver.service.ts" header="src/app/crisis-center/crisis-detail-resolver.service.ts">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-detail-resolver.service.ts" header="src/app/crisis-center/crisis-detail-resolver.service.ts"></code-example>
Import this resolver in the `crisis-center-routing.module.ts`
and add a `resolve` object to the `CrisisDetailComponent` route configuration.
<code-example path="router/src/app/crisis-center/crisis-center-routing.module.4.ts" linenums="false" header="src/app/crisis-center/crisis-center-routing.module.ts (resolver)">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-center-routing.module.4.ts" header="src/app/crisis-center/crisis-center-routing.module.ts (resolver)"></code-example>
@ -3748,9 +3614,7 @@ that's where you said it should be when you re-configured the route.
It will be there when the `CrisisDetailComponent` ask for it.
<code-example path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts" linenums="false" header="src/app/crisis-center/crisis-detail/crisis-detail.component.ts (ngOnInit v2)" region="ngOnInit">
</code-example>
<code-example path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts" header="src/app/crisis-center/crisis-detail/crisis-detail.component.ts (ngOnInit v2)" region="ngOnInit"></code-example>
@ -3853,9 +3717,7 @@ Add an `anchor` element so you can jump to a certain point on the page.
Add the `NavigationExtras` object to the `router.navigate()` method that navigates you to the `/login` route.
<code-example path="router/src/app/auth/auth.guard.4.ts" linenums="false" header="src/app/auth/auth.guard.ts (v3)">
</code-example>
<code-example path="router/src/app/auth/auth.guard.4.ts" header="src/app/auth/auth.guard.ts (v3)"></code-example>
@ -3866,9 +3728,7 @@ and provide the `queryParamsHandling` and `preserveFragment` to pass along the c
and fragment to the next route.
<code-example path="router/src/app/auth/login/login.component.ts" linenums="false" header="src/app/auth/login/login.component.ts (preserve)" region="preserve">
</code-example>
<code-example path="router/src/app/auth/login/login.component.ts" header="src/app/auth/login/login.component.ts (preserve)" region="preserve"></code-example>
<div class="alert is-helpful">
@ -3885,9 +3745,7 @@ As you'll be navigating to the *Admin Dashboard* route after logging in, you'll
query parameters and fragment.
<code-example path="router/src/app/admin/admin-dashboard/admin-dashboard.component.1.ts" linenums="false" header="src/app/admin/admin-dashboard/admin-dashboard.component.ts (v2)">
</code-example>
<code-example path="router/src/app/admin/admin-dashboard/admin-dashboard.component.1.ts" header="src/app/admin/admin-dashboard/admin-dashboard.component.ts (v2)"></code-example>
@ -3959,9 +3817,7 @@ The `loadChildren` property takes a function that returns a promise using the br
The path is the location of the `AdminModule` (relative to the app root).
After the code is requested and loaded, the `Promise` resolves an object that contains the `NgModule`, in this case the `AdminModule`.
<code-example path="router/src/app/app-routing.module.5.ts" region="admin-1" header="app-routing.module.ts (load children)">
</code-example>
<code-example path="router/src/app/app-routing.module.5.ts" region="admin-1" header="app-routing.module.ts (load children)"></code-example>
<div class="alert is-important">
@ -4020,9 +3876,7 @@ Add it to the `AuthGuard` class's `implements` list.
Then implement `canLoad()` as follows:
<code-example path="router/src/app/auth/auth.guard.ts" linenums="false" header="src/app/auth/auth.guard.ts (CanLoad guard)" region="canLoad">
</code-example>
<code-example path="router/src/app/auth/auth.guard.ts" header="src/app/auth/auth.guard.ts (CanLoad guard)" region="canLoad"></code-example>
@ -4034,9 +3888,7 @@ array property for the `admin` route.
The completed admin route looks like this:
<code-example path="router/src/app/app-routing.module.5.ts" region="admin" header="app-routing.module.ts (lazy admin route)">
</code-example>
<code-example path="router/src/app/app-routing.module.5.ts" region="admin" header="app-routing.module.ts (lazy admin route)"></code-example>
@ -4135,9 +3987,7 @@ The second argument in the `RouterModule.forRoot()` method takes an object for a
The `preloadingStrategy` is one of those options.
Add the `PreloadAllModules` token to the `forRoot()` call:
<code-example path="router/src/app/app-routing.module.6.ts" linenums="false" header="src/app/app-routing.module.ts (preload all)" region="forRoot">
</code-example>
<code-example path="router/src/app/app-routing.module.6.ts" header="src/app/app-routing.module.ts (preload all)" region="forRoot"></code-example>
@ -4182,9 +4032,7 @@ Recall that you can add anything to the `data` property of a route.
Set the `data.preload` flag in the `crisis-center` route in the `AppRoutingModule`.
<code-example path="router/src/app/app-routing.module.ts" linenums="false" header="src/app/app-routing.module.ts (route data preload)" region="preload-v2">
</code-example>
<code-example path="router/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts (route data preload)" region="preload-v2"></code-example>
Generate a new `SelectivePreloadingStrategy` service.
@ -4193,9 +4041,7 @@ Generate a new `SelectivePreloadingStrategy` service.
</code-example>
<code-example path="router/src/app/selective-preloading-strategy.service.ts" linenums="false" header="src/app/selective-preloading-strategy.service.ts (excerpt)">
</code-example>
<code-example path="router/src/app/selective-preloading-strategy.service.ts" header="src/app/selective-preloading-strategy.service.ts (excerpt)"></code-example>
@ -4233,9 +4079,7 @@ Now edit the `AdminDashboardComponent` to display the log of preloaded routes.
When you're done it looks like this.
<code-example path="router/src/app/admin/admin-dashboard/admin-dashboard.component.ts" linenums="false" header="src/app/admin/admin-dashboard/admin-dashboard.component.ts (preloaded modules)">
</code-example>
<code-example path="router/src/app/admin/admin-dashboard/admin-dashboard.component.ts" header="src/app/admin/admin-dashboard/admin-dashboard.component.ts (preloaded modules)"></code-example>
@ -4257,9 +4101,7 @@ You've setup the routes for navigating around your application. You've used navi
Let's take the `Hero` routes and migrate them to new URLs. The `Router` checks for redirects in your configuration before navigating, so each redirect is triggered when needed. To support this change, you'll add redirects from the old routes to the new routes in the `heroes-routing.module`.
<code-example path="router/src/app/heroes/heroes-routing.module.ts" linenums="false" header="src/app/heroes/heroes-routing.module.ts (heroes redirects)">
</code-example>
<code-example path="router/src/app/heroes/heroes-routing.module.ts" header="src/app/heroes/heroes-routing.module.ts (heroes redirects)"></code-example>
You'll notice two different types of redirects. The first change is from `/heroes` to `/superheroes` without any parameters. This is a straightforward redirect, unlike the change from `/hero/:id` to `/superhero/:id`, which includes the `:id` route parameter. Router redirects also use powerful pattern matching, so the `Router` inspects the URL and replaces route parameters in the `path` with their appropriate destination. Previously, you navigated to a URL such as `/hero/15` with a route parameter `id` of `15`.
@ -4277,21 +4119,15 @@ Before updating the `app-routing.module.ts`, you'll need to consider an importan
So instead, you'll update the empty path route in `app-routing.module.ts` to redirect to `/superheroes`.
<code-example path="router/src/app/app-routing.module.ts" linenums="false" header="src/app/app-routing.module.ts (superheroes redirect)">
</code-example>
<code-example path="router/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts (superheroes redirect)"></code-example>
`RouterLink`s aren't tied to route configuration, so you'll need to update the associated router links so they remain active when the new route is active. You'll update the `app.component.ts` template for the `/heroes` routerLink.
<code-example path="router/src/app/app.component.html" linenums="false" header="src/app/app.component.html (superheroes active routerLink)">
</code-example>
<code-example path="router/src/app/app.component.html" header="src/app/app.component.html (superheroes active routerLink)"></code-example>
Update the `goToHeroes()` method in the `hero-detail.component.ts` to navigate back to `/superheroes` with the optional route parameters.
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.ts" linenums="false" region="redirect" header="src/app/heroes/hero-detail/hero-detail.component.ts (goToHeroes)">
</code-example>
<code-example path="router/src/app/heroes/hero-detail/hero-detail.component.ts" region="redirect" header="src/app/heroes/hero-detail/hero-detail.component.ts (goToHeroes)"></code-example>
With the redirects setup, all previous routes now point to their new destinations and both URLs still function as intended.
@ -4312,9 +4148,7 @@ examining its `config` property.
For example, update the `AppModule` as follows and look in the browser console window
to see the finished route configuration.
<code-example path="router/src/app/app.module.7.ts" linenums="false" header="src/app/app.module.ts (inspect the router config)" region="inspect-config">
</code-example>
<code-example path="router/src/app/app.module.7.ts" header="src/app/app.module.ts (inspect the router config)" region="inspect-config"></code-example>
{@a final-app}
@ -4353,27 +4187,21 @@ A link parameters array holds the following ingredients for router navigation:
You can bind the `RouterLink` directive to such an array like this:
<code-example path="router/src/app/app.component.3.ts" linenums="false" header="src/app/app.component.ts (h-anchor)" region="h-anchor">
</code-example>
<code-example path="router/src/app/app.component.3.ts" header="src/app/app.component.ts (h-anchor)" region="h-anchor"></code-example>
You've written a two element array when specifying a route parameter like this:
<code-example path="router/src/app/heroes/hero-list/hero-list.component.1.html" linenums="false" header="src/app/heroes/hero-list/hero-list.component.html (nav-to-detail)" region="nav-to-detail">
</code-example>
<code-example path="router/src/app/heroes/hero-list/hero-list.component.1.html" header="src/app/heroes/hero-list/hero-list.component.html (nav-to-detail)" region="nav-to-detail"></code-example>
You can provide optional route parameters in an object like this:
<code-example path="router/src/app/app.component.3.ts" linenums="false" header="src/app/app.component.ts (cc-query-params)" region="cc-query-params">
</code-example>
<code-example path="router/src/app/app.component.3.ts" header="src/app/app.component.ts (cc-query-params)" region="cc-query-params"></code-example>
@ -4383,9 +4211,7 @@ The moment you add a child router, such as the crisis center, you create new lin
Recall that you specified a default child route for the crisis center so this simple `RouterLink` is fine.
<code-example path="router/src/app/app.component.3.ts" linenums="false" header="src/app/app.component.ts (cc-anchor-w-default)" region="cc-anchor-w-default">
</code-example>
<code-example path="router/src/app/app.component.3.ts" header="src/app/app.component.ts (cc-anchor-w-default)" region="cc-anchor-w-default"></code-example>
@ -4401,9 +4227,7 @@ Take it a step further. Consider the following router link that
navigates from the root of the application down to the *Dragon Crisis*:
<code-example path="router/src/app/app.component.3.ts" linenums="false" header="src/app/app.component.ts (Dragon-anchor)" region="Dragon-anchor">
</code-example>
<code-example path="router/src/app/app.component.3.ts" header="src/app/app.component.ts (Dragon-anchor)" region="Dragon-anchor"></code-example>
@ -4418,9 +4242,7 @@ navigates from the root of the application down to the *Dragon Crisis*:
If you wanted to, you could redefine the `AppComponent` template with *Crisis Center* routes exclusively:
<code-example path="router/src/app/app.component.3.ts" linenums="false" header="src/app/app.component.ts (template)" region="template">
</code-example>
<code-example path="router/src/app/app.component.3.ts" header="src/app/app.component.ts (template)" region="template"></code-example>
@ -4553,9 +4375,7 @@ If the `app` folder is the application root, as it is for this application,
set the `href` value in **`index.html`** *exactly* as shown here.
<code-example path="router/src/index.html" linenums="false" header="src/index.html (base-href)" region="base-href">
</code-example>
<code-example path="router/src/index.html" header="src/index.html (base-href)" region="base-href"></code-example>
#### HTML5 URLs and the *&lt;base href>*
@ -4568,9 +4388,7 @@ The preferred way to configure the strategy is to add a
tag in the `<head>` of the `index.html`.
<code-example path="router/src/index.html" linenums="false" header="src/index.html (base-href)" region="base-href">
</code-example>
<code-example path="router/src/index.html" header="src/index.html (base-href)" region="base-href"></code-example>
@ -4596,6 +4414,4 @@ providing the `useHash: true` in an object as the second argument of the `Router
in the `AppModule`.
<code-example path="router/src/app/app.module.6.ts" linenums="false" header="src/app/app.module.ts (hash URL strategy)">
</code-example>
<code-example path="router/src/app/app.module.6.ts" header="src/app/app.module.ts (hash URL strategy)"></code-example>

View File

@ -32,7 +32,7 @@ The context also defines a *merge strategy* that determines how changes are merg
When you create a new blank schematic with the [Schematics CLI](#cli), the generated entry function is a *rule factory*.
A `RuleFactory`object defines a higher-order function that creates a `Rule`.
<code-example language="TypeScript" linenums="false">
<code-example language="TypeScript">
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
// You don't have to export the function as default.
@ -49,7 +49,7 @@ You need a rule, for example, to define how a template in the schematic is to be
Rules can make use of utilities provided with the `@schematics/angular` package. Look for helper functions for working with modules, dependencies, TypeScript, AST, JSON, Angular CLI workspaces and projects, and more.
<code-example language="none" linenums="false">
<code-example language="none">
import {
JsonAstObject,
@ -78,7 +78,7 @@ You can see examples of schema files for the Angular CLI command schematics in [
Schematics come with their own command-line tool.
Using Node 6.9 or above, install the Schematics command line tool globally:
<code-example language="bash" linenums="false">
<code-example language="bash">
npm install -g @angular-devkit/schematics-cli
</code-example>
@ -94,7 +94,7 @@ See [Schematics for Libraries](guide/schematics-for-libraries).
The following command creates a new schematic named `hello-world` in a new project folder of the same name.
<code-example language="bash" linenums="false">
<code-example language="bash">
schematics blank --name=hello-world
</code-example>
@ -102,7 +102,7 @@ The `blank` schematic is provided by the Schematics CLI. The command creates a n
Go to the collection folder, install your npm dependencies, and open your new collection in your favorite editor to see the generated files. For example, if you are using VSCode:
<code-example language="bash" linenums="false">
<code-example language="bash">
cd hello-world
npm install
npm run build
@ -118,14 +118,14 @@ Each schematic name must be unique within the collection.
Use the `schematics` command to run a named schematic.
Provide the path to the project folder, the schematic name, and any mandatory options, in the following format.
<code-example language="bash" linenums="false">
<code-example language="bash">
schematics &lt;path-to-schematics-project&gt;:&lt;schematics-name&gt; --&lt;required-option&gt;=&lt;value&gt;
</code-example>
The path can be absolute or relative to the current working directory where the command is executed.
For example, to run the schematic we just generated (which has no required options), use the following command.
<code-example language="bash" linenums="false">
<code-example language="bash">
schematics .:hello-world
</code-example>
@ -133,7 +133,7 @@ schematics .:hello-world
To add a schematic to an existing collection, use the same command you use to start a new schematics project, but run the command inside the project folder.
<code-example language="bash" linenums="false">
<code-example language="bash">
cd hello-world
schematics blank --name=goodbye-world
</code-example>
@ -147,7 +147,7 @@ The top level of the root project folder for a collection contains configuration
The `src/` folder contains subfolders for named schematics in the collection, and a schema, `collection.json`, which describes the collected schematics.
Each schematic is created with a name, description, and factory function.
<code-example language="none" linenums="false">
<code-example language="none">
{
"$schema":
"../node_modules/@angular-devkit/schematics/collection-schema.json",

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