Compare commits

...

252 Commits

Author SHA1 Message Date
ec6ff1155b feat(core): upgrade rxjs to 6.0.0-alpha.4 2018-03-14 12:38:02 -07:00
ed78457c38 build: temporarily disable tests that depend on angular-in-memory-web-api
angular-in-memory-web-api is not yet compatible with rxjs v6 and rxjs v6 backwards compatibility package is not yet ready to be used.
2018-03-14 12:38:02 -07:00
8e3b940461 build: temporarily disable offline_compiler_test.sh 2018-03-14 12:38:02 -07:00
804d8c89d4 build: temporarily increase payload size limit for cli-hello-world until we update cli to v6 2018-03-14 12:38:02 -07:00
ea1dd3a2fc ci: improve logging when running aio/examples e2e tests 2018-03-14 12:38:02 -07:00
a5e6c64f25 build: update to zone.js@0.8.20 2018-03-14 12:38:02 -07:00
57760c8d20 build: remove obsolete rollup-test 2018-03-14 12:38:02 -07:00
683066fef1 build(aio): temporarily use RxJS from root node_modules/ when using local packages 2018-03-14 12:38:02 -07:00
f5a98f41fe fix(core): remove core animation import symbols (#22692)
This patch removes the deprecated support for animation
symbol imports from @angular/core.

BREAKING CHANGE: it is no longer possible to import
animation-related functions from @angular/core. All
animation symbols must now be imported from @angular/animations.

PR Close #22692
2018-03-14 12:23:51 -07:00
c09bd67aee fix(ivy): fix views manipulation logic (#22656)
This commit fixes a bug that would result in views insert / remove
even if a view needed only refresh operation.

The crux of the bug was that we were looking for a view to update
only in the LContainer.nextIndex position. This is incorrect as a
view with a given block id could be present later in the views
array (this happens if we about to remove a view in the middle of
the views array).

The code in this fix searches for a view to update in the views array and
can remove views in the middle of the views collection. Previously we
would remove views at the end of the collection only.

PR Close #22656
2018-03-14 12:07:15 -07:00
9df13add5d docs(aio): add ng-japan 2018 to events (#22750)
ng-japan 2018 will be held at June 16 in Tokyo, Japan! 

https://ngjapan.org/en.html
PR Close #22750
2018-03-14 10:59:55 -07:00
049757b237 fix(aio): constrain error logging to improve reporting (#22713)
The `Logger.error()` method now only accepts a single `Error` parameter
and passes this through to the error handler.
This allows the error handler to serialize the error more accurately.

The various places that use `Logger.error()` have been updated.

See #21943#issuecomment-370230047

PR Close #22713
2018-03-14 10:52:11 -07:00
1f9734315d docs: testing - highlight dispatchEvent (#22726)
PR Close #22726
2018-03-14 10:21:41 -07:00
6f0dad1710 build(aio): render doc-gen issues in overview dump (#22675)
Related to #22138

PR Close #22675
2018-03-14 10:20:30 -07:00
37fedd001c feat(core): add task tracking to Testability (#16863)
Allow passing an optional timeout to Testability's whenStable(). If
specified, if Angular is not stable before the timeout is hit, the
done callback will be invoked with a list of pending macrotasks.

Also, allows an optional update callback, which will be invoked whenever
the set of pending macrotasks changes. If this callback returns true,
the timeout will be cancelled and the done callback will not be invoked.

If the optional parameters are not passed, whenStable() will work
as it did before, whether or not the task tracking zone spec is
available.

This change also migrates the Testability unit tests off the deprecated
AsyncTestCompleter.

PR Close #16863
2018-03-14 08:48:48 -07:00
b1365d1fa8 refactor(ivy): remove directiveRefresh instruction (#22745)
PR Close #22745
2018-03-13 23:29:21 -07:00
4ac606b419 docs(compiler): fix spelling errors (#22704)
PR Close #22704
2018-03-13 21:45:13 -07:00
51027d73cc fix(ivy): Update rollup rule to prevent inlining symbols in debug. (#22747)
The new rollup rule disables inlining symbols in debug mode. This makes 
it look as if there would be more symbols but in reality these are the
symbols which are no longer being inlined.
PR Close #22747
2018-03-13 19:58:30 -07:00
48636f3e85 build(aio): compute stability and deprecate @stable tag (#22674)
Closes #22635

PR Close #22674
2018-03-13 19:55:00 -07:00
bd9d4df735 refactor(ivy): remove inputsPropertyName (#22716)
Closes #22591

PR Close #22716
2018-03-13 13:26:15 -07:00
34e355a3b0 build(bazel): ng_package rxjs/operators rollup config (#22744)
PR Close #22744
2018-03-13 12:12:11 -07:00
58b94e6f5e feat(animations): expose element and params within transition matchers (#22693)
PR Close #22693
2018-03-13 09:42:24 -07:00
db56836425 feat: tree-shakeable providers API updates (#22655)
Rename @Injectable({scope -> providedIn}).

Instead of {providedIn: APP_ROOT_SCOPE}, accept {providedIn: 'root'}.
Also, {providedIn: null} implies the injectable should not be added
to any scope.

PR Close #22655
2018-03-13 09:28:05 -07:00
21e44c6ba9 ci: add alexeagle to pullapprove root group (#22724)
PR Close #22724
2018-03-12 16:23:58 -07:00
f5d75d8efd build: fix postinstall for windows (#22720)
PR Close #22720
2018-03-12 15:11:25 -07:00
6e00410e1c fix(compiler-cli): annotate Ivy fields as @nocollapse in closure mode (#22691)
Closure has a transformation which turns:

Service.ngInjectableDef = ...;

into:

Service$ngInjectableDef = ...;

This transformation obviously breaks Ivy in a major way. The solution is
to annotate the fields as @nocollapse. However, Typescript appears to ignore
synthetic comments added to a node during a transformation, so the "right"
way to add these comments doesn't work.

As an interim measure, a post-processing step just before the compiled JS is
written to disk appends the correct comments with a regular expression.

PR Close #22691
2018-03-12 14:34:22 -07:00
f95730b8e2 fix(ivy): elements properties should not be stringified (#22683)
PR Close #22683
2018-03-12 13:16:05 -07:00
cd58c0a6d9 build(aio): remove unwanted overview headings (#22681)
PR Close #22681
2018-03-12 11:23:47 -07:00
38fef1588d build(aio): move "see also" block to export-base template (#22681)
This makes it easier for all the API docs to display "see also" links
in a consitent manner.

PR Close #22681
2018-03-12 11:23:46 -07:00
3f70aba272 fix(compiler-cli): disableTypeScriptVersionCheck should be applied even for older tsc versions (#22669)
Previously the flag would only disable the check in the case we tried to use newer tsc version.

In g3 we sometimes take a while to update tsc, but as a prerequisite of that Angular needs to be
updated first. This change enables us to update Angular and use it in g3 while g3 is being update
to the required tsc. Of course extra care is required when this check is disabled, but since we
control everything in g3, it's on us to get this right.

I don't see any preexisting tests for this, and I'm not sure how to write them right now.
I filed https://github.com/angular/angular/issues/22699

PR Close #22669
2018-03-12 09:27:24 -07:00
eb6fb2d8f9 build: switch from uglify-js to uglify-es (#22669)
This enables us to minify ES2015 code.

PR Close #22669
2018-03-12 09:27:24 -07:00
c602563589 feat(compiler-cli): require node 8 as runtime engine (#22669)
This is not expected to be a breaking change for anyone who's on Node LTS (currently v8)
and aligns @angular/compilar-cli with @angular/cli's runtime requirements.

PR Close #22669
2018-03-12 09:27:23 -07:00
8449eb8d62 build: upgrade to TypeScript 2.7 (#22669)
Fixes: #21571

PR Close #22669
2018-03-12 09:27:23 -07:00
a225b48482 build: introduce a temporary patch to make node_modules/rxjs compile with typescript 2.7 (#22669)
This patch can be removed once we update to rxjs v6. See #22573.

PR Close #22669
2018-03-12 09:27:23 -07:00
129d1e0fb1 build: add postinstall-patches.js script suitable for postinstall patching of dependencies (#22669)
Because sometimes one has to do what one has to do...

PR Close #22669
2018-03-12 09:27:23 -07:00
aa7dba244b feat(ivy): support checkNoChanges (#22710)
PR Close #22710
2018-03-11 22:16:38 -07:00
0bf6fa5b32 fix(router): correct over-encoding of URL fragment (#22687)
Relates to: #10280 #22337

PR Close #22687
2018-03-11 22:15:01 -07:00
40315bef3d fix(compiler-cli): enableResourceInlining handles both styles and styleUrls (#22688)
When both are present, the inlined styles are appended to the end of the styles

PR Close #22688
2018-03-11 22:14:32 -07:00
123efba388 fix(compiler-cli): resolve resource URLs before loading them under enableResourceInlining (#22688)
Also turn on the feature for Bazel ng_module rules

PR Close #22688
2018-03-11 22:14:31 -07:00
fa451bcd19 feat(ivy): support markForCheck (#22690)
PR Close #22690
2018-03-09 20:29:05 -08:00
0d8deb0795 fix(compiler-cli): generate proper exports.* identifiers in cjs output (#22564)
When the compiler generates a reference to an exported variable in the
same file, it inserts a synthetic ts.Identifier node. In CommonJS
output, this synthetic node would not be properly rewritten with an
`exports.` prefix.

This change sets the TS original node property on the synthetic node
we generate, which ensures TS knows to rewrite it in CommonJS output.

PR Close #22564
2018-03-09 13:09:57 -08:00
e8326e600d fix: overloading a function doesn't generate all of the signatures (#22569)
PR Close #22569
2018-03-09 13:07:36 -08:00
b5be18f405 feat(compiler-cli): add resource inlining to ngc (#22615)
When angularCompilerOptions { enableResourceInlining: true }, we replace all templateUrl and styleUrls properties in @Component with template/styles

PR Close #22615
2018-03-09 09:15:12 -08:00
1e6cc42a01 test: migrate remaining public-api tests to Bazel (#22639)
We now create npm packages to cover all the public api assertions in tools/public_api_guard.
We no longer depend on ts-api-guardian from npm - it is now stale since the repository was archived.
There is no longer a gulp task to enforce or accept the public API, this is in CircleCI as part of running all bazel test targets.

PR Close #22639
2018-03-09 09:11:40 -08:00
b26a90567c feat(ivy): support attaching and detaching views from change detection (#22670)
PR Close #22670
2018-03-08 23:44:33 -08:00
b0b9ca3386 feat(ivy): produce Renderer2 back-patching and factories. (#22506)
Produces back-patch as described in the #22235 and referenced in #22480.

This just contains the compiler implementations and the corresponding unit
tests. Connecting the dots as described in #22480 will be in a follow on
change.

PR Close #22506
2018-03-08 22:39:07 -08:00
5412e10bcd docs(core): replace ancient live demos (#22665)
PR Close #22665
2018-03-08 16:43:14 -08:00
489fec1299 feat: update tslib to 1.9.0 (#22667)
BREAKING CHANGE: after this change, npm and yarn will issue incompatible peerDependencies warning

We don't expect this to actually break an application, but the application/library package.json
will need to be updated to provide tslib 1.9.0 or higher.

PR Close #22667
2018-03-08 16:42:34 -08:00
2fee5cc095 test(ivy): add injection canonical specs (#22595)
PR Close #22595
2018-03-08 12:09:39 -08:00
f13f4db9dc refactor(ivy): fix rebase error (#22661)
PR Close #22661
2018-03-08 11:37:42 -08:00
2ca77d80ec docs: refactor revert() and call to lifecylce hook, edit doc to changes (#22094)
PR Close #22094
2018-03-08 10:58:42 -08:00
73c203fda9 feat(ivy): support host attribute and property bindings (#22334)
PR Close #22334
2018-03-08 10:57:30 -08:00
c499c8f4db build: update angular-bot g3sync paths (#22637)
We already trimmed these paths from the g3sync

PR Close #22637
2018-03-08 10:55:15 -08:00
4c089c1d93 feat(ivy): support ChangeDetectorRef.detectChanges (#22614)
PR Close #22614
2018-03-07 21:08:25 -08:00
d485346d3c fix(ivy): lifecycle hooks should be queued for root component (#22614)
PR Close #22614
2018-03-07 21:08:25 -08:00
8407fcc979 ci: double our cores on CircleCI (#22641)
This should cut our build time in ~half, assuming it's widely parallel.
See
https://circleci.com/docs/2.0/configuration-reference/#resource_class

Also enable bazel repository caching, and store the external
repositories in the CircleCI cache for later builds.

PR Close #22641
2018-03-07 21:00:03 -08:00
f64ee15487 feat(ivy): implement pipes (#22254)
PR Close #22254
2018-03-07 20:58:48 -08:00
5d4fa7f0c8 test(ivy): add canonical examples of bindings on elements (#22403)
PR Close #22403
2018-03-07 20:55:49 -08:00
8fb34bcd43 refactor(forms): deprecate ngModel usage on same field as formControl (#22633)
Support for using the `ngModel` input property and `ngModelChange`
event with reactive form directives has been deprecated in
Angular v6 and will be removed in Angular v7.

Now deprecated:
```html
<input [formControl]="control" [(ngModel)]="value">
```

```ts
this.value = 'some value';
```

This has been deprecated for a few reasons. First, developers have
found this pattern confusing. It seems like the actual `ngModel`
directive is being used, but in fact it's an input/output property
named `ngModel` on the reactive form directive that simply approximates
(some of) its behavior. Specifically, it allows getting/setting the
value and intercepting value events. However, some of `ngModel`'s other
features - like delaying updates with`ngModelOptions` or exporting the
directive - simply don't work, which has understandably caused some
confusion.

In addition, this pattern mixes template-driven and reactive forms
strategies, which we generally don't recommend because it doesn't take
advantage of the full benefits of either strategy. Setting the value in
the template violates the template-agnostic principles behind reactive
forms, whereas adding a FormControl/FormGroup layer in the class removes
the convenience of defining forms in the template.

To update your code before v7, you'll want to decide whether to stick
with reactive form directives (and get/set values using reactive forms
patterns) or switch over to template-driven directives.

After (choice 1 - use reactive forms):

```html
<input [formControl]="control">
```

```ts
this.control.setValue('some value');
```

After (choice 2 - use template-driven forms):

```html
<input [(ngModel)]="value">
```

```ts
this.value = 'some value';
```

You can also choose to silence this warning by providing a config for
`ReactiveFormsModule` at import time:

```ts
imports: [
  ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'});
]
```

Alternatively, you can choose to surface a separate warning for each
instance of this pattern with a config value of `"always"`. This may
help to track down where in the code the pattern is being used as the
code is being updated.

Note: `warnOnNgModelWithFormControl` is set up as deprecated so that it
can be removed in v7 when it is no longer needed. This will not display
properly in API docs yet because dgeni doesn't yet support deprecating
properties in object literals, but we have an open issue to resolve the
discrepancy here: https://github.com/angular/angular/issues/22640.

PR Close #22633
2018-03-07 20:47:53 -08:00
6d1367d297 feat(ivy): provide sanitization methods which can be tree shaken (#22540)
By providing a top level sanitization methods (rather than service) the
compiler can generate calls into the methods only when needed. This makes
the methods tree shakable.

PR Close #22540
2018-03-07 18:24:07 -08:00
538f1d980f refactor(core): move sanitization into core (#22540)
This is in preparation of having Ivy have sanitization inline.

PR Close #22540
2018-03-07 18:24:06 -08:00
065bcc5aad docs: add HeroService to code tabs and fix headers (#22373)
PR Close #22373
2018-03-07 18:20:53 -08:00
8ad4ae0a07 docs: add changelog for 6.0.0-beta.7 2018-03-07 14:59:33 -08:00
ffc6ee0086 release: cut the 6.0.0-beta.7 release 2018-03-07 14:57:04 -08:00
78167915ee build(common): export locale data as commonjs instead of es2015 (#20624)
PR Close #20624
2018-03-07 14:33:45 -08:00
ad8fb8484f test: include router in public_api_guard tests (#22628)
Remove duplicate public api testing from the gulp task.

PR Close #22628
2018-03-07 10:56:27 -08:00
ce649f725f build: add a ng_package rule for @angular/router (#22628)
PR Close #22628
2018-03-07 10:56:27 -08:00
fcb8c492d6 build: add an npm_package rule for @angular/bazel (#22628)
PR Close #22628
2018-03-07 10:56:27 -08:00
4f744cc66f docs: update RELEASE_SCHEDULE.md by pushing out v6 rc by one week
We are pushing RC and Final out by one week because of RxJS v6 complications that are blocking the release. No further delays are currently expected.
2018-03-07 10:50:55 -08:00
505ae752b6 docs(aio): update deprecated Http reference to HttpClientModule, remove Http reference because another context is used (#21984)
docs(aio): change HttpClientModule reference to HttpClient

docs(aio): capitalize Http to HTTP

docs(aio): fix typo mistake in 'universal' guide

docs(aio): gets rid of the parentheses and the "e.g." in 'universal' guide

PR Close #21984
2018-03-06 15:03:54 -08:00
363dfa5437 test(ivy): Back patch example (#22235)
PR Close #22235
2018-03-06 15:02:02 -08:00
b3d1761825 build(aio): compute and display short descriptions in methods (#22583)
Previously only export docs were displaying a short description.
Now methods in classes and interfaces also compute and render
the short description.

Closes #22500

PR Close #22583
2018-03-06 11:05:21 -08:00
d0db9ded90 docs: fix cli-quickstart doc and specs (#22338)
* tests were broken
* incorrect instructions.
* didn't match current CLI template for new project

PR Close #22338
2018-03-06 09:41:53 -08:00
4c40812b71 fix(bazel): fixes for ng_package on Windows (#22597)
PR Close #22597
2018-03-06 07:52:48 -08:00
fa974c7d4e fix(router): fix URL serialization so special characters are only encoded where needed (#22337)
This change brings Angular largely in line with how AngularJS previously serialized URLs. This is based on RFC 3986 and resolves issues such as the above #10280 where URLs could be parsed, re-serialized, then parsed again producing a different result on the second parsing.

Adjustments to be aware of in this commit:

* URI fragments will now serialize the same as query strings
* In the URI path or segments (portion prior to query string and/or fragment), the plus sign (`+`) and ampersand (`&`) will appear decoded
* In the URL path or segments, parentheses values (`(` and `)`) will now appear percent encoded as `%28` and `%29` respectively
* In the URL path or segments, semicolons will be encoded in their percent encoding `%3B`

NOTE: Parentheses and semicolons denoting auxillary routes or matrix params will still appear in their decoded form -- only parentheses and semicolons used as values in a segment or key/value pair for matrix params will be encoded.

While these changes are not considered breaking because applications should be decoding URLs and key/value pairs, it is possible that some unit tests will break if comparing hard-coded URLs in tests since that hard coded string will represent the old encoding. Therefore we are releasing this fix in the upcoming Angular v6 rather than adding it to a patch for v5.

Fixes: #10280

PR Close #22337
2018-03-06 06:58:08 -08:00
2c75acc5b3 feat(ivy): add support for the ngProjectAs attribute (#22498)
PR Close #22498
2018-03-06 06:55:51 -08:00
f86d8ae0fd docs(compiler): fix a line about ivy library (#22579)
PR Close #22579
2018-03-05 21:25:43 -08:00
94bc277b1b fix(aio): tidy up embedded ToC styling (#22570)
The spacing didn't work well when the screen was narrow.

PR Close #22570
2018-03-05 21:25:09 -08:00
8ea4c57174 fix(aio): reposition and shrink the API badges (#22570)
Closes #22130

PR Close #22570
2018-03-05 21:25:09 -08:00
53b0fe8144 feat(aio): allow template to position embedded ToC (#22570)
Previously the doc-viewer would insert an embedded `<aio-toc>` element
into the DOM directly after the H1 element. Now it will not do this
if there is already a such element in the doc contents.

This allows the content-author/template-developer to position the ToC
for specific cases.

PR Close #22570
2018-03-05 21:25:09 -08:00
2a1e3d191f docs: add info about the WebStorm plugin to BAZEL.md (#22572)
PR Close #22572
2018-03-05 21:24:23 -08:00
2c2b62f45f fix(ivy): preventDefault when listener returns false (#22529)
Closes #22495

PR Close #22529
2018-03-05 12:15:17 -08:00
58932c7f38 build(aio): indicate whether properties are read-only in API pages (#22584)
PR Close #22584
2018-03-05 10:15:37 -08:00
5bb9f64218 fixup! feat(aio): allow template to position embedded ToC (#22565)
PR Close #22565
2018-03-05 10:14:16 -08:00
405d97431f fixup! feat(aio): allow template to position embedded ToC (#22565)
PR Close #22565
2018-03-05 10:14:16 -08:00
41064fcb36 fix(aio): reposition and simplify github links (#22565)
Closes #22379

PR Close #22565
2018-03-05 10:14:16 -08:00
b80fd6be58 build(aio): render whether API classes and members are abstract (#22563)
Closes #22537

PR Close #22563
2018-03-05 10:13:43 -08:00
3aea8fd5f3 docs(aio): fix table header (#22553)
PR Close #22553
2018-03-05 10:13:16 -08:00
b64139650c build(aio): class API template once again extends export-base (#22534)
PR Close #22534
2018-03-05 10:12:55 -08:00
1d2bdcb4d0 build(aio): render param descriptions for function exports (#22534)
Closes #22501

PR Close #22534
2018-03-05 10:12:55 -08:00
12be311618 fix(aio): remove all links from toc titles (#22533)
The previous approach just removed the first `a` tag that
was found, but now that the header-link anchor is not at
the start of the heading, it could fail.

Closes #22493

PR Close #22533
2018-03-05 10:12:35 -08:00
51ca643c27 test(ivy): add injectAttribute spec (#22510)
PR Close #22510
2018-03-05 10:10:32 -08:00
69d359bb51 refactor(ivy): break compiler canonical test into smaller files (#22510)
PR Close #22510
2018-03-05 10:10:32 -08:00
4f60968704 test(bazel): Build and test ts-api-guardian locally (#22544)
Also use it to test the public API for core and common

Once we have an ng_package for every package, we can remove
the npm dependency on ts-api-guardian and the gulp-based
public api check.

PR Close #22544
2018-03-02 15:00:00 -08:00
25faf808a5 build: copy ts-api-guardian sources (#22544)
This is an exact mirror of 750f651eca

PR Close #22544
2018-03-02 15:00:00 -08:00
d7e5d45f43 release: packageGroup should use scoped package names (#22538)
PR Close #22538
2018-03-02 14:05:59 -08:00
ba8df8a3f1 build: update to latest bazel rules (#22558)
PR Close #22558
2018-03-02 13:27:25 -08:00
0451fd93df feat(ivy): support generating view and content queries (#22330)
PR Close #22330
2018-03-01 13:06:47 -08:00
49f074f61d feat(ivy): support array and object literals in binding expressions (#22336)
PR Close #22336
2018-03-01 13:02:58 -08:00
ec445b5c73 ci: speed up lint job on CircleCI (#22526)
When I enabled bazel remote caching, I also switched to running
buildifier and skylint from the package.json script, which builds them
from head. With remote caching, we do get cache hits for these, but
looking up the action inputs actually takes quite a bit of time since we
have to first fetch the remote repository, then do loading and
analysis, then read the inputs to determine the cache key.

It's more important to keep the lint job fast, so I'm reverting that
part of the change for now. We can experiment with building them from
head in a less critical repo.

PR Close #22526
2018-03-01 09:12:58 -08:00
ab790f3c84 build: Add support for bazelOptions.maxCacheSizeMb in ngc-wrapped. (#22511)
PR Close #22511
2018-03-01 08:41:10 -08:00
dd534471ec fix(compiler): allow tree-shakeable injectables to depend on string tokens (#22376)
Previously the injectable compiler assumed all tree-shakeable injectables
would have dependencies that were injectables or InjectionTokens. However
old code still uses string tokens (e.g. NgUpgrade and '$injector'). Using
such tokens would cause the injectable compiler to crash.

Now, the injectable compiler can properly generate a dependency on such a
string token.

PR Close #22376
2018-03-01 08:15:13 -08:00
8bb2f5c71d docs(compiler): ivy separate compilation design document (#22480)
PR Close #22480
2018-03-01 08:14:35 -08:00
0e311e3918 build(aio): improve accuracy of code auto-linking (#22494)
The new version of `dgeni-packages/typescript` no longer strips
out "namespaces" from types, which was part of the problem of
not autolinking correctly to `HttpEventType.Response`.

Another part of the problem was that we did not include `.`
characters when matching potential code blocks for auto-linking,
which precluded properties of enums from being linked.

Finally, members we not being given a `path` property, which is
needed to effectively autolink to them. This is now set in
the `simplifyMemberAnchors` processor.

Closes #21375

PR Close #22494
2018-03-01 08:11:19 -08:00
997b30a093 build(aio): move link disambiguation from getLinkInfo to getDocFromAlias (#22494)
The disambiguation needs to be done earlier so that the auto-link-code
post-processor can benefit from it.

PR Close #22494
2018-03-01 08:11:19 -08:00
94707fe795 build(aio): initialise exampleMap correctly (#22502)
The `exampleMap` needs to hold an hash object for each
of the `collectExamples.exampleFolders` paths.

Previously these hash objects were only created if there
was actually an example file the hash's respective
example folder.  This could cause crashes during
`yarn docs-watch` (and so also `yarn sync-and-serve`)
if no examples were read in for a particular run of
the doc-gen.

PR Close #22502
2018-03-01 08:10:15 -08:00
2f0ab7ee98 docs: correct changelog version for 6.0.0-beta.6 2018-03-01 06:05:24 -08:00
b8fe121a16 release: cut the 6.0.0-beta.6 release 2018-02-28 15:23:54 -08:00
e751a0a2bb docs: add changelog for 6.0.0-beta.6 2018-02-28 15:17:30 -08:00
288851c41e release: add ng update package group metadata to angular (#22482)
"ng update" supports having multiple packages as part of a group which should be updated together, meaning that e.g. calling "ng update @angular/core" would be equivalent to updating all packages of the group (that are part of the package.json already).

In order to support the grouping feature, the package.json of the version the user is updating to needs to include an "ng-update" key that points to this metadata.

The entire specification for the update workflow can be found here: 2e8b12a4ef/docs/specifications/update.md

PR Close #22482
2018-02-28 14:57:53 -08:00
9eaf1bbe67 feat(ivy): support injecting ChangeDetectorRef (#22469)
PR Close #22469
2018-02-28 13:35:48 -08:00
aabe16c08c fix(bazel): ng_package includes transitive .d.ts and flatModuleMetadata (#22499)
Fixes #22419

PR Close #22499
2018-02-28 13:29:56 -08:00
b6c941053e feat(bazel): ng_package adds package.json props (#22499)
We now add the 'main', 'module', 'es2015', and 'typings' properties,
pointing to where the packaging tool lays them out.

Fixes #22416

PR Close #22499
2018-02-28 13:29:56 -08:00
c82cef8bc6 docs: fix dynamic component loader example (#22181)
closes #21903

PR Close #22181
2018-02-28 10:46:37 -08:00
f8749bfb70 fix(core): export inject() from @angular/core (#22389)
inject() supports the ngInjectableDef-based configuration of the injector
(otherwise known as tree-shakeable services). It was missing from the
exported API of @angular/core, this PR adds it.

The test added here is correct in theory, but may pass accidentally due
to the decorator side-effect replacing the inject() call at runtime. An
upcoming compiler PR will strip reified decorators from the output
entirely.

Fixes #22388

PR Close #22389
2018-02-28 10:44:37 -08:00
7d65356ae3 build(aio): add @usageNotes tag def for API docs (#22401)
PR Close #22401
2018-02-28 10:43:27 -08:00
11f30fc351 style(aio): add newline between test blocks (#22401)
PR Close #22401
2018-02-28 10:43:27 -08:00
b107131f8a build(aio): split the description property in API docs (#22401)
* The first paragraph is now split off into the `shortDescription` property.
* Usage of `howToUse` and `whatItDoes` have been updated.
* The "Overview" heading for class is removed as it is self-evident
* The original horizontal rule styling below the main heading is removed as not part of the new design

Closes #22385

PR Close #22401
2018-02-28 10:43:27 -08:00
11264e2174 fix(aio): remove heading border (#22401)
PR Close #22401
2018-02-28 10:43:27 -08:00
b924ce3a62 build(aio): add processor to migrate legacy tags @whatItDoes and @howToUse (#22401)
See https://github.com/angular/angular/issues/22135#issuecomment-367632372

PR Close #22401
2018-02-28 10:43:27 -08:00
e75f0cee18 build(aio): deprecate @howToUse and @whatItDoes tags (#22401)
See https://github.com/angular/angular/issues/22135#issuecomment-367632372

PR Close #22401
2018-02-28 10:43:27 -08:00
8c358844dd feat(ivy): support OnPush change detection (#22417)
PR Close #22417
2018-02-28 10:42:11 -08:00
e454c5a98e refactor(ivy): store creationMode in LView.flags (#22417)
PR Close #22417
2018-02-28 10:42:11 -08:00
930ecacd86 build: update ts-api-guardian version (#22402)
PR Close #22402
2018-02-28 09:29:29 -08:00
5170ffe844 build: update api golden files (#22402)
`ts-api-guardion` has been updated to accept new TypeScript syntax

PR Close #22402
2018-02-28 09:29:29 -08:00
e95b61d42a docs: fix community tab in GitHub by copying CoC 2018-02-27 19:02:30 -08:00
8a85888773 fix(upgrade): correctly destroy nested downgraded component (#22400)
Previously, when a downgraded component was destroyed in a way that did
not trigger the `$destroy` event on the element (e.g. when a parent
element was removed from the DOM by Angular, not AngularJS), the
`ComponentRef` was not destroyed and unregistered.
This commit fixes it by listening for the `$destroy` event on both the
element and the scope.

Fixes #22392

PR Close #22400
2018-02-27 18:41:02 -08:00
83b32a0a0a build(aio): render heading anchors on the right
This approach simplifies the styling needed considerably.
Previously, we had to make room on the left for heading that
are in visual containers. Also we had to apply a `float:right`
when on narrow screens as the gutter not available then.
This float didn't render nicely if the heading text was longer
than could be rendered on a single line.

Closes #22131
2018-02-27 18:32:32 -08:00
8d34364ff5 ci: update github bot config (#22453)
PR Close #22453
2018-02-27 15:18:36 -08:00
142117f6bb fix(aio): do not show Properties/Methods sections if only internal members (#22471)
PR Close #22471
2018-02-27 15:17:22 -08:00
79656e7f96 docs(aio): add Observable and Rx docs (#21423)
PR Close #21423
2018-02-27 11:24:31 -08:00
d100f1b187 build(aio): fix API docs breadcrumbs (#22446)
This also prevents some extra `<a>` elements inserted by the browser's
trying to fix the HTML structure, which also fixes the `.header-link`
added in ToC.

Fixes #22387
Closes #22437

PR Close #22446
2018-02-27 07:08:07 -08:00
4bd3e5f92f build(aio): do not render "constructor()" heading in API docs (#22380)
Closes #22363

PR Close #22380
2018-02-27 07:07:16 -08:00
3f3be429c9 style(aio): updated padding-right for the .alert class in _heading-anchors.scss (#22431)
The h3 element is overflowing over its surrounding div element. Modified padding-right to align consistently with the remainder of div contents.

fixes: #22407

PR Close #22431
2018-02-26 17:52:29 -08:00
7e4c13f2de style(aio): added padding-left to h3 in _subsection.scss (#22431)
The h3 element is overflowing over its surrounding div element. Modified padding-left to align consistently with the remainder of div contents.

fixes: #22407

PR Close #22431
2018-02-26 17:52:29 -08:00
82a791223c docs: update i18n guide for projects that don't use the cli (#21767)
PR Close #21767
2018-02-26 17:51:58 -08:00
ef99126aea test(aio): move forgotten e2e test to the correct folder (#22445)
PR Close #22445
2018-02-26 17:50:42 -08:00
c10c831b8e build(aio): render subclasses + see-also block in the main flow (#22445)
Closes #22386

PR Close #22445
2018-02-26 17:50:42 -08:00
40ba009e25 fix(platform-server): generate correct stylings for camel case names (#22263)
* Add correct mapping from camel case to kebab case for CSS style
names
* Remove internal CSS methods in favor of native Domino APIs

Fixes #19235

PR Close #22263
2018-02-26 17:46:21 -08:00
d3827a0017 feat(platform-server): bump Domino to v2.0 (#22411)
BREAKING CHANGE:

* Bump the dependency on Domino to 2.0 to resolve issues with
  namespacing

PR Close #22411
2018-02-26 14:55:52 -08:00
a7e1f236ff docs: testing guide for CLI (#20697)
- updates tests
- heavy prose revisions
- uses HttpClient (with angular-in-memory-web-api)
- test HeroService using `HttpClientTestingModule`
- scrub away most By.CSS
- fake async observable with `asyncData()`
- extensive Twain work
- different take on retryWhen
- remove app barrels (& systemjs.extras) which troubled plunker/systemjs
- add dummy export const to hero.ts (plunkr/systemjs fails w/o it)
- shrink and re-organize TOC
- add marble testing package and tests
- demonstrate the "no beforeEach()" test coding style
- add section on Http service testing
- prepare for stackblitz
- confirm works in plunker except excluded marble test
- add tests for avoidFile class feature of CodeExampleComponent

PR Close #20697
2018-02-26 13:40:23 -08:00
1f599818bd build(aio): fix rendering of callable and constructable interface members (#22428)
Closes #22136

PR Close #22428
2018-02-26 13:35:15 -08:00
5a32d7e36f build(aio): render default value for optional parameters (#22435)
Closes #22134

PR Close #22435
2018-02-26 13:34:38 -08:00
1ea41d48d3 build(aio): render whether parameters are optional (#22435)
Closes #22134

PR Close #22435
2018-02-26 13:34:38 -08:00
25a43041d2 build(aio): group API members by type in overview (#22438)
Now the overview groups the members in the following order:

* static properties
* static methods
* constructor
* instance properties
* instance members

Closes #22132

PR Close #22438
2018-02-26 13:34:04 -08:00
c593d69ce7 docs(aio): fix doc typo referring to httpOptions (#22456)
The variable name mention should match the actual tutorial code.

PR Close #22456
2018-02-26 13:32:44 -08:00
13ab91e05d fix(upgrade): fix empty transclusion content with AngularJS@>=1.5.8 (#22167)
The function provided by `ngUpgrade` as `parentBoundTranscludeFn` when
upgrading a component with transclusion, will break in AngularJS v1.5.8+
if no transclusion content is provided. The reason is that AngularJS
will try to destroy the transclusion scope (which would not be needed
any more). But since the transcluded content comes from Angular, not
AngularJS, there is no transclusion scope to destroy.
This commit fixes it by providing a dummy scope object with a no-op
`$destroy()` method.

Fixes #22175

PR Close #22167
2018-02-25 10:06:14 -08:00
f089bf5333 fix(upgrade): correctly handle = bindings in @angular/upgrade (#22167)
Previously, having a `=` binding on an upgraded components would result
in setting the corresponding property to an EventEmitter function. This
should only happen for `&` bindings.
This commit rstrores the correct behavior.

Note:
The issue was only present in the dynamic version of `ngUpgrade`. The
static version worked as expected.
The error did not show up in tests, because in AngularJS v1.5.x a
function would be serialized to an empty string in interpolations, thus
making them indistinguishable from uninitialized properties (in the
view). The serialization behavior changed in AngularJS v1.6.x, making
the errors visible.

PR Close #22167
2018-02-25 10:06:14 -08:00
8e1e040f72 test(upgrade): run tests against multiple AngularJS versions (#22167)
Fixes #19332

PR Close #22167
2018-02-25 10:06:14 -08:00
28240625e6 refactor(upgrade): use correct paths for imports (#22167)
`packages/upgrade/static/src` is anymlink to `packages/upgrade/src`.
Still, using the correct paths (e.g. using
`@angular/upgrade/static/src/...` for `@angula/upgrade/static` specs
ensures that the module loader (e.g. SystemJS) can map the imports to
the same instances.

PR Close #22167
2018-02-25 10:06:14 -08:00
0d248079ba test(platform-browser): remove stray debugger statement (#22167)
PR Close #22167
2018-02-25 10:06:14 -08:00
a4032296cc Revert "fix(router): fix URL serialization so special characters are only encoded where needed (#22337)"
This reverts commit 094666da17.
2018-02-23 18:12:40 -08:00
4180912538 feat(common): export functions to format numbers, percents, currencies & dates (#22423)
The utility functions `formatNumber`, `formatPercent`, `formatCurrency`, and `formatDate` used by the number, percent, currency and date pipes are now available for developers who want to use them outside of templates.

Fixes #20536

PR Close #22423
2018-02-23 15:27:10 -08:00
094666da17 fix(router): fix URL serialization so special characters are only encoded where needed (#22337)
Fixes: #10280

This change brings Angular largely in line with how AngularJS previously serialized URLs. This is based on [RFC 3986](http://tools.ietf.org/html/rfc3986) and resolves issues such as the above #10280 where URLs could be parsed, re-serialized, then parsed again producing a different result on the second parsing.

Adjustments to be aware of in this commit:

* Query strings will now serialize with decoded slash (`/`) and question mark (`?`)
* URI fragments will now serialize the same as query strings, but hash sign (`#`) will also appear decoded
* In the URI path or segments (portion prior to query string and/or fragment), the plus sign (`+`) and ampersand (`&`) will appear decoded
* In the URL path or segments, parentheses values (`(` and `)`) will now appear percent encoded as `%28` and `%29` respectively
* In the URL path or segments, semicolons will be encoded in their percent encoding `%3B`

NOTE: Parentheses and semicolons denoting auxillary routes or matrix params will still appear in their decoded form -- only parentheses and semicolons used as values in a segment or key/value pair for matrix params will be encoded.

While these changes are not considered breaking because applications should be decoding URLs and key/value pairs, it is possible that some unit tests will break if comparing hard-coded URLs in tests since that hard coded string will represent the old encoding. Therefore we are releasing this fix in the upcoming Angular v6 rather than adding it to a patch for v5.

PR Close #22337
2018-02-23 13:20:51 -08:00
3a809cb431 build: add support for the "merge-assistance" label in merge-pr (#22414)
fixes #22256

PR Close #22414
2018-02-23 12:58:30 -08:00
b43b164a61 feat(bazel): add an ng_package rule (#22221)
This produces a directory following the Angular Package layout spec.

Includes integration test coverage by making a minimal ng_package in integration/bazel.
Unit tests verify the content of the @angular/core and @angular/common packages.

This doesn't totally match our current output, but is good enough to unblock some
early adopters.

It re-uses logic from the rollup_bundle rule in rules_nodejs. It should also
eventually have the .pack and .publish secondary targets like npm_package rule.

PR Close #22221
2018-02-23 11:19:04 -08:00
1dcbc12fd3 docs(aio): Essential JS 2 url updated (#19739)
PR Close #19739
2018-02-23 11:18:11 -08:00
ae2e85e8ef docs(aio): Essential JS 2 UI Components. (#19739)
PR Close #19739
2018-02-23 11:18:11 -08:00
aad431642a refactor(ivy): rename componentRefresh to directiveRefresh (#22395)
PR Close #22395
2018-02-23 09:42:08 -08:00
a81d599bfc ci: don't use bazel git_repository rule (#22406)
It's currently broken on CircleCI because of a TLS change made by GitHub.
This is okay as a permanent change, we don't really want bazel to fetch a full git history.

Fixes #22405

PR Close #22406
2018-02-23 09:41:10 -08:00
7effb0016c fix(ivy): ngOnChanges to receive SimpleChanges with non minified property names as keys (#22352)
PR Close #22352
2018-02-22 17:48:52 -08:00
f791862e52 build: add release helper scripts (#22378)
PR Close #22378
2018-02-22 16:12:50 -08:00
b2f366b3b7 fix(animations): only use the WA-polyfill alongside AnimationBuilder (#22143)
This patch removes the need to include the Web Animations API Polyfill
(web-animations-js) as a dependency. Angular will now fallback to using
CSS Keyframes in the event that `element.animate` is no longer supported
by the browser.

In the event that an application does use `AnimationBuilder` then the
web-animations-js polyfill is required to enable programmatic,
position-based access to an animation.

Closes #17496

PR Close #22143
2018-02-22 16:07:53 -08:00
9eecb0b27f docs: fix deployment sample path (#22048)
PR Close #22048
2018-02-22 13:40:57 -08:00
45eff4cc65 fix(router): don't mutate route configs (#22358)
Fixes #22203

PR Close #22358
2018-02-22 13:35:38 -08:00
b3ffeaa22b fix(ivy): OnDestroy hook should not be called twice for a directive on an element (#22350)
PR Close #22350
2018-02-22 13:35:17 -08:00
f194d00366 build: disable bazel-out symlink (#22375)
It causes headaches on MacOS High Sierra, see https://github.com/bazelbuild/bazel/issues/4603

PR Close #22375
2018-02-22 13:31:59 -08:00
b7544cccc6 feat(core): support metadata reflection for native class types (#22356)
closes #21731

PR Close #22356
2018-02-22 13:22:03 -08:00
894b098eb3 test(ivy): add missing tests on directive lifecycle hooks (#22368)
PR Close #22368
2018-02-22 11:21:15 -08:00
022ad4a420 docs: fix ngmodules-jsmodules pre-req (#22316)
closes #22157

PR Close #22316
2018-02-22 11:20:47 -08:00
a4f9e8180b docs: edit styleguide recommendation on components as elements (#22074)
Change recommendation on using attributes for components since there are use cases including the use of <button mat-button> in MD

Closes #19401.

PR Close #22074
2018-02-22 11:20:21 -08:00
e86b64b620 feat(forms): allow markAsPending to emit events (#20212)
closes #17958

BREAKING CHANGE:
- `AbstractControl#statusChanges` now emits an event of `'PENDING'` when you call `AbstractControl#markAsPending`
- Previously it did not emit an event when you called `markAsPending`
- To migrate you would need to ensure that if you are filtering or checking events from `statusChanges` that you account for the new event when calling `markAsPending`

PR Close #20212
2018-02-22 11:15:33 -08:00
90e9c59e23 Revert "feat(core): support metadata reflection for native class types (#22356)"
This reverts commit 5c89d6bffa.
2018-02-22 10:26:06 -08:00
ca06af40f4 build: allow passing node options to ngc. (#22245)
PR Close #22245
2018-02-22 10:20:04 -08:00
6091a954cc docs: add changelog for 6.0.0-beta.5 2018-02-21 17:15:41 -08:00
d27fca9301 release: cut the 6.0.0-beta.5 release 2018-02-21 16:57:40 -08:00
5c89d6bffa feat(core): support metadata reflection for native class types (#22356)
closes #21731

PR Close #22356
2018-02-21 16:09:27 -08:00
3e6a86fb0a fix(forms): set state before emitting a value from ngModelChange (#21514)
Closes #21513.

PR Close #21514
2018-02-21 15:59:33 -08:00
a7ebf5aadd fix(core): properly handle function without prototype in reflector (#22284)
closes #19978

PR Close #22284
2018-02-21 14:52:04 -08:00
b42921bbd2 docs(aio): updates directive event hooks real capabilities (#16654)
Minor documentation update to include event hooks that were assumed to only work on components.

Closes angular/angular#10221

PR Close #16654
2018-02-21 14:51:04 -08:00
722dec11b0 docs(aio): Wrong code example. Form status field was added later in the guide. (#21275)
PR Close #21275
2018-02-21 11:06:47 -08:00
9e6268ba59 docs(http): fix a typo in code comment (#22327)
PR Close #22327
2018-02-21 11:06:06 -08:00
435f6eecd2 build: make git revert messages valid (#22339)
`git revert` default message is "Revert <original message>" (no semi-colon)

PR Close #22339
2018-02-21 11:05:35 -08:00
1c1cbba04b docs: add ngStyle to cheat sheet (#22070)
PR Close #22070
2018-02-20 16:08:15 -08:00
3b692a55a7 docs(aio): fix incorrect quote mark usage (#22335)
PR Close #22335
2018-02-20 15:42:55 -08:00
69a0578e00 docs(aio): fix the css of the heroes component's buttons (#22333)
Fixes #22222

PR Close #22333
2018-02-20 15:41:56 -08:00
b5ca275590 docs(aio): Fix name of component (#22332)
PR Close #22332
2018-02-20 15:41:35 -08:00
519f022b02 docs(aio): update installed mobile tool list (#22331)
PR Close #22331
2018-02-20 15:41:15 -08:00
236a9320df build: update tsickle dep from compiler-cli (#22295)
PR Close #22295
2018-02-20 15:40:44 -08:00
28ac24444f fix(compiler-cli): add missing entry point to package, update tsickle (#22295)
PR Close #22295
2018-02-20 15:40:44 -08:00
99909bbf2c feat(ivy): generate pipe references and definitions (#22034)
PR Close #22034
2018-02-20 13:58:03 -08:00
ee60bb5b36 fix(ivy): pureFunction8 should update the right bindings (#22313)
PR Close #22313
2018-02-20 11:36:50 -08:00
f6120c09e7 docs(aio): add Nx and Angular Enterprise Playbook to resources (#22321)
PR Close #22321
2018-02-20 10:09:33 -08:00
e2bdef4cf6 test(language-service): fix minor typos (#21372)
PR Close #21372
2018-02-20 10:08:55 -08:00
8115edc82f fix(common): then and else template might be set to null (#22298)
PR Close #22298
2018-02-18 19:25:28 -08:00
a8b5465e24 fix(ivy): update master with renamings (#22268)
PR Close #22268
2018-02-18 18:48:41 -08:00
9ce495b3d8 refactor(ivy): simplify interpolation instructions (#22268)
PR Close #22268
2018-02-18 18:48:41 -08:00
d40263447d refactor(ivy): move get functions next to their underlying variable (#22268)
PR Close #22268
2018-02-18 18:48:41 -08:00
31c5c1060a docs(ivy): update the API docs instructions to add details about removing attributes (#22268)
PR Close #22268
2018-02-18 18:48:41 -08:00
c9ebd60435 refactor(ivy): interpolatiom instructions do not support NO_CHANGE at input. (#22268)
PR Close #22268
2018-02-18 18:48:41 -08:00
5a14e2238f refactor(ivy): split the memory instruction into store and load (#22268)
PR Close #22268
2018-02-18 18:48:41 -08:00
3ceee99e22 feat(compiler-cli): Check unvalidated combination of ngc and TypeScript (#22293)
closes #20669

PR Close #22293
2018-02-18 15:12:46 -08:00
28b23f954c docs(aio): add angular-buch to resources (#22163)
adds a link to the website of our book. second version of the text. thanks!

PR Close #22163
2018-02-18 15:12:13 -08:00
ad17e5e791 docs(aio): add angular-buch to resources (#22163)
adds a link to the website of our book. many thanks for reviewing this

PR Close #22163
2018-02-18 15:12:13 -08:00
c30d329faa fix(ivy): fix merge errors (master is broken) (#22291)
PR Close #22291
2018-02-18 15:03:39 -08:00
991300b86c feat(platform-browser): do not throw error when Hammer.js not loaded (#22257)
closes #16992

PR Close #22257
2018-02-18 13:29:14 -08:00
7c45db3a19 docs: correct grammar mistakes in CONTRIBUTING.md (#22285)
Various grammar mistakes were present in the contribution guidelines
This commit corrects some of them

PR Close #22285
2018-02-18 13:27:23 -08:00
67cf11d071 feat(common): better error message when non-template element used in NgIf (#22274)
closes #16410

PR Close #22274
2018-02-18 13:26:50 -08:00
49082d7ab2 feat(ivy): support host attributes (#22213)
PR Close #22213
2018-02-18 13:22:38 -08:00
6b627f67db test(ivy): add missing host listener and host attribute binding tests (#22213)
PR Close #22213
2018-02-18 13:22:38 -08:00
5c320b4c2a test(ivy): add missing host binding and query tests (#22213)
PR Close #22213
2018-02-18 13:22:34 -08:00
ac2b04a5ab test(ivy): Add small_app spec for sprint #3 (#22018)
PR Close #22018
2018-02-18 13:18:54 -08:00
a63b764b54 test(ivy): move compiler canonical specs into a single directory (#22018)
PR Close #22018
2018-02-18 13:18:54 -08:00
2654357c72 docs: update BAZEL.md crosstool error instructions (#22018)
PR Close #22018
2018-02-18 13:18:54 -08:00
4ec40c6ab2 fix(aio): improve announcement-bar layout with wide logos (#22272)
PR Close #22272
2018-02-18 13:16:30 -08:00
80d424798e docs(aio): added ngconf announcement (#22272)
PR Close #22272
2018-02-18 13:16:30 -08:00
7fa2d4b503 fix: merge-pr script (#22290)
PR Close #22290
2018-02-18 13:13:29 -08:00
f4845fae12 build: use authenticated mode for the merge script (#22269)
`TOKEN` is the name with use for other GH scripts

PR Close #22269
2018-02-18 12:44:42 -08:00
f693be3996 feat(ivy): add pureFunction0 instruction (#22214)
PR Close #22214
2018-02-16 18:03:55 -08:00
a73d5308e0 refactor(ivy): rename objectLiteral to pureFn to prep for pipes (#22214)
PR Close #22214
2018-02-16 18:03:55 -08:00
e1bf067090 fix(animations): report correct totalTime value even during noOp animations (#22225)
This patch ensures that if the NoopAnimationsModule is used then it will
correctly report the associated `totalTime` property within the emitted
AnimationEvent instance when an animation event trigger is fired.

BREAKING CHANGE: When animation is trigged within a disabled zone, the
associated event (which an instance of AnimationEvent) will no longer
report the totalTime as 0 (it will emit the actual time of the
animation). To detect if an animation event is reporting a disabled
animation then the `event.disabled` property can be used instead.

PR Close #22225
2018-02-16 18:03:31 -08:00
884de18cba docs: replace plnkr with StackBlitz (#20365)
PR Close #20365
2018-02-16 15:12:10 -08:00
dfa2fb95d5 test(ivy): clean the imported renderer2 (#22255)
PR Close #22255
2018-02-16 15:11:23 -08:00
2639b4bffb fix(common): correct mapping of Observable methods (#20518)
fixes #20516
PR Close #20518
2018-02-16 15:10:31 -08:00
978f97cc59 test(aio): increase docs-test timeouts to prevent flakes on Travis (#22261)
PR Close #22261
2018-02-16 14:46:23 -08:00
f1a063298e feat(core): set preserveWhitespaces to false by default (#22046)
Fixes #22027

PR Close #22046
2018-02-16 09:06:14 -08:00
d241532488 docs(ivy): add a note about exporting top level variables (#22234)
PR Close #22234
2018-02-15 16:16:40 -08:00
f755db78dc fix(core): require factory to be provided for shakeable InjectionToken (#22207)
InjectionToken can be created with an ngInjectableDef, and previously
this allowed the full expressiveness of @Injectable. However, this
requires a runtime reflection system in order to generate factories
from expressed provider declarations.

Instead, this change requires scoped InjectionTokens to provide the
factory directly (likely using inject() for the arguments), bypassing
the need for a reflection system.

Fixes #22205

PR Close #22207
2018-02-15 16:16:16 -08:00
5dd2b5135d refactor(ivy): rename bindX() functions to interpolationX() (#22229)
rationale: remove the confusion with `bind()` and `bind0()`

PR Close #22229
2018-02-15 14:20:53 -08:00
7ac34e42a0 feat: allow direct scoping of @Injectables to the root injector (#22185)
@Injectable() supports a scope parameter which specifies the target module.
However, it's still difficult to specify that a particular service belongs
in the root injector. A developer attempting to ensure that must either
also provide a module intended for placement in the root injector or target
a module known to already be in the root injector (e.g. BrowserModule).
Both of these strategies are cumbersome and brittle.

Instead, this commit adds a token APP_ROOT_SCOPE which provides a
straightforward way of targeting the root injector directly, without
requiring special knowledge of modules within it.

PR Close #22185
2018-02-15 14:20:27 -08:00
029dbf0e18 feat(bazel): ng_module produces bundle index (#22176)
It creates the bundle index .d.ts and .metadata.json files.
The names are based on the ng_module target.

PR Close #22176
2018-02-15 14:08:53 -08:00
bba65e0f41 feat(bazel): introduce a binary stamping feature (#22176)
This grabs version control metadata and makes it available in the build, eg. to put in the version field for released artifacts

PR Close #22176
2018-02-15 14:08:53 -08:00
a069e08354 refactor(bazel): convert most ts_library to ng_module (#22176)
This is necessary so we can produce ng metadata for our packages that are published as libraries

PR Close #22176
2018-02-15 14:08:53 -08:00
03d93c96a3 Revert: "build: merge-pr new checks that all requested changes have been addressed (#21817)"
This reverts commit 4a4d749710.
2018-02-15 11:00:52 -08:00
020338230f style: fix typos boostrap to bootstrap (#21917)
PR Close #21917
2018-02-15 09:54:00 -08:00
a1d86daa71 refactor(ivy): assertion (#22189)
Encourage the use of message to explain the assertion

PR Close #22189
2018-02-15 09:53:05 -08:00
7078fbffb4 fix(aio): improve printing styles (#19651)
printfix

PR Close #19651
2018-02-15 09:52:32 -08:00
0aa9b46b79 Revert "build: allow bazel build ... (#22168)"
This reverts commit 265ac8a106.
2018-02-15 03:28:35 -08:00
831592c381 Revert "style: fix typos boostrap to bootstrap (#21917)"
This reverts commit 363498b6b4.
2018-02-14 22:56:44 -05:00
f628797d91 Revert "refactor(ivy): assertion (#22189)"
This reverts commit 0b683123d2.
2018-02-14 22:56:11 -05:00
47f51c2ead Revert "Revert "build: merge-pr new checks that all requested changes have been addressed (#21817)""
This reverts commit 5b8eb9c5c7.
2018-02-14 22:55:56 -05:00
ba9cd5bbc4 Revert "fix(aio): improve printing styles (#19651)"
This reverts commit b54ad053f9.
2018-02-14 22:55:24 -05:00
b54ad053f9 fix(aio): improve printing styles (#19651)
printfix

PR Close #19651
2018-02-14 18:49:58 -05:00
5b8eb9c5c7 Revert "build: merge-pr new checks that all requested changes have been addressed (#21817)"
This reverts commit 4a4d749710.
2018-02-14 18:48:45 -05:00
0b683123d2 refactor(ivy): assertion (#22189)
Encourage the use of message to explain the assertion

PR Close #22189
2018-02-14 18:42:04 -05:00
363498b6b4 style: fix typos boostrap to bootstrap (#21917)
PR Close #21917
2018-02-14 18:21:52 -05:00
a1bb56f739 docs: fix changelog errors (#22226)
PR Close #22226
2018-02-14 18:18:22 -05:00
5bb9fcad3e build: comment-out chromium version checking code temporarily (#22232)
Related #22231

PR Close #22232
2018-02-14 17:26:43 -05:00
Pat
f4697f351e docs: typo - components should be possessive (#22172)
PR Close #22172
2018-02-14 15:06:52 -05:00
1d571b299d feat(platform-browser): fix #19604, can config hammerOptions (#21979)
PR Close #21979
2018-02-14 15:02:58 -05:00
3a0b5a928c docs(aio): fix extraneous divs (#22069)
PR Close #22069
2018-02-14 15:02:36 -05:00
265ac8a106 build: allow bazel build ... (#22168)
Note, the reason this commit removes `firebase-tools` is:

1) firebase-tools has an optional dependency on
https://www.npmjs.com/package/@google-cloud/functions-emulator
2) yarn's `--ignore-optional` doesn't work for transitive deps, so
there's no way to yarn install without getting that functions-emulator
package
3) functions-emulator has a transitive dep on `grpc`
4) the version of `grpc` we get has `BUILD` files and no `WORKSPACE`
file so it always breaks `bazel build ...`

It could be solved by any of:
1) remove firebase-tools - this is what I did
2) fix yarn so you can omit optional deps of a transitive dep
3) make functions-emulator depend transitively on a more recent `grpc`
version
4) patch `grpc` after install by doing an `rm` command in our
postinstall or something

In its place we must install protobufjs. This is needed by the
ngc-wrapped test, which needs jasmine as well as bazel's worker mode
dependencies, and therefore cannot simply rely on
node_modules =
"@build_bazel_rules_typescript_tsc_wrapped_deps//:node_modules"

PR Close #22168
2018-02-14 15:01:41 -05:00
962 changed files with 42905 additions and 12675 deletions

View File

@ -15,11 +15,16 @@ build --experimental_remote_spawn_cache --remote_rest_cache=http://localhost:764
# Prevent unstable environment variables from tainting cache keys
build --experimental_strict_action_env
# Save downloaded repositories such as the go toolchain
# This directory can then be included in the CircleCI cache
# It should save time running the first build
build --experimental_repository_cache=/home/circleci/bazel_repository_cache
# Workaround https://github.com/bazelbuild/bazel/issues/3645
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
# Limit Bazel to consuming resources that fit in CircleCI "medium" class which is the default:
# Limit Bazel to consuming resources that fit in CircleCI "xlarge" class
# https://circleci.com/docs/2.0/configuration-reference/#resource_class
build --local_resources=3072,2.0,1.0
build --local_resources=14336,8.0,1.0
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
test --flaky_test_attempts=2

View File

@ -13,7 +13,7 @@
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.1.0
var_2: &cache_key angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.1.0
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.1.0
# See remote cache documentation in /docs/BAZEL.md
var_3: &setup-bazel-remote-cache
@ -41,14 +41,14 @@ jobs:
steps:
- 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
- run: 'yarn buildifier -mode=check ||
(echo -e "\nBUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
- run: 'yarn skylint ||
# Check BUILD.bazel formatting before we have a node_modules directory
# Then we don't need any exclude pattern to avoid checking those files
- run: 'buildifier -mode=check $(find . -type f \( -name BUILD.bazel -or -name BUILD \)) ||
(echo "BUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
# Run the skylark linter to check our Bazel rules
- run: 'find . -type f -name "*.bzl" |
xargs java -jar /usr/local/bin/Skylint_deploy.jar ||
(echo -e "\n.bzl files have lint errors. Please run ''yarn skylint''"; exit 1)'
- restore_cache:
@ -59,7 +59,7 @@ jobs:
build:
<<: *job_defaults
resource_class: large
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
@ -71,6 +71,7 @@ jobs:
- restore_cache:
key: *cache_key
- run: ls /home/circleci/bazel_repository_cache || true
- run: bazel info release
- run: bazel run @yarn//:yarn
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
@ -91,6 +92,7 @@ jobs:
key: *cache_key
paths:
- "node_modules"
- "~/bazel_repository_cache"
workflows:
version: 2

View File

@ -25,7 +25,7 @@ ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.
## Minimal reproduction of the problem with instructions
<!--
For bug reports please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5).
https://stackblitz.com or similar (you can use this template as a starting point: https://stackblitz.com/fork/angular-gitter).
-->
## What is the motivation / use case for changing the behavior?

View File

@ -26,9 +26,7 @@ merge:
# list of patterns to check for the files changed by the PR
# this list must be manually kept in sync with google3/third_party/javascript/angular2/copy.bara.sky
include:
- "BUILD.bazel"
- "LICENSE"
- "WORKSPACE"
- "modules/**"
- "packages/**"
# list of patterns to ignore for the files changed by the PR
@ -36,6 +34,11 @@ merge:
- "packages/language-service/**"
- "**/.gitignore"
- "**/.gitkeep"
- "**/tsconfig-build.json"
- "**/tsconfig.json"
- "**/rollup.config.js"
- "**/BUILD.bazel"
- "packages/**/test/**"
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.
@ -80,12 +83,14 @@ merge:
# options for the triage plugin
triage:
# number of the milestone to apply when the issue has not been triaged yet
needsTriageMilestone: 83,
# number of the milestone to apply when the issue is triaged
defaultMilestone: 82,
# arrays of labels that determine if an issue is triaged
triagedLabels:
-
- "type: bug"
- "type: bug/fix"
- "severity*"
- "freq*"
- "comp: *"

View File

@ -68,6 +68,7 @@ groups:
- "packages/*"
- "tools/*"
users:
- alexeagle
- IgorMinar
- mhevery

View File

@ -2,8 +2,16 @@ package(default_visibility = ["//visibility:public"])
exports_files([
"tsconfig.json",
"LICENSE",
])
# Developers should always run `bazel run :install`
# This ensures that package.json in subdirectories get installed as well.
alias(
name = "install",
actual = "@yarn//:yarn",
)
# This rule belongs in node_modules/BUILD
# It's here as a workaround for
# https://github.com/bazelbuild/bazel/issues/374#issuecomment-296217940
@ -49,6 +57,7 @@ filegroup(
"//:node_modules/zone.js/dist/async-test.js",
"//:node_modules/zone.js/dist/sync-test.js",
"//:node_modules/zone.js/dist/fake-async-test.js",
"//:node_modules/zone.js/dist/task-tracking.js",
"//:node_modules/zone.js/dist/proxy.js",
"//:node_modules/zone.js/dist/jasmine-patch.js",
],

View File

@ -1,18 +1,190 @@
<a name="6.0.0-beta.7"></a>
# [6.0.0-beta.7](https://github.com/angular/angular/compare/6.0.0-beta.6...6.0.0-beta.7) (2018-03-07)
### Bug Fixes
* **bazel:** fixes for ng_package on Windows ([#22597](https://github.com/angular/angular/issues/22597)) ([4c40812](https://github.com/angular/angular/commit/4c40812))
* **compiler:** allow tree-shakeable injectables to depend on string tokens ([#22376](https://github.com/angular/angular/issues/22376)) ([dd53447](https://github.com/angular/angular/commit/dd53447))
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([fa974c7](https://github.com/angular/angular/commit/fa974c7)), closes [#10280](https://github.com/angular/angular/issues/10280)
<a name="5.2.8"></a>
## [5.2.8](https://github.com/angular/angular/compare/5.2.7...5.2.8) (2018-03-07)
### Bug Fixes
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
<a name="6.0.0-beta.6"></a>
# [6.0.0-beta.6](https://github.com/angular/angular/compare/6.0.0-beta.5...6.0.0-beta.6) (2018-02-28)
### Bug Fixes
* **animations:** only use the WA-polyfill alongside AnimationBuilder ([#22143](https://github.com/angular/angular/issues/22143)) ([b2f366b](https://github.com/angular/angular/commit/b2f366b)), closes [#17496](https://github.com/angular/angular/issues/17496)
* **animations:** report correct totalTime value even during noOp animations ([#22225](https://github.com/angular/angular/issues/22225)) ([e1bf067](https://github.com/angular/angular/commit/e1bf067))
* **bazel:** ng_package includes transitive .d.ts and flatModuleMetadata ([#22499](https://github.com/angular/angular/issues/22499)) ([aabe16c](https://github.com/angular/angular/commit/aabe16c)), closes [#22419](https://github.com/angular/angular/issues/22419)
* **common:** correct mapping of Observable methods ([#20518](https://github.com/angular/angular/issues/20518)) ([2639b4b](https://github.com/angular/angular/commit/2639b4b)), closes [#20516](https://github.com/angular/angular/issues/20516)
* **common:** then and else template might be set to null ([#22298](https://github.com/angular/angular/issues/22298)) ([8115edc](https://github.com/angular/angular/commit/8115edc))
* **compiler-cli:** add missing entry point to package, update tsickle ([#22295](https://github.com/angular/angular/issues/22295)) ([28ac244](https://github.com/angular/angular/commit/28ac244))
* **core:** export inject() from [@angular](https://github.com/angular)/core ([#22389](https://github.com/angular/angular/issues/22389)) ([f8749bf](https://github.com/angular/angular/commit/f8749bf)), closes [#22388](https://github.com/angular/angular/issues/22388)
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([a7ebf5a](https://github.com/angular/angular/commit/a7ebf5a)), closes [#19978](https://github.com/angular/angular/issues/19978)
* **core:** require factory to be provided for shakeable InjectionToken ([#22207](https://github.com/angular/angular/issues/22207)) ([f755db7](https://github.com/angular/angular/commit/f755db7)), closes [#22205](https://github.com/angular/angular/issues/22205)
* **forms:** set state before emitting a value from ngModelChange ([#21514](https://github.com/angular/angular/issues/21514)) ([3e6a86f](https://github.com/angular/angular/commit/3e6a86f)), closes [#21513](https://github.com/angular/angular/issues/21513)
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([40ba009](https://github.com/angular/angular/commit/40ba009)), closes [#19235](https://github.com/angular/angular/issues/19235)
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([45eff4c](https://github.com/angular/angular/commit/45eff4c)), closes [#22203](https://github.com/angular/angular/issues/22203)
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([094666d](https://github.com/angular/angular/commit/094666d)), closes [#10280](https://github.com/angular/angular/issues/10280)
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([8a85888](https://github.com/angular/angular/commit/8a85888)), closes [#22392](https://github.com/angular/angular/issues/22392)
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([f089bf5](https://github.com/angular/angular/commit/f089bf5))
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([13ab91e](https://github.com/angular/angular/commit/13ab91e)), closes [#22175](https://github.com/angular/angular/issues/22175)
### Features
* **bazel:** add an ng_package rule ([#22221](https://github.com/angular/angular/issues/22221)) ([b43b164](https://github.com/angular/angular/commit/b43b164))
* **bazel:** introduce a binary stamping feature ([#22176](https://github.com/angular/angular/issues/22176)) ([bba65e0](https://github.com/angular/angular/commit/bba65e0))
* **bazel:** ng_module produces bundle index ([#22176](https://github.com/angular/angular/issues/22176)) ([029dbf0](https://github.com/angular/angular/commit/029dbf0))
* **bazel:** ng_package adds package.json props ([#22499](https://github.com/angular/angular/issues/22499)) ([b6c9410](https://github.com/angular/angular/commit/b6c9410)), closes [#22416](https://github.com/angular/angular/issues/22416)
* **common:** better error message when non-template element used in NgIf ([#22274](https://github.com/angular/angular/issues/22274)) ([67cf11d](https://github.com/angular/angular/commit/67cf11d)), closes [#16410](https://github.com/angular/angular/issues/16410)
* **common:** export functions to format numbers, percents, currencies & dates ([#22423](https://github.com/angular/angular/issues/22423)) ([4180912](https://github.com/angular/angular/commit/4180912)), closes [#20536](https://github.com/angular/angular/issues/20536)
* **compiler-cli:** Check unvalidated combination of ngc and TypeScript ([#22293](https://github.com/angular/angular/issues/22293)) ([3ceee99](https://github.com/angular/angular/commit/3ceee99)), closes [#20669](https://github.com/angular/angular/issues/20669)
* **core:** set preserveWhitespaces to false by default ([#22046](https://github.com/angular/angular/issues/22046)) ([f1a0632](https://github.com/angular/angular/commit/f1a0632)), closes [#22027](https://github.com/angular/angular/issues/22027)
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([5c89d6b](https://github.com/angular/angular/commit/5c89d6b)), closes [#21731](https://github.com/angular/angular/issues/21731)
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([b7544cc](https://github.com/angular/angular/commit/b7544cc)), closes [#21731](https://github.com/angular/angular/issues/21731)
* **forms:** allow markAsPending to emit events ([#20212](https://github.com/angular/angular/issues/20212)) ([e86b64b](https://github.com/angular/angular/commit/e86b64b)), closes [#17958](https://github.com/angular/angular/issues/17958)
* allow direct scoping of @Injectables to the root injector ([#22185](https://github.com/angular/angular/issues/22185)) ([7ac34e4](https://github.com/angular/angular/commit/7ac34e4))
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
* **platform-server:** bump Domino to v2.0 ([#22411](https://github.com/angular/angular/issues/22411)) ([d3827a0](https://github.com/angular/angular/commit/d3827a0))
### BREAKING CHANGES
* **platform-server:** * Bump the dependency on Domino to 2.0 to resolve issues with
namespacing
* **forms:** - `AbstractControl#statusChanges` now emits an event of `'PENDING'` when you call `AbstractControl#markAsPending`
- Previously it did not emit an event when you called `markAsPending`
- To migrate you would need to ensure that if you are filtering or checking events from `statusChanges` that you account for the new event when calling `markAsPending`
* **animations:** When animation is trigged within a disabled zone, the
associated event (which an instance of AnimationEvent) will no longer
report the totalTime as 0 (it will emit the actual time of the
animation). To detect if an animation event is reporting a disabled
animation then the `event.disabled` property can be used instead.
<a name="5.2.7"></a>
## [5.2.7](https://github.com/angular/angular/compare/5.2.6...5.2.7) (2018-02-28)
### Bug Fixes
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
<a name="6.0.0-beta.5"></a>
# [6.0.0-beta.5](https://github.com/angular/angular/compare/6.0.0-beta.4...6.0.0-beta.5) (2018-02-22)
### Bug Fixes
* **animations:** report correct totalTime value even during noOp animations ([#22225](https://github.com/angular/angular/issues/22225)) ([e1bf067](https://github.com/angular/angular/commit/e1bf067))
* **common:** correct mapping of Observable methods ([#20518](https://github.com/angular/angular/issues/20518)) ([2639b4b](https://github.com/angular/angular/commit/2639b4b)), closes [#20516](https://github.com/angular/angular/issues/20516)
* **common:** then and else template might be set to null ([#22298](https://github.com/angular/angular/issues/22298)) ([8115edc](https://github.com/angular/angular/commit/8115edc))
* **compiler-cli:** add missing entry point to package, update tsickle ([#22295](https://github.com/angular/angular/issues/22295)) ([28ac244](https://github.com/angular/angular/commit/28ac244))
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([a7ebf5a](https://github.com/angular/angular/commit/a7ebf5a)), closes [#19978](https://github.com/angular/angular/issues/19978)
* **core:** require factory to be provided for shakeable InjectionToken ([#22207](https://github.com/angular/angular/issues/22207)) ([f755db7](https://github.com/angular/angular/commit/f755db7)), closes [#22205](https://github.com/angular/angular/issues/22205)
* **forms:** set state before emitting a value from ngModelChange ([#21514](https://github.com/angular/angular/issues/21514)) ([3e6a86f](https://github.com/angular/angular/commit/3e6a86f)), closes [#21513](https://github.com/angular/angular/issues/21513)
* **core:** set `preserveWhitespaces` to false by default ([#22046](https://github.com/angular/angular/issues/22046)) ([f1a0632](https://github.com/angular/angular/commit/f1a0632)), closes [#22027](https://github.com/angular/angular/issues/22027)
### Features
* **common:** better error message when non-template element used in NgIf ([#22274](https://github.com/angular/angular/issues/22274)) ([67cf11d](https://github.com/angular/angular/commit/67cf11d)), closes [#16410](https://github.com/angular/angular/issues/16410)
* **compiler-cli:** Check unvalidated combination of ngc and TypeScript ([#22293](https://github.com/angular/angular/issues/22293)) ([3ceee99](https://github.com/angular/angular/commit/3ceee99)), closes [#20669](https://github.com/angular/angular/issues/20669)
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([5c89d6b](https://github.com/angular/angular/commit/5c89d6b)), closes [#21731](https://github.com/angular/angular/issues/21731)
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
### BREAKING CHANGES
* **animations:** When animation is triggered within a disabled zone, the
associated event (which an instance of AnimationEvent) will no longer
report the totalTime as 0 (it will emit the actual time of the
animation). To detect if an animation event is reporting a disabled
animation then the `event.disabled` property can be used instead.
* **forms:** ngModelChange is now emitted after the value/validity is updated on its control.
Previously, ngModelChange was emitted before its underlying control was updated.
This was fine if you passed through the value directly through the $event keyword, e.g.
```
<input [(ngModel)]="name" (ngModelChange)="onChange($event)">
onChange(value) {
console.log(value); // would log updated value
}
```
However, if you had a handler for the ngModelChange event that checked the value through the control,
you would get the old value rather than the updated value. e.g:
```
<input #modelDir="ngModel" [(ngModel)]="name" (ngModelChange)="onChange(modelDir)">
onChange(ngModel: NgModel) {
console.log(ngModel.value); // would log old value, not updated value
}
```
Now the value and validity will be updated before the ngModelChange event is emitted,
so the same setup will log the updated value.
```
onChange(ngModel: NgModel) {
console.log(ngModel.value); // will log updated value
}
```
We think this order will be less confusing when the control is checked directly.
You will only need to update your app if it has relied on this bug to keep track of the old control value.
If that is the case, you should be able to track the old value directly by saving it on your component.
<a name="5.2.6"></a>
## [5.2.6](https://github.com/angular/angular/compare/5.2.5...5.2.6) (2018-02-22)
### Bug Fixes
* **common:** correct mapping of Observable methods ([#20518](https://github.com/angular/angular/issues/20518)) ([ce5e8fa](https://github.com/angular/angular/commit/ce5e8fa)), closes [#20516](https://github.com/angular/angular/issues/20516)
* **common:** then and else template might be set to null ([#22298](https://github.com/angular/angular/issues/22298)) ([af6a056](https://github.com/angular/angular/commit/af6a056))
* **compiler-cli:** add missing entry point to package, update tsickle ([#22295](https://github.com/angular/angular/issues/22295)) ([c5418c7](https://github.com/angular/angular/commit/c5418c7))
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([5ec38f2](https://github.com/angular/angular/commit/5ec38f2)), closes [#19978](https://github.com/angular/angular/issues/19978)
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([ee91de9](https://github.com/angular/angular/commit/ee91de9)), closes [#21731](https://github.com/angular/angular/issues/21731)
<a name="6.0.0-beta.4"></a>
# [6.0.0-beta.4](https://github.com/angular/angular/compare/6.0.0-beta.3...6.0.0-beta.4) (2018-02-14)
### Bug Fixes
* **bazel:** allow TS to read ambient typings ([#21876](https://github.com/angular/angular/issues/21876)) ([b081dfe](https://github.com/angular/angular/commit/b081dfe)), closes [#21872](https://github.com/angular/angular/issues/21872)
* **bazel:** improve error message for missing assets ([#22096](https://github.com/angular/angular/issues/22096)) ([dcf64a0](https://github.com/angular/angular/commit/dcf64a0)), closes [#22095](https://github.com/angular/angular/issues/22095)
* **common:** add locale currency values ([#21783](https://github.com/angular/angular/issues/21783)) ([420cc7a](https://github.com/angular/angular/commit/420cc7a)), closes [#20385](https://github.com/angular/angular/issues/20385)
* **common:** regenerate i18n locale data files ([#21783](https://github.com/angular/angular/issues/21783)) ([0b2f7d1](https://github.com/angular/angular/commit/0b2f7d1))
* **common:** round currencies based on decimal digits in `CurrencyPipe` ([#21783](https://github.com/angular/angular/issues/21783)) ([44154e7](https://github.com/angular/angular/commit/44154e7)), closes [#10189](https://github.com/angular/angular/issues/10189)
* **common:** weaken AsyncPipe transform signature ([#22169](https://github.com/angular/angular/issues/22169)) ([be59c3a](https://github.com/angular/angular/commit/be59c3a))
* **compiler:** make unary plus operator consistent to JavaScript ([#22154](https://github.com/angular/angular/issues/22154)) ([72f8abd](https://github.com/angular/angular/commit/72f8abd)), closes [#22089](https://github.com/angular/angular/issues/22089)
* **core:** add stacktrace in log when error during cleanup component in TestBed ([#22162](https://github.com/angular/angular/issues/22162)) ([16d1700](https://github.com/angular/angular/commit/16d1700))
* **core:** ensure initial value of QueryList length ([#21980](https://github.com/angular/angular/issues/21980)) ([#21982](https://github.com/angular/angular/issues/21982)) ([e56de10](https://github.com/angular/angular/commit/e56de10)), closes [/github.com/angular/angular/commit/e54474215629aa6a0e0497fe61bfc896cea532c9#diff-a85dbe0991a7577ea24b49374e9ae90](https://github.com//github.com/angular/angular/commit/e54474215629aa6a0e0497fe61bfc896cea532c9/issues/diff-a85dbe0991a7577ea24b49374e9ae90)
* **core:** ensure initial value of QueryList length ([#21980](https://github.com/angular/angular/issues/21980)) ([#21982](https://github.com/angular/angular/issues/21982)) ([e56de10](https://github.com/angular/angular/commit/e56de10)), closes [#21980](https://github.com/angular/angular/issues/21980)
* **core:** use appropriate inert document strategy for Firefox & Safari ([#17019](https://github.com/angular/angular/issues/17019)) ([a751649](https://github.com/angular/angular/commit/a751649))
* **forms:** make Validators.email support optional controls ([#20869](https://github.com/angular/angular/issues/20869)) ([140e7c0](https://github.com/angular/angular/commit/140e7c0))
* **forms:** prevent event emission on enable/disable when emitEvent is false ([#12366](https://github.com/angular/angular/issues/12366)) ([#21018](https://github.com/angular/angular/issues/21018)) ([0bcfae7](https://github.com/angular/angular/commit/0bcfae7))
@ -29,32 +201,26 @@
* **forms:** multiple validators for array method ([#20766](https://github.com/angular/angular/issues/20766)) ([941e88f](https://github.com/angular/angular/commit/941e88f)), closes [#20665](https://github.com/angular/angular/issues/20665)
* change @Injectable() to support tree-shakeable tokens ([#22005](https://github.com/angular/angular/issues/22005)) ([235a235](https://github.com/angular/angular/commit/235a235))
<a name="5.2.5"></a>
## [5.2.5](https://github.com/angular/angular/compare/5.2.4...5.2.5) (2018-02-14)
### Bug Fixes
(https://github.com/angular/angular/commit/15ff7ba)), closes [#21377](https://github.com/angular/angular/issues/21377)
* **aio:** update Firebase redirects and SW routes ([#21763](https://github.com/angular/angular/pull/21763)) ([#22104](https://github.com/angular/angular/pull/22104)) ([15ff7ba](https://github.com/angular/angular/commit/15ff7ba)), closes [#21377](https://github.com/angular/angular/issues/21377)
* **bazel:** allow TS to read ambient typings ([#21876](https://github.com/angular/angular/issues/21876)) ([d57fd0b](https://github.com/angular/angular/commit/d57fd0b)), closes [#21872](https://github.com/angular/angular/issues/21872)
* **bazel:** improve error message for missing assets ([#22096](https://github.com/angular/angular/issues/22096)) ([c5ec8d9](https://github.com/angular/angular/commit/c5ec8d9)), closes [#22095](https://github.com/angular/angular/issues/22095)
* **common:** weaken AsyncPipe transform signature ([#22169](https://github.com/angular/angular/issues/22169)) ([c6bdc83](https://github.com/angular/angular/commit/c6bdc83))
* **compiler:** make unary plus operator consistent to JavaScript ([#22154](https://github.com/angular/angular/issues/22154)) ([1b8ea10](https://github.com/angular/angular/commit/1b8ea10)), closes [#22089](https://github.com/angular/angular/issues/22089)
* **core:** add stacktrace in log when error during cleanup component in TestBed ([#22162](https://github.com/angular/angular/issues/22162)) ([c4f841f](https://github.com/angular/angular/commit/c4f841f))
* **core:** ensure initial value of QueryList length ([#21980](https://github.com/angular/angular/issues/21980)) ([#21982](https://github.com/angular/angular/issues/21982)) ([47b73fd](https://github.com/angular/angular/commit/47b73fd)), closes [/github.com/angular/angular/commit/e54474215629aa6a0e0497fe61bfc896cea532c9#diff-a85dbe0991a7577ea24b49374e9ae90](https://github.com//github.com/angular/angular/commit/e54474215629aa6a0e0497fe61bfc896cea532c9/issues/diff-a85dbe0991a7577ea24b49374e9ae90)
* **core:** ensure initial value of QueryList length ([#21980](https://github.com/angular/angular/issues/21980)) ([#21982](https://github.com/angular/angular/issues/21982)) ([47b73fd](https://github.com/angular/angular/commit/47b73fd)), closes [#21980](https://github.com/angular/angular/issues/21980)
* **core:** use appropriate inert document strategy for Firefox & Safari ([#17019](https://github.com/angular/angular/issues/17019)) ([47b71d9](https://github.com/angular/angular/commit/47b71d9))
* **forms:** prevent event emission on enable/disable when emitEvent is false ([#12366](https://github.com/angular/angular/issues/12366)) ([#21018](https://github.com/angular/angular/issues/21018)) ([56b9591](https://github.com/angular/angular/commit/56b9591))
* **language-service:** correct instructions to install the language service ([#22000](https://github.com/angular/angular/issues/22000)) ([0b23573](https://github.com/angular/angular/commit/0b23573))
* **platform-browser:** support 0/false/null values in transfer_state ([#22179](https://github.com/angular/angular/issues/22179)) ([da6ab91](https://github.com/angular/angular/commit/da6ab91))
<a name="6.0.0-beta.3"></a>
# [6.0.0-beta.3](https://github.com/angular/angular/compare/6.0.0-beta.2...6.0.0-beta.3) (2018-02-07)
### Bug Fixes
* **common:** don't convert null to a string when flushing a mock request ([#21417](https://github.com/angular/angular/issues/21417)) ([8b14488](https://github.com/angular/angular/commit/8b14488)), closes [#20744](https://github.com/angular/angular/issues/20744)

12
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,12 @@
# Contributor Code of Conduct
## Version 0.3b-angular
As contributors and maintainers of the Angular project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities.
Communication through any of Angular's channels (GitHub, Gitter, IRC, mailing lists, Google+, Twitter, etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the Angular project to do the same.
If any member of the community violates this code of conduct, the maintainers of the Angular project may take action, removing issues, comments, and PRs or blocking accounts as deemed appropriate.
If you are subject to or witness unacceptable behavior, or have any other concerns, please email us at [conduct@angular.io](mailto:conduct@angular.io).

View File

@ -51,7 +51,7 @@ and help you to craft the change so that it is successfully accepted into the pr
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs we will systematically ask you to provide a minimal reproduction scenario using http://plnkr.co. Having a live, reproducible scenario gives us wealth of important information without going back & forth to you with additional questions like:
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs, we will systematically ask you to provide a minimal reproduction scenario using http://plnkr.co. Having a live, reproducible scenario gives us a wealth of important information without going back & forth to you with additional questions like:
- version of Angular used
- 3rd-party libraries and their versions
@ -61,7 +61,7 @@ A minimal reproduce scenario using http://plnkr.co/ allows us to quickly confirm
We will be insisting on a minimal reproduce scenario in order to save maintainers time and ultimately be able to fix more bugs. Interestingly, from our experience users often find coding problems themselves while preparing a minimal plunk. We understand that sometimes it might be hard to extract essentials bits of code from a larger code-base but we really need to isolate the problem before we can fix it.
Unfortunately we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you we are going to close an issue that don't have enough info to be reproduced.
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you we are going to close an issue that doesn't have enough info to be reproduced.
You can file new issues by filling out our [new issue form](https://github.com/angular/angular/issues/new).
@ -173,12 +173,12 @@ The **header** is mandatory and the **scope** of the header is optional.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
Footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.
The footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.
Samples: (even more [samples](https://github.com/angular/angular/commits/master))
```
docs(changelog): update change log to beta.5
docs(changelog): update changelog to beta.5
```
```
fix(release): need to depend on latest rxjs and zone.js
@ -203,7 +203,7 @@ Must be one of the following:
* **test**: Adding missing tests or correcting existing tests
### Scope
The scope should be the name of the npm package affected (as perceived by person reading changelog generated from commit messages.
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages.
The following is the list of supported scopes:
@ -232,10 +232,10 @@ There are currently a few exceptions to the "use package name" rule:
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`)
### Subject
The subject contains succinct description of the change:
The subject contains a succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* don't capitalize the first letter
* no dot (.) at the end
### Body
@ -266,7 +266,7 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
* https://help.github.com/articles/about-commit-email-addresses/
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.

View File

@ -2,21 +2,24 @@ workspace(name = "angular")
http_archive(
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.4.1.zip",
strip_prefix = "rules_nodejs-0.4.1",
sha256 = "e9bc013417272b17f302dc169ad597f05561bb277451f010043f4da493417607",
url = "https://github.com/bazelbuild/rules_nodejs/archive/f03c8b5df155da2a640b6775afdd4fe4aa6fec72.zip",
strip_prefix = "rules_nodejs-f03c8b5df155da2a640b6775afdd4fe4aa6fec72",
sha256 = "9d541f49af8cf60c73efb102186bfa5670ee190a088ce52638dcdf90cd9e2de6",
)
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
check_bazel_version("0.9.0")
node_repositories(package_json = ["//:package.json"])
node_repositories(package_json = [
"//:package.json",
"//tools/ts-api-guardian:package.json",
])
http_archive(
name = "build_bazel_rules_typescript",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.10.1.zip",
strip_prefix = "rules_typescript-0.10.1",
sha256 = "a2c81776a4a492ff9f878f9705639f5647bef345f7f3e1da09c9eeb8dec80485",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.11.1.zip",
strip_prefix = "rules_typescript-0.11.1",
sha256 = "7406bea7954e1c906f075115dfa176551a881119f6820b126ea1eacb09f34a1a",
)
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
@ -28,13 +31,16 @@ local_repository(
path = "node_modules/rxjs/src",
)
git_repository(
# This commit matches the version of buildifier in angular/ngcontainer
# If you change this, also check if it matches the version in the angular/ngcontainer
# version in /.circleci/config.yml
BAZEL_BUILDTOOLS_VERSION = "b3b620e8bcff18ed3378cd3f35ebeb7016d71f71"
http_archive(
name = "com_github_bazelbuild_buildtools",
remote = "https://github.com/bazelbuild/buildtools.git",
# Note, this commit matches the version of buildifier in angular/ngcontainer
# If you change this, also check if it matches the version in the angular/ngcontainer
# version in /.circleci/config.yml
commit = "b3b620e8bcff18ed3378cd3f35ebeb7016d71f71",
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
sha256 = "dad19224258ed67cbdbae9b7befb785c3b966e5a33b04b3ce58ddb7824b97d73",
)
http_archive(

View File

@ -1,20 +1,19 @@
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{title}}!!
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular logo" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=">
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul>
<li>
<h2><a target="_blank" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
</li>
<li>
<h2><a target="_blank" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
<h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
</li>
<li>
<h2><a target="_blank" href="http://angularjs.blogspot.ca/">Angular blog</a></h2>
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
</li>
</ul>

View File

@ -1,7 +1,5 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
@ -20,13 +18,13 @@ describe('AppComponent', () => {
it(`should have as title 'app'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('app');
expect(app.title).toMatch(/app/i);
}));
it('should render title in a h1 tag', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!!');
expect(compiled.querySelector('h1').textContent).toMatch(/app/i);
}));
});

View File

@ -11,6 +11,6 @@ import { Component } from '@angular/core';
// #enddocregion metadata
// #docregion title, class
export class AppComponent {
title = 'My First Angular App';
title = 'My First Angular App!';
}
// #enddocregion title, class

View File

@ -2,7 +2,7 @@
import { Component, Input, OnDestroy } from '@angular/core';
import { MissionService } from './mission.service';
import { Subscription } from 'rxjs/Subscription';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-astronaut',

View File

@ -1,6 +1,6 @@
// #docregion
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Subject } from 'rxjs';
@Injectable()
export class MissionService {

View File

@ -1,12 +1,12 @@
// #docregion
import { Component, Input, AfterViewInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';
import { Component, Input, OnInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';
import { AdDirective } from './ad.directive';
import { AdItem } from './ad-item';
import { AdComponent } from './ad.component';
@Component({
selector: 'app-add-banner',
selector: 'app-ad-banner',
// #docregion ad-host
template: `
<div class="ad-banner">
@ -17,16 +17,15 @@ import { AdComponent } from './ad.component';
// #enddocregion ad-host
})
// #docregion class
export class AdBannerComponent implements AfterViewInit, OnDestroy {
export class AdBannerComponent implements OnInit, OnDestroy {
@Input() ads: AdItem[];
currentAddIndex: number = -1;
currentAdIndex: number = -1;
@ViewChild(AdDirective) adHost: AdDirective;
subscription: any;
interval: any;
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
ngAfterViewInit() {
ngOnInit() {
this.loadComponent();
this.getAds();
}
@ -36,8 +35,8 @@ export class AdBannerComponent implements AfterViewInit, OnDestroy {
}
loadComponent() {
this.currentAddIndex = (this.currentAddIndex + 1) % this.ads.length;
let adItem = this.ads[this.currentAddIndex];
this.currentAdIndex = (this.currentAdIndex + 1) % this.ads.length;
let adItem = this.ads[this.currentAdIndex];
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);

View File

@ -8,7 +8,7 @@ import { AdItem } from './ad-item';
selector: 'app-root',
template: `
<div>
<app-add-banner [ads]="ads"></app-add-banner>
<app-ad-banner [ads]="ads"></app-ad-banner>
</div>
`
})

View File

@ -1,6 +1,6 @@
// #docregion
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Hero, HeroTaxReturn } from './hero';
import { HeroesService } from './heroes.service';

View File

@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { Observable, Observer } from 'rxjs';
import { Hero, HeroTaxReturn } from './hero';

View File

@ -1,6 +1,6 @@
// #docregion
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Villain, VillainsService } from './villains.service';

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { of } from 'rxjs/observable/of';
import { of } from 'rxjs';
export interface Villain { id: number; name: string; }

View File

@ -28,7 +28,10 @@ let checkLogForMessage = (message: string) => {
expect(page.logList.getText()).toContain(message);
};
describe('Http Tests', function() {
// TODO(i): temorarily disable these tests because angular-in-memory-web-api is not compatible with rxjs v6 yet
// and we don't have the backwards compatibility package yet.
// Reenable after rxjs v6 compatibility package is out or angular-in-memory-web-api is compatible with rxjs v6
xdescribe('Http Tests', function() {
beforeEach(() => {
browser.get('');
});

View File

@ -30,7 +30,7 @@ export class ConfigComponent {
this.configService.getConfig()
// #enddocregion v1, v2
.subscribe(
data => this.config = { ...data }, // success path
(data: Config) => this.config = { ...data }, // success path
error => this.error = error // error path
);
}
@ -39,7 +39,7 @@ export class ConfigComponent {
showConfig_v1() {
this.configService.getConfig_1()
// #docregion v1, v1_callback
.subscribe(data => this.config = {
.subscribe((data: Config) => this.config = {
heroesUrl: data['heroesUrl'],
textfile: data['textfile']
});
@ -51,7 +51,7 @@ export class ConfigComponent {
this.configService.getConfig()
// #docregion v2, v2_callback
// clone the data object, using its known Config shape
.subscribe(data => this.config = { ...data });
.subscribe((data: Config) => this.config = { ...data });
// #enddocregion v2_callback
}
// #enddocregion v2

View File

@ -6,8 +6,7 @@ import { HttpClient } from '@angular/common/http';
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
// #docregion rxjs-imports
import { Observable } from 'rxjs/Observable';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
// #enddocregion rxjs-imports
@ -82,8 +81,8 @@ export class ConfigService {
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an ErrorObservable with a user-facing error message
return new ErrorObservable(
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
};
// #enddocregion handleError

View File

@ -6,8 +6,7 @@ import { HttpHeaders } from '@angular/common/http';
// #enddocregion http-options
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Hero } from './hero';

View File

@ -1,8 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { MessageService } from './message.service';

View File

@ -4,8 +4,6 @@ import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
// #docregion
import { AuthService } from '../auth.service';

View File

@ -5,8 +5,7 @@ import {
HttpInterceptor, HttpHandler
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { startWith, tap } from 'rxjs/operators';
import { RequestCache } from '../request-cache.service';

View File

@ -3,7 +3,7 @@ import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
@Injectable()
export class EnsureHttpsInterceptor implements HttpInterceptor {

View File

@ -4,7 +4,6 @@ import {
HttpRequest, HttpResponse
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
// #docregion excerpt
import { finalize, tap } from 'rxjs/operators';
import { MessageService } from '../message.service';

View File

@ -3,7 +3,7 @@ import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
/** Pass untouched request through to the next request handler. */
@Injectable()

View File

@ -3,7 +3,7 @@ import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
@Injectable()
export class TrimNameInterceptor implements HttpInterceptor {

View File

@ -5,8 +5,7 @@ import {
HttpEventType, HttpProgressEvent
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable } from 'rxjs';
/** Simulate server replying to file upload request */
@Injectable()

View File

@ -1,7 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Observable, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
import { NpmPackageInfo, PackageSearchService } from './package-search.service';

View File

@ -1,8 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { HttpErrorHandler, HandleError } from '../http-error-handler.service';

View File

@ -4,7 +4,7 @@ import {
HttpRequest, HttpResponse, HttpErrorResponse
} from '@angular/common/http';
import { of } from 'rxjs/observable/of';
import { of } from 'rxjs';
import { catchError, last, map, tap } from 'rxjs/operators';
import { MessageService } from '../message.service';

View File

@ -2,8 +2,7 @@
// #docregion
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Contact {

View File

@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Crisis,
CrisisService } from './crisis.service';

View File

@ -1,7 +1,6 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Crisis {

View File

@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Hero,
HeroService } from './hero.service';

View File

@ -1,7 +1,6 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Hero {

View File

@ -1,8 +1,7 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { delay } from 'rxjs/operator/delay';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Contact {
constructor(public id: number, public name: string) { }
@ -24,12 +23,12 @@ export class ContactService implements OnDestroy {
ngOnDestroy() { console.log('ContactService instance destroyed.'); }
getContacts(): Observable<Contact[]> {
return delay.call(of(CONTACTS), FETCH_LATENCY);
return of(CONTACTS).pipe(delay(FETCH_LATENCY));
}
getContact(id: number | string): Observable<Contact> {
const contact$ = of(CONTACTS.find(contact => contact.id === +id));
return delay.call(contact$, FETCH_LATENCY);
return contact$.pipe(delay(FETCH_LATENCY));
}
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Customer,
CustomersService } from './customers.service';

View File

@ -1,8 +1,7 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { delay } from 'rxjs/operator/delay';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Customer {
constructor(public id: number, public name: string) { }
@ -27,11 +26,11 @@ export class CustomersService implements OnDestroy {
ngOnDestroy() { console.log('CustomersService instance destroyed.'); }
getCustomers(): Observable<Customer[]> {
return delay.call(of(CUSTOMERS), FETCH_LATENCY);
return of(CUSTOMERS).pipe(delay(FETCH_LATENCY));
}
getCustomer(id: number | string): Observable<Customer> {
const customer$ = of(CUSTOMERS.find(customer => customer.id === +id));
return delay.call(customer$, FETCH_LATENCY);
return customer$.pipe(delay(FETCH_LATENCY));
}
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Observable }from 'rxjs/Observable';
import { Observable }from 'rxjs';
import { Item,
ItemService } from './items.service';

View File

@ -1,6 +1,7 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ItemsComponent } from './items.component';
import { ItemsListComponent } from './items-list.component';
import { ItemsDetailComponent } from './items-detail.component';
import { ItemService } from './items.service';
@ -8,7 +9,7 @@ import { ItemsRoutingModule } from './items-routing.module';
@NgModule({
imports: [ CommonModule, ItemsRoutingModule ],
declarations: [ ItemsDetailComponent, ItemsListComponent ],
declarations: [ ItemsComponent, ItemsDetailComponent, ItemsListComponent ],
providers: [ ItemService ]
})
export class ItemsModule {}

View File

@ -1,8 +1,7 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { delay } from 'rxjs/operator/delay';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Item {
constructor(public id: number, public name: string) { }
@ -25,12 +24,12 @@ export class ItemService implements OnDestroy {
ngOnDestroy() { console.log('ItemService instance destroyed.'); }
getItems(): Observable<Item[]> {
return delay.call(of(ITEMS), FETCH_LATENCY);
return of(ITEMS).pipe(delay(FETCH_LATENCY));
}
getItem(id: number | string): Observable<Item> {
const item$ = of(ITEMS.find(item => item.id === +id));
return delay.call(item$, FETCH_LATENCY);
return item$.pipe(delay(FETCH_LATENCY));
}
}

View File

@ -0,0 +1,131 @@
import { Component, Output, OnInit, EventEmitter, NgModule } from '@angular/core';
import { Observable } from 'rxjs';
// #docregion eventemitter
@Component({
selector: 'zippy',
template: `
<div class="zippy">
<div (click)="toggle()">Toggle</div>
<div [hidden]="!visible">
<ng-content></ng-content>
</div>
</div>`})
export class ZippyComponent {
visible = true;
@Output() open = new EventEmitter<any>();
@Output() close = new EventEmitter<any>();
toggle() {
this.visible = !this.visible;
if (this.visible) {
this.open.emit(null);
} else {
this.close.emit(null);
}
}
}
// #enddocregion eventemitter
// #docregion pipe
@Component({
selector: 'async-observable-pipe',
template: `<div><code>observable|async</code>:
Time: {{ time | async }}</div>`
})
export class AsyncObservablePipeComponent {
time = new Observable(observer =>
setInterval(() => observer.next(new Date().toString()), 1000)
);
}
// #enddocregion pipe
// #docregion router
import { Router, NavigationStart } from '@angular/router';
import { filter } from 'rxjs/operators';
@Component({
selector: 'app-routable',
templateUrl: './routable.component.html',
styleUrls: ['./routable.component.css']
})
export class Routable1Component implements OnInit {
navStart: Observable<NavigationStart>;
constructor(private router: Router) {
// Create a new Observable the publishes only the NavigationStart event
this.navStart = router.events.pipe(
filter(evt => evt instanceof NavigationStart)
) as Observable<NavigationStart>;
}
ngOnInit() {
this.navStart.subscribe(evt => console.log('Navigation Started!'));
}
}
// #enddocregion router
// #docregion activated_route
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-routable',
templateUrl: './routable.component.html',
styleUrls: ['./routable.component.css']
})
export class Routable2Component implements OnInit {
constructor(private activatedRoute: ActivatedRoute) {}
ngOnInit() {
this.activatedRoute.url
.subscribe(url => console.log('The URL changed to: ' + url));
}
}
// #enddocregion activated_route
// #docregion forms
import { FormGroup } from '@angular/forms';
@Component({
selector: 'my-component',
template: 'MyComponent Template'
})
export class MyComponent implements OnInit {
nameChangeLog: string[] = [];
heroForm: FormGroup;
ngOnInit() {
this.logNameChange();
}
logNameChange() {
const nameControl = this.heroForm.get('name');
nameControl.valueChanges.forEach(
(value: string) => this.nameChangeLog.push(value)
);
}
}
// #enddocregion forms
@NgModule({
declarations:
[ZippyComponent, AsyncObservablePipeComponent, Routable1Component, Routable2Component, MyComponent]
})
export class AppModule {
}

View File

@ -0,0 +1,66 @@
import { Observable } from 'rxjs';
// #docregion subscriber
// This function runs when subscribe() is called
function sequenceSubscriber(observer) {
// synchronously deliver 1, 2, and 3, then complete
observer.next(1);
observer.next(2);
observer.next(3);
observer.complete();
// unsubscribe function doesn't need to do anything in this
// because values are delivered synchronously
return {unsubscribe() {}};
}
// Create a new Observable that will deliver the above sequence
const sequence = new Observable(sequenceSubscriber);
// execute the Observable and print the result of each notification
sequence.subscribe({
next(num) { console.log(num); },
complete() { console.log('Finished sequence'); }
});
// Logs:
// 1
// 2
// 3
// Finished sequence
// #enddocregion subscriber
// #docregion fromevent
function fromEvent(target, eventName) {
return new Observable((observer) => {
const handler = (e) => observer.next(e);
// Add the event handler to the target
target.addEventListener(eventName, handler);
return () => {
// Detach the event handler from the target
target.removeEventListener(eventName, handler);
};
});
}
// #enddocregion fromevent
// #docregion fromevent_use
const ESC_KEY = 27;
const nameInput = document.getElementById('name') as HTMLInputElement;
const subscription = fromEvent(nameInput, 'keydown')
.subscribe((e: KeyboardEvent) => {
if (e.keyCode === ESC_KEY) {
nameInput.value = '';
}
});
// #enddocregion fromevent_use

View File

@ -0,0 +1,32 @@
import { Observable } from 'rxjs';
// #docregion
// Create an Observable that will start listening to geolocation updates
// when a consumer subscribes.
const locations = new Observable((observer) => {
// Get the next and error callbacks. These will be passed in when
// the consumer subscribes.
const {next, error} = observer;
let watchId;
// Simple geolocation API check provides values to publish
if ('geolocation' in navigator) {
watchId = navigator.geolocation.watchPosition(next, error);
} else {
error('Geolocation not available');
}
// When the consumer unsubscribes, clean up data ready for next subscription.
return {unsubscribe() { navigator.geolocation.clearWatch(watchId); }};
});
// Call subscribe() to start listening for updates.
const locationsSubscription = locations.subscribe({
next(position) { console.log('Current Position: ', position); },
error(msg) { console.log('Error Getting Location: ', msg); }
});
// Stop listening for location after 10 seconds
setTimeout(() => { locationsSubscription.unsubscribe(); }, 10000);
// #enddocregion

View File

@ -0,0 +1,5 @@
import './geolocation';
import './subscribing';
import './creating';
import './multicasting';

View File

@ -0,0 +1,155 @@
import { Observable } from 'rxjs';
// #docregion delay_sequence
function sequenceSubscriber(observer) {
const seq = [1, 2, 3];
let timeoutId;
// Will run through an array of numbers, emitting one value
// per second until it gets to the end of the array.
function doSequence(arr, idx) {
timeoutId = setTimeout(() => {
observer.next(arr[idx]);
if (idx === arr.length - 1) {
observer.complete();
} else {
doSequence(arr, idx++);
}
}, 1000);
}
doSequence(seq, 0);
// Unsubscribe should clear the timeout to stop execution
return {unsubscribe() {
clearTimeout(timeoutId);
}};
}
// Create a new Observable that will deliver the above sequence
const sequence = new Observable(sequenceSubscriber);
sequence.subscribe({
next(num) { console.log(num); },
complete() { console.log('Finished sequence'); }
});
// Logs:
// (at 1 second): 1
// (at 2 seconds): 2
// (at 3 seconds): 3
// (at 3 seconds): Finished sequence
// #enddocregion delay_sequence
// #docregion subscribe_twice
// Subscribe starts the clock, and will emit after 1 second
sequence.subscribe({
next(num) { console.log('1st subscribe: ' + num); },
complete() { console.log('1st sequence finished.'); }
});
// After 1/2 second, subscribe again.
setTimeout(() => {
sequence.subscribe({
next(num) { console.log('2nd subscribe: ' + num); },
complete() { console.log('2nd sequence finished.'); }
});
}, 500);
// Logs:
// (at 1 second): 1st subscribe: 1
// (at 1.5 seconds): 2nd subscribe: 1
// (at 2 seconds): 1st subscribe: 2
// (at 2.5 seconds): 2nd subscribe: 2
// (at 3 seconds): 1st subscribe: 3
// (at 3 seconds): 1st sequence finished
// (at 3.5 seconds): 2nd subscribe: 3
// (at 3.5 seconds): 2nd sequence finished
// #enddocregion subscribe_twice
// #docregion multicast_sequence
function multicastSequenceSubscriber() {
const seq = [1, 2, 3];
// Keep track of each observer (one for every active subscription)
const observers = [];
// Still a single timeoutId because there will only ever be one
// set of values being generated, multicasted to each subscriber
let timeoutId;
// Return the subscriber function (runs when subscribe()
// function is invoked)
return (observer) => {
observers.push(observer);
// When this is the first subscription, start the sequence
if (observers.length === 1) {
timeoutId = doSequence({
next(val) {
// Iterate through observers and notify all subscriptions
observers.forEach(obs => obs.next(val));
},
complete() {
// Notify all complete callbacks
observers.forEach(obs => obs.complete());
}
}, seq, 0);
}
return {
unsubscribe() {
// Remove from the observers array so it's no longer notified
observers.splice(observers.indexOf(observer), 1);
// If there's no more listeners, do cleanup
if (observers.length === 0) {
clearTimeout(timeoutId);
}
}
};
};
}
// Run through an array of numbers, emitting one value
// per second until it gets to the end of the array.
function doSequence(observer, arr, idx) {
return setTimeout(() => {
observer.next(arr[idx]);
if (idx === arr.length - 1) {
observer.complete();
} else {
doSequence(observer, arr, idx++);
}
}, 1000);
}
// Create a new Observable that will deliver the above sequence
const multicastSequence = new Observable(multicastSequenceSubscriber);
// Subscribe starts the clock, and begins to emit after 1 second
multicastSequence.subscribe({
next(num) { console.log('1st subscribe: ' + num); },
complete() { console.log('1st sequence finished.'); }
});
// After 1 1/2 seconds, subscribe again (should "miss" the first value).
setTimeout(() => {
multicastSequence.subscribe({
next(num) { console.log('2nd subscribe: ' + num); },
complete() { console.log('2nd sequence finished.'); }
});
}, 1500);
// Logs:
// (at 1 second): 1st subscribe: 1
// (at 2 seconds): 1st subscribe: 2
// (at 2 seconds): 2nd subscribe: 2
// (at 3 seconds): 1st subscribe: 3
// (at 3 seconds): 1st sequence finished
// (at 3 seconds): 2nd subscribe: 3
// (at 3 seconds): 2nd sequence finished
// #enddocregion multicast_sequence

View File

@ -0,0 +1,32 @@
import { Observable, of } from 'rxjs';
// #docregion observer
// Create simple observable that emits three values
const myObservable = Observable.of(1, 2, 3);
// Create observer object
const myObserver = {
next: x => console.log('Observer got a next value: ' + x),
error: err => console.error('Observer got an error: ' + err),
complete: () => console.log('Observer got a complete notification'),
};
// Execute with the observer object
myObservable.subscribe(myObserver);
// Logs:
// Observer got a next value: 1
// Observer got a next value: 2
// Observer got a next value: 3
// Observer got a complete notification
// #enddocregion observer
// #docregion sub_fn
myObservable.subscribe(
x => console.log('Observer got a next value: ' + x),
err => console.error('Observer got an error: ' + err),
() => console.log('Observer got a complete notification')
);
// #enddocregion sub_fn

View File

@ -2,7 +2,7 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular//common/http';
import { AppComponent } from './app.component';
import {
@ -26,7 +26,7 @@ import { ExponentialStrengthPipe } from './exponential-strength.pipe';
imports: [
BrowserModule,
FormsModule,
HttpModule
HttpClientModule
],
declarations: [
AppComponent,

View File

@ -1,9 +1,6 @@
// #docregion
import { Pipe, PipeTransform } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import { HttpClient } from '@angular/common/http';
// #docregion pipe-metadata
@Pipe({
name: 'fetch',
@ -14,15 +11,13 @@ export class FetchJsonPipe implements PipeTransform {
private cachedData: any = null;
private cachedUrl = '';
constructor(private http: Http) { }
constructor(private http: HttpClient) { }
transform(url: string): any {
if (url !== this.cachedUrl) {
this.cachedData = null;
this.cachedUrl = url;
this.http.get(url)
.map( result => result.json() )
.subscribe( result => this.cachedData = result );
this.http.get(url).subscribe( result => this.cachedData = result );
}
return this.cachedData;

View File

@ -1,10 +1,8 @@
// #docregion
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { Observable, interval } from 'rxjs';
import { map, take } from 'rxjs/operators';
@Component({
selector: 'app-hero-message',
@ -25,14 +23,17 @@ export class HeroAsyncMessageComponent {
constructor() { this.resend(); }
resend() {
this.message$ = Observable.interval(500)
.map(i => this.messages[i])
.take(this.messages.length);
this.message$ = interval(500).pipe(
map(i => this.messages[i]),
take(this.messages.length)
);
}
}
// #enddocregion
// Alternative message$ formula:
// this.message$ = Observable.fromArray(this.messages)
// .map(message => Observable.timer(500).map(() => message))
// .concatAll();
// this.message$ = fromArray(this.messages).pipe(
// map(message => timer(500),
// map(() => message)),
// concatAll()
// );

View File

@ -0,0 +1,24 @@
import { pipe, range, timer, zip } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { retryWhen, map, mergeMap } from 'rxjs/operators';
function backoff(maxTries, ms) {
return pipe(
retryWhen(attempts => range(1, maxTries)
.pipe(
zip(attempts, (i) => i),
map(i => i * i),
mergeMap(i => timer(i * ms))
)
)
);
}
ajax('/api/endpoint')
.pipe(backoff(3, 250))
.subscribe(data => handleData(data));
function handleData(data) {
// ...
}

View File

@ -0,0 +1,18 @@
import { fromEvent } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { map, filter, debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
const searchBox = document.getElementById('search-box');
const typeahead = fromEvent(searchBox, 'input').pipe(
map((e: KeyboardEvent) => e.target.value),
filter(text => text.length > 2),
debounceTime(10),
distinctUntilChanged(),
switchMap(() => ajax('/api/endpoint'))
);
typeahead.subscribe(data => {
// Handle the data from the API
});

View File

@ -6,32 +6,38 @@ import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms'; // <-- #1 import module
import { AppComponent } from './app.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component'; // <-- #1 import component
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
// #enddocregion v1
// #docregion hero-service-list
// add JavaScript imports
import { HeroListComponent } from './hero-list/hero-list.component';
import { HeroService } from './hero.service'; // <-- #1 import service
import { HeroService } from './hero.service';
// #docregion v1
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule // <-- #2 add to @NgModule imports
],
declarations: [
AppComponent,
HeroDetailComponent,
// #enddocregion v1
HeroListComponent
HeroListComponent // <--declare HeroListComponent
// #docregion v1
],
// #enddocregion v1
exports: [ // export for the DemoModule
// #enddocregion hero-service-list
imports: [
BrowserModule,
ReactiveFormsModule // <-- #2 add to @NgModule imports
],
// #enddocregion v1
// export for the DemoModule
// #docregion hero-service-list
// ...
exports: [
AppComponent,
HeroDetailComponent,
HeroListComponent
HeroListComponent // <-- export HeroListComponent
],
providers: [ HeroService ], // <-- #4 provide HeroService
providers: [ HeroService ], // <-- provide HeroService
// #enddocregion hero-service-list
// #docregion v1
bootstrap: [ AppComponent ]
})

View File

@ -1,6 +1,7 @@
/* tslint:disable:member-ordering */
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { Hero } from './data-model';
import { HeroService } from './hero.service';
@ -33,8 +34,9 @@ export class DemoComponent {
getHeroes() {
this.isLoading = true;
this.heroes = this.heroService.getHeroes()
.finally(() => this.isLoading = false);
this.heroes = this.heroService.getHeroes().pipe(
finalize(() => this.isLoading = false)
);
this.selectedHero = undefined;
}

View File

@ -1,7 +1,7 @@
<!-- #docregion basic-form-->
<h2>Hero Detail</h2>
<h3><i>FormControl in a FormGroup</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -1,7 +1,7 @@
<!-- #docregion basic-form-->
<h2>Hero Detail</h2>
<h3><i>A FormGroup with a single FormControl using FormBuilder</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">
@ -13,4 +13,4 @@
<!-- #docregion form-value-json -->
<p>Form value: {{ heroForm.value | json }}</p>
<p>Form status: {{ heroForm.status | json }}</p>
<!-- #enddocregion form-value-json -->
<!-- #enddocregion form-value-json -->

View File

@ -1,7 +1,7 @@
<!-- #docregion -->
<h2>Hero Detail</h2>
<h3><i>A FormGroup with multiple FormControls</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -1,5 +1,5 @@
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -1,7 +1,7 @@
<!-- #docregion -->
<h2>Hero Detail</h2>
<h3><i>PatchValue to initialize a value</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -44,7 +44,13 @@ export class HeroDetailComponent6 implements OnChanges {
}
// #docregion patch-value-on-changes
ngOnChanges() { // <-- wrap patchValue in ngOnChanges
ngOnChanges() { // <-- call rebuildForm in ngOnChanges
this.rebuildForm();
}
// #enddocregion patch-value-on-changes
// #docregion patch-value-rebuildform
rebuildForm() { // <-- wrap patchValue in rebuildForm
this.heroForm.reset();
// #docregion patch-value
this.heroForm.patchValue({
@ -52,7 +58,9 @@ export class HeroDetailComponent6 implements OnChanges {
});
// #enddocregion patch-value
}
// #enddocregion patch-value-on-changes
// #enddocregion patch-value-rebuildform
}
// #enddocregion v6

View File

@ -1,7 +1,7 @@
<!-- #docregion -->
<h2>Hero Detail</h2>
<h3><i>A FormGroup with multiple FormControls</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -38,32 +38,31 @@ export class HeroDetailComponent7 implements OnChanges {
// #docregion ngOnChanges
ngOnChanges() {
this.rebuildForm();
}
// #enddocregion ngOnChanges
// #docregion rebuildForm
rebuildForm() {
this.heroForm.reset({
name: this.hero.name,
address: this.hero.addresses[0] || new Address()
});
}
// #enddocregion ngOnChanges
/* First version of ngOnChanges
// #docregion ngOnChanges-1
ngOnChanges()
// #enddocregion ngOnChanges-1
*/
ngOnChanges1() {
// #docregion reset
this.heroForm.reset();
// #enddocregion reset
// #docregion ngOnChanges-1
// #docregion set-value
this.heroForm.setValue({
name: this.hero.name,
// #docregion set-value-address
address: this.hero.addresses[0] || new Address()
// #enddocregion set-value-address
});
}
// #enddocregion rebuildForm
/* First version of rebuildForm */
rebuildForm1() {
// #docregion reset
this.heroForm.reset();
// #enddocregion reset
// #docregion set-value
this.heroForm.setValue({
name: this.hero.name,
address: this.hero.addresses[0] || new Address()
});
// #enddocregion set-value
}
// #enddocregion ngOnChanges-1
}

View File

@ -1,7 +1,7 @@
<!-- #docplaster-->
<h3><i>Using FormArray to add groups</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<p>Form Changed: {{ heroForm.dirty }}</p>
<div class="form-group">
@ -11,7 +11,9 @@
</div>
<!-- #docregion form-array-->
<!-- #docregion form-array-skeleton -->
<!-- #docregion form-array-name -->
<div formArrayName="secretLairs" class="well well-lg">
<!-- #enddocregion form-array-name -->
<div *ngFor="let address of secretLairs.controls; let i=index" [formGroupName]="i" >
<!-- The repeated address template -->
<!-- #enddocregion form-array-skeleton -->

View File

@ -39,12 +39,18 @@ export class HeroDetailComponent8 implements OnChanges {
// #docregion onchanges
ngOnChanges() {
this.rebuildForm();
}
// #enddocregion onchanges
// #docregion rebuildform
rebuildForm() {
this.heroForm.reset({
name: this.hero.name
});
this.setAddresses(this.hero.addresses);
}
// #enddocregion onchanges
// #enddocregion rebuildform
// #docregion get-secret-lairs
get secretLairs(): FormArray {

View File

@ -1,11 +1,11 @@
<!-- #docplaster -->
<!-- #docregion -->
<!-- #docregion buttons -->
<form [formGroup]="heroForm" (ngSubmit)="onSubmit()" novalidate>
<form [formGroup]="heroForm" (ngSubmit)="onSubmit()">
<div style="margin-bottom: 1em">
<button type="submit"
[disabled]="heroForm.pristine" class="btn btn-success">Save</button> &nbsp;
<button type="reset" (click)="revert()"
<button type="button" (click)="revert()"
[disabled]="heroForm.pristine" class="btn btn-danger">Revert</button>
</div>

View File

@ -13,7 +13,10 @@ import { HeroService } from '../hero.service';
templateUrl: './hero-detail.component.html',
styleUrls: ['./hero-detail.component.css']
})
// #docregion onchanges-implementation
export class HeroDetailComponent implements OnChanges {
// #enddocregion onchanges-implementation
@Input() hero: Hero;
heroForm: FormGroup;
@ -42,6 +45,10 @@ export class HeroDetailComponent implements OnChanges {
}
ngOnChanges() {
this.rebuildForm();
}
rebuildForm() {
this.heroForm.reset({
name: this.hero.name
});
@ -66,7 +73,7 @@ export class HeroDetailComponent implements OnChanges {
onSubmit() {
this.hero = this.prepareSaveHero();
this.heroService.updateHero(this.hero).subscribe(/* error handling */);
this.ngOnChanges();
this.rebuildForm();
}
// #enddocregion on-submit
@ -92,7 +99,7 @@ export class HeroDetailComponent implements OnChanges {
// #enddocregion prepare-save-hero
// #docregion revert
revert() { this.ngOnChanges(); }
revert() { this.rebuildForm(); }
// #enddocregion revert
// #docregion log-name-change

View File

@ -1,7 +1,7 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/finally';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { Hero } from '../data-model';
import { HeroService } from '../hero.service';
@ -24,7 +24,7 @@ export class HeroListComponent implements OnInit {
this.isLoading = true;
this.heroes = this.heroService.getHeroes()
// Todo: error handling
.finally(() => this.isLoading = false);
.pipe(finalize(() => this.isLoading = false));
this.selectedHero = undefined;
}

View File

@ -1,9 +1,8 @@
// #docregion
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/delay';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
import { Hero, heroes } from './data-model';
@ -14,13 +13,13 @@ export class HeroService {
// Fake server get; assume nothing can go wrong
getHeroes(): Observable<Hero[]> {
return of(heroes).delay(this.delayMs); // simulate latency with delay
return of(heroes).pipe(delay(this.delayMs)); // simulate latency with delay
}
// Fake server update; assume nothing can go wrong
updateHero(hero: Hero): Observable<Hero> {
const oldHero = heroes.find(h => h.id === hero.id);
const newHero = Object.assign(oldHero, hero); // Demo: mutate cached hero
return of(newHero).delay(this.delayMs); // simulate latency with delay
return of(newHero).pipe(delay(this.delayMs)); // simulate latency with delay
}
}

View File

@ -1,8 +1,8 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
template: `
@ -23,11 +23,11 @@ export class AdminDashboardComponent implements OnInit {
// Capture the session ID if available
this.sessionId = this.route
.queryParamMap
.map(params => params.get('session_id') || 'None');
.pipe(map(params => params.get('session_id') || 'None'));
// Capture the fragment if available
this.token = this.route
.fragment
.map(fragment => fragment || 'None');
.pipe(map(fragment => fragment || 'None'));
}
}

View File

@ -1,11 +1,11 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { SelectivePreloadingStrategy } from '../selective-preloading-strategy';
import 'rxjs/add/operator/map';
@Component({
template: `
@ -37,11 +37,11 @@ export class AdminDashboardComponent implements OnInit {
// Capture the session ID if available
this.sessionId = this.route
.queryParamMap
.map(params => params.get('session_id') || 'None');
.pipe(map(params => params.get('session_id') || 'None'));
// Capture the fragment if available
this.token = this.route
.fragment
.map(fragment => fragment || 'None');
.pipe(map(fragment => fragment || 'None'));
}
}

View File

@ -1,8 +1,8 @@
// #docregion
import { animate, AnimationEntryMetadata, state, style, transition, trigger } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
// Component transition animations
export const slideInDownAnimation: AnimationEntryMetadata =
export const slideInDownAnimation =
trigger('routeAnimation', [
state('*',
style({

View File

@ -1,10 +1,8 @@
// #docregion
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/delay';
import { Observable, of } from 'rxjs';
import { tap, delay } from 'rxjs/operators';
@Injectable()
export class AuthService {
@ -14,7 +12,10 @@ export class AuthService {
redirectUrl: string;
login(): Observable<boolean> {
return Observable.of(true).delay(1000).do(val => this.isLoggedIn = true);
return of(true).pipe(
delay(1000),
tap(val => this.isLoggedIn = true)
);
}
logout(): void {

View File

@ -1,6 +1,6 @@
// #docregion
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { CanDeactivate,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';

View File

@ -1,7 +1,7 @@
// #docregion
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;

View File

@ -1,10 +1,9 @@
// #docregion
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Router, Resolve, RouterStateSnapshot,
ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { Crisis, CrisisService } from './crisis.service';
@ -15,13 +14,16 @@ export class CrisisDetailResolver implements Resolve<Crisis> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Crisis> {
let id = route.paramMap.get('id');
return this.cs.getCrisis(id).take(1).map(crisis => {
if (crisis) {
return crisis;
} else { // id not found
this.router.navigate(['/crisis-center']);
return null;
}
});
return this.cs.getCrisis(id).pipe(
take(1),
map(crisis => {
if (crisis) {
return crisis;
} else { // id not found
this.router.navigate(['/crisis-center']);
return null;
}
})
);
}
}

View File

@ -1,9 +1,9 @@
// #docplaster
// #docregion
import 'rxjs/add/operator/switchMap';
import { Component, OnInit, HostBinding } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { slideInDownAnimation } from '../animations';
import { Crisis, CrisisService } from './crisis.service';
@ -46,8 +46,9 @@ export class CrisisDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getCrisis(params.get('id')))
.pipe(
switchMap((params: ParamMap) =>
this.service.getCrisis(params.get('id'))))
.subscribe((crisis: Crisis) => {
if (crisis) {
this.editName = crisis.name;

View File

@ -2,7 +2,7 @@
// #docregion
import { Component, OnInit, HostBinding } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { slideInDownAnimation } from '../animations';
import { Crisis } from './crisis.service';

View File

@ -1,10 +1,10 @@
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Component({
// #docregion relative-navigation-router-link
@ -34,10 +34,11 @@ export class CrisisListComponent implements OnInit {
ngOnInit() {
this.crises$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.crises$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => {
this.selectedId = +params.get('id');
return this.service.getCrises();
});
})
);
}
}

View File

@ -1,10 +1,10 @@
// #docregion
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Component({
template: `
@ -32,10 +32,11 @@ export class CrisisListComponent implements OnInit {
// #enddocregion ctor
ngOnInit() {
this.crises$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.crises$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => {
this.selectedId = +params.get('id');
return this.service.getCrises();
});
})
);
}
}

View File

@ -1,8 +1,7 @@
// #docplaster
// #docregion , mock-crises
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { BehaviorSubject } from 'rxjs';
import { map } from 'rxjs/operators';
export class Crisis {
constructor(public id: number, public name: string) { }
@ -26,8 +25,9 @@ export class CrisisService {
getCrises() { return this.crises$; }
getCrisis(id: number | string) {
return this.getCrises()
.map(crises => crises.find(crisis => crisis.id === +id));
return this.getCrises().pipe(
map(crises => crises.find(crisis => crisis.id === +id))
);
}
// #enddocregion

View File

@ -1,7 +1,6 @@
// #docregion
import 'rxjs/add/observable/of';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable, of } from 'rxjs';
/**
* Async modal dialog service
@ -17,6 +16,6 @@ export class DialogService {
confirm(message?: string): Observable<boolean> {
const confirmation = window.confirm(message || 'Is it OK?');
return Observable.of(confirmation);
return of(confirmation);
};
}

View File

@ -1,10 +1,10 @@
// #docplaster
// #docregion
// #docregion rxjs-operator-import
import 'rxjs/add/operator/switchMap';
import { switchMap } from 'rxjs/operators';
// #enddocregion rxjs-operator-import
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
// #docregion imports
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
// #enddocregion imports
@ -41,9 +41,10 @@ export class HeroDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')));
this.hero$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')))
);
}
// #enddocregion ngOnInit

View File

@ -2,7 +2,7 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Hero, HeroService } from './hero.service';

View File

@ -1,11 +1,11 @@
// #docplaster
// #docregion
// #docregion rxjs-operator-import
import 'rxjs/add/operator/switchMap';
import { switchMap } from 'rxjs/operators';
// #enddocregion rxjs-operator-import
import { Component, OnInit, HostBinding } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { Observable } from 'rxjs';
import { slideInDownAnimation } from '../animations';
@ -48,9 +48,10 @@ export class HeroDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')));
this.hero$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')))
);
}
// #enddocregion ngOnInit

View File

@ -3,7 +3,7 @@
// TODO SOMEDAY: Feature Componetized like HeroCenter
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Hero, HeroService } from './hero.service';

View File

@ -2,8 +2,8 @@
// #docregion
// TODO SOMEDAY: Feature Componetized like CrisisCenter
// #docregion rxjs-imports
import 'rxjs/add/operator/switchMap';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
// #enddocregion rxjs-imports
import { Component, OnInit } from '@angular/core';
// #docregion import-router
@ -41,12 +41,13 @@ export class HeroListComponent implements OnInit {
) {}
ngOnInit() {
this.heroes$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.heroes$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => {
// (+) before `params.get()` turns the string into a number
this.selectedId = +params.get('id');
return this.service.getHeroes();
});
})
);
}
// #enddocregion ctor
// #docregion ctor

View File

@ -1,8 +1,7 @@
// #docregion
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
export class Hero {
constructor(public id: number, public name: string) { }
@ -19,11 +18,12 @@ const HEROES = [
@Injectable()
export class HeroService {
getHeroes() { return Observable.of(HEROES); }
getHeroes() { return of(HEROES); }
getHero(id: number | string) {
return this.getHeroes()
return this.getHeroes().pipe(
// (+) before `id` turns the string into a number
.map(heroes => heroes.find(hero => hero.id === +id));
map(heroes => heroes.find(hero => hero.id === +id))
);
}
}

View File

@ -1,8 +1,7 @@
// #docregion
import 'rxjs/add/observable/of';
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable, of } from 'rxjs';
@Injectable()
export class SelectivePreloadingStrategy implements PreloadingStrategy {
@ -18,7 +17,7 @@ export class SelectivePreloadingStrategy implements PreloadingStrategy {
return load();
} else {
return Observable.of(null);
return of(null);
}
}
}

View File

@ -0,0 +1,25 @@
import { of } from 'rxjs';
// #docregion
import { ajax } from 'rxjs/ajax';
import { map, catchError } from 'rxjs/operators';
// Return "response" from the API. If an error happens,
// return an empty array.
const apiData = ajax('/api/data').pipe(
map(res => {
if (!res.response) {
throw new Error('Value expected!');
}
return res.response;
}),
catchError(err => of([]))
);
apiData.subscribe({
next(x) { console.log('data: ', x); },
error(err) { console.log('errors already caught... will not run'); }
});
// #enddocregion

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