Compare commits

...

315 Commits

Author SHA1 Message Date
8dfcc78c08 docs(aio): api page cleanup 2018-07-18 20:16:52 -07:00
23dc9a90b0 docs: fix typo in user input guide (#22630)
PR Close #22630
2018-07-18 14:04:09 -04:00
0b28732d77 docs: typos in directives docs (#24665)
Fixes some typos introduced by #23902

PR Close #24665
2018-07-17 16:45:17 -04:00
06a33984af build: rename angular_devkit dependency to angular_cli (#24842)
PR Close #24842
2018-07-17 16:44:01 -04:00
ba3eb8b654 feat(ivy): properly apply class="", [class], [class.foo] and [attr.class] bindings (#24822)
PR Close #24822
2018-07-17 16:33:25 -04:00
c8ad9657c9 fix(compiler): i18n_extractor now outputs the correct source file name (#24885)
for non-inline templates

- Non-inline templates used to ouput the path to the component TS file
instead of the path to the original HTML file.
- Inline templates keep the same behavior.

Fixes #24884

PR Close #24885
2018-07-16 16:09:01 -04:00
9be8abd012 build: disable IE web worker tests (#24908)
Travis (saucelabs) has been super flaky when running IE
web worker tests lately. This patch temporarily disables
these tests on IE (not edge) until things get more stable.

PR Close #24908
2018-07-16 16:07:56 -04:00
74b250b146 feat(docs-infra): enable filtering by package on API list page (#24631)
PR Close #24631
2018-07-13 19:45:55 -04:00
d8c828c9b1 build(docs-infra): implement the 'package' API template (#24631)
PR Close #24631
2018-07-13 19:45:54 -04:00
97277bc9fb build: update to Bazel 0.15 (#24841)
PR Close #24841
2018-07-13 15:05:16 -04:00
1821b75530 test(ivy): run render3 tests with test.sh (#24866)
PR Close #24866
2018-07-13 14:27:54 -04:00
82004c76ac docs: update component styles doc regarding relative URL (#24471)
Update the documentation to match the CLI mechanics regarding relative URL in link tags.
docs: update info on stylesheet location for CLI


PR Close #24471
2018-07-12 16:44:00 -04:00
a663565403 build: fix windows scripts (#23121)
The `packages/core/src/animation/dsl.ts` symlink ws removed in #22692,
so `create-/remove-symlinks.sh` scripts for Windows should not try to
"fix" it.

PR Close #23121
2018-07-12 16:42:56 -04:00
85d9c20b1d docs(aio): Add Angular Training to list of training companies (#23907)
PR Close #23907
2018-07-12 16:39:56 -04:00
80a74b450a docs(forms): update form builder API reference (#24693)
PR Close #24693
2018-07-12 16:38:26 -04:00
9a6f27c34c fix(ivy): support zero-argument @NgModule() invocations (#24738)
It's possible to declare an argument-less NgModule:

@NgModule() export class Foo {}

Update the @NgModule compiler to support this usage.

PR Close #24738
2018-07-12 16:36:35 -04:00
d723a69b31 fix(ivy): animations should not be a hard error yet (#24738)
Previously the Ivy template compiler would throw on encountering
an animation binding (e.g. [@anim]). This is unneccessary and
precludes testing existing code. This commit changes the error to a
warning.

PR Close #24738
2018-07-12 16:36:35 -04:00
d98b1c3bc4 fix(ivy): strip newlines from selectors in .d.ts files (#24738)
When writing selectors as string literal types in .d.ts files,
strip newlines to avoid generating invalid code. Newlines carry
no meaning in selectors anyway.

PR Close #24738
2018-07-12 16:36:35 -04:00
02b5087685 build(ivy): enable ngtsc AOT builds for a few packages (#24738)
Turn on AOT builds using ngtsc for:

* animations
* common
* compiler
* compiler-cli
* forms
* platform-browser

PR Close #24738
2018-07-12 16:36:35 -04:00
48394c64ae fix(ivy): remove spurious comma in ngtsc-built .d.ts files (#24738)
On accident a comma was emitted between imports when generating .d.ts
files. This commit removes it.

PR Close #24738
2018-07-12 16:36:35 -04:00
cde0b4b361 fix(ivy): *Def types are private (ɵ) symbols (#24738)
On accident a few of the definition types were emitted as public API
symbols. Much of the Ivy API surface is still prefixed with ɵ,
indicating it's a private API. The definition types should be private
for now.

PR Close #24738
2018-07-12 16:36:35 -04:00
9f20dd937a feat(ivy): give ngtsc a basic understanding of ModuleWithProviders (#24738)
This commit changes the @NgModule provider to understand that sometimes
an import will resolve to an object instead of a type, and that object
could be of the ModuleWithProviders type. In that case, the 'ngModule'
property is read, and its value used instead.

This still will not handle ModuleWithProviders references across
compilation units; that work is coming in a future PR.

PR Close #24738
2018-07-12 16:36:35 -04:00
a1b630ee8f fix(ivy): generate a type parameter for InjectorDef (#24738)
InjectorDef is parameterized on the type of the injector
configuration class (e.g. the @NgModule decorated type). Previously
this parameter was not included when generating .d.ts files that
contained InjectorDefs.

PR Close #24738
2018-07-12 16:36:35 -04:00
d05d28629d test(common): run common/http tests with Bazel (#24738)
@angular/common/http had tests which were not executed in Bazel. This
commit adds a BUILD.bazel file and ensures the tests pass.

PR Close #24738
2018-07-12 16:36:35 -04:00
ee50ee493d build(bazel): try removing gazelle (#24787)
PR Close #24787
2018-07-12 16:34:45 -04:00
161ff5c79d feat(bazel): protractor_web_test_suite for release (#24787)
PR Close #24787
2018-07-12 16:34:45 -04:00
71e0df039c feat(bazel): Initial commit of protractor_web_test_suite (#24787)
Co-authored-by: Andrew Z Allen <me@andrewzallen.com>

PR Close #24787
2018-07-12 16:34:45 -04:00
0399c6972a refactor(ivy): remove content query creation from directive factories (#24811)
PR Close #24811
2018-07-12 16:32:33 -04:00
328971ffcc feat(router): add urlUpdateStrategy allow updating the browser URL at the beginning of navigation (#24820)
Fixes #24616

PR Close #24820
2018-07-12 14:40:08 -04:00
4d8b8ad372 build(bazel): Undo temporary dependency on unleased TS bazel rules (#24826)
Point to a proper new release version 0.15.1.

PR Close #24826
2018-07-12 14:38:14 -04:00
0d6b74dd87 docs: fix typo in component architecture guide (#24832)
Change the sentence from 'this tells Angular how provide ...' to 'this tells Angular how to provide ...'. The current sentence does not make grammatical sense.

PR Close #24832
2018-07-12 14:31:27 -04:00
52d11f63cf release: cut the v6.0.9 release 2018-07-12 09:10:44 -07:00
a14f25c338 release: cut the v6.1.0-rc.0 release 2018-07-12 09:08:20 -07:00
0b4d85e9f1 fix(common): format fractional seconds (#24844)
fix a bug introduced in #24831

PR Close #24844
2018-07-11 14:32:32 -07:00
b9e095aa31 release: cut the v6.0.8 release 2018-07-11 14:01:40 -07:00
05e3e4d71e docs(forms): update API reference for form validators (#24734)
PR Close #24734
2018-07-10 18:52:40 -07:00
81a9db2b0a docs(forms): added missing backtick (#24451)
Fixed trivial markdown problem with a missing backtick.

PR Close #24451
2018-07-10 18:51:08 -07:00
b7823e7087 docs: unified string chaining (#22735)
PR Close #22735
2018-07-10 18:50:44 -07:00
3f8ab80583 docs(aio): unified string chaining (#22735)
PR Close #22735
2018-07-10 18:50:44 -07:00
ffb9dc6cf9 docs: fix incorrect forms selector references (#22631)
PR Close #22631
2018-07-10 18:50:17 -07:00
86d254d386 fix(router): add ability to recover from malformed url (#23283)
Fixes #21468

PR Close #23283
2018-07-10 18:48:52 -07:00
505b54b86b docs: fix typos referencing inline component styles (#22557)
PR Close #22557
2018-07-10 18:48:29 -07:00
a527c695aa fix(common): do not round factional seconds (#24831)
fixes #24384

PR Close #24831
2018-07-10 18:48:05 -07:00
80576641a8 build: update to latest nodejs bazel rules (#24817)
PR Close #24817
2018-07-10 18:47:39 -07:00
50fbed8e5f docs: correct project definition (#24807)
PR Close #24807
2018-07-10 18:47:19 -07:00
7d27ecc319 fix(platform-browser): workaround wrong import path generated by ngc for DOCUMENT (#24830) 2018-07-10 17:09:29 -07:00
03616bcb43 docs: fix typo in Universal guide (#24812)
PR Close #24812
2018-07-10 11:12:45 -07:00
3a19f70d1c refactor(ivy): replace pNextOrParent with TNode props (#24752)
PR Close #24752
2018-07-10 11:12:27 -07:00
dc1f1295ee fix(ivy): support projecting into dynamic views (#24752)
PR Close #24752
2018-07-10 11:12:27 -07:00
49df4ef454 docs: add tree-shakable providers (#24481)
PR Close #24481
2018-07-10 11:12:07 -07:00
e1146f3d06 docs: clarify wording in architecture overview (#24481)
Closes #23463
Closes #22158

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

PR Close #22856
2018-07-10 11:11:48 -07:00
a167bca927 docs: unified console.log single string style (#22737)
PR Close #22737
2018-07-10 11:11:29 -07:00
e3709f5d48 docs(aio): unified console.log single string style (#22737)
PR Close #22737
2018-07-10 11:11:29 -07:00
197387d05e fix(platform-browser): mark Meta and Title services as tree shakable providers (#24815)
This lets services that use Meta and Title services to be tree shakable and provided in root.

PR Close #24815
2018-07-10 11:11:09 -07:00
1089261717 fix(core): mark NgModule as not the root if APP_ROOT is set to false (#24814)
Tree shakable providers use the APP_ROOT token to determine where to attach themselves. APP_ROOT gets set on NgModule with BrowserModule irrespective of whether it is actually the root(Ex. in case of SSR app where the shell app is first bootstrapped without BrowserModule being the root module).

This change allows a NgModule with BrowserModule to explicitly mark itself as not the root by setting APP_ROOT token to false. This allows tree shakable providers to be attached to the right rott module.

PR Close #24814
2018-07-10 11:09:36 -07:00
ddb792da28 build: remove unnecessary internal-angular karma reporter (#24803)
The reporter was added in 87d56acda, with the purpose of fixing
source-map paths (which was apparently needed back then). Things have
moved around a lot since then and the custom reporter doesn't seem to be
necessary any more. By removing the reporter, we have one less thing to
worry about while upgrading karma; plus we get improvements in built-in
reporters for free.

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

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

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

PR Close #24803
2018-07-09 15:10:49 -07:00
3d20c50156 fix(ivy): correctly resolve Array property access (#24664)
PR Close #24664
2018-07-09 15:10:29 -07:00
dcabb05102 fix(common): use correct currency format for locale de-AT (#24658)
Fixes #24609
PR Close #24658
2018-07-09 15:10:06 -07:00
68814040e3 fix(language-service): do not overwrite native Reflect (#24299)
Fixes #21420

PR Close #24299
2018-07-09 15:09:16 -07:00
3980640d53 feat(ivy): properly apply style="", [style], [style.foo] and [attr.style] bindings (#24602)
PR Close #24602
2018-07-06 13:51:00 -07:00
52d43a99ef fix(service-worker): avoid network requests when looking up hashed resources in cache (#24127)
PR Close #24127
2018-07-06 13:50:37 -07:00
45feb10c46 refactor(service-worker): avoid unnecessary operations and remove unused code (#24127)
PR Close #24127
2018-07-06 13:50:37 -07:00
250527ca68 feat(service-worker): add support for ? in SW config globbing (#24105)
The globbing is used in the following sections:
- `assetGroups` > `resources` > `files`/`versionedFiles`
- `assetGroups` > `resources` > `urls`
- `dataGroups` > `urls`
- `navigationUrls`

Query params are ignored for `files`/`versionedFiles` and
`navigationUrls`, but they are still taken into account for
`assetGroups`/`dataGroups` `urls`. To avoid a breaking change, `?` is
matched literally for these patterns.

PR Close #24105
2018-07-06 13:50:17 -07:00
94076c934c docs: update Angular Boot Camp description (#23653)
PR Close #23653
2018-07-06 13:49:56 -07:00
f936b8cbd2 docs: refactored ng-container code (#22742)
PR Close #22742
2018-07-06 13:49:35 -07:00
d571a51739 build: upgrade karma and related dependencies (#19904)
PR Close #19904
2018-07-06 13:48:02 -07:00
86b1cc7313 build: upgrade jasmine to 3.1.0 (#19904)
PR Close #19904
2018-07-06 13:48:02 -07:00
787c54736c test: run unit tests in random order (#19904)
PR Close #19904
2018-07-06 13:48:02 -07:00
19544060d3 refactor: re-organize and "modernize" cjs-jasmine scripts (#19904)
PR Close #19904
2018-07-06 13:48:02 -07:00
c0e2dba07b build: upgrade jasmine to 2.99.x and fix tests (#19904)
PR Close #19904
2018-07-06 13:48:02 -07:00
e01b539ee5 refactor: infer type for it() assertion functions (#19904)
PR Close #19904
2018-07-06 13:48:02 -07:00
809e8f742e test: make NgMatchers type-aware (#19904)
PR Close #19904
2018-07-06 13:48:02 -07:00
00c110b055 build: upgrade jasmine (and related typings) to latest version (#19904)
With these changes, the types are a little stricter now and also not
compatible with Protractor's jasmine-like syntax. So, we have to also
use `@types/jasminewd2` for e2e tests (but not for non-e2e tests).

I also had to "augment" `@types/jasminewd2`, because the latest
typings from [DefinitelyTyped][1] do not reflect the fact that the
`jasminewd2` version (v2.1.0) currently used by Protractor supports
passing a `done` callback to a spec.

[1]: 566e039485/types/jasminewd2/index.d.ts (L9-L15)

Fixes #23952
Closes #24733

PR Close #19904
2018-07-06 13:48:02 -07:00
1e74ea9e60 build(bazel): update to rule_nodejs 0.10.0 (#24759)
PR Close #24759
2018-07-06 10:17:36 -07:00
f62876bbcb fix(ivy): pipes are pure by default (#24750)
PR Close #24750
2018-07-06 10:17:17 -07:00
fddd2af4fc test: integration test for TS 2.9.x (#24749)
PR Close #24749
2018-07-06 10:16:58 -07:00
d5a9396017 docs(changelog): correct inaccuracies (#24713)
PR Close #24713
2018-07-06 10:16:37 -07:00
3e6a722ddb docs: add workspace and related cli terms (#24633)
PR Close #24633
2018-07-06 10:13:39 -07:00
5fe1e74dd3 docs(common): fix in the documentation of PUT (#24528)
PR Close #24528
2018-07-06 10:13:20 -07:00
f974c48885 docs: describe rounding behaviour of 'DecimalPipe' (#24303)
PR Close #24303
2018-07-06 10:13:00 -07:00
568612349f docs(aio): added a link to Angular Zero online course (Traditional Chinese) (#24228)
PR Close #24228
2018-07-06 10:11:01 -07:00
b719905f9b docs: clarify faqs about services (#24079)
PR Close #24079
2018-07-06 10:10:41 -07:00
56a8533cf3 docs: add app.module to changed documents (#23876)
PR Close #23876
2018-07-06 10:10:20 -07:00
b72dbc843f docs(router): add paramsInheritanceStrategy documentation (#22590)
PR Close #22590
2018-07-06 10:10:01 -07:00
8fe8b8fcff docs: fix typos in 'Httpclient' docs (#19127)
PR Close #19127
2018-07-06 10:09:40 -07:00
b6af8700ce feat(ivy): AOT support for compilation of @Pipes (#24703)
This commit adds support to ngtsc for compilation of the @Pipe
annotation, including support for pipes in @NgModule scopes.

PR Close #24703
2018-07-03 18:36:02 -04:00
3d52174bf1 feat(ivy): JIT support for compilation of @Pipes (#24703)
Adds support for compiling @Pipe in JIT mode, along with tests
to verify that certain aspects of compilation are correct.

PR Close #24703
2018-07-03 18:36:02 -04:00
dbdcfed2bd feat(ivy): support pipe compilation from local metadata (#24703)
This updates the r3_pipe_compiler to not depend on global analysis,
and to produce ngPipeDef instructions in the same way that the other
compilers do. It's a precursor to JIT and AOT implementations of
@Pipe compilation.

PR Close #24703
2018-07-03 18:36:02 -04:00
ffbacdf4ac fix(ivy): export the true ComponentDef/DirectiveDef types (not internal) (#24703)
This was a bug introduced in a previous commit.

PR Close #24703
2018-07-03 18:36:02 -04:00
7f3242affb docs: fix documention for attributes directive (#24367)
fix:update documentation for attributes directive to fix error

PR Close #24367
2018-07-03 18:34:58 -04:00
e3064d5432 feat: typescript 2.9 support (#24652)
PR Close #24652
2018-07-03 13:32:06 -07:00
0c3738a780 feat(ivy): support templateUrl for ngtsc (#24704)
This commit adds support for templateUrl in component templates within
ngtsc. The compilation pipeline is split into sync and async versions,
where asynchronous compilation invokes a special preanalyze() phase of
analysis. The preanalyze() phase can optionally return a Promise which
will delay compilation until it resolves.

A ResourceLoader interface is used to resolve templateUrls to template
strings and can return results either synchronously or asynchronously.
During sync compilation it is an error if the ResourceLoader returns a
Promise.

Two ResourceLoader implementations are provided. One uses 'fs' to read
resources directly from disk and is chosen if the CompilerHost doesn't
provide a readResource method. The other wraps the readResource method
from CompilerHost if it's provided.

PR Close #24704
2018-07-03 13:31:44 -07:00
0922228024 fix(core): use addCustomEqualityTester instead of overriding toEqual (#22983)
This propagates other custom equality testers added by users. Additionally, if
an Angular project is using jasmine 2.6+, it will allow Jasmine's custom object
differ to print out pretty test error messages.

fixes #22939

PR Close #22983
2018-07-03 08:35:15 -07:00
c94a2c9e3f build(bazel): update to latest rules_typescript (#24737)
PR Close #24737
2018-07-03 08:34:41 -07:00
948e2236c0 docs(aio): update contributors entry (#23786)
PR Close #23786
2018-07-02 15:45:39 -07:00
a294e0dd79 fix(ivy): correct position for re-projected containers (#24721)
PR Close #24721
2018-07-02 14:38:12 -07:00
3553977bd7 feat(core): add support for ShadowDOM v1 (#24718)
add a new ViewEncapsulation.ShadowDom option that uses the v1 Shadow DOM API to provide style encapsulation.

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

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

PR Close #23972
2018-07-02 14:36:24 -07:00
d243baf48a refactor(ivy): remove pChild from LNode (#24705)
PR Close #24705
2018-06-29 06:44:08 -07:00
ff84c5c4da fix(common): properly update collection reference in NgForOf (#24684)
closes #24155

PR Close #24684
2018-06-29 06:43:44 -07:00
87ddbdf919 docs(core): rephrase doc for Injector.get (#24670)
PR Close #24670
2018-06-29 06:43:18 -07:00
9803cb011e feat(ivy): Add InheritanceDefinitionFeature to support directive inheritance (#24570)
- Adds InheritanceDefinitionFeature to ivy
- Ensures that lifecycle hooks are inherited from super classes whether they are defined as directives or not
- Directives cannot inherit from Components
- Components can inherit from Directives or Components
- Ensures that Inputs, Outputs, and Host Bindings are inherited
- Ensures that super class Features are run

PR Close #24570
2018-06-29 06:42:40 -07:00
13d60eac61 fix(platform-browser): add missing deps for HammerGesturesPlugin (#24682)
PR Close #24682
2018-06-28 15:13:11 -07:00
d876700c26 build(docs-infra): render short description of parameters in API docs (#24537)
PR Close #24537
2018-06-28 15:03:14 -07:00
99bdd257a6 fix(ivy): support projecting containers into containers (#24695)
PR Close #24695
2018-06-28 15:01:42 -07:00
3db9d57de3 fix(docs-infra): use clean package.json template when generating zips (#24691)
Closes #24689

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

PR Close #24691
2018-06-28 15:01:00 -07:00
0ede987ced feat(ivy): Support resource resolution in JIT mode. (#24637)
Used to resolve resource URLs on `@Component` when used with JIT compilation.

```
@Component({
  selector: 'my-comp',
  templateUrl: 'my-comp.html', // This requires asynchronous resolution
})
class MyComponnent{
}

// Calling `renderComponent` will fail because `MyComponent`'s `@Compenent.templateUrl`
// needs to be resolved because `renderComponent` is synchronous process.
// renderComponent(MyComponent);

// Calling `resolveComponentResources` will resolve `@Compenent.templateUrl` into
// `@Compenent.template`, which would allow `renderComponent` to proceed in synchronous manner.
// Use browser's `fetch` function as the default resource resolution strategy.
resolveComponentResources(fetch).then(() => {
  // After resolution all URLs have been converted into strings.
  renderComponent(MyComponent);
});

```

PR Close #24637
2018-06-28 14:59:48 -07:00
71100e6d72 feat(core): add support for using async/await with Jasmine (#24637)
Example:
```
it('...', await(async() => {
  doSomething();
  await asyncFn();
  doSomethingAfter();
}));
```

PR Close #24637
2018-06-28 14:59:48 -07:00
676ec411b9 docs: consistent spacing in tutorial html files (#23105) (#24497)
- Removed surrounding spaces in interpolation expressions following the styleguide
- Consistant spacing of two spaces in html

Fixes #23105

PR Close #24497
2018-06-28 17:56:19 -04:00
01e7ff682c test(ivy): todo app only includes reflect-metadata in JIT mode (#24677)
Previously the todo app imported reflect-metadata, since it is a dependency
of JIT and the todo app tests run in both JIT and AOT modes. However, the
code doesn't get tree-shaken away in AOT mode.

This change adds a target //packages/core/test/bundling/util:reflect_metadata
which, depending on whether the compile flag is in JIT or AOT mode, either
includes reflect-metadata or is a no-op.

Not including reflect-metadata gets the compressed todo bundle down to 12.5 kB.

PR Close #24677
2018-06-28 17:51:42 -04:00
34c42836cf test(ivy): move hello_world and todo fully to ngtsc (#24677)
ngtsc is sufficiently capable now that it can compile hello_world
and todo and achieve equivalent results to ngc in ivy (global) mode.

Bundle sizes:
hello_world - 3.0 kB
todo        - 14.7 kB

PR Close #24677
2018-06-28 17:51:42 -04:00
50d4a4fe5c fix(compiler): fix a few non-tree-shakeable code patterns (#24677)
This change makes @angular/compiler more tree-shakeable by changing
an enum to a const enum and by getting rid of a top-level map that
the tree-shaker was seeing as a reference which caused r3_identifiers
to be retained.

This drops a few hundred bytes of JS from tree-shaken ngtsc compiled
apps.

PR Close #24677
2018-06-28 17:51:42 -04:00
69510acb20 test(ivy): symbol extractor should handle different compile options (#24677)
The js_expected_symbol_test implementation extracts symbols names
from a rollup iife bundle. Previously, it only handled the case
with a simple 'var bundle = ...;' statement.

Sometimes, rollup produces a more complex bundle, where the 'bundle'
variable is not the only top-level variable declared in the same
declaration statement. This commit patches the symbol exctractor
to support this more complex case.

Additionally, when the symbol test fails, it prints a command to
accept the symbol diff. This command needs to include the
--define=compile flag to ensure the diff is applied in the same
compile mode as the test was run.

PR Close #24677
2018-06-28 17:51:42 -04:00
ef1c6d8c26 feat(ivy): dummy handler for @Pipe to cause decorator removal (#24677)
Currently ngtsc does not compile @Pipe. This has a side effect
of not removing the @Pipe decorator.

This adds a dummy DecoratorHandler that compiles @Pipe into an
empty ngPipeDef. Eventually this will be replaced with a full
implementation, but for now this solution allows compield code
to be tree-shaken properly.

PR Close #24677
2018-06-28 17:51:42 -04:00
2ecaa40e64 build(ivy): run latest build-optimizer on ngtsc compiled code (#24677)
Previously the repo was depending on an old version of build optimizer.
This change updates to the latest (an RC release in the CLI package).

Additionally, this changes the behavior of ng_rollup_bundle to apply
the optimizer to ngtsc compiled code, and configures it to treat the
@angular/compiler package as side-effect-free.

This results in a substantial size reduction of ngtsc compiled code.

PR Close #24677
2018-06-28 17:51:42 -04:00
fc4dc35426 feat(ivy): strip all Angular decorators in compiled classes (#24677)
Previously ngtsc removed the class-level decorators (@Component,
etc) but left all the ancillary decorators (@Input, @Optional,
etc).

This changes the transform to descend into the members of decorated
classes and remove any Angular decorators, not just the class-level
ones.

PR Close #24677
2018-06-28 17:51:41 -04:00
104d30507a feat(ivy): able to compile @angular/core with ngtsc (#24677)
@angular/core is unique in that it defines the Angular decorators
(@Component, @Directive, etc). Ordinarily ngtsc looks for imports
from @angular/core in order to identify these decorators. Clearly
within core itself, this strategy doesn't work.

Instead, a special constant ITS_JUST_ANGULAR is declared within a
known file in @angular/core. If ngtsc sees this constant it knows
core is being compiled and can ignore the imports when evaluating
decorators.

Additionally, when compiling decorators ngtsc will often write an
import to @angular/core for needed symbols. However @angular/core
cannot import itself. This change creates a module within core to
export all the symbols needed to compile it and adds intelligence
within ngtsc to write relative imports to that module, instead of
absolute imports to @angular/core.

PR Close #24677
2018-06-28 17:51:41 -04:00
c57b491778 release: cut the v6.1.0-beta.3 release 2018-06-27 18:12:36 -07:00
1dc7d0d29e release: cut the v6.0.7 release 2018-06-27 17:53:49 -07:00
39c8baea31 fix(common): use correct ICU plural for locale mk (#24659)
PR Close #24659
2018-06-27 15:03:34 -07:00
abed2cd52c refactor(upgrade): fix examples for strictPropertyInitialization and remove internal comments (#18487) (#18487)
PR Close #18487

PR Close #18487
2018-06-27 15:01:47 -07:00
22758912a0 docs(aio): tech edits to upgrade-lazy (#18487) (#18487)
PR Close #18487

PR Close #18487
2018-06-27 15:01:47 -07:00
bb6b59128f docs(upgrade): use a class for upgraded service (#18487) (#18487)
This makes the resulting use in Angular more ideomatic, since we can just
use the class type as the injection indicator.

PR Close #18487

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

PR Close #18487

PR Close #18487
2018-06-27 15:01:47 -07:00
70156bc4ed docs(upgrade): add guide about downgradeModule() (#18487) (#18487)
PR Close #18487

PR Close #18487
2018-06-27 15:01:47 -07:00
2ac2ab7ff6 docs(upgrade): add API docs for downgradeModule() (#18487) (#18487)
PR Close #18487

PR Close #18487
2018-06-27 15:01:47 -07:00
ca0a55f4ee docs(upgrade): add API docs for propagateDigest (#18487) (#18487)
PR Close #18487

PR Close #18487
2018-06-27 15:01:47 -07:00
0b3d25d67e docs(upgrade): update API docs for upgrade/static (#18487) (#18487)
PR Close #18487

PR Close #18487
2018-06-27 15:01:47 -07:00
24e0c3d43d docs: minor fixes in docs-style-guide (#18487) (#18487)
PR Close #18487

PR Close #18487
2018-06-27 15:01:47 -07:00
922908818f test: minor improvements in examples e2e tests script (#18487) (#18487)
PR Close #18487

PR Close #18487
2018-06-27 15:01:47 -07:00
8dec381145 docs: fix unit tests in toh-pt6 (#24491)
Resolves #20373

PR Close #24491
2018-06-27 14:33:26 -07:00
32da3e1602 docs: add explanation for enableResourceInlining (#24644)
PR Close #24644
2018-06-27 14:31:53 -07:00
6d68f3e39a docs(changelog): remove repeating blocks (#24654)
PR Close #24654
2018-06-27 14:29:20 -07:00
50fb13fb09 fix(ivy): report results to appropriate content queries (#24673)
PR Close #24673
2018-06-27 14:20:34 -07:00
fe8fcc834c refactor(ivy): remove dynamicParent from LNode (#24678)
PR Close #24678
2018-06-27 14:14:46 -07:00
5c0e681bf3 docs(aio): fix adding to template driven forms (#23743)
PR Close #23743
2018-06-26 11:03:36 -07:00
7d6e833a6f docs(aio): fix issues suggested by Brandon (#23743)
PR Close #23743
2018-06-26 11:03:35 -07:00
49e900d6fc docs(aio): fix issues suggested by Kara (#23743)
PR Close #23743
2018-06-26 11:03:35 -07:00
5feb9e1935 docs(aio): address pr review issues (#23743)
PR Close #23743
2018-06-26 11:03:35 -07:00
002a5afa98 docs(aio): add cross field validation example (#23743)
PR Close #23743
2018-06-26 11:03:35 -07:00
cf0968f98e build(docs-infra): support hiding constructors of injectable classes (#24529)
Classes that are injectable often have constructors that should not be
called by the application developer. It is the responsibility of the
injector to instantiate the class and the constructor often contains
private implementation details that may need to change.

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

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

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

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

PR Close #24529
2018-06-26 10:58:11 -07:00
855e8ad9f6 fix(ivy): use closure-safe field name for JIT of ngInjectableDef (#24632)
PR Close #24632
2018-06-26 10:56:54 -07:00
89c442270a feat(ivy): generate ngInjectorDef for @NgModule in JIT mode (#24632)
This commit takes advantage of the @angular/compiler work for ngInjectorDef
in AOT mode in order to generate the same definition in JIT mode.

PR Close #24632
2018-06-26 10:56:53 -07:00
ae9418c7de feat(ivy): generate ngInjectorDef for @NgModule in AOT mode (#24632)
This change generates ngInjectorDef as well as ngModuleDef for @NgModule
annotated types, reflecting the dual nature of @NgModules as both compilation
scopes and as DI configuration containers.

This required implementing ngInjectorDef compilation in @angular/compiler as
well as allowing for multiple generated definitions for a single decorator in
the core of ngtsc.

PR Close #24632
2018-06-26 10:56:53 -07:00
166d90d2a9 ci: fix broken build 2018-06-25 11:36:35 -07:00
7d318743c1 docs: test doc for decorator templates (#23902) (#23902)
PR Close #23902

PR Close #23902
2018-06-25 10:49:31 -07:00
2a68ba4cbb docs: fix misdirected group links (#24569)
PR Close #24569
2018-06-25 10:03:42 -07:00
d244523ae6 docs: test api doc for pipes (#24141)
PR Close #24141
2018-06-25 09:37:30 -07:00
941d2cdaaf test(aio): fix upgrade-phonecat examples e2e tests (#24583)
Closes #19625

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

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

PR Close #24583
2018-06-25 09:30:46 -07:00
f841e36543 ci: scripts to review PRs locally (#24623)
PR Close #24623
2018-06-25 08:45:12 -07:00
f229449c67 refactor(ivy): insert embedded views immediately (#24629)
PR Close #24629
2018-06-25 07:58:33 -07:00
6e20e0aac8 fix(animations): set animations styles properly on platform-server (#24624)
Animations styles weren't getting properly set on platform-server because of erroneous checks and absence of reflection of style property to attribute on the server.

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

PR Close #24624
2018-06-25 07:58:11 -07:00
1e139d4339 refactor(ivy): rename, limit usage of global vars (#24604)
PR Close #24604
2018-06-25 07:57:52 -07:00
fba3f10938 docs: add guide-angular.wishtack.io to education resources (#24585)
PR Close #24585
2018-06-25 07:57:33 -07:00
c95437f15d build(bazel): Turning on strictPropertyInitialization for Angular. (#24572)
All errors for existing fields have been detected and suppressed with a
`!` assertion.

Issue/24571 is tracking proper clean up of those instances.

One-line change required in ivy/compilation.ts, because it appears that
the new syntax causes tsickle emitted node to no longer track their
original sourceFiles.

PR Close #24572
2018-06-25 07:57:13 -07:00
39c7769c9e docs(core): typo in static injector tests (#24548)
PR Close #24548
2018-06-25 07:56:56 -07:00
8c51ce6f3b build(docs-infra): move overload short description above syntax (#24526)
PR Close #24526
2018-06-25 07:56:36 -07:00
71b0c3d469 docs(elements): mention comp: elements as a valid label (#24443)
PR Close #24443
2018-06-25 07:56:14 -07:00
b8760a0ca5 test(elements): test typings against TS 2.7 and 2.8 (#24443)
PR Close #24443
2018-06-25 07:56:14 -07:00
50fb58fd01 test: remove unnecessary yarn.lock file (#24443)
PR Close #24443
2018-06-25 07:56:14 -07:00
fe8fe9ba9e docs: update Angular CLI option for sourcemaps (#24437)
PR Close #24437
2018-06-25 07:53:26 -07:00
637805a0c9 docs: update lowercase pipe example in "AngularJS to Angular" guide (#24588)
PR Close #24588
2018-06-21 13:14:31 -07:00
7b2b1afe71 fix(ivy): support inputs/outputs in decorator metadata in JIT (#24565)
PR Close #24565
2018-06-21 13:14:10 -07:00
7d3fd4d655 fix(ivy): inject() no longer uses default value parameters (#24565)
inject() was changed in da31db7 to not take a default value parameter,
so injectable_compiler_2 should not request the use of one when
using inject().

PR Close #24565
2018-06-21 13:14:10 -07:00
10da6a45c6 refactor(ivy): first pass at extracting ReflectionHost for abstract reflection (#24541)
ngtsc needs to reflect over code to property compile it. It performs operations
such as enumerating decorators on a type, reading metadata from constructor
parameters, etc.

Depending on the format (ES5, ES6, etc) of the underlying code, the AST
structures over which this reflection takes place can be very different. For
example, in TS/ES6 code `class` declarations are `ts.ClassDeclaration` nodes,
but in ES5 code they've been downleveled to `ts.VariableDeclaration` nodes that
are initialized to IIFEs that build up the classes being defined.

The ReflectionHost abstraction allows ngtsc to perform these operations without
directly querying the AST. Different implementations of ReflectionHost allow
support for different code formats.

PR Close #24541
2018-06-21 13:13:49 -07:00
84272e2227 feat(ivy): runtime i18n (#24037)
PR Close #24037
2018-06-21 13:13:30 -07:00
cb31381734 build(docs-infra): redirect removed webpack guide to v5.angular.io (#24595)
The outdated webpack guide has been removed in #24478, but people might
still try to access it (via direct links or search-engine results).

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

PR Close #24595
2018-06-20 16:51:33 -07:00
3e1a3b2e32 fix(ivy): support queries for views inserted in lifecycle hooks (#24587)
Closes #23707

PR Close #24587
2018-06-20 16:51:14 -07:00
1e6a226703 test(ivy): ngTemplateOutlet runtime integration test (#24587)
PR Close #24587
2018-06-20 16:51:14 -07:00
b91254fc43 docs(aio): add elana olson to contributor.json file (#24579)
Add new contributor, elana olson, to the contributors list.

PR Close #24579
2018-06-20 16:50:54 -07:00
8b8168262d fix(ivy): nested ngFor should be supported (#24564)
PR Close #24564
2018-06-20 16:50:37 -07:00
a26965812b feat(docs-infra): Add GitHub and Twitter external icon links to topnav toolbar (#24542)
PR Close #24542
2018-06-20 16:50:15 -07:00
def354de16 release: cut the v6.1.0-beta.2 release 2018-06-20 16:37:10 -07:00
9782736e00 release: cut the v6.0.6 release 2018-06-20 16:32:02 -07:00
e8354edcd2 test(animations): properly reference body node for SSR environments (#23300)
PR Close #23300
2018-06-20 11:00:41 -07:00
5b76f04b7f docs: More edits (#24255)
PR Close #24255
2018-06-19 10:53:13 -07:00
a57825acf3 docs: More form control API edits (#24255)
PR Close #24255
2018-06-19 10:53:13 -07:00
efc7639352 docs: Added multicast to observable descriptions (#24255)
PR Close #24255
2018-06-19 10:53:13 -07:00
3e26cabe02 docs: formatting (#24255)
PR Close #24255
2018-06-19 10:53:13 -07:00
9d114c052a docs: More form control API references fixes (#24255)
PR Close #24255
2018-06-19 10:53:13 -07:00
43e61c25e1 docs(docs-infra): Update with review changes (#24255)
PR Close #24255
2018-06-19 10:53:13 -07:00
4e1493a1d6 docs(forms): update API reference for FormControl (#24255)
PR Close #24255
2018-06-19 10:53:13 -07:00
794584e353 docs: Remove outdated Webpack guide and example (#24478)
A supporting Webpack guide will be introduced as part of the guidance
for ejecting from the Angular CLI.

Closes #23937

PR Close #24478
2018-06-18 15:03:22 -07:00
45862d0812 build(docs-infra): ensure all headings are sentence cased (#24527)
PR Close #24527
2018-06-15 09:13:45 -07:00
f3625e424b test(common): rename keyvalue e2e test (#24489)
PR Close #24489
2018-06-14 16:55:17 -07:00
ccbda9de65 fix(core): Injector correctly honors the @Self flag (#24520)
Injector was incorrectly returning instance from parent injector even
when `@Self` was specified.

PR Close #24520
2018-06-14 16:42:07 -07:00
27bc7dcb43 feat(ivy): ngtsc compiles @Component, @Directive, @NgModule (#24427)
This change supports compilation of components, directives, and modules
within ngtsc. Support is not complete, but is enough to compile and test
//packages/core/test/bundling/todo in full AOT mode. Code size benefits
are not yet achieved as //packages/core itself does not get compiled, and
some decorators (e.g. @Input) are not stripped, leading to unwanted code
being retained by the tree-shaker. This will be improved in future commits.

PR Close #24427
2018-06-14 14:36:45 -07:00
0f7e4fae20 style(ivy): defeat clang format issue (#24479)
clang-format (on mac) has taken a disliking to this particular line, and
rewrites one of the ɵ characters to an invalid Unicode sequence.

PR Close #24479
2018-06-14 14:15:58 -07:00
a45fad3dd9 fix(ivy): keep JIT symbol table and r3_identifiers in sync (#24479)
At runtime in JIT mode, when the compiler writes a reference to a symbol that symbol
is resolved through a symbol table named angularCoreEnv in render3/jit/environment.
Previously, this symbol table was not kept up-to-date with the Ivy instruction set
and the names of symbols the compiler could reference.

This change brings the symbol table in sync, and also adds a test that verifies every
symbol the compiler can reference is available at runtime in the symbol table.

PR Close #24479
2018-06-14 14:15:58 -07:00
f00ae516eb feat(ivy): implement host bindings in JIT mode (#24479)
PR Close #24479
2018-06-14 14:15:58 -07:00
6d246d6c72 fix(ivy): allow view and content queries to match the same element (#24507)
When creating content queries from a directive on an element we need to take into account
existing view queries. The same element can be reported to both content and view queries
so freshly created content queries must be combined with pre-existing view queries.

PR Close #24507
2018-06-14 14:15:38 -07:00
7c8159b3e2 test(bazel): fix flakey bazel integration e2e test (#24522)
PR Close #24522
2018-06-14 14:14:59 -07:00
5aa12c73ae build: update to Bazel 0.14.0 (#24512)
Includes a fix for out-of-memory condition which caused this to be
reverted yesterday.

PR Close #24512
2018-06-14 10:04:42 -07:00
d8f7b293d7 fix(compiler): support . in import statements. (#20634)
fix #20363

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

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

PR Close #24000
2018-06-13 16:47:40 -07:00
8daadf360c build(aio): compute breadcrums for all API doc types (#24000)
PR Close #24000
2018-06-13 16:47:40 -07:00
859a3d5784 build(aio): fix decorator doc "inherited from" heading (#24000)
We should not include the package path in the inherited
from heading for decorator API docs

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

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

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

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

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

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

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

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

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

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

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

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

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

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

PR Close #24000
2018-06-13 16:47:40 -07:00
03f93b3772 Revert "build: update to Bazel 0.14.0 (#24296)" (#24492)
This reverts commit 0d07d273dc.

Fixes #24484

PR Close #24492
2018-06-13 16:47:18 -07:00
3ccb4490a4 release: cut the v6.1.0-beta.1 release 2018-06-13 16:08:29 -07:00
2ea197b99f release: cut the v6.0.5 release 2018-06-13 15:56:42 -07:00
503a524d27 docs: change capitalization for css hex color values (#23511)
PR Close #23511
2018-06-13 13:31:30 -07:00
a577c9e1f4 docs: edit api doc comments for new template and style (#23682)
PR Close #23682
2018-06-13 13:31:10 -07:00
52ce9d5dcb feat(core): KeyValueDiffer#diff allows null values (#24319)
PR Close #24319
2018-06-13 13:30:49 -07:00
2b49bf77af feat(common): introduce KeyValuePipe (#24319)
PR Close #24319
2018-06-13 13:30:49 -07:00
92b278c097 feat(core): export defaultKeyValueDiffers to private api (#24319)
PR Close #24319
2018-06-13 13:30:49 -07:00
513f645894 docs(aio): remove links to outdated live examples from the API documenation (#23966)
Closes #21525

PR Close #23966
2018-06-13 13:29:12 -07:00
0bd2d7bac6 docs: add message property to compose-message component (#24310)
PR Close #24310
2018-06-13 13:28:47 -07:00
82c5313740 feat(ivy): namespaced attributes added to output instructions (#24386)
NOTE: This does NOT add parsing of namespaced attributes

- Adds AttributeMarker for namespaced attributes
- Adds test for namespaced attributes
- Updates AttributeMarker enum to use CamelCase, and not UPPER_CASE names

PR Close #24386
2018-06-13 13:28:16 -07:00
c8e865ac8e docs: fix typo (#24470)
PR Close #24470
2018-06-13 11:54:26 -07:00
d9bf6e37ae docs: fix wording in 4-10 (#24385)
PR Close #24385
2018-06-13 11:53:20 -07:00
e3c54e4465 refactor(ivy): use comment nodes to mark view containers (#24346)
PR Close #24346
2018-06-13 11:23:21 -07:00
153ba4dff3 docs(aio): Reorganize style guide sections on prefixing components/directives (#22571)
Closes https://github.com/angular/angular/issues/22081

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

PR Close #23459
2018-06-13 11:20:20 -07:00
70ef061fa6 fix(ivy): remove debugger statement (#24480)
PR Close #24480
2018-06-13 10:30:08 -07:00
c2b5ebfa24 build: update buildifier to latest (#24296)
this matches the version in ngcontainer:0.3.1

PR Close #24296
2018-06-12 11:42:35 -07:00
0d07d273dc build: update to Bazel 0.14.0 (#24296)
Also update usage of the ctx.actions.args to a newer preferred API

PR Close #24296
2018-06-12 11:42:35 -07:00
131602474d docs: change aio scope to docs-infra (#24410)
Related to #24295

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

PR Close #24162
2018-06-11 14:04:30 -04:00
4d55dfd9d9 test(service-worker): allow SwPush tests to run on Node.js (#24162)
PR Close #24162
2018-06-11 14:04:30 -04:00
86bf5f3912 test(service-worker): add tests for SwPush (#24162)
PR Close #24162
2018-06-11 14:04:30 -04:00
dbfb6b9d45 refactor(service-worker): minor mocks refactoring (#24162)
PR Close #24162
2018-06-11 14:04:30 -04:00
8dd99ac550 refactor(ivy): add element instruction, reducing output size (#24379)
- Adds an element instruction
- Reduces size of compiled output slightly

PR Close #24379
2018-06-11 14:02:48 -04:00
014949f74c fix(ivy): correctly handle queries with embedded views (#24418)
This PR takes care of all the remaining cases where embedded view definition
and insertion points are different.

PR Close #24418
2018-06-11 14:01:01 -04:00
5e8bf2f88d build(docs-infra): ensure dist/ directory is cleaned before running tsc --watch (#24372)
PR Close #24372
2018-06-11 09:18:46 -07:00
ea143e7498 build(docs-infra): upgrade preview server to latest @types/shelljs (#24372)
PR Close #24372
2018-06-11 09:18:46 -07:00
29eb24b142 refactor(ivy): combine LView with data (#24382)
PR Close #24382
2018-06-08 21:41:01 -07:00
dc4a3d00d0 fix(animations): always render end-state styles for orphaned DOM nodes (#24236)
This patch ensures that any destination animation styling (state values)
are always applied even if the DOM node is not apart of the DOM.

PR Close #24236
2018-06-08 16:35:26 -07:00
8aa70c2477 docs: adds information about the VSCode clang-format extension (#24351)
PR Close #24351
2018-06-08 16:35:05 -07:00
49c5234c68 feat(router): implement scrolling restoration service (#20030)
For documentation, see `RouterModule.scrollPositionRestoration`

Fixes #13636 #10929 #7791 #6595

PR Close #20030
2018-06-08 15:30:52 -07:00
1b253e14ff fix(ivy): special case [style] and [class] bindings for future use (#23232)
PR Close #23232
2018-06-08 15:27:58 -07:00
8c1ac28275 feat(ivy): now supports SVG and MathML elements (#24377)
- Adds support for ivy creating SVG and MathML elements properly using
createElementNS

PR Close #24377
2018-06-08 15:27:35 -07:00
5ef7a07c4b docs(ivy): add <ng-container> to the remaining work items (#24381)
PR Close #24381
2018-06-08 15:27:16 -07:00
113556357a fix(ivy): compute transitive scopes from NgModuleDef only (#24334)
Previously, the transitive scopes of an NgModuleDef were computed
during execution of the @NgModule decorator. This meant that JIT-
compiled modules could only import other JIT-compiled modules, as
the import mechanism relied on the calculation of transitive scopes
to already have happened for the imported module.

This change moves computation of transitive scopes to a function
`transitiveScopesFor` (and makes it lazy). This opens the door for
AOT -> JIT or JIT -> AOT imports, as transitive scopes for AOT
modules can be calculated when needed by JIT, and AOT modules can
also write expressions that call `transitiveScopesFor` when
importing a JIT-compiled module.

PR Close #24334
2018-06-08 13:37:10 -07:00
7983f0a69b ci(ivy): configure CI environments for Ivy JIT and AOT (#24309)
Two new CircleCI environments are created: test_ivy_jit and test_ivy_aot.
Both run a subset of the tests that have been marked with Bazel tags as
being appropriate for that environment.

Once all the tests pass, builds are published to the *-builds repo both
for the legacy View Engine compiled code as well as for ivy-jit and ivy-aot.

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

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

Fixes #23647

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

Closes #24329

PR Close #24356
2018-06-08 13:33:32 -07:00
4664226b97 docs(aio): add mix and connect to front page campaigns (#24357)
PR Close #24357
2018-06-08 13:31:28 -07:00
d4c66d5edb docs(ivy): update status of impl progress (#24323)
Updating runtime implementation progress after merge of #23991

PR Close #24323
2018-06-07 18:47:36 -04:00
ce1543fcde docs(aio): Added resource link to Amexio Canvas Web Based IDE (#24336)
PR Close #24336
2018-06-07 18:46:32 -04:00
a6e797b8f5 build(bazel): fix ng_package rollup root dir for fesm2015 output (#24298)
PR Close #24298
2018-06-07 17:56:09 -04:00
ca79e11bfa feat(ivy): a generic visitor which allows prefixing nodes for ngtsc (#24230)
This adds ngtsc/util/src/visitor, a utility for visiting TS ASTs that
can add synthetic nodes immediately prior to certain types of nodes (e.g.
class declarations). It's useful to lift definitions that need to be
referenced repeatedly in generated code outside of the class that defines
them.

PR Close #24230
2018-06-07 17:55:14 -04:00
f781f741ea refactor(ivy): remove need for LContainer.template (#24335)
PR Close #24335
2018-06-07 16:40:21 -04:00
bd02b27ee1 feat(core): expose a Compiler API for accessing module ids from NgModule types (#24258)
This will allow RouterTestingModule to better support lazy loading of modules
when using summaries, since it can detect whether a module is already loaded
if it can access the id.

PR Close #24258
2018-06-07 16:19:08 -04:00
e3759f7a73 feat(ivy): add support of ApplicationRef.bootstrapModuleFactory (#23811)
PR Close #23811
2018-06-07 16:15:26 -04:00
7de2ba0e22 Revert "feat(ivy): add namespace instructions for SVG and others (#23899)"
This reverts commit 81e4b2a4bf.
2018-06-06 13:38:21 -07:00
07b4c8be42 Revert "feat(ivy): added namespaced attributes (#23899)"
This reverts commit d6989c80d3.
2018-06-06 13:38:20 -07:00
3128b26e5c Revert "feat(ivy): add element instruction (#23899)"
This reverts commit b415010222.
2018-06-06 13:38:19 -07:00
4f5b01a98a Revert "refactor(ivy): Use AttributeMarker instead of NS (#23899)"
This reverts commit 1208a35373.
2018-06-06 13:38:18 -07:00
c151f9cdc8 Revert "refactor(ivy): rename setNS, setHtmlNS and friends to namespace, namespaceHTML, etc (#23899)"
This reverts commit 0d06c866c6.
2018-06-06 13:38:17 -07:00
24ab0a7db0 Revert "refactor(ivy): clean up (#23899)"
This reverts commit 856ee73464.
2018-06-06 13:38:13 -07:00
31988a6ff9 Revert "test(ivy): add testing for namespaced attributes (#23899)"
This reverts commit e994b11105.
2018-06-06 13:38:12 -07:00
8ac74da016 Revert "docs(ivy): update SVG status (#23899)"
This reverts commit 1915e47d11.
2018-06-06 13:38:12 -07:00
355e0b0587 Revert "test(ivy): update test that is flaky in IE (#23899)"
This reverts commit 51e9e64c5a.
2018-06-06 13:38:11 -07:00
d96ae123b2 Revert "feat(ivy): SVG now handled by ivy compiler (#23899)"
This reverts commit 1007d1ad27.
2018-06-06 13:38:10 -07:00
7e73287676 Revert "feat(ivy): added new namespace and element instructions to JIT environment (#23899)"
This reverts commit acf270d724.
2018-06-06 13:38:00 -07:00
9dd647b087 release: cut the v6.1.0-beta.0 release 2018-06-06 13:15:33 -07:00
47814b4cdf release: cut the v6.0.4 release 2018-06-06 12:04:16 -07:00
700e55ce14 build(docs-infra): log warning rather than error if content errors are not fatal (#24320)
PR Close #24320
2018-06-06 10:25:04 -07:00
68d37ef0c1 build(aio): ensure the correct decorator properties are merged (#24289)
Previously only the `description` and `usageNotes` were being copied over
from the call-member of the decorator interface. Important properties such
as `shortDescription` were missed.

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

PR Close #24289
2018-06-06 10:23:47 -07:00
acf270d724 feat(ivy): added new namespace and element instructions to JIT environment (#23899)
PR Close #23899
2018-06-06 10:22:28 -07:00
1007d1ad27 feat(ivy): SVG now handled by ivy compiler (#23899)
PR Close #23899
2018-06-06 10:22:28 -07:00
51e9e64c5a test(ivy): update test that is flaky in IE (#23899)
PR Close #23899
2018-06-06 10:22:27 -07:00
1915e47d11 docs(ivy): update SVG status (#23899)
PR Close #23899
2018-06-06 10:22:27 -07:00
e994b11105 test(ivy): add testing for namespaced attributes (#23899)
PR Close #23899
2018-06-06 10:22:27 -07:00
856ee73464 refactor(ivy): clean up (#23899)
- remove unnecessary debugger statement
- rename `isSelfClosingElement` to `isEmptyElement`
- remove unnecessary template anchor in test

PR Close #23899
2018-06-06 10:22:27 -07:00
0d06c866c6 refactor(ivy): rename setNS, setHtmlNS and friends to namespace, namespaceHTML, etc (#23899)
- Renames functions
- Adds documentation

PR Close #23899
2018-06-06 10:22:27 -07:00
1208a35373 refactor(ivy): Use AttributeMarker instead of NS (#23899)
- Removes NS enum
- Uses existing AttributeMarker
- Adds enum value NAMESPACE_URI

PR Close #23899
2018-06-06 10:22:27 -07:00
b415010222 feat(ivy): add element instruction (#23899)
Adds a simplified element instruction that can be used if an element
has no children.

PR Close #23899
2018-06-06 10:22:27 -07:00
d6989c80d3 feat(ivy): added namespaced attributes (#23899)
PR Close #23899
2018-06-06 10:22:27 -07:00
81e4b2a4bf feat(ivy): add namespace instructions for SVG and others (#23899)
PR Close #23899
2018-06-06 10:22:27 -07:00
c494d3cf60 Revert "feat(ivy): add support of ApplicationRef.bootstrapModuleFactory (#23811)"
This reverts commit 22b58a717a.
This commit causes a breakage in g3.
2018-06-05 22:11:47 -07:00
22b58a717a feat(ivy): add support of ApplicationRef.bootstrapModuleFactory (#23811)
PR Close #23811
2018-06-05 20:10:25 -07:00
86b13ccf80 refactor(ivy): move static parts of LView.cleanup to TView (#24301)
PR Close #24301
2018-06-05 18:30:28 -07:00
8db928df9d fix(animations): retain trigger-state for nodes that are moved around (#24238)
This patch ensures that if a list of nodes (that contain
animation triggers) are moved around then they will retain their
trigger-value state when animated again at a later point.

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

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

PR Close #23949
2018-06-05 17:32:36 -07:00
20c463e97c feat(router): add navigation execution context info to activation hooks (#24204)
This change adds to internal API hooks (undocumented API) for
`before/afterPreactivation`. The immediate need for this API is to
allow applications to build support for marshalling navigation between
a web worker and the main application.

Fixes #24202

PR Close #24204
2018-06-05 15:15:54 -07:00
57eacf4b5a refactor(ivy): move LView.template and component templates to TView (#24300)
PR Close #24300
2018-06-05 15:13:36 -07:00
d814eaad95 build(bazel): ran format (#24279)
PR Close #24279
2018-06-05 13:36:27 -07:00
678fd32406 build(bazel): ran buildifier (#24279)
PR Close #24279
2018-06-05 13:36:27 -07:00
3e938279d0 build(bazel): fix //packages/platform-browser/test:test_web (#24279)
PR Close #24279
2018-06-05 13:36:27 -07:00
d700a409da build(bazel): enable manual ts_web_test_suite tests that require static_files (#24279)
PR Close #24279
2018-06-05 13:36:27 -07:00
b750919ce0 feat(ivy): implement ViewContainerRef.remove (#24221)
PR Close #24221
2018-06-05 13:33:40 -07:00
9c403753e2 refactor(ivy): misc minor fixes in the JIT compiler (#24308)
PR Close #24308
2018-06-05 11:33:54 -07:00
83a06863f9 docs: rename the "aio" component to "docs-infra" (#24295)
The legacy "aio" is still active for currently pending PRs,
The GH label has been renamed as well

PR Close #24295
2018-06-04 17:25:13 -07:00
08a18b82de refactor(common): Remove ngOnChanges from NgForOf (#23378)
`NgForOf` used to implement `OnChanges` and than use
`ngOnChanges` callback to detect when `ngForOf` binding
changed to update the differ. We now do the checking
manually which puts less pressure on the runtime to do
the bookkeeping and should result in minor perf improvement.

PR Close #23378
2018-06-04 13:24:43 -07:00
255463ed48 fix(aio): remove unnecessary scrollbar in code-tabs (#24207)
PR Close #24207
2018-06-04 12:07:25 -07:00
b4bbdb4ce2 fix(aio): add right-margin to .home link (#24207)
PR Close #24207
2018-06-04 12:07:25 -07:00
7623d74607 docs(aio): clean up frequent ng-modules (#24025)
Closes #24017

PR Close #24025
2018-06-04 10:13:18 -07:00
ccaa199366 docs(aio): remove an extraneous apostrophe (#24293)
PR Close #24293
2018-06-04 10:11:28 -07:00
854 changed files with 30525 additions and 13210 deletions

View File

@ -12,8 +12,8 @@
## IMPORTANT ## IMPORTANT
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of # If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file. # `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.3.0 var_1: &docker_image angular/ngcontainer:0.3.3
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.0 var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.3
# Define common ENV vars # Define common ENV vars
var_3: &define_env_vars var_3: &define_env_vars
@ -111,6 +111,42 @@ jobs:
paths: paths:
- "node_modules" - "node_modules"
- "~/bazel_repository_cache" - "~/bazel_repository_cache"
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_jit:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- restore_cache:
key: *cache_key
- run: bazel run @yarn//:yarn
- run: bazel query --output=label //... | xargs bazel test --define=compile=jit --build_tag_filters=ivy-jit --test_tag_filters=-manual,ivy-jit
test_ivy_aot:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- restore_cache:
key: *cache_key
- run: bazel run @yarn//:yarn
- run: bazel query --output=label //... | xargs bazel test --define=compile=local --build_tag_filters=ivy-local --test_tag_filters=-manual,ivy-local
# This job exists only for backwards-compatibility with old scripts and tests # This job exists only for backwards-compatibility with old scripts and tests
# that rely on the pre-Bazel dist/packages-dist layout. # that rely on the pre-Bazel dist/packages-dist layout.
@ -140,6 +176,8 @@ jobs:
root: dist root: dist
paths: paths:
- packages-dist - packages-dist
- packages-dist-ivy-jit
- packages-dist-ivy-local
# We run the integration tests outside of Bazel for now. # We run the integration tests outside of Bazel for now.
# They are a separate workflow job so that they can be easily re-run. # They are a separate workflow job so that they can be easily re-run.
@ -149,6 +187,10 @@ jobs:
# See comments inside the integration/run_tests.sh script. # See comments inside the integration/run_tests.sh script.
integration_test: integration_test:
<<: *job_defaults <<: *job_defaults
# Note: we run Bazel in one of the integration tests, and it can consume >2G
# of memory. Together with the system under test, this can exhaust the RAM
# on a 4G worker so we use a larger machine here too.
resource_class: xlarge
steps: steps:
- *define_env_vars - *define_env_vars
- checkout: - checkout:
@ -200,6 +242,8 @@ workflows:
jobs: jobs:
- lint - lint
- test - test
- test_ivy_jit
- test_ivy_aot
- build-packages-dist - build-packages-dist
- integration_test: - integration_test:
requires: requires:
@ -212,6 +256,8 @@ workflows:
requires: requires:
# Only publish if tests and integration tests pass # Only publish if tests and integration tests pass
- test - test
- test_ivy_jit
- test_ivy_aot
- integration_test - integration_test
# Get the artifacts to publish from the build-packages-dist job # Get the artifacts to publish from the build-packages-dist job
# since the publishing script expects the legacy outputs layout. # since the publishing script expects the legacy outputs layout.

View File

@ -22,6 +22,7 @@ node_modules_filegroup(
"jasmine", "jasmine",
"minimist", "minimist",
"protobufjs", "protobufjs",
"protractor",
"reflect-metadata", "reflect-metadata",
"source-map-support", "source-map-support",
"tsickle", "tsickle",
@ -34,6 +35,9 @@ node_modules_filegroup(
"@types", "@types",
"@webcomponents/custom-elements", "@webcomponents/custom-elements",
], ],
patterns = [
"node_modules/protractor/**",
],
) )
filegroup( filegroup(
@ -44,6 +48,7 @@ filegroup(
"//:node_modules/zone.js/dist/zone.js", "//:node_modules/zone.js/dist/zone.js",
"//:node_modules/zone.js/dist/zone-testing.js", "//:node_modules/zone.js/dist/zone-testing.js",
"//:node_modules/zone.js/dist/task-tracking.js", "//:node_modules/zone.js/dist/task-tracking.js",
"//:test-events.js",
], ],
) )

View File

@ -1,3 +1,205 @@
<a name="6.0.9"></a>
## [6.0.9](https://github.com/angular/angular/compare/6.0.8...6.0.9) (2018-07-11)
### Bug Fixes
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([3c93d07](https://github.com/angular/angular/commit/3c93d07)), closes [#24831](https://github.com/angular/angular/issues/24831)
<a name="6.1.0-rc.0"></a>
# [6.1.0-rc.0](https://github.com/angular/angular/compare/6.1.0-beta.3...6.1.0-rc.0) (2018-07-11)
### Bug Fixes
* **common:** do not round factional seconds ([#24831](https://github.com/angular/angular/issues/24831)) ([a527c69](https://github.com/angular/angular/commit/a527c69)), closes [#24384](https://github.com/angular/angular/issues/24384)
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([ff84c5c](https://github.com/angular/angular/commit/ff84c5c)), closes [#24155](https://github.com/angular/angular/issues/24155)
* **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([dcabb05](https://github.com/angular/angular/commit/dcabb05)), closes [#24609](https://github.com/angular/angular/issues/24609)
* **compiler:** fix a few non-tree-shakeable code patterns ([#24677](https://github.com/angular/angular/issues/24677)) ([50d4a4f](https://github.com/angular/angular/commit/50d4a4f))
* **compiler-cli:** Use typescript to resolve modules for metadata ([#22856](https://github.com/angular/angular/issues/22856)) ([0d5f2d3](https://github.com/angular/angular/commit/0d5f2d3))
* **core:** mark NgModule as not the root if APP_ROOT is set to false ([#24814](https://github.com/angular/angular/issues/24814)) ([1089261](https://github.com/angular/angular/commit/1089261))
* **core:** use addCustomEqualityTester instead of overriding toEqual ([#22983](https://github.com/angular/angular/issues/22983)) ([0922228](https://github.com/angular/angular/commit/0922228)), closes [#22939](https://github.com/angular/angular/issues/22939)
* **language-service:** do not overwrite native `Reflect` ([#24299](https://github.com/angular/angular/issues/24299)) ([6881404](https://github.com/angular/angular/commit/6881404)), closes [#21420](https://github.com/angular/angular/issues/21420)
* **platform-browser:** add missing deps for HammerGesturesPlugin ([#24682](https://github.com/angular/angular/issues/24682)) ([13d60ea](https://github.com/angular/angular/commit/13d60ea))
* **platform-browser:** mark Meta and Title services as tree shakable providers ([#24815](https://github.com/angular/angular/issues/24815)) ([197387d](https://github.com/angular/angular/commit/197387d))
* **platform-browser:** workaround wrong import path generated by ngc for DOCUMENT ([#24830](https://github.com/angular/angular/issues/24830)) ([7d27ecc](https://github.com/angular/angular/commit/7d27ecc))
* **router:** add ability to recover from malformed url ([#23283](https://github.com/angular/angular/issues/23283)) ([86d254d](https://github.com/angular/angular/commit/86d254d)), closes [#21468](https://github.com/angular/angular/issues/21468)
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([52d43a9](https://github.com/angular/angular/commit/52d43a9))
### Features
* **core:** add support for ShadowDOM v1 ([#24718](https://github.com/angular/angular/issues/24718)) ([3553977](https://github.com/angular/angular/commit/3553977))
* **core:** add support for using async/await with Jasmine ([#24637](https://github.com/angular/angular/issues/24637)) ([71100e6](https://github.com/angular/angular/commit/71100e6))
* typescript 2.9 support ([#24652](https://github.com/angular/angular/issues/24652)) ([e3064d5](https://github.com/angular/angular/commit/e3064d5))
* **service-worker:** add support for `?` in SW config globbing ([#24105](https://github.com/angular/angular/issues/24105)) ([250527c](https://github.com/angular/angular/commit/250527c))
<a name="6.0.8"></a>
## [6.0.8](https://github.com/angular/angular/compare/6.0.7...6.0.8) (2018-07-11)
### Bug Fixes
* **common:** do not round factional seconds ([#24831](https://github.com/angular/angular/issues/24831)) ([0746485](https://github.com/angular/angular/commit/0746485)), closes [#24384](https://github.com/angular/angular/issues/24384)
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([9a98de9](https://github.com/angular/angular/commit/9a98de9)), closes [#24155](https://github.com/angular/angular/issues/24155)
* **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([a92f111](https://github.com/angular/angular/commit/a92f111)), closes [#24609](https://github.com/angular/angular/issues/24609)
* **compiler-cli:** Use typescript to resolve modules for metadata ([#22856](https://github.com/angular/angular/issues/22856)) ([7717ff1](https://github.com/angular/angular/commit/7717ff1))
* **core:** use addCustomEqualityTester instead of overriding toEqual ([#22983](https://github.com/angular/angular/issues/22983)) ([b8975a9](https://github.com/angular/angular/commit/b8975a9)), closes [#22939](https://github.com/angular/angular/issues/22939)
* **language-service:** do not overwrite native `Reflect` ([#24299](https://github.com/angular/angular/issues/24299)) ([de1c44f](https://github.com/angular/angular/commit/de1c44f)), closes [#21420](https://github.com/angular/angular/issues/21420)
* **router:** add ability to recover from malformed url ([#23283](https://github.com/angular/angular/issues/23283)) ([2d4f4b5](https://github.com/angular/angular/commit/2d4f4b5)), closes [#21468](https://github.com/angular/angular/issues/21468)
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([183b079](https://github.com/angular/angular/commit/183b079))
### Features
* **core:** add support for ShadowDOM v1 ([#24718](https://github.com/angular/angular/issues/24718)) ([6c55a13](https://github.com/angular/angular/commit/6c55a13))
<a name="6.1.0-beta.3"></a>
# [6.1.0-beta.3](https://github.com/angular/angular/compare/6.1.0-beta.2...6.1.0-beta.3) (2018-06-28)
### Bug Fixes
* **animations:** set animations styles properly on platform-server ([#24624](https://github.com/angular/angular/issues/24624)) ([0b356d4](https://github.com/angular/angular/commit/0b356d4))
* **common:** use correct ICU plural for locale mk ([#24659](https://github.com/angular/angular/issues/24659)) ([64a8584](https://github.com/angular/angular/commit/64a8584))
<a name="6.0.7"></a>
## [6.0.7](https://github.com/angular/angular/compare/6.0.6...6.0.7) (2018-06-27)
### Bug Fixes
* **animations:** set animations styles properly on platform-server ([#24624](https://github.com/angular/angular/issues/24624)) ([0b356d4](https://github.com/angular/angular/commit/0b356d4))
* **common:** use correct ICU plural for locale mk ([#24659](https://github.com/angular/angular/issues/24659)) ([64a8584](https://github.com/angular/angular/commit/64a8584))
<a name="6.1.0-beta.2"></a>
# [6.1.0-beta.2](https://github.com/angular/angular/compare/6.1.0-beta.1...6.1.0-beta.2) (2018-06-20)
### Bug Fixes
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([d8f7b29](https://github.com/angular/angular/commit/d8f7b29)), closes [#20363](https://github.com/angular/angular/issues/20363)
* **core:** Injector correctly honors the @Self flag ([#24520](https://github.com/angular/angular/issues/24520)) ([ccbda9d](https://github.com/angular/angular/commit/ccbda9d))
<a name="6.0.6"></a>
## [6.0.6](https://github.com/angular/angular/compare/6.0.5...6.0.6) (2018-06-20)
### Bug Fixes
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([e543c73](https://github.com/angular/angular/commit/e543c73)), closes [#20363](https://github.com/angular/angular/issues/20363)
* **core:** Injector correctly honors the @Self flag ([#24520](https://github.com/angular/angular/issues/24520)) ([f5b3661](https://github.com/angular/angular/commit/f5b3661))
<a name="6.1.0-beta.1"></a>
# [6.1.0-beta.1](https://github.com/angular/angular/compare/6.1.0-beta.0...6.1.0-beta.1) (2018-06-13)
### Bug Fixes
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([dc4a3d0](https://github.com/angular/angular/commit/dc4a3d0))
* **bazel:** Allow ng_module to depend on targets w no deps ([#24446](https://github.com/angular/angular/issues/24446)) ([282d351](https://github.com/angular/angular/commit/282d351))
* **docs-infra:** use script nomodule to load IE polyfills, skip other polyfills ([#24317](https://github.com/angular/angular/issues/24317)) ([8be6892](https://github.com/angular/angular/commit/8be6892)), closes [#23647](https://github.com/angular/angular/issues/23647)
* **ivy:** compute transitive scopes from NgModuleDef only ([#24334](https://github.com/angular/angular/issues/24334)) ([1135563](https://github.com/angular/angular/commit/1135563))
* **ivy:** correctly handle queries with embedded views ([#24418](https://github.com/angular/angular/issues/24418)) ([014949f](https://github.com/angular/angular/commit/014949f))
* **ivy:** remove debugger statement ([#24480](https://github.com/angular/angular/issues/24480)) ([70ef061](https://github.com/angular/angular/commit/70ef061))
* **ivy:** special case [style] and [class] bindings for future use ([#23232](https://github.com/angular/angular/issues/23232)) ([1b253e1](https://github.com/angular/angular/commit/1b253e1))
* **router:** fix lazy loading of aux routes ([#23459](https://github.com/angular/angular/issues/23459)) ([5731d07](https://github.com/angular/angular/commit/5731d07)), closes [#10981](https://github.com/angular/angular/issues/10981)
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([3ed2d75](https://github.com/angular/angular/commit/3ed2d75)), closes [#24095](https://github.com/angular/angular/issues/24095)
### Features
* **common:** introduce KeyValuePipe ([#24319](https://github.com/angular/angular/issues/24319)) ([2b49bf7](https://github.com/angular/angular/commit/2b49bf7))
* **core:** export defaultKeyValueDiffers to private api ([#24319](https://github.com/angular/angular/issues/24319)) ([92b278c](https://github.com/angular/angular/commit/92b278c))
* **core:** expose a Compiler API for accessing module ids from NgModule types ([#24258](https://github.com/angular/angular/issues/24258)) ([bd02b27](https://github.com/angular/angular/commit/bd02b27))
* **core:** KeyValueDiffer#diff allows null values ([#24319](https://github.com/angular/angular/issues/24319)) ([52ce9d5](https://github.com/angular/angular/commit/52ce9d5))
* **ivy:** a generic visitor which allows prefixing nodes for ngtsc ([#24230](https://github.com/angular/angular/issues/24230)) ([ca79e11](https://github.com/angular/angular/commit/ca79e11))
* **ivy:** add support of ApplicationRef.bootstrapModuleFactory ([#23811](https://github.com/angular/angular/issues/23811)) ([e3759f7](https://github.com/angular/angular/commit/e3759f7))
* **ivy:** namespaced attributes added to output instructions ([#24386](https://github.com/angular/angular/issues/24386)) ([82c5313](https://github.com/angular/angular/commit/82c5313))
* **ivy:** now supports SVG and MathML elements ([#24377](https://github.com/angular/angular/issues/24377)) ([8c1ac28](https://github.com/angular/angular/commit/8c1ac28))
* **router:** implement scrolling restoration service ([#20030](https://github.com/angular/angular/issues/20030)) ([49c5234](https://github.com/angular/angular/commit/49c5234)), closes [#13636](https://github.com/angular/angular/issues/13636) [#10929](https://github.com/angular/angular/issues/10929) [#7791](https://github.com/angular/angular/issues/7791) [#6595](https://github.com/angular/angular/issues/6595)
<a name="6.0.5"></a>
## [6.0.5](https://github.com/angular/angular/compare/6.0.4...6.0.5) (2018-06-13)
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([0139173](https://github.com/angular/angular/commit/0139173))
* **bazel:** Allow ng_module to depend on targets w no deps ([#24446](https://github.com/angular/angular/issues/24446)) ([ea3669e](https://github.com/angular/angular/commit/ea3669e))
* **docs-infra:** use script nomodule to load IE polyfills, skip other polyfills ([#24317](https://github.com/angular/angular/issues/24317)) ([e876535](https://github.com/angular/angular/commit/e876535)), closes [#23647](https://github.com/angular/angular/issues/23647)
* **router:** fix lazy loading of aux routes ([#23459](https://github.com/angular/angular/issues/23459)) ([d20877b](https://github.com/angular/angular/commit/d20877b)), closes [#10981](https://github.com/angular/angular/issues/10981)
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([ea2987c](https://github.com/angular/angular/commit/ea2987c)), closes [#24095](https://github.com/angular/angular/issues/24095)
<a name="6.1.0-beta.0"></a>
# [6.1.0-beta.0](https://github.com/angular/angular/compare/6.0.0-rc.5...6.1.0-beta.0) (2018-06-06)
### Bug Fixes
* **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([d2a8687](https://github.com/angular/angular/commit/d2a8687))
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([b492b9e](https://github.com/angular/angular/commit/b492b9e))
* **animations:** properly clean up queried element styles in safari/edge ([#23633](https://github.com/angular/angular/issues/23633)) ([da9ff25](https://github.com/angular/angular/commit/da9ff25))
* **animations:** retain state styling for nodes that are moved around ([#23534](https://github.com/angular/angular/issues/23534)) ([65211f4](https://github.com/angular/angular/commit/65211f4))
* **animations:** retain trigger-state for nodes that are moved around ([#24238](https://github.com/angular/angular/issues/24238)) ([8db928d](https://github.com/angular/angular/commit/8db928d))
* **benchpress:** Fix promise chain in chrome_driver_extension. ([#23458](https://github.com/angular/angular/issues/23458)) ([d4b6c41](https://github.com/angular/angular/commit/d4b6c41))
* **compiler:** avoid a crash in ngc-wrapped. ([#23468](https://github.com/angular/angular/issues/23468)) ([e1c4930](https://github.com/angular/angular/commit/e1c4930))
* **compiler:** generate constant array for i18n attributes ([#23837](https://github.com/angular/angular/issues/23837)) ([cfde36d](https://github.com/angular/angular/commit/cfde36d))
* **compiler:** generate core-compliant hostBindings property ([#24087](https://github.com/angular/angular/issues/24087)) ([01b5acd](https://github.com/angular/angular/commit/01b5acd)), closes [#24013](https://github.com/angular/angular/issues/24013)
* **compiler:** handle undefined annotation metadata ([#23349](https://github.com/angular/angular/issues/23349)) ([ca776c5](https://github.com/angular/angular/commit/ca776c5))
* **compiler-cli:** don't rely on incompatible TS method ([#23550](https://github.com/angular/angular/issues/23550)) ([b1f040f](https://github.com/angular/angular/commit/b1f040f))
* **core:** avoid eager providers re-initialization ([#23559](https://github.com/angular/angular/issues/23559)) ([0c6dc45](https://github.com/angular/angular/commit/0c6dc45))
* **core:** call ngOnDestroy on all services that have it ([#23755](https://github.com/angular/angular/issues/23755)) ([fc03427](https://github.com/angular/angular/commit/fc03427)), closes [#22466](https://github.com/angular/angular/issues/22466) [#22240](https://github.com/angular/angular/issues/22240) [#14818](https://github.com/angular/angular/issues/14818)
* **elements:** always check to create strategy ([#23825](https://github.com/angular/angular/issues/23825)) ([b1cda36](https://github.com/angular/angular/commit/b1cda36))
* **elements:** prevent closure renaming of platform properties ([#23843](https://github.com/angular/angular/issues/23843)) ([d4b8b24](https://github.com/angular/angular/commit/d4b8b24))
* **forms:** properly handle special properties in FormGroup.get ([#22249](https://github.com/angular/angular/issues/22249)) ([9367e91](https://github.com/angular/angular/commit/9367e91)), closes [#17195](https://github.com/angular/angular/issues/17195)
* **platform-server:** avoid clash between server and client style encapsulation attributes ([#24158](https://github.com/angular/angular/issues/24158)) ([b96a3c8](https://github.com/angular/angular/commit/b96a3c8))
* **platform-server:** avoid dependency cycle when using http interceptor ([#24229](https://github.com/angular/angular/issues/24229)) ([60aa943](https://github.com/angular/angular/commit/60aa943)), closes [#23023](https://github.com/angular/angular/issues/23023)
* **platform-server:** don't reflect innerHTML property to attibute ([#24213](https://github.com/angular/angular/issues/24213)) ([6a663a4](https://github.com/angular/angular/commit/6a663a4)), closes [#19278](https://github.com/angular/angular/issues/19278)
* **platform-server:** provide Domino DOM types globally ([#24116](https://github.com/angular/angular/issues/24116)) ([c73196e](https://github.com/angular/angular/commit/c73196e)), closes [#23280](https://github.com/angular/angular/issues/23280) [#23133](https://github.com/angular/angular/issues/23133)
* **router:** avoid freezing queryParams in-place ([#22663](https://github.com/angular/angular/issues/22663)) ([89f64e5](https://github.com/angular/angular/commit/89f64e5)), closes [#22617](https://github.com/angular/angular/issues/22617)
* **router:** cache route handle if found ([#22475](https://github.com/angular/angular/issues/22475)) ([4cfa571](https://github.com/angular/angular/commit/4cfa571)), closes [#22474](https://github.com/angular/angular/issues/22474)
* **router:** correct the segment parsing so it won't break on ampersand ([#23684](https://github.com/angular/angular/issues/23684)) ([553a680](https://github.com/angular/angular/commit/553a680))
* **service-worker:** add badge to NOTIFICATION_OPTION_NAMES ([#23241](https://github.com/angular/angular/issues/23241)) ([fb59b2d](https://github.com/angular/angular/commit/fb59b2d)), closes [#23196](https://github.com/angular/angular/issues/23196)
* **service-worker:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0bdd30e](https://github.com/angular/angular/commit/0bdd30e))
* **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([e0ed59e](https://github.com/angular/angular/commit/e0ed59e)), closes [#23526](https://github.com/angular/angular/issues/23526)
* **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([1d378e2](https://github.com/angular/angular/commit/1d378e2))
### Features
* **compiler:** support `// ...` and `// TODO` in mock compiler expectations ([#23441](https://github.com/angular/angular/issues/23441)) ([c6b206e](https://github.com/angular/angular/commit/c6b206e))
* **compiler-cli:** update `tsickle` to `0.29.x` ([#24233](https://github.com/angular/angular/issues/24233)) ([f69ac67](https://github.com/angular/angular/commit/f69ac67))
* **platform-browser:** add HammerJS lazy-loader symbols to public API ([#23943](https://github.com/angular/angular/issues/23943)) ([26fbf1d](https://github.com/angular/angular/commit/26fbf1d))
* **platform-browser:** allow lazy-loading HammerJS ([#23906](https://github.com/angular/angular/issues/23906)) ([313bdce](https://github.com/angular/angular/commit/313bdce))
* **platform-server:** use EventManagerPlugin on the server ([#24132](https://github.com/angular/angular/issues/24132)) ([d6595eb](https://github.com/angular/angular/commit/d6595eb))
* **router:** add navigation execution context info to activation hooks ([#24204](https://github.com/angular/angular/issues/24204)) ([20c463e](https://github.com/angular/angular/commit/20c463e)), closes [#24202](https://github.com/angular/angular/issues/24202)
<a name="6.0.4"></a>
## [6.0.4](https://github.com/angular/angular/compare/6.0.3...6.0.4) (2018-06-06)
### Bug Fixes
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([c9eb491](https://github.com/angular/angular/commit/c9eb491))
* **animations:** retain trigger-state for nodes that are moved around ([#24238](https://github.com/angular/angular/issues/24238)) ([19deca1](https://github.com/angular/angular/commit/19deca1))
* **forms:** properly handle special properties in FormGroup.get ([#22249](https://github.com/angular/angular/issues/22249)) ([dc3e8aa](https://github.com/angular/angular/commit/dc3e8aa)), closes [#17195](https://github.com/angular/angular/issues/17195)
* **platform-server:** avoid clash between server and client style encapsulation attributes ([#24158](https://github.com/angular/angular/issues/24158)) ([e9f2203](https://github.com/angular/angular/commit/e9f2203))
* **platform-server:** avoid dependency cycle when using http interceptor ([#24229](https://github.com/angular/angular/issues/24229)) ([2991b1b](https://github.com/angular/angular/commit/2991b1b)), closes [#23023](https://github.com/angular/angular/issues/23023)
* **platform-server:** don't reflect innerHTML property to attibute ([#24213](https://github.com/angular/angular/issues/24213)) ([c17098d](https://github.com/angular/angular/commit/c17098d)), closes [#19278](https://github.com/angular/angular/issues/19278)
* **platform-server:** provide Domino DOM types globally ([#24116](https://github.com/angular/angular/issues/24116)) ([906b3ec](https://github.com/angular/angular/commit/906b3ec)), closes [#23280](https://github.com/angular/angular/issues/23280) [#23133](https://github.com/angular/angular/issues/23133)
<a name="6.0.3"></a> <a name="6.0.3"></a>
## [6.0.3](https://github.com/angular/angular/compare/6.0.2...6.0.3) (2018-05-22) ## [6.0.3](https://github.com/angular/angular/compare/6.0.2...6.0.3) (2018-05-22)

View File

@ -227,10 +227,15 @@ The following is the list of supported scopes:
There are currently a few exceptions to the "use package name" rule: There are currently a few exceptions to the "use package name" rule:
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc. * **packaging**: used for changes that change the npm package layout in all of our packages, e.g.
public path changes, package.json changes done to all packages, d.ts file/format changes, changes
to bundles, etc.
* **changelog**: used for updating the release notes in CHANGELOG.md * **changelog**: used for updating the release notes in CHANGELOG.md
* **aio**: used for docs-app (angular.io) related changes within the /aio directory of the repo * **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`) repo
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all
packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a
specific package (e.g. `docs: fix typo in tutorial`).
### Subject ### Subject
The subject contains a succinct description of the change: The subject contains a succinct description of the change:

View File

@ -6,23 +6,23 @@ workspace(name = "angular")
http_archive( http_archive(
name = "build_bazel_rules_nodejs", name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.9.1.zip", url = "https://github.com/bazelbuild/rules_nodejs/archive/0.10.1.zip",
strip_prefix = "rules_nodejs-0.9.1", strip_prefix = "rules_nodejs-0.10.1",
sha256 = "6139762b62b37c1fd171d7f22aa39566cb7dc2916f0f801d505a9aaf118c117f", sha256 = "634206524d90dc03c52392fa3f19a16637d2bcf154910436fe1d669a0d9d7b9c",
) )
http_archive( http_archive(
name = "io_bazel_rules_webtesting", name = "io_bazel_rules_webtesting",
url = "https://github.com/bazelbuild/rules_webtesting/archive/v0.2.0.zip", url = "https://github.com/bazelbuild/rules_webtesting/archive/7ffe970bbf380891754487f66c3d680c087d67f2.zip",
strip_prefix = "rules_webtesting-0.2.0", strip_prefix = "rules_webtesting-7ffe970bbf380891754487f66c3d680c087d67f2",
sha256 = "cecc12f07e95740750a40d38e8b14b76fefa1551bef9332cb432d564d693723c", sha256 = "4fb0dca8c9a90547891b7ef486592775a523330fc4555c88cd8f09270055c2ce",
) )
http_archive( http_archive(
name = "build_bazel_rules_typescript", name = "build_bazel_rules_typescript",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.15.0.zip", url = "https://github.com/bazelbuild/rules_typescript/archive/0.15.1.zip",
strip_prefix = "rules_typescript-0.15.0", strip_prefix = "rules_typescript-0.15.1",
sha256 = "1aa75917330b820cb239b3c10a936a10f0a46fe215063d4492dd76dc6e1616f4", sha256 = "3792cc20ef13bb1d1d8b1760894c3320f02a87843e3a04fed7e8e454a75328b6",
) )
http_archive( http_archive(
@ -34,13 +34,13 @@ http_archive(
# This commit matches the version of buildifier in angular/ngcontainer # This commit matches the version of buildifier in angular/ngcontainer
# If you change this, also check if it matches the version in the angular/ngcontainer # If you change this, also check if it matches the version in the angular/ngcontainer
# version in /.circleci/config.yml # version in /.circleci/config.yml
BAZEL_BUILDTOOLS_VERSION = "fd9878fd5de921e0bbab3dcdcb932c2627812ee1" BAZEL_BUILDTOOLS_VERSION = "82b21607e00913b16fe1c51bec80232d9d6de31c"
http_archive( http_archive(
name = "com_github_bazelbuild_buildtools", name = "com_github_bazelbuild_buildtools",
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION, url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION, strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
sha256 = "27bb461ade23fd44ba98723ad98f84ee9c83cd3540b773b186a1bc5037f3d862", sha256 = "edb24c2f9c55b10a820ec74db0564415c0cf553fa55e9fc709a6332fb6685eff",
) )
# Fetching the Bazel source code allows us to compile the Skylark linter # Fetching the Bazel source code allows us to compile the Skylark linter
@ -58,10 +58,10 @@ http_archive(
# Even better, things like aspects will visit the entire graph including # Even better, things like aspects will visit the entire graph including
# ts_library rules in the devkit repository. # ts_library rules in the devkit repository.
http_archive( http_archive(
name = "angular_devkit", name = "angular_cli",
url = "https://github.com/angular/devkit/archive/v0.3.1.zip", url = "https://github.com/angular/angular-cli/archive/v6.1.0-rc.0.zip",
strip_prefix = "devkit-0.3.1", strip_prefix = "angular-cli-6.1.0-rc.0",
sha256 = "31d4b597fe9336650acf13df053c1c84dcbe9c29c6a833bcac3819cd3fd8cad3", sha256 = "8cf320ea58c321e103f39087376feea502f20eaf79c61a4fdb05c7286c8684fd",
) )
http_archive( http_archive(
@ -77,7 +77,7 @@ http_archive(
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install") load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
check_bazel_version("0.13.0") check_bazel_version("0.15.0")
node_repositories(package_json = ["//:package.json"]) node_repositories(package_json = ["//:package.json"])
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains") load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,6 +7,7 @@
<div [hidden]="formDir.submitted"> <div [hidden]="formDir.submitted">
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
<div class="form-group"> <div class="form-group">
<label for="name">Name</label> <label for="name">Name</label>
@ -36,6 +37,13 @@
formControlName="alterEgo" > formControlName="alterEgo" >
</div> </div>
<!-- #docregion cross-validation-error-message -->
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
Name cannot match alter ego.
</div>
<!-- #enddocregion cross-validation-error-message -->
</div>
<div class="form-group"> <div class="form-group">
<label for="power">Hero Power</label> <label for="power">Hero Power</label>
<select id="power" class="form-control" <select id="power" class="form-control"

View File

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

View File

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

View File

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

View File

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

View File

@ -2,11 +2,11 @@
<div class="container"> <div class="container">
<h1>Template-Driven Form</h1> <h1>Template-Driven Form</h1>
<!-- #docregion form-tag--> <!-- #docregion cross-validation-register-validator -->
<form #heroForm="ngForm"> <form #heroForm="ngForm" appIdentityRevealed>
<!-- #enddocregion form-tag--> <!-- #enddocregion cross-validation-register-validator -->
<div [hidden]="heroForm.submitted"> <div [hidden]="heroForm.submitted">
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
<div class="form-group"> <div class="form-group">
<label for="name">Name</label> <label for="name">Name</label>
<!-- #docregion name-with-error-msg --> <!-- #docregion name-with-error-msg -->
@ -39,6 +39,13 @@
name="alterEgo" [(ngModel)]="hero.alterEgo" > name="alterEgo" [(ngModel)]="hero.alterEgo" >
</div> </div>
<!-- #docregion cross-validation-error-message -->
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
Name cannot match alter ego.
</div>
<!-- #enddocregion cross-validation-error-message -->
</div>
<div class="form-group"> <div class="form-group">
<label for="power">Hero Power</label> <label for="power">Hero Power</label>
<select id="power" name="power" class="form-control" <select id="power" name="power" class="form-control"
@ -62,5 +69,4 @@
<button (click)="heroForm.resetForm({})">Add new hero</button> <button (click)="heroForm.resetForm({})">Add new hero</button>
</div> </div>
</form> </form>
</div> </div>

View File

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

View File

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

View File

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

View File

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

View File

@ -14,6 +14,7 @@ export class AppComponent {
heroTraits = ['honest', 'brave', 'considerate']; heroTraits = ['honest', 'brave', 'considerate'];
// flags for the table // flags for the table
attrDirs = true; attrDirs = true;
strucDirs = true; strucDirs = true;
divNgIf = false; divNgIf = false;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -97,6 +97,9 @@ You can control your app compilation by providing template compiler options in t
} }
} }
``` ```
### *enableResourceInlining*
This options tell the compiler to replace the `templateUrl` and `styleUrls` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
When enabled, the `.js` output of ngc will have no lazy-loaded `templateUrl` or `styleUrls`.
### *skipMetadataEmit* ### *skipMetadataEmit*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1034,7 +1034,7 @@ 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" path="http/src/testing/http-client.spec.ts"
region="network-error" region="404"
linenums="false"> linenums="false">
</code-example> </code-example>

View File

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

View File

@ -3,7 +3,7 @@
Every application starts out with what seems like a simple task: get data, transform them, and show them to users. Every application starts out with what seems like a simple task: get data, transform them, and show them to users.
Getting data could be as simple as creating a local variable or as complex as streaming data over a WebSocket. Getting data could be as simple as creating a local variable or as complex as streaming data over a WebSocket.
Once data arrive, you could push their raw `toString` values directly to the view, Once data arrives, you could push their raw `toString` values directly to the view,
but that rarely makes for a good user experience. but that rarely makes for a good user experience.
For example, in most use cases, users prefer to see a date in a simple format like For example, in most use cases, users prefer to see a date in a simple format like
<samp>April 15, 1988</samp> rather than the raw string format <samp>April 15, 1988</samp> rather than the raw string format

View File

@ -23,6 +23,7 @@ Unless otherwise noted, patterns use a limited glob format:
* `**` matches 0 or more path segments. * `**` matches 0 or more path segments.
* `*` matches 0 or more characters excluding `/`. * `*` matches 0 or more characters excluding `/`.
* `?` matches exactly one character excluding `/`.
* The `!` prefix marks the pattern as being negative, meaning that only files that don't match the pattern will be included. * The `!` prefix marks the pattern as being negative, meaning that only files that don't match the pattern will be included.
Example patterns: Example patterns:
@ -106,7 +107,7 @@ This section describes the resources to cache, broken up into three groups.
* `versionedFiles` has been deprecated. As of v6 `versionedFiles` and `files` options have the same behavior. Use `files` instead. * `versionedFiles` has been deprecated. As of v6 `versionedFiles` and `files` options have the same behavior. Use `files` instead.
* `urls` includes both URLs and URL patterns that will be matched at runtime. These resources are not fetched directly and do not have content hashes, but they will be cached according to their HTTP headers. This is most useful for CDNs such as the Google Fonts service.<br> * `urls` includes both URLs and URL patterns that will be matched at runtime. These resources are not fetched directly and do not have content hashes, but they will be cached according to their HTTP headers. This is most useful for CDNs such as the Google Fonts service.<br>
_(Negative glob patterns are not supported.)_ _(Negative glob patterns are not supported and `?` will be matched literally; i.e. it will not match any character other than `?`.)_
## `dataGroups` ## `dataGroups`
@ -133,7 +134,7 @@ Similar to `assetGroups`, every data group has a `name` which uniquely identifie
### `urls` ### `urls`
A list of URL patterns. URLs that match these patterns will be cached according to this data group's policy.<br> A list of URL patterns. URLs that match these patterns will be cached according to this data group's policy.<br>
_(Negative glob patterns are not supported.)_ _(Negative glob patterns are not supported and `?` will be matched literally; i.e. it will not match any character other than `?`.)_
### `version` ### `version`
Occasionally APIs change formats in a way that is not backward-compatible. A new version of the app may not be compatible with the old API format and thus may not be compatible with existing cached resources from that API. Occasionally APIs change formats in a way that is not backward-compatible. A new version of the app may not be compatible with the old API format and thus may not be compatible with existing cached resources from that API.

View File

@ -933,29 +933,18 @@ As always, strive for consistency.
<a href="#toc">Back to top</a> <a href="#toc">Back to top</a>
{@a 02-06} {@a 05-02}
### Directive selectors ### Component selectors
#### Style 02-06 #### Style 05-02
<div class="s-rule do"> <div class="s-rule do">
**Do** Use lower camel case for naming the selectors of directives. **Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.
</div>
<div class="s-why">
**Why?** Keeps the names of the properties defined in the directives that are bound to the view consistent with the attribute names.
</div> </div>
@ -966,16 +955,40 @@ As always, strive for consistency.
**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case. **Why?** Keeps the element names consistent with the specification for [Custom Elements](https://www.w3.org/TR/custom-elements/).
</div> </div>
<code-example path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" title="app/heroes/shared/hero-button/hero-button.component.ts">
</code-example>
<code-tabs>
<code-pane title="app/heroes/shared/hero-button/hero-button.component.ts" path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts" region="example">
</code-pane>
<code-pane title="app/app.component.html" path="styleguide/src/05-02/app/app.component.html">
</code-pane>
</code-tabs>
<a href="#toc">Back to top</a> <a href="#toc">Back to top</a>
{@a 02-07} {@a 02-07}
### Custom prefix for components ### Component custom prefix
#### Style 02-07 #### Style 02-07
@ -1078,11 +1091,51 @@ For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the
<a href="#toc">Back to top</a>
{@a 02-06}
### Directive selectors
#### Style 02-06
<div class="s-rule do">
**Do** Use lower camel case for naming the selectors of directives.
</div>
<div class="s-why">
**Why?** Keeps the names of the properties defined in the directives that are bound to the view consistent with the attribute names.
</div>
<div class="s-why-last">
**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.
</div>
<a href="#toc">Back to top</a>
{@a 02-08} {@a 02-08}
### Custom prefix for directives ### Directive custom prefix
#### Style 02-08 #### Style 02-08
@ -3056,9 +3109,9 @@ module are referenced across the entire application.
**Avoid** providing services in shared modules. Services are usually **Consider** _not_ providing services in shared modules. Services are usually
singletons that are provided once for the entire application or singletons that are provided once for the entire application or
in a particular feature module. in a particular feature module. There are exceptions, however. For example, in the sample code that follows, notice that the `SharedModule` provides `FilterTextService`. This is acceptable here because the service is stateless;that is, the consumers of the service aren't impacted by new instances.
</div> </div>
@ -3710,59 +3763,6 @@ A typical *lazy loaded folder* contains a *routing component*, its child compone
## Components ## Components
{@a 05-02}
### Component selector names
#### Style 05-02
<div class="s-rule do">
**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.
</div>
<div class="s-why-last">
**Why?** Keeps the element names consistent with the specification for [Custom Elements](https://www.w3.org/TR/custom-elements/).
</div>
<code-example path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" title="app/heroes/shared/hero-button/hero-button.component.ts">
</code-example>
<code-tabs>
<code-pane title="app/heroes/shared/hero-button/hero-button.component.ts" path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts" region="example">
</code-pane>
<code-pane title="app/app.component.html" path="styleguide/src/05-02/app/app.component.html">
</code-pane>
</code-tabs>
<a href="#toc">Back to top</a>
{@a 05-03} {@a 05-03}
### Components as elements ### Components as elements

View File

@ -398,7 +398,7 @@ But a component is more than just its class.
A component interacts with the DOM and with other components. A component interacts with the DOM and with other components.
The _class-only_ tests can tell you about class behavior. The _class-only_ tests can tell you about class behavior.
They cannot tell you if the component is going to render properly, They cannot tell you if the component is going to render properly,
respond to user input and gestures, or integrate with its parent and and child components. respond to user input and gestures, or integrate with its parent and child components.
None of the _class-only_ tests above can answer key questions about how the None of the _class-only_ tests above can answer key questions about how the
components actually behave on screen. components actually behave on screen.

View File

@ -132,7 +132,7 @@ QuickStart identifies two *typings*, or `d.ts`, files:
* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework. * [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework.
* [node](https://www.npmjs.com/package/@types/node) for code that references objects in the *Node.js®* environment; * [node](https://www.npmjs.com/package/@types/node) for code that references objects in the *Node.js®* environment;
you can view an example in the [webpack](guide/webpack) page.
QuickStart doesn't require these typings but many of the samples do. QuickStart doesn't require these typings but many of the samples do.

View File

@ -241,7 +241,7 @@ even when the Universal web server is capable of handling those requests.
You'll have to change the services to make requests with absolute URLs when running on the server You'll have to change the services to make requests with absolute URLs when running on the server
and with relative URLs when running in the browser. and with relative URLs when running in the browser.
One solution is to provide the server's runtime origin under the Angular [`APP_BASE_REF` token](api/common/APP_BASE_HREF), One solution is to provide the server's runtime origin under the Angular [`APP_BASE_HREF` token](api/common/APP_BASE_HREF),
inject it into the service, and prepend the origin to the request URL. inject it into the service, and prepend the origin to the request URL.
Start by changing the `HeroService` constructor to take a second `origin` parameter that is optionally injected via the `APP_BASE_HREF` token. Start by changing the `HeroService` constructor to take a second `origin` parameter that is optionally injected via the `APP_BASE_HREF` token.

View File

@ -0,0 +1,352 @@
# Upgrading for Performance
<div class="alert is-helpful">
_Angular_ is the name for the Angular of today and tomorrow.<br />
_AngularJS_ is the name for all 1.x versions of Angular.
</div>
This guide describes some of the built-in tools for efficiently migrating AngularJS projects over to
the Angular platform, one piece at a time. It is very similar to
[Upgrading from AngularJS](guide/upgrade) with the exception that this one uses the {@link
downgradeModule downgradeModule()} helper function instead of the {@link UpgradeModule
UpgradeModule} class. This affects how the app is bootstrapped and how change detection is
propagated between the two frameworks. It allows you to upgrade incrementally while improving the
speed of your hybrid apps and leveraging the latest of Angular in AngularJS apps early in the
process of upgrading.
## Preparation
Before discussing how you can use `downgradeModule()` to create hybrid apps, there are things that
you can do to ease the upgrade process even before you begin upgrading. Because the steps are the
same regardless of how you upgrade, refer to the [Preparation](guide/upgrade#preparation) section of
[Upgrading from AngularJS](guide/upgrade).
## Upgrading with `ngUpgrade`
With the `ngUpgrade` library in Angular you can upgrade an existing AngularJS app incrementally by
building a hybrid app where you can run both frameworks side-by-side. In these hybrid apps you can
mix and match AngularJS and Angular components and services and have them interoperate seamlessly.
That means you don't have to do the upgrade work all at once as there is a natural coexistence
between the two frameworks during the transition period.
### How `ngUpgrade` Works
Regardless of whether you choose `downgradeModule()` or `UpgradeModule`, the basic principles of
upgrading, the mental model behind hybrid apps, and how you use the {@link upgrade/static
upgrade/static} utilities remain the same. For more information, see the
[How `ngUpgrade` Works](guide/upgrade#how-ngupgrade-works) section of
[Upgrading from AngularJS](guide/upgrade).
<div class="alert is-helpful">
The [Change Detection](guide/upgrade#change-detection) section of
[Upgrading from AngularJS](guide/upgrade) only applies to apps that use `UpgradeModule`. Though
you handle change detection differently with `downgradeModule()`, which is the focus of this
guide, reading the [Change Detection](guide/upgrade#change-detection) section provides helpful
context for what follows.
</div>
#### Change Detection with `downgradeModule()`
As mentioned before, one of the key differences between `downgradeModule()` and `UpgradeModule` has
to do with change detection and how it is propagated between the two frameworks.
With `UpgradeModule`, the two change detection systems are tied together more tightly. Whenever
something happens in the AngularJS part of the app, change detection is automatically triggered on
the Angular part and vice versa. This is convenient as it ensures that neither framework misses an
important change. Most of the time, though, these extra change detection runs are unnecessary.
`downgradeModule()`, on the other side, avoids explicitly triggering change detection unless it
knows the other part of the app is interested in the changes. For example, if a downgraded component
defines an `@Input()`, chances are that the app needs to be aware when that value changes. Thus,
`downgradeComponent()` automatically triggers change detection on that component.
In most cases, though, the changes made locally in a particular component are of no interest to the
rest of the app. For example, if the user clicks a button that submits a form, the component usually
handles the result of this action. That being said, there _are_ cases where you want to propagate
changes to some other part of the app that may be controlled by the other framework. In such cases,
you are responsible for notifying the interested parties by manually triggering change detection.
If you want a particular piece of code to trigger change detection in the AngularJS part of the app,
you need to wrap it in
[scope.$apply()](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply). Similarly, for
triggering change detection in Angular you would use {@link NgZone#run ngZone.run()}.
In many cases, a few extra change detection runs may not matter much. However, on larger or
change-detection-heavy apps they can have a noticeable impact. By giving you more fine-grained
control over the change detection propagation, `downgradeModule()` allows you to achieve better
performance for your hybrid apps.
## Using `downgradeModule()`
Both AngularJS and Angular have their own concept of modules to help organize an app into cohesive
blocks of functionality.
Their details are quite different in architecture and implementation. In AngularJS, you create a
module by specifying its name and dependencies with
[angular.module()](https://docs.angularjs.org/api/ng/function/angular.module). Then you can add
assets using its various methods. In Angular, you create a class adorned with an {@link NgModule
NgModule} decorator that describes assets in metadata.
In a hybrid app you run both frameworks at the same time. This means that you need at least one
module each from both AngularJS and Angular.
For the most part, you specify the modules in the same way you would for a regular app. Then, you
use the `upgrade/static` helpers to let the two frameworks know about assets they can use from each
other. This is known as "upgrading" and "downgrading".
<div class="alert is-helpful">
<b>Definitions:</b>
- _Upgrading_: The act of making an AngularJS asset, such as a component or service, available to
the Angular part of the app.
- _Downgrading_: The act of making an Angular asset, such as a component or service, available to
the AngularJS part of the app.
</div>
An important part of inter-linking dependencies is linking the two main modules together. This is
where `downgradeModule()` comes in. Use it to create an AngularJS module&mdash;one that you can use
as a dependency in your main AngularJS module&mdash;that will bootstrap your main Angular module and
kick off the Angular part of the hybrid app. In a sense, it "downgrades" an Angular module to an
AngularJS module.
There are a few things to note, though:
1. You don't pass the Angular module directly to `downgradeModule()`. All `downgradeModule()` needs
is a "recipe", for example, a factory function, to create an instance for your module.
2. The Angular module is not instantiated until the app actually needs it.
The following is an example of how you can use `downgradeModule()` to link the two modules.
```ts
// Import `downgradeModule()`.
import { downgradeModule } from '@angular/upgrade/static';
// Use it to downgrade the Angular module to an AngularJS module.
const downgradedModule = downgradeModule(MainAngularModuleFactory);
// Use the downgraded module as a dependency to the main AngularJS module.
angular.module('mainAngularJsModule', [
downgradedModule
]);
```
#### Specifying a factory for the Angular module
As mentioned earlier, `downgradeModule()` needs to know how to instantiate the Angular module. It
needs a recipe. You define that recipe by providing a factory function that can create an instance
of the Angular module. `downgradeModule()` accepts two types of factory functions:
1. `NgModuleFactory`
2. `(extraProviders: StaticProvider[]) => Promise<NgModuleRef>`
When you pass an `NgModuleFactory`, `downgradeModule()` uses it to instantiate the module using
{@link platformBrowser platformBrowser}'s {@link PlatformRef#bootstrapModuleFactory
bootstrapModuleFactory()}, which is compatible with ahead-of-time (AOT) compilation. AOT compilation
helps make your apps load faster. For more about AOT and how to create an `NgModuleFactory`, see the
[Ahead-of-Time Compilation](guide/aot-compiler) guide.
Alternatively, you can pass a plain function, which is expected to return a promise resolving to an
{@link NgModuleRef NgModuleRef} (i.e. an instance of your Angular module). The function is called
with an array of extra {@link StaticProvider Providers} that are expected to be available on the
returned `NgModuleRef`'s {@link Injector Injector}. For example, if you are using {@link
platformBrowser platformBrowser} or {@link platformBrowserDynamic platformBrowserDynamic}, you can
pass the `extraProviders` array to them:
```ts
const bootstrapFn = (extraProviders: StaticProvider[]) => {
const platformRef = platformBrowserDynamic(extraProviders);
return platformRef.bootstrapModule(MainAngularModule);
};
// or
const bootstrapFn = (extraProviders: StaticProvider[]) => {
const platformRef = platformBrowser(extraProviders);
return platformRef.bootstrapModuleFactory(MainAngularModuleFactory);
};
```
Using an `NgModuleFactory` requires less boilerplate and is a good default option as it supports AOT
out-of-the-box. Using a custom function requires slightly more code, but gives you greater
flexibility.
#### Instantiating the Angular module on-demand
Another key difference between `downgradeModule()` and `UpgradeModule` is that the latter requires
you to instantiate both the AngularJS and Angular modules up-front. This means that you have to pay
the cost of instantiating the Angular part of the app, even if you don't use any Angular assets
until later. `downgradeModule()` is again less aggressive. It will only instantiate the Angular part
when it is required for the first time; that is, as soon as it needs to create a downgraded
component.
You could go a step further and not even download the code for the Angular part of the app to the
user's browser until it is needed. This is especially useful when you use Angular on parts of the
hybrid app that are not necessary for the initial rendering or that the user doesn't reach.
A few examples are:
- You use Angular on specific routes only and you don't need it until/if a user visits such a route.
- You use Angular for features that are only visible to specific types of users; for example,
logged-in users, administrators, or VIP members. You don't need to load Angular until a user is
authenticated.
- You use Angular for a feature that is not critical for the initial rendering of the app and you
can afford a small delay in favor of better initial load performance.
### Bootstrapping with `downgradeModule()`
As you might have guessed, you don't need to change anything in the way you bootstrap your existing
AngularJS app. Unlike `UpgradeModule`&mdash;which requires some extra steps&mdash;
`downgradeModule()` is able to take care of bootstrapping the Angular module, as long as you provide
the recipe.
In order to start using any `upgrade/static` APIs, you still need to load the Angular framework as
you would in a normal Angular app. You can see how this can be done with SystemJS by following the
instructions in the [Setup](guide/setup) guide, selectively copying code from the
[QuickStart github repository](https://github.com/angular/quickstart).
You also need to install the `@angular/upgrade` package via `npm install @angular/upgrade --save`
and add a mapping for the `@angular/upgrade/static` package:
<code-example title="system.config.js">
'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
</code-example>
Next, create an `app.module.ts` file and add the following `NgModule` class:
<code-example title="app.module.ts">
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
imports: [
BrowserModule
]
})
export class MainAngularModule {
// Empty placeholder method to satisfy the `Compiler`.
ngDoBootstrap() {}
}
</code-example>
This bare minimum `NgModule` imports `BrowserModule`, the module every Angular browser-based app
must have. It also defines an empty `ngDoBootstrap()` method, to prevent the {@link Compiler
Compiler} from returning errors. This is necessary because the module will not have a `bootstrap`
declaration on its `NgModule` decorator.
<div class="alert is-important">
You do not add a `bootstrap` declaration to the `NgModule` decorator since AngularJS owns the root
template of the app and `ngUpgrade` bootstraps the necessary components.
</div>
You can now link the AngularJS and Angular modules together using `downgradeModule()`.
<code-example title="app.module.ts">
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { downgradeModule } from '@angular/upgrade/static';
const bootstrapFn = (extraProviders: StaticProvider[]) => {
const platformRef = platformBrowserDynamic(extraProviders);
return platformRef.bootstrapModule(MainAngularModule);
};
const downgradedModule = downgradeModule(bootstrapFn);
angular.module('mainAngularJsModule', [
downgradedModule
]);
</code-example>
The existing AngularJS code works as before _and_ you are ready to start adding Angular code.
### Using Components and Injectables
The differences between `downgradeModule()` and `UpgradeModule` end here. The rest of the
`upgrade/static` APIs and concepts work in the exact same way for both types of hybrid apps.
See [Upgrading from AngularJS](guide/upgrade) to learn about:
- [Using Angular Components from AngularJS Code](guide/upgrade#using-angular-components-from-angularjs-code).
- [Using AngularJS Component Directives from Angular Code](guide/upgrade#using-angularjs-component-directives-from-angular-code).
- [Projecting AngularJS Content into Angular Components](guide/upgrade#projecting-angularjs-content-into-angular-components).
- [Transcluding Angular Content into AngularJS Component Directives](guide/upgrade#transcluding-angular-content-into-angularjs-component-directives).
- [Making AngularJS Dependencies Injectable to Angular](guide/upgrade#making-angularjs-dependencies-injectable-to-angular).
- [Making Angular Dependencies Injectable to AngularJS](guide/upgrade#making-angular-dependencies-injectable-to-angularjs).
<div class="alert is-important">
While it is possible to downgrade injectables, downgraded injectables will not be available until
the Angular module is instantiated. In order to be safe, you need to ensure that the downgraded
injectables are not used anywhere _outside_ the part of the app that is controlled by Angular.
For example, it is _OK_ to use a downgraded service in an upgraded component that is only used
from Angular components, but it is _not OK_ to use it in an AngularJS component that may be used
independently of Angular.
</div>
## Using ahead-of-time compilation with hybrid apps
You can take advantage of ahead-of-time (AOT) compilation in hybrid apps just like in any other
Angular app. The setup for a hybrid app is mostly the same as described in the
[Ahead-of-Time Compilation](guide/aot-compiler) guide save for differences in `index.html` and
`main-aot.ts`.
AOT needs to load any AngularJS files that are in the `<script>` tags in the AngularJS `index.html`.
An easy way to copy them is to add each to the `copy-dist-files.js`file.
You also need to pass the generated `MainAngularModuleFactory` to `downgradeModule()` instead of the
custom bootstrap function:
<code-example title="app/main-aot.ts">
import { downgradeModule } from '@angular/upgrade/static';
import { MainAngularModuleNgFactory } from '../aot/app/app.module.ngfactory';
const downgradedModule = downgradeModule(MainAngularModuleNgFactory);
angular.module('mainAngularJsModule', [
downgradedModule
]);
</code-example>
And that is all you need to do to get the full benefit of AOT for hybrid Angular apps.
## Conclusion
This page covered how to use the {@link upgrade/static upgrade/static} package to incrementally
upgrade existing AngularJS apps at your own pace and without impeding further development of the app
for the duration of the upgrade process.
Specifically, this guide showed how you can achieve better performance and greater flexibility in
your hybrid apps by using {@link downgradeModule downgradeModule()} instead of {@link UpgradeModule
UpgradeModule}.
To summarize, the key differentiating factors of `downgradeModule()` are:
1. It allows instantiating or even loading the Angular part lazily, which improves the initial
loading time. In some cases this may waive the cost of running a second framework altogether.
2. It improves performance by avoiding unnecessary change detection runs while giving the developer
greater ability to customize.
3. It does not require you to change how you bootstrap your AngularJS app.
Using `downgradeModule()` is a good option for hybrid apps when you want to keep the AngularJS and
Angular parts less coupled. You can still mix and match components and services from both
frameworks, but you might need to manually propagate change detection. In return,
`downgradeModule()` offers more control and better performance.

View File

@ -1,7 +1,7 @@
# Upgrading from AngularJS to Angular # Upgrading from AngularJS to Angular
_Angular_ is the name for the Angular of today and tomorrow. _Angular_ is the name for the Angular of today and tomorrow.<br />
_AngularJS_ is the name for all v1.x versions of Angular. _AngularJS_ is the name for all 1.x versions of Angular.
AngularJS apps are great. AngularJS apps are great.
Always consider the business case before moving to Angular. Always consider the business case before moving to Angular.
@ -195,7 +195,7 @@ transition period.
### How ngUpgrade Works ### How ngUpgrade Works
The primary tool provided by ngUpgrade is called the `UpgradeModule`. One of the primary tools provided by ngUpgrade is called the `UpgradeModule`.
This is a module that contains utilities for bootstrapping and managing hybrid This is a module that contains utilities for bootstrapping and managing hybrid
applications that support both Angular and AngularJS code. applications that support both Angular and AngularJS code.
@ -252,7 +252,7 @@ frameworks in how it actually works.
</table> </table>
Even accounting for these differences you can still have dependency injection Even accounting for these differences you can still have dependency injection
interoperability. The `UpgradeModule` resolves the differences and makes interoperability. `upgrade/static` resolves the differences and makes
everything work seamlessly: everything work seamlessly:
* You can make AngularJS services available for injection to Angular code * You can make AngularJS services available for injection to Angular code
@ -569,7 +569,7 @@ So, you can write an Angular component and then use it from AngularJS
code. This is useful when you start to migrate from lower-level code. This is useful when you start to migrate from lower-level
components and work your way up. But in some cases it is more convenient components and work your way up. But in some cases it is more convenient
to do things in the opposite order: To start with higher-level components to do things in the opposite order: To start with higher-level components
and work your way down. This too can be done using the `UpgradeModule`. and work your way down. This too can be done using the `upgrade/static`.
You can *upgrade* AngularJS component directives and then use them from You can *upgrade* AngularJS component directives and then use them from
Angular. Angular.
@ -710,7 +710,7 @@ and then provide the input and output using Angular template syntax:
When you are using a downgraded Angular component from an AngularJS When you are using a downgraded Angular component from an AngularJS
template, the need may arise to *transclude* some content into it. This template, the need may arise to *transclude* some content into it. This
is also possible. While there is no such thing as transclusion in Angular, is also possible. While there is no such thing as transclusion in Angular,
there is a very similar concept called *content projection*. The `UpgradeModule` there is a very similar concept called *content projection*. `upgrade/static`
is able to make these two features interoperate. is able to make these two features interoperate.
Angular components that support content projection make use of an `<ng-content>` Angular components that support content projection make use of an `<ng-content>`

View File

@ -69,7 +69,7 @@ DOM event object in the `$event` variable which this code passes as a parameter
The properties of an `$event` object vary depending on the type of DOM event. For example, The properties of an `$event` object vary depending on the type of DOM event. For example,
a mouse event includes different information than a input box editing event. a mouse event includes different information than an input box editing event.
All [standard DOM event objects](https://developer.mozilla.org/en-US/docs/Web/API/Event) All [standard DOM event objects](https://developer.mozilla.org/en-US/docs/Web/API/Event)
have a `target` property, a reference to the element that raised the event. have a `target` property, a reference to the element that raised the event.

View File

@ -1,801 +0,0 @@
# Webpack: An Introduction
<style>
h4 {font-size: 17px !important; text-transform: none !important;}
.syntax { font-family: Consolas, 'Lucida Sans', Courier, sans-serif; color: black; font-size: 85%; }
</style>
[**Webpack**](https://webpack.github.io/) is a popular module bundler,
a tool for bundling application source code in convenient _chunks_
and for loading that code from a server into a browser.
It's an excellent alternative to the *SystemJS* approach used elsewhere in the documentation.
This guide offers a taste of Webpack and explains how to use it with Angular applications.
{@a top}
<!--
# Contents
* [What is Webpack?](guide/webpack#what-is-webpack)
* [Entries and outputs](guide/webpack#entries-outputs)
* [Multiple bundles](guide/webpack#multiple-bundles)
* [Loaders](guide/webpack#loaders)
* [Plugins](guide/webpack#plugins)
* [Configuring Webpack](guide/webpack#configure-webpack)
* [Polyfills](guide/webpack#polyfills)
* [Common configuration](guide/webpack#common-configuration)
* [Inside `webpack.common.js`](guide/webpack#inside-webpack-commonjs)
* [entry](guide/webpack#common-entries)
* [resolve extension-less imports](guide/webpack#common-resolves)
* [`module.rules`](guide/webpack#common-rules)
* [Plugins](guide/webpack#plugins)
* [`CommonsChunkPlugin`](guide/webpack#commons-chunk-plugin)
* [`HtmlWebpackPlugin`](guide/webpack#html-webpack-plugin)
* [Environment specific configuration](guide/webpack#environment-configuration)
* [Development configuration](guide/webpack#development-configuration)
* [Production configuration](guide/webpack#production-configuration)
* [Test configuration](guide/webpack#test-configuration)
* [Trying it out](guide/webpack#try)
* [Highlights](guide/webpack#highlights)
* [Conclusion](guide/webpack#conclusion)
-->
You can also <a href="generated/zips/webpack/webpack.zip" target="_blank">download the final result.</a>
{@a what-is-webpack}
## What is Webpack?
Webpack is a powerful module bundler.
A _bundle_ is a JavaScript file that incorporates _assets_ that *belong* together and
should be served to the client in a response to a single file request.
A bundle can include JavaScript, CSS styles, HTML, and almost any other kind of file.
Webpack roams over your application source code,
looking for `import` statements, building a dependency graph, and emitting one or more _bundles_.
With plugins and rules, Webpack can preprocess and minify different non-JavaScript files such as TypeScript, SASS, and LESS files.
You determine what Webpack does and how it does it with a JavaScript configuration file, `webpack.config.js`.
{@a entries-outputs}
### Entries and outputs
You supply Webpack with one or more *entry* files and let it find and incorporate the dependencies that radiate from those entries.
The one entry point file in this example is the application's root file, `src/main.ts`:
<code-example path="webpack/config/webpack.common.js" region="one-entry" title="webpack.config.js (single entry)" linenums="false">
</code-example>
Webpack inspects that file and traverses its `import` dependencies recursively.
<code-example path="webpack/src/app/app.component.ts" region="component" title="src/main.ts" linenums="false">
</code-example>
It sees that you're importing `@angular/core` so it adds that to its dependency list for potential inclusion in the bundle.
It opens the `@angular/core` file and follows _its_ network of `import` statements until it has built the complete dependency graph from `main.ts` down.
Then it **outputs** these files to the `app.js` _bundle file_ designated in configuration:
<code-example name="webpack.config.js (single output)" language="javascript">
output: {
filename: 'app.js'
}
</code-example>
This `app.js` output bundle is a single JavaScript file that contains the application source and its dependencies.
You'll load it later with a `<script>` tag in the `index.html`.
{@a multiple-bundles}
#### Multiple bundles
You probably don't want one giant bundle of everything.
It's preferable to separate the volatile application app code from comparatively stable vendor code modules.
Change the configuration so that it has two entry points, `main.ts` and `vendor.ts`:
<code-example language="javascript">
entry: {
app: 'src/app.ts',
vendor: 'src/vendor.ts'
},
output: {
filename: '[name].js'
}
</code-example>
Webpack constructs two separate dependency graphs
and emits *two* bundle files, one called `app.js` containing only the application code and
another called `vendor.js` with all the vendor dependencies.
<div class="l-sub-section">
The `[name]` in the output name is a *placeholder* that a Webpack plugin replaces with the entry names,
`app` and `vendor`. Plugins are [covered later](guide/webpack#commons-chunk-plugin) in the guide.
</div>
To tell Webpack what belongs in the vendor bundle,
add a `vendor.ts` file that only imports the application's third-party modules:
<code-example path="webpack/src/vendor.ts" title="src/vendor.ts" linenums="false">
</code-example>
{@a loaders}
### Loaders
Webpack can bundle any kind of file: JavaScript, TypeScript, CSS, SASS, LESS, images, HTML, fonts, whatever.
Webpack _itself_ only understands JavaScript files.
Teach it to transform non-JavaScript file into their JavaScript equivalents with *loaders*.
Configure loaders for TypeScript and CSS as follows.
<code-example language="javascript">
rules: [
{
test: /\.ts$/,
loader: 'awesome-typescript-loader'
},
{
test: /\.css$/,
loaders: 'style-loader!css-loader'
}
]
</code-example>
When Webpack encounters `import` statements like the following,
it applies the `test` RegEx patterns.
<code-example language="typescript">
import { AppComponent } from './app.component.ts';
import 'uiframework/dist/uiframework.css';
</code-example>
When a pattern matches the filename, Webpack processes the file with the associated loader.
The first `import` file matches the `.ts` pattern so Webpack processes it with the `awesome-typescript-loader`.
The imported file doesn't match the second pattern so its loader is ignored.
The second `import` matches the second `.css` pattern for which you have *two* loaders chained by the (!) character.
Webpack applies chained loaders *right to left*. So it applies
the `css` loader first to flatten CSS `@import` and `url(...)` statements.
Then it applies the `style` loader to append the css inside `<style>` elements on the page.
{@a plugins}
### Plugins
Webpack has a build pipeline with well-defined phases.
Tap into that pipeline with plugins such as the `uglify` minification plugin:
<code-example language="javascript">
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
</code-example>
{@a configure-webpack}
## Configuring Webpack
After that brief orientation, you are ready to build your own Webpack configuration for Angular apps.
Begin by setting up the development environment.
Create a new project folder.
<code-example language="sh" class="code-shell">
mkdir angular-webpack
cd angular-webpack
</code-example>
Add these files:
<code-tabs>
<code-pane title="package.json" path="webpack/package.webpack.json">
</code-pane>
<code-pane title="src/tsconfig.json" path="webpack/src/tsconfig.1.json">
</code-pane>
<code-pane title="webpack.config.js" path="webpack/webpack.config.js">
</code-pane>
<code-pane title="karma.conf.js" path="webpack/karma.webpack.conf.js">
</code-pane>
<code-pane title="config/helpers.js" path="webpack/config/helpers.js">
</code-pane>
</code-tabs>
<div class="l-sub-section">
Many of these files should be familiar from other Angular documentation guides,
especially the [Typescript configuration](guide/typescript-configuration) and
[npm packages](guide/npm-packages) guides.
Webpack, the plugins, and the loaders are also installed as packages.
They are listed in the updated `packages.json`.
</div>
Open a terminal window and install the npm packages.
<code-example language="sh" class="code-shell">
npm install
</code-example>
{@a polyfills}
### Polyfills
You'll need polyfills to run an Angular application in most browsers as explained
in the [Browser Support](guide/browser-support) guide.
Polyfills should be bundled separately from the application and vendor bundles.
Add a `polyfills.ts` like this one to the `src/` folder.
<code-example path="webpack/src/polyfills.ts" title="src/polyfills.ts" linenums="false">
</code-example>
<div class="callout is-critical">
<header>
Loading polyfills
</header>
Load `zone.js` early within `polyfills.ts`, immediately after the other ES6 and metadata shims.
</div>
Because this bundle file will load first, `polyfills.ts` is also a good place to configure the browser environment
for production or development.
{@a common-configuration}
### Common configuration
Developers typically have separate configurations for development, production, and test environments.
All three have a lot of configuration in common.
Gather the common configuration in a file called `webpack.common.js`.
<code-example path="webpack/config/webpack.common.js" title="config/webpack.common.js" linenums="false">
</code-example>
{@a inside-webpack-commonjs}
### Inside _webpack.common.js_
Webpack is a NodeJS-based tool that reads configuration from a JavaScript commonjs module file.
The configuration imports dependencies with `require` statements
and exports several objects as properties of a `module.exports` object.
* [`entry`](guide/webpack#common-entries)&mdash;the entry-point files that define the bundles.
* [`resolve`](guide/webpack#common-resolves)&mdash;how to resolve file names when they lack extensions.
* [`module.rules`](guide/webpack#common-rules)&mdash; `module` is an object with `rules` for deciding how files are loaded.
* [`plugins`](guide/webpack#common-plugins)&mdash;creates instances of the plugins.
{@a common-entries}
#### _entry_
The first export is the `entry` object:
<code-example path="webpack/config/webpack.common.js" region="entries" title="config/webpack.common.js" linenums="false">
</code-example>
This `entry` object defines the three bundles:
* `polyfills`&mdash;the polyfills needed to run Angular applications in most modern browsers.
* `vendor`&mdash;the third-party dependencies such as Angular, lodash, and bootstrap.css.
* `app`&mdash;the application code.
{@a common-resolves}
#### _resolve_ extension-less imports
The app will `import` dozens if not hundreds of JavaScript and TypeScript files.
You could write `import` statements with explicit extensions like this example:
<code-example language="typescript">
import { AppComponent } from './app.component.ts';
</code-example>
But most `import` statements don't mention the extension at all.
Tell Webpack to resolve extension-less file requests by looking for matching files with
`.ts` extension or `.js` extension (for regular JavaScript files and pre-compiled TypeScript files).
<code-example path="webpack/config/webpack.common.js" region="resolve" title="config/webpack.common.js" linenums="false">
</code-example>
<div class="l-sub-section">
If Webpack should resolve extension-less files for styles and HTML,
add `.css` and `.html` to the list.
</div>
{@a common-rules}
#### _module.rules_
Rules tell Webpack which loaders to use for each file, or module:
<code-example path="webpack/config/webpack.common.js" region="loaders" title="config/webpack.common.js" linenums="false">
</code-example>
* `awesome-typescript-loader`&mdash;a loader to transpile the Typescript code to ES5, guided by the `tsconfig.json` file.
* `angular2-template-loader`&mdash;loads angular components' template and styles.
* `html-loader`&mdash;for component templates.
* images/fonts&mdash;Images and fonts are bundled as well.
* CSS&mdash;the first pattern matches application-wide styles; the second handles
component-scoped styles (the ones specified in a component's `styleUrls` metadata property).
<div class="l-sub-section">
The first pattern is for the application-wide styles. It excludes `.css` files within the `src/app` directory
where the component-scoped styles sit. The `ExtractTextPlugin` (described below) applies the `style` and `css`
loaders to these files.
The second pattern filters for component-scoped styles and loads them as strings via the `raw-loader`,
which is what Angular expects to do with styles specified in a `styleUrls` metadata property.
</div>
<div class="l-sub-section">
Multiple loaders can be chained using the array notation.
</div>
{@a common-plugins}
#### _plugins_
Finally, create instances of three plugins:
<code-example path="webpack/config/webpack.common.js" region="plugins" title="config/webpack.common.js" linenums="false">
</code-example>
{@a commons-chunk-plugin}
#### *CommonsChunkPlugin*
The `app.js` bundle should contain only application code. All vendor code belongs in the `vendor.js` bundle.
Of course the application code imports vendor code.
On its own, Webpack is not smart enough to keep the vendor code out of the `app.js` bundle.
The `CommonsChunkPlugin` does that job.
<div class="l-sub-section">
The `CommonsChunkPlugin` identifies the hierarchy among three _chunks_: `app` -> `vendor` -> `polyfills`.
Where Webpack finds that `app` has shared dependencies with `vendor`, it removes them from `app`.
It would remove `polyfills` from `vendor` if they shared dependencies, which they don't.
</div>
{@a html-webpack-plugin}
#### _HtmlWebpackPlugin_
Webpack generates a number of js and CSS files.
You _could_ insert them into the `index.html` _manually_. That would be tedious and error-prone.
Webpack can inject those scripts and links for you with the `HtmlWebpackPlugin`.
{@a environment-configuration}
### Environment-specific configuration
The `webpack.common.js` configuration file does most of the heavy lifting.
Create separate, environment-specific configuration files that build on `webpack.common`
by merging into it the peculiarities particular to the target environments.
These files tend to be short and simple.
{@a development-configuration}
### Development configuration
Here is the `webpack.dev.js` development configuration file.
<code-example path="webpack/config/webpack.dev.js" title="config/webpack.dev.js" linenums="false">
</code-example>
The development build relies on the Webpack development server, configured near the bottom of the file.
Although you tell Webpack to put output bundles in the `dist` folder,
the dev server keeps all bundles in memory; it doesn't write them to disk.
You won't find any files in the `dist` folder, at least not any generated from *this development build*.
The `HtmlWebpackPlugin`, added in `webpack.common.js`, uses the `publicPath` and the `filename` settings to generate
appropriate `<script>` and `<link>` tags into the `index.html`.
The CSS styles are buried inside the Javascript bundles by default. The `ExtractTextPlugin` extracts them into
external `.css` files that the `HtmlWebpackPlugin` inscribes as `<link>` tags into the `index.html`.
Refer to the [Webpack documentation](https://webpack.github.io/docs/) for details on these and
other configuration options in this file.
Grab the app code at the end of this guide and try:
<code-example language="sh" class="code-shell">
npm start
</code-example>
{@a production-configuration}
### Production configuration
Configuration of a *production* build resembles *development* configuration with a few key changes.
<code-example path="webpack/config/webpack.prod.js" title="config/webpack.prod.js" linenums="false">
</code-example>
You'll deploy the application and its dependencies to a real production server.
You won't deploy the artifacts needed only in development.
Put the production output bundle files in the `dist` folder.
Webpack generates file names with cache-busting hash.
Thanks to the `HtmlWebpackPlugin`, you don't have to update the `index.html` file when the hash changes.
There are additional plugins:
* *`NoEmitOnErrorsPlugin`&mdash;stops the build if there is an error.
* *`UglifyJsPlugin`&mdash;minifies the bundles.
* *`ExtractTextPlugin`&mdash;extracts embedded css as external files, adding cache-busting hash to the filename.
* *`DefinePlugin`&mdash;use to define environment variables that you can reference within the application.
* *`LoaderOptionsPlugins`&mdash;to override options of certain loaders.
Thanks to the `DefinePlugin` and the `ENV` variable defined at top, you can enable Angular production mode like this:
<code-example path="webpack/src/main.ts" region="enable-prod" title="src/main.ts" linenums="false">
</code-example>
Grab the app code at the end of this guide and try:
<code-example language="sh" class="code-shell">
npm run build
</code-example>
{@a test-configuration}
### Test configuration
You don't need much configuration to run unit tests.
You don't need the loaders and plugins that you declared for your development and production builds.
You probably don't need to load and process the application-wide styles files for unit tests and doing so would slow you down;
you'll use the `null` loader for those CSS files.
You could merge the test configuration into the `webpack.common` configuration and override the parts you don't want or need.
But it might be simpler to start over with a completely fresh configuration.
<code-example path="webpack/config/webpack.test.js" title="config/webpack.test.js" linenums="false">
</code-example>
Reconfigure [Karma](https://karma-runner.github.io/1.0/index.html) to use Webpack to run the tests:
<code-example path="webpack/config/karma.conf.js" title="config/karma.conf.js" linenums="false">
</code-example>
You don't precompile the TypeScript; Webpack transpiles the Typescript files on the fly, in memory, and feeds the emitted JS directly to Karma.
There are no temporary files on disk.
The `karma-test-shim` tells Karma what files to pre-load and
primes the Angular test framework with test versions of the providers that every app expects to be pre-loaded.
<code-example path="webpack/config/karma-test-shim.js" title="config/karma-test-shim.js" linenums="false">
</code-example>
Notice that you do _not_ load the application code explicitly.
You tell Webpack to find and load the test files (the files ending in `.spec.ts`).
Each spec file imports all&mdash;and only&mdash;the application source code that it tests.
Webpack loads just _those_ specific application files and ignores the other files that you aren't testing.
Grab the app code at the end of this guide and try:
<code-example language="sh" class="code-shell">
npm test
</code-example>
{@a try}
## Trying it out
Here is the source code for a small application that bundles with the
Webpack techniques covered in this guide.
<code-tabs>
<code-pane title="src/index.html" path="webpack/src/index.html">
</code-pane>
<code-pane title="src/main.ts" path="webpack/src/main.ts">
</code-pane>
<code-pane title="src/assets/css/styles.css" path="webpack/src/assets/css/styles.css">
</code-pane>
</code-tabs>
<code-tabs>
<code-pane title="src/app/app.component.ts" path="webpack/src/app/app.component.ts">
</code-pane>
<code-pane title="src/app/app.component.html" path="webpack/src/app/app.component.html">
</code-pane>
<code-pane title="src/app/app.component.css" path="webpack/src/app/app.component.css">
</code-pane>
<code-pane title="src/app/app.component.spec.ts" path="webpack/src/app/app.component.spec.ts">
</code-pane>
<code-pane title="src/app/app.module.ts" path="webpack/src/app/app.module.ts">
</code-pane>
</code-tabs>
The <code>app.component.html</code> displays this downloadable Angular logo
<a href="assets/images/logos/angular/angular.png">
<img src="assets/images/logos/angular/angular.png" height="40px" title="download Angular logo"></a>.
Create a folder called `images` under the project's `assets` folder, then right-click (Cmd+click on Mac)
on the image and download it to that folder.
{@a bundle-ts}
Here again are the TypeScript entry-point files that define the `polyfills` and `vendor` bundles.
<code-tabs>
<code-pane title="src/polyfills.ts" path="webpack/src/polyfills.ts">
</code-pane>
<code-pane title="src/vendor.ts" path="webpack/src/vendor.ts">
</code-pane>
</code-tabs>
{@a highlights}
<h3 class="no-toc">Highlights</h3>
* There are no `<script>` or `<link>` tags in the `index.html`.
The `HtmlWebpackPlugin` inserts them dynamically at runtime.
* The `AppComponent` in `app.component.ts` imports the application-wide css with a simple `import` statement.
* The `AppComponent` itself has its own html template and css file. WebPack loads them with calls to `require()`.
Webpack stashes those component-scoped files in the `app.js` bundle too.
You don't see those calls in the source code;
they're added behind the scenes by the `angular2-template-loader` plug-in.
* The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.
The application imports these modules too; they'd be duplicated in the `app.js` bundle
if the `CommonsChunkPlugin` hadn't detected the overlap and removed them from `app.js`.
{@a conclusion}
## Conclusion
You've learned just enough Webpack to configurate development, test and production builds
for a small Angular application.
_You could always do more_. Search the web for expert advice and expand your Webpack knowledge.
[Back to top](guide/webpack#top)

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -12,5 +12,19 @@
"message": "Watch ng-conf live stream <br/>Apr 18th-20th, 2018", "message": "Watch ng-conf live stream <br/>Apr 18th-20th, 2018",
"imageUrl": "generated/images/marketing/home/ng-conf.png", "imageUrl": "generated/images/marketing/home/ng-conf.png",
"linkUrl": "https://www.ng-conf.org/livestream/" "linkUrl": "https://www.ng-conf.org/livestream/"
},
{
"startDate": "2018-06-01",
"endDate": "2018-08-15",
"message": "Join us for Angular Mix<br/>October 10th-12th, 2018",
"imageUrl": "generated/images/marketing/home/angular-mix.png",
"linkUrl": "https://angularmix.com/"
},
{
"startDate": "2018-08-15",
"endDate": "2018-11-06",
"message": "Join us for Angular Connect<br/>November 6th-7th, 2018",
"imageUrl": "generated/images/marketing/home/angular-connect.png",
"linkUrl": "https://angularconnect.com/"
} }
] ]

View File

@ -360,7 +360,7 @@
"picture": "jorgeucano.jpg", "picture": "jorgeucano.jpg",
"twitter": "jorgeucano", "twitter": "jorgeucano",
"website": "https://medium.com/@jorgeucano", "website": "https://medium.com/@jorgeucano",
"bio": "Jorge is a Fulll Stack Developer in ByteDefault ... Professor in several courses related to javascript , speaker, and writer of technical articles and a book Entendiendo Angular, Google Developer Expert in web technologies nominate by Google, Nativescript Developer Expert nominated by Telerik.", "bio": "Jorge is a Full Stack Developer in ByteDefault, a professor for several courses related to JavaScript, a speaker, and an author of technical articles and the book \"Entendiendo Angular.\" He is a Google Developer Expert in web technologies (nominated by Google) and a NativeScript Developer Expert (nominated by Telerik).",
"group": "GDE" "group": "GDE"
}, },
@ -378,8 +378,8 @@
"picture": "michaelprentice.jpg", "picture": "michaelprentice.jpg",
"twitter": "splaktar", "twitter": "splaktar",
"website": "https://www.DevIntent.com", "website": "https://www.DevIntent.com",
"bio": "Owner and consultant at DevIntent. Active open-source contributor and leader. Passionate advocate, coach, and consultant for LEAN and Agile teams. Google Developer Expert (GDE) in Angular. Founder and organizer for the Google Developers Group (GDG) community on the Space Coast of Florida, USA.", "bio": "Lead for AngularJS Material. Owner and consultant at DevIntent. Ex-Angular GDE. Founder of the Google Developers Group (GDG) community on the Space Coast of Florida, USA.",
"group": "GDE" "group": "Angular"
}, },
"mikebrocchi": { "mikebrocchi": {
@ -645,5 +645,13 @@
"website": "https://kmaida.io/", "website": "https://kmaida.io/",
"bio": "Kim is an an Angular consultant, developer, speaker, writer, and Google Developer Expert. She is passionate about learning from and sharing knowledge with other developers through blogging, speaking, workshops, and open source.", "bio": "Kim is an an Angular consultant, developer, speaker, writer, and Google Developer Expert. She is passionate about learning from and sharing knowledge with other developers through blogging, speaking, workshops, and open source.",
"group": "GDE" "group": "GDE"
},
"elanaolson": {
"name": "Elana Olson",
"picture": "elanaolson.jpg",
"twitter": "elanathellama",
"bio": "Elana is a Developer Relations intern on the Angular team at Google. She is working on migration paths from AngularJS to Angular and would love to chat about your experience with upgrading.",
"group": "Angular"
} }
} }

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