Compare commits

...

88 Commits
4.3.4 ... 4.4.0

Author SHA1 Message Date
4e7d2bd5bf docs: add changelog for 4.4.0 2017-09-15 14:58:32 -07:00
395ac510f7 release: cut the 4.4.0 release 2017-09-15 14:51:21 -07:00
b20c5d2c37 fix(upgrade): remove code setting id attribute. (#19182)
The id was leftover from previous iterations of ngUpgrade and is
no longer needed. Moreover, setting it can clash with CSS usage of id.

Fixes #18446

PR Close #19182
2017-09-15 17:19:50 -04:00
ea02b1ccfa fix(upgrade): remove code setting id attribute.
The id was leftover from previous iterations of ngUpgrade and is
no longer needed. Moreover, setting it can clash with CSS usage of id.

Fixes #18446
2017-09-15 17:19:50 -04:00
0bafd03e85 revert: test(packaging): added test for source map correctness
This reverts commit 86f7b4170c.
2017-09-15 11:55:29 -07:00
e8d1858c64 revert: build(platform-browser): fix typo
This reverts commit 991a802a8e.
2017-09-15 13:47:07 -04:00
d1efc5ae90 revert: fix(upgrade): remove code setting id attribute
This reverts commit 1302e54947.
2017-09-13 13:19:19 -07:00
86f7b4170c test(packaging): added test for source map correctness 2017-09-13 13:48:36 -04:00
9d93c859d7 build(aio): auto-link more code items
We now parse all code blocks, after they have been rendered by dgeni
and insert links to API docs that match "words" in the code.
2017-09-12 14:06:26 -04:00
5baa069b16 docs(aio): fix typo 2017-09-12 14:06:14 -04:00
12b7d00747 fix(aio): relax search on titles further
This change will now match `ControlValueAccessor` for the query `accessor`.

Closes #18872
2017-09-12 14:06:02 -04:00
d777d79c61 build(aio): do not render annotations block for directives 2017-09-12 14:05:46 -04:00
062a772e48 build(aio): improve rendering of directive selectors 2017-09-12 14:05:41 -04:00
3618cc6d34 build(aio): do not render comments in decorators
Closes #18873
2017-09-12 14:05:35 -04:00
9413ca8a2e build(aio): update karma & systemjs config for HttpClient
While adding the references to the `HttpClient` packages it also crucially
adds ref to new “tslib” library required by `HttpClient`.
2017-09-12 13:46:12 -04:00
1302e54947 fix(upgrade): remove code setting id attribute.
The id was leftover from previous iterations of ngUpgrade and is
no longer needed. Moreover, setting it can clash with CSS usage of id.

Fixes #18446
2017-09-08 16:30:18 -07:00
edf423af3d build(aio): update package.json for angular-in-mem-web-api 0.4.0 2017-09-08 18:25:20 -04:00
37086748bf docs(aio): provide link text for AbstractControl references in reactive directives for forms
Closes #17484
2017-09-08 18:25:14 -04:00
6c3f1f70ba build(aio): render metadata members from decorator ancestors 2017-09-08 18:25:08 -04:00
8a8c4d37aa build(aio): render ancestor members in directives
See `CheckBoxRequiredValidator` for an example.
2017-09-08 18:25:00 -04:00
f6a7183c52 fix(tsc-wrapped): fix metadata symbol reference 2017-09-08 17:26:28 -04:00
c86e16db5f feat(aio): include more API results in search
By adding a more relaxed search on the title
of docs, we are more likely to catch API docs.

The additional search terms match anything
with a word in the title that starts with the
characters of the first term in the search.

E.g. if the search is "ngCont guide" then
search for "ngCont guide titleWords:ngCont*"
2017-09-08 17:01:39 -04:00
c3907893c1 build(aio): don't show constructor detail if there is none 2017-09-08 17:01:39 -04:00
d61c6f996a build(aio): support rendering of constructor overloads in API docs
Closes #18258
2017-09-08 17:01:39 -04:00
bd04cd61f8 docs(aio): change Stack Overflow link 2017-09-08 16:29:17 -04:00
96dcfafe45 docs(aio): Updated jqwidgets resource desc and url
Updated the description and url of the jqwidgets item in the resources page
2017-09-07 16:07:52 -04:00
991a802a8e build(platform-browser): fix typo
fixes #19033
2017-09-07 16:07:27 -04:00
48ae1a6574 fix(tsc-wrapped): deduplicate metadata for re-exported modules 2017-09-07 16:06:12 -04:00
dd2d1be006 fix(aio): align footer background image repeat (#19035)
Refs #17465
PR Close #19035
2017-09-05 23:25:06 -05:00
5369de80d6 docs(aio): add changelog, as hidden, to navigation (#19028)
This ensures that the changelog page is formatted correctly.

Closes #17604

PR Close #19028
2017-09-05 23:25:06 -05:00
552dbfc2f1 docs(aio): add Nir Kaufman to GDE resources (#19012)
PR Close #19012
2017-09-05 23:25:06 -05:00
0aa4cbdbc8 docs(forms): clarify ControlValueAccessor docs (#19008)
Closes #18174

PR Close #19008
2017-09-05 23:25:06 -05:00
9f16c2620c docs(aio): updating about page for team changes (#19003)
PR Close #19003
2017-09-05 23:25:06 -05:00
9b256a9144 build(aio): render the extends ancestors of classes in API docs (#18927)
PR Close #18927
2017-09-05 23:25:06 -05:00
0f1476be33 build(aio): ensure dgeni can load all angular Typescript modules (#18927)
PR Close #18927
2017-09-05 23:25:06 -05:00
769b2aada2 docs(aio): add new lib to Data Libraries (#18656)
add AngularCommerse, set of components to build e-commerce solutions with Angular + Firebase

PR Close #18656
2017-09-05 23:25:06 -05:00
301236e1a5 docs(aio): Updated usage of Observables in router guide. Added section for advanced redirects (#18197)
PR Close #18197
2017-09-05 23:25:06 -05:00
aeb98dbcdf docs: add changelog for 4.4.0-RC.0 2017-09-01 22:01:41 -07:00
8036d05412 release: cut the 4.4.0-RC.0 release 2017-09-01 23:49:51 -05:00
7d137d7f88 fix(core): complete EventEmitter in QueryList on component destroy (#18902)
Fixes #18741

PR Close #18902
2017-09-01 22:52:03 -05:00
b8b551cf2b perf(core): add option to remove blank text nodes from compiled templates (#18823)
PR Close #18823
2017-09-01 13:30:04 -05:00
7ec28fe9af feat(compiler): allow multiple exportAs names (#18723)
This change allows users to specify multiple exportAs names for a
directive by giving a comma-delimited list inside the string.

The primary motivation for this change is to allow these names to be
changed in a backwards compatible way.

PR Close #18723
2017-09-01 13:26:10 -05:00
1cc3fe21b6 fix(animations): do not leak DOM nodes/styling for host triggered animations (#18853)
Closes #18606

PR Close #18853
2017-09-01 10:24:14 -07:00
ba7d70e5e0 build: fix changelog to remove AIO line items (#18956)
fixes 18740

PR Close #18956
2017-08-30 18:10:56 -07:00
497e0178cc fix(compiler): normalize the locale name (#18963)
PR Close #18963
2017-08-30 17:48:08 -07:00
8821723526 fix(common): fix XSSI prefix stripping by using JSON.parse always (#18466)
Currently HttpClient sends requests for JSON data with the
XMLHttpRequest.responseType set to 'json'. With this flag, the browser
will attempt to parse the response as JSON, but will return 'null' on
any errors. If the JSON response contains an XSSI-prevention prefix,
this will cause the browser's parsing to fail, which is unrecoverable.

The only compelling reason to use the responseType 'json' is for
performance (especially if the browser offloads JSON parsing to a
separate thread). I'm not aware of any browser which does this currently,
nor of any plans to do so. JSON.parse and responseType 'json' both
end up using the same V8 code path in Chrome to implement the parse.

Thus, this change switches all JSON parsing in HttpClient to use
JSON.parse directly.

Fixes #18396, #18453.

PR Close #18466
2017-08-29 17:19:02 -07:00
a203a959ae fix(common): fix improper packaging for @angular/common/http (#18613)
PR Close #18613
2017-08-29 17:16:56 -07:00
dfe2bad663 build: Add GitHub scripts for rebasing PRs (#18359)
PR Close #18359
2017-08-28 18:33:11 -05:00
f09a266e01 docs: add changelog for 4.3.6 2017-08-23 15:01:42 -05:00
3853fff795 release: cut the 4.3.6 release 2017-08-23 14:59:49 -05:00
641be64544 docs(aio): add info about --local option in the readme (#18824)
PR Close #18824
2017-08-23 13:19:23 -05:00
bcf211bdb3 docs(aio): fix "Error handling" section in "HttpClient" (#18821)
Removed additional curly brackets to fix blocks. Also replaced tab with 2 spaces.

PR Close #18821
2017-08-23 13:19:15 -05:00
ee5591d583 fix(core): make sure onStable runs in the right zone (#18706)
Make sure the callbacks to the NgZone callbacks run in the right zone
with or without the rxjs Zone patch -
1ed83d08ac.

PR Close #18706
2017-08-23 13:18:47 -05:00
1f43713506 fix(aio): do not redirect API pages on archive and next deployments (#18791)
PR Close #18791
2017-08-21 18:34:55 -05:00
325b9b4562 docs(aio): add ngAtlanta to the events page (#18649)
PR Close #18649
2017-08-21 18:34:25 -05:00
88abdbd50b docs(aio): update resources to include NinjaCodeGen Angular CRUD generator (#18518)
PR Close #18518
2017-08-21 18:34:17 -05:00
14d34c9bdf style(animations): format integration spec (#18805)
PR Close #18805
2017-08-21 17:09:53 -05:00
e1f45a33b7 fix(animations): restore auto-style support for removed DOM nodes (#18787)
PR Close #18787
2017-08-18 23:32:41 -05:00
9a754f9f0f fix(animations): make sure animation cancellations respect AUTO style values (#18787)
Closes #17450

PR Close #18787
2017-08-18 23:32:34 -05:00
c3dcbf9cb3 fix(animations): make sure @.disabled respects disabled parent/sub animation sequences (#18715)
Prior to this fix if @parent and @child animations ran at the same
time within a disabled region then there was a chance that a @child
sub animation would never complete. This would cause *directives to
never close a removal when a @child trigger was placed on them. This
patch fixes this issue.

PR Close #18715
2017-08-18 23:32:28 -05:00
5d68c830d2 fix(animations): ensure animations are disabled on the element containing the @.disabled flag (#18714)
Prior to fix this fix, @.disabled would only work to disable child
animations. Now it will also disable animations for the element that has
the @.disabled flag (which makes more sense).

PR Close #18714
2017-08-18 23:32:21 -05:00
ac58914b97 feat(animations): allow @.disabled property to work without an expression (#18713)
PR Close #18713
2017-08-18 23:32:13 -05:00
Joe
77ebd2b020 docs(aio): fix card inconsistency (#18726)
PR Close #18726
2017-08-18 23:15:36 -05:00
fec3b1a0e9 fix(core): correct order in ContentChildren query result (#18326)
Fixes #16568

PR Close #18326
2017-08-18 23:15:17 -05:00
3b571a4f3d build(aio): do not auto-link code elements already inside a link (#18776)
Closes #18769

PR Close #18776
2017-08-18 13:38:43 -05:00
Tea
efee81eb57 docs(aio): typo in template-syntax guide (#18765)
PR Close #18765
2017-08-18 13:38:16 -05:00
a7a698c36f docs(aio): update resource for codelyzer (#18742)
PR Close #18742
2017-08-18 13:22:11 -05:00
b5f1dc32d1 test(aio): fix error logged during tests (#18659)
The fixed test expected there to be a doc version without a URL. This used to be
the case but not any more. As a result, an error was logged in the test output
(but no failure).

This commit fixes it by ensuring that a version without a URL exists.

PR Close #18659
2017-08-18 13:20:22 -05:00
eef28144ce docs(aio): move code snippet to appropriate location (#18650)
PR Close #18650
2017-08-18 13:19:15 -05:00
f9b290570e fix(animations): resolve error when using AnimationBuilder with platform-server (#18642)
Use an injected DOCUMENT instead of assuming the global 'document'
exists.

Fixes #18635.

PR Close #18642
2017-08-18 13:15:05 -05:00
4852f55875 build(packaging): increase node memory for tests (#18731)
PR Close #18731
2017-08-18 13:15:05 -05:00
793f31b9b3 feat(common): add an empty DeprecatedI18NPipesModule module
Adding an empty module to ease the migration to the i18n pipes.
2017-08-18 13:15:05 -05:00
7e94405271 docs: add changelog for 4.3.5 2017-08-16 10:51:23 -07:00
6076a8d7bb release: cut the 4.3.5 release 2017-08-16 10:49:38 -07:00
a1624f217c fix(forms): re-assigning options should not clear select
Fixes #18330
2017-08-16 10:34:23 -07:00
b2f4d53bf0 docs(forms): fix reactive-forms guide typo
closes #17943
2017-08-15 16:43:21 -07:00
7662cefe6f docs: remove TypeScript to JavaScript guide & sample 2017-08-15 16:35:01 -07:00
1cb607697a build(aio): switch from @angular/http to @angular/common/http
```
$ ls -l dist/*.js

 14942            dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.a1b446562b36eebb766d.bundle.js
524385  (+  682)  dist/main.19fec4390ff7837ee6ef.bundle.js
 37402            dist/polyfills.9f7e0e53bce2a6c8326e.bundle.js
 54001            dist/worker-basic.min.js

632265  (+  682)  total
```
2017-08-15 15:16:10 -07:00
1990c3c722 build(aio): upgrade zone.js to 0.8.16
```
$ ls -l dist/*.js

 14942            dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.a1b446562b36eebb766d.bundle.js
523703            dist/main.19fec4390ff7837ee6ef.bundle.js
 37402  (+ 3088)  dist/polyfills.9f7e0e53bce2a6c8326e.bundle.js
 54001            dist/worker-basic.min.js

631583  (+ 3088)  total
```
2017-08-15 15:16:10 -07:00
b589d85d6f build(aio): upgrade @angular/* to 5.0.0-beta.3
```
$ ls -l dist/*.js

 14942            dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.7813f9128903f164bc00.bundle.js
523703  (-18484)  dist/main.19fec4390ff7837ee6ef.bundle.js
 34314            dist/polyfills.9b05df3b6c9270ebf575.bundle.js
 54001            dist/worker-basic.min.js

628495  (-18484)  total
```
2017-08-15 15:16:10 -07:00
03ec3a2169 build(aio): upgrade @angular/* to 4.3.4
```
$ ls -l dist/*.js

 14942            dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.dd77b84267809087d225.bundle.js
542187  (+ 2191)  dist/main.f3ffdb5bb1a5bcec2163.bundle.js
 34314            dist/polyfills.9b05df3b6c9270ebf575.bundle.js
 54001            dist/worker-basic.min.js

646979  (+ 2191)  total
```
2017-08-15 15:16:10 -07:00
a5baed6b97 build(aio): upgrade @angular/cli to 1.3.0
```
$ ls -l dist/*.js

 14942  (+    4)  dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.e07e02e29b7fc93816c6.bundle.js
539996  (-56433)  dist/main.f466098a873c1169a6dc.bundle.js
 34314  (-   33)  dist/polyfills.9b05df3b6c9270ebf575.bundle.js
 54001            dist/worker-basic.min.js

644788  (-56462)  total
```
2017-08-15 15:16:10 -07:00
259fc91305 docs(core): correct code examples for ChangeDetectorRef 2017-08-15 15:12:35 -07:00
a618d6e4ce docs(forms): add api docs for AbstractControlDirective 2017-08-15 15:07:44 -07:00
b315a84ba0 docs(aio): add Metadata guide based on Chuck’s docs
Chuck’s gist
https://gist.github.com/chuckjaz/65dcc2fd5f4f5463e492ed0cb93bca60#file-Angular%20Metadata-md
Also chuck’s doc on metadata-related errors (link needed)
2017-08-15 12:21:23 -07:00
972538be7a fix(core): forbid destroyed views to be inserted or moved in VC
Fixes #18615
2017-08-14 12:09:22 -07:00
d7be4f12b5 perf(aio): update to new version of build-optimizer 2017-08-11 13:29:01 -07:00
b9c1c913c1 fix(aio): skip PWA test when redeploying non-public commit 2017-08-11 13:29:01 -07:00
260 changed files with 4790 additions and 4611 deletions

View File

@ -1,3 +1,92 @@
<a name="4.4.0"></a>
# [4.4.0](https://github.com/angular/angular/compare/4.4.0-RC.0...4.4.0) (2017-09-15)
### Bug Fixes
* **tsc-wrapped:** deduplicate metadata for re-exported modules ([48ae1a6](https://github.com/angular/angular/commit/48ae1a6))
* **tsc-wrapped:** fix metadata symbol reference ([f6a7183](https://github.com/angular/angular/commit/f6a7183))
* **upgrade:** remove code setting id attribute. ([#19182](https://github.com/angular/angular/issues/19182)) ([b20c5d2](https://github.com/angular/angular/commit/b20c5d2)), closes [#18446](https://github.com/angular/angular/issues/18446)
<a name="4.4.0-RC.0"></a>
# [4.4.0-RC.0](https://github.com/angular/angular/compare/4.3.6...4.4.0-RC.0) (2017-09-02)
### Bug Fixes
* **animations:** do not leak DOM nodes/styling for host triggered animations ([#18853](https://github.com/angular/angular/issues/18853)) ([1cc3fe2](https://github.com/angular/angular/commit/1cc3fe2)), closes [#18606](https://github.com/angular/angular/issues/18606)
* **common:** fix improper packaging for [@angular](https://github.com/angular)/common/http ([#18613](https://github.com/angular/angular/issues/18613)) ([a203a95](https://github.com/angular/angular/commit/a203a95))
* **common:** fix XSSI prefix stripping by using JSON.parse always ([#18466](https://github.com/angular/angular/issues/18466)) ([8821723](https://github.com/angular/angular/commit/8821723)), closes [#18396](https://github.com/angular/angular/issues/18396) [#18453](https://github.com/angular/angular/issues/18453)
* **compiler:** normalize the locale name ([#18963](https://github.com/angular/angular/issues/18963)) ([497e017](https://github.com/angular/angular/commit/497e017))
* **core:** complete EventEmitter in QueryList on component destroy ([#18902](https://github.com/angular/angular/issues/18902)) ([7d137d7](https://github.com/angular/angular/commit/7d137d7)), closes [#18741](https://github.com/angular/angular/issues/18741)
### Features
* **compiler:** allow multiple exportAs names ([#18723](https://github.com/angular/angular/issues/18723)) ([7ec28fe](https://github.com/angular/angular/commit/7ec28fe))
* **core:** add option to remove blank text nodes from compiled templates ([#18823](https://github.com/angular/angular/issues/18823)) ([b8b551c](https://github.com/angular/angular/commit/b8b551c))
<a name="4.3.6"></a>
## [4.3.6](https://github.com/angular/angular/compare/4.3.5...4.3.6) (2017-08-23)
### Bug Fixes
* **animations:** ensure animations are disabled on the element containing the @.disabled flag ([#18714](https://github.com/angular/angular/issues/18714)) ([5d68c83](https://github.com/angular/angular/commit/5d68c83))
* **animations:** make sure @.disabled respects disabled parent/sub animation sequences ([#18715](https://github.com/angular/angular/issues/18715)) ([c3dcbf9](https://github.com/angular/angular/commit/c3dcbf9))
* **animations:** make sure animation cancellations respect AUTO style values ([#18787](https://github.com/angular/angular/issues/18787)) ([9a754f9](https://github.com/angular/angular/commit/9a754f9)), closes [#17450](https://github.com/angular/angular/issues/17450)
* **animations:** resolve error when using AnimationBuilder with platform-server ([#18642](https://github.com/angular/angular/issues/18642)) ([f9b2905](https://github.com/angular/angular/commit/f9b2905)), closes [#18635](https://github.com/angular/angular/issues/18635)
* **animations:** restore auto-style support for removed DOM nodes ([#18787](https://github.com/angular/angular/issues/18787)) ([e1f45a3](https://github.com/angular/angular/commit/e1f45a3))
* **core:** correct order in ContentChildren query result ([#18326](https://github.com/angular/angular/issues/18326)) ([fec3b1a](https://github.com/angular/angular/commit/fec3b1a)), closes [#16568](https://github.com/angular/angular/issues/16568)
* **core:** make sure onStable runs in the right zone ([#18706](https://github.com/angular/angular/issues/18706)) ([ee5591d](https://github.com/angular/angular/commit/ee5591d))
### Features
* **animations:** allow @.disabled property to work without an expression ([#18713](https://github.com/angular/angular/issues/18713)) ([ac58914](https://github.com/angular/angular/commit/ac58914))
* **common:** add an empty DeprecatedI18NPipesModule module ([793f31b](https://github.com/angular/angular/commit/793f31b))
<a name="5.0.0-beta.4"></a>
# [5.0.0-beta.4](https://github.com/angular/angular/compare/5.0.0-beta.3...5.0.0-beta.4) (2017-08-16)
### Bug Fixes
* **compiler:** Don't strip CSS source maps ([64b4be9](https://github.com/angular/angular/commit/64b4be9))
* **forms:** re-assigning options should not clear select ([32ff21c](https://github.com/angular/angular/commit/32ff21c)), closes [#18330](https://github.com/angular/angular/issues/18330)
* **language-service:** remove tsickle dependency ([bc22ff1](https://github.com/angular/angular/commit/bc22ff1))
### Features
* **common:** mark NgTemplateOutlet API as stable ([0a73e8d](https://github.com/angular/angular/commit/0a73e8d))
* **forms:** add status to `AbstractControlDirective` ([233ef93](https://github.com/angular/angular/commit/233ef93))
* **forms:** add updateOn support to ngModelOptions ([1cfa79c](https://github.com/angular/angular/commit/1cfa79c))
### Performance Improvements
* **core:** add option to remove blank text nodes from compiled templates ([d2c0d98](https://github.com/angular/angular/commit/d2c0d98))
* **core:** Remove decorator DSL which depends on Reflect ([cac130e](https://github.com/angular/angular/commit/cac130e))
<a name="4.3.5"></a>
## [4.3.5](https://github.com/angular/angular/compare/4.3.4...4.3.5) (2017-08-16)
### Bug Fixes
* **core:** forbid destroyed views to be inserted or moved in VC ([972538b](https://github.com/angular/angular/commit/972538b)), closes [#18615](https://github.com/angular/angular/issues/18615)
* **forms:** re-assigning options should not clear select ([a1624f2](https://github.com/angular/angular/commit/a1624f2)), closes [#18330](https://github.com/angular/angular/issues/18330)
<a name="4.3.4"></a>
## [4.3.4](https://github.com/angular/angular/compare/4.3.3...4.3.4) (2017-08-10)
@ -1104,7 +1193,6 @@ templates is unaffected. We expect no or little impact on apps from this change,
### Features
* **aio:** add initial angular-cli scaffold ([#14118](https://github.com/angular/angular/issues/14118)) ([e130bc1](https://github.com/angular/angular/commit/e130bc1))
* **common:** rename underlying `NgFor` class and add a type parameter ([#14104](https://github.com/angular/angular/issues/14104)) ([86b2b25](https://github.com/angular/angular/commit/86b2b25))
* **compiler:** allow missing translations ([#14113](https://github.com/angular/angular/issues/14113)) ([8775ab9](https://github.com/angular/angular/commit/8775ab9)), closes [#13861](https://github.com/angular/angular/issues/13861)
* **compiler:** do not parse xtb messages not needed by angular ([#14111](https://github.com/angular/angular/issues/14111)) ([f7fba74](https://github.com/angular/angular/commit/f7fba74)), closes [#14046](https://github.com/angular/angular/issues/14046)

View File

@ -26,7 +26,7 @@ Here are the most important tasks you might need to use:
* `yarn docs-lint` - check that the doc gen code follows our style rules.
* `yarn docs-test` - run the unit tests for the doc generation code.
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally.
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally. Add the option `-- --local` to use your local version of Angular contained in the "dist" folder.
* `yarn boilerplate:remove` - remove all the boilerplate code that was added via `yarn boilerplate:add`.
* `yarn generate-plunkers` - generate the plunker files that are used by the `live-example` tags in the docs.
* `yarn generate-zips` - generate the zip files from the examples. Zip available via the `live-example` tags in the docs.
@ -34,6 +34,7 @@ Here are the most important tasks you might need to use:
* `yarn example-e2e` - run all e2e tests for examples
- `yarn example-e2e -- --setup` - force webdriver update & other setup, then run tests
- `yarn example-e2e -- --filter=foo` - limit e2e tests to those containing the word "foo"
- `yarn example-e2e -- --setup --local` - run e2e tests with the local version of Angular contained in the "dist" folder
* `yarn build-ie-polyfills` - generates a js file of polyfills that can be loaded in Internet Explorer.

View File

@ -32,7 +32,8 @@ export class BuildCreator extends EventEmitter {
then(() => Promise.all([this.exists(prDir), this.exists(shaDir)])).
then(([prDirExisted, shaDirExisted]) => {
if (shaDirExisted) {
throw new UploadError(409, `Request to overwrite existing directory: ${shaDir}`);
const publicOrNot = isPublic ? 'public' : 'non-public';
throw new UploadError(409, `Request to overwrite existing ${publicOrNot} directory: ${shaDir}`);
}
dirToRemoveOnError = prDirExisted ? shaDir : prDir;

View File

@ -110,6 +110,7 @@ describe('upload-server (on HTTP)', () => {
const authorizationHeader2 = isPublic ?
authorizationHeader : `--header "Authorization: ${c.BV_verify_verifiedNotTrusted}"`;
const cmdPrefix = curl('', `${authorizationHeader2} ${xFileHeader}`);
const overwriteRe = RegExp(`^Request to overwrite existing ${isPublic ? 'public' : 'non-public'} directory`);
it('should not overwrite existing builds', done => {
@ -120,7 +121,7 @@ describe('upload-server (on HTTP)', () => {
expect(h.readBuildFile(pr, sha9, 'index.html', isPublic)).toBe('My content');
h.runCmd(`${cmdPrefix} http://${host}/create-build/${pr}/${sha9}`).
then(h.verifyResponse(409, /^Request to overwrite existing directory/)).
then(h.verifyResponse(409, overwriteRe)).
then(() => expect(h.readBuildFile(pr, sha9, 'index.html', isPublic)).toBe('My content')).
then(done);
});
@ -141,7 +142,7 @@ describe('upload-server (on HTTP)', () => {
expect(h.readBuildFile(pr, sha9, 'index.html', isPublic)).toBe('My content');
h.runCmd(`${cmdPrefix} http://${host}/create-build/${pr}/${sha9Almost}`).
then(h.verifyResponse(409, /^Request to overwrite existing directory/)).
then(h.verifyResponse(409, overwriteRe)).
then(() => expect(h.readBuildFile(pr, sha9, 'index.html', isPublic)).toBe('My content')).
then(done);
});
@ -310,7 +311,7 @@ describe('upload-server (on HTTP)', () => {
expect(h.buildExists(pr, sha0, isPublic)).toBe(false);
uploadBuild(sha0).
then(h.verifyResponse(409, /^Request to overwrite existing directory/)).
then(h.verifyResponse(409, overwriteRe)).
then(() => {
checkPrVisibility(isPublic);
expect(h.readBuildFile(pr, sha0, 'index.html', isPublic)).toContain(pr);

View File

@ -153,7 +153,8 @@ describe('BuildCreator', () => {
it('should abort and skip further operations if the build does already exist', done => {
existsValues[shaDir] = true;
bc.create(pr, sha, archive, isPublic).catch(err => {
expectToBeUploadError(err, 409, `Request to overwrite existing directory: ${shaDir}`);
const publicOrNot = isPublic ? 'public' : 'non-public';
expectToBeUploadError(err, 409, `Request to overwrite existing ${publicOrNot} directory: ${shaDir}`);
expect(shellMkdirSpy).not.toHaveBeenCalled();
expect(bcExtractArchiveSpy).not.toHaveBeenCalled();
expect(bcEmitSpy).not.toHaveBeenCalled();
@ -169,7 +170,8 @@ describe('BuildCreator', () => {
expect(bcExistsSpy(shaDir)).toBe(false);
bc.create(pr, sha, archive, isPublic).catch(err => {
expectToBeUploadError(err, 409, `Request to overwrite existing directory: ${shaDir}`);
const publicOrNot = isPublic ? 'public' : 'non-public';
expectToBeUploadError(err, 409, `Request to overwrite existing ${publicOrNot} directory: ${shaDir}`);
expect(shellMkdirSpy).not.toHaveBeenCalled();
expect(bcExtractArchiveSpy).not.toHaveBeenCalled();
expect(bcEmitSpy).not.toHaveBeenCalled();

View File

@ -6,7 +6,7 @@
"interface-name": [true, "never-prefix"],
"max-classes-per-file": [true, 4],
"no-consecutive-blank-lines": [true, 2],
"no-console": false,
"no-console": [false],
"no-namespace": [true, "allow-declarations"],
"no-string-literal": false,
"quotemark": [true, "single"],

View File

@ -46,8 +46,8 @@ with a bried explanation of what they mean:
Request method other than POST.
- **409 (Conflict)**:
Request to overwrite existing directory (e.g. deploy existing build or change PR visibility when
the destination directory does already exist).
Request to overwrite existing (public or non-public) directory (e.g. deploy existing build or
change PR visibility when the destination directory does already exist).
- **413 (Payload Too Large)**:
Payload larger than size specified in `AIO_UPLOAD_MAX_SIZE`.
@ -71,7 +71,8 @@ with a bried explanation of what they mean:
Request method other than POST.
- **409 (Conflict)**:
Request to overwrite existing directory (i.e. directories for both visibilities exist).
Request to overwrite existing (public or non-public) directory (i.e. directories for both
visibilities exist).
(Normally, this should not happen.)

View File

@ -55,10 +55,6 @@ dist/
!testing/src/browser-test-shim.js
!testing/karma*.js
# TS to JS
!ts-to-js/js*/**/*.js
ts-to-js/js*/**/system*.js
# webpack
!webpack/**/config/*.js
!webpack/**/*webpack*.js

View File

@ -12,13 +12,13 @@ describe('Router', () => {
beforeAll(() => browser.get(''));
function getPageStruct() {
const hrefEles = element.all(by.css('my-app a'));
const hrefEles = element.all(by.css('my-app > nav a'));
const crisisDetail = element.all(by.css('my-app > ng-component > ng-component > ng-component > div')).first();
const heroDetail = element(by.css('my-app > ng-component > div'));
return {
hrefs: hrefEles,
activeHref: element(by.css('my-app a.active')),
activeHref: element(by.css('my-app > nav a.active')),
crisisHref: hrefEles.get(0),
crisisList: element.all(by.css('my-app > ng-component > ng-component li')),

View File

@ -15,6 +15,10 @@
height: 1.6em;
border-radius: 4px;
}
.items li a {
display: block;
text-decoration: none;
}
.items li:hover {
color: #607D8B;
background-color: #DDD;

View File

@ -28,7 +28,7 @@ const appRoutes: Routes = [
data: { preload: true }
},
// #enddocregion preload-v2
{ path: '', redirectTo: '/heroes', pathMatch: 'full' },
{ path: '', redirectTo: '/superheroes', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
];

View File

@ -0,0 +1,23 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
// #docregion template
template: `
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<router-outlet></router-outlet>
<router-outlet name="popup"></router-outlet>
`
// #enddocregion template
})
export class AppComponent {
}

View File

@ -9,7 +9,7 @@ import { Component } from '@angular/core';
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/superheroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>

View File

@ -1,5 +1,6 @@
// #docregion
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { CanDeactivate,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';
@ -13,7 +14,7 @@ export class CanDeactivateGuard implements CanDeactivate<CrisisDetailComponent>
component: CrisisDetailComponent,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise<boolean> | boolean {
): Observable<boolean> | boolean {
// Get the Crisis Center ID
console.log(route.paramMap.get('id'));
@ -25,7 +26,7 @@ export class CanDeactivateGuard implements CanDeactivate<CrisisDetailComponent>
return true;
}
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
// observable which resolves to true or false when the user decides
return component.dialogService.confirm('Discard changes?');
}
}

View File

@ -1,18 +1,21 @@
// #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 { Crisis, CrisisService } from './crisis.service';
import { Crisis, CrisisService } from './crisis.service';
@Injectable()
export class CrisisDetailResolver implements Resolve<Crisis> {
constructor(private cs: CrisisService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Crisis> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Crisis> {
let id = route.paramMap.get('id');
return this.cs.getCrisis(id).then(crisis => {
return this.cs.getCrisis(id).take(1).map(crisis => {
if (crisis) {
return crisis;
} else { // id not found

View File

@ -1,8 +1,9 @@
// #docplaster
// #docregion
import 'rxjs/add/operator/switchMap';
import { Component, OnInit, HostBinding } from '@angular/core';
import { Component, OnInit, HostBinding } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { slideInDownAnimation } from '../animations';
import { Crisis, CrisisService } from './crisis.service';
@ -45,7 +46,8 @@ export class CrisisDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.route.paramMap
.switchMap((params: ParamMap) => this.service.getCrisis(params.get('id')))
.switchMap((params: ParamMap) =>
this.service.getCrisis(params.get('id')))
.subscribe((crisis: Crisis) => {
if (crisis) {
this.editName = crisis.name;
@ -66,13 +68,13 @@ export class CrisisDetailComponent implements OnInit {
this.gotoCrises();
}
canDeactivate(): Promise<boolean> | boolean {
canDeactivate(): Observable<boolean> | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
}
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
// observable which resolves to true or false when the user decides
return this.dialogService.confirm('Discard changes?');
}

View File

@ -2,6 +2,7 @@
// #docregion
import { Component, OnInit, HostBinding } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { slideInDownAnimation } from '../animations';
import { Crisis } from './crisis.service';
@ -62,13 +63,13 @@ export class CrisisDetailComponent implements OnInit {
// #enddocregion cancel-save
// #docregion canDeactivate
canDeactivate(): Promise<boolean> | boolean {
canDeactivate(): Observable<boolean> | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
}
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
// observable which resolves to true or false when the user decides
return this.dialogService.confirm('Discard changes?');
}
// #enddocregion canDeactivate

View File

@ -1,7 +1,7 @@
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Observable } from 'rxjs/Observable';
@ -10,35 +10,34 @@ import { Observable } from 'rxjs/Observable';
// #docregion relative-navigation-router-link
template: `
<ul class="items">
<li *ngFor="let crisis of crises | async">
<a [routerLink]="[crisis.id]"
[class.selected]="isSelected(crisis)">
<span class="badge">{{ crisis.id }}</span>
{{ crisis.name }}
<li *ngFor="let crisis of crises$ | async"
[class.selected]="crisis.id === selectedId">
<a [routerLink]="[crisis.id]">
<span class="badge">{{ crisis.id }}</span>{{ crisis.name }}
</a>
</li>
</ul>`
</ul>
<router-outlet></router-outlet>
`
// #enddocregion relative-navigation-router-link
})
export class CrisisListComponent implements OnInit {
crises: Observable<Crisis[]>;
crises$: Observable<Crisis[]>;
selectedId: number;
constructor(
private service: CrisisService,
private route: ActivatedRoute,
private router: Router
private route: ActivatedRoute
) {}
ngOnInit() {
this.crises = this.route.paramMap
this.crises$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.selectedId = +params.get('id');
return this.service.getCrises();
});
}
isSelected(crisis: Crisis) {
return crisis.id === this.selectedId;
}
}

View File

@ -1,20 +1,19 @@
// #docregion
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Observable } from 'rxjs/Observable';
@Component({
template: `
<ul class="items">
<li *ngFor="let crisis of crises | async"
(click)="onSelect(crisis)"
[class.selected]="isSelected(crisis)">
<span class="badge">{{ crisis.id }}</span>
{{ crisis.name }}
<li *ngFor="let crisis of crises$ | async"
[class.selected]="crisis.id === selectedId">
<a [routerLink]="[crisis.id]">
<span class="badge">{{ crisis.id }}</span>{{ crisis.name }}
</a>
</li>
</ul>
@ -22,35 +21,21 @@ import { Crisis, CrisisService } from './crisis.service';
`
})
export class CrisisListComponent implements OnInit {
crises: Observable<Crisis[]>;
crises$: Observable<Crisis[]>;
selectedId: number;
// #docregion ctor
constructor(
private service: CrisisService,
private route: ActivatedRoute,
private router: Router
private route: ActivatedRoute
) {}
// #enddocregion ctor
isSelected(crisis: Crisis) {
return crisis.id === this.selectedId;
}
ngOnInit() {
this.crises = this.route.paramMap
this.crises$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.selectedId = +params.get('id');
return this.service.getCrises();
});
}
// #docregion onSelect
onSelect(crisis: Crisis) {
this.selectedId = crisis.id;
// Navigate with relative link
this.router.navigate([crisis.id], { relativeTo: this.route });
}
// #enddocregion onSelect
}

View File

@ -1,5 +1,9 @@
// #docplaster
// #docregion , mock-crises
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
export class Crisis {
constructor(public id: number, public name: string) { }
}
@ -12,20 +16,18 @@ const CRISES = [
];
// #enddocregion mock-crises
let crisesPromise = Promise.resolve(CRISES);
import { Injectable } from '@angular/core';
@Injectable()
export class CrisisService {
static nextCrisisId = 100;
private crises$: BehaviorSubject<Crisis[]> = new BehaviorSubject<Crisis[]>(CRISES);
getCrises() { return crisesPromise; }
getCrises() { return this.crises$; }
getCrisis(id: number | string) {
return crisesPromise
.then(crises => crises.find(crisis => crisis.id === +id));
return this.getCrises()
.map(crises => crises.find(crisis => crisis.id === +id));
}
// #enddocregion
@ -33,7 +35,8 @@ export class CrisisService {
name = name.trim();
if (name) {
let crisis = new Crisis(CrisisService.nextCrisisId++, name);
crisesPromise.then(crises => crises.push(crisis));
CRISES.push(crisis);
this.crises$.next(CRISES);
}
}
// #docregion

View File

@ -1,5 +1,8 @@
// #docregion
import 'rxjs/add/observable/of';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
/**
* Async modal dialog service
* DialogService makes this app easier to test by faking this service.
@ -9,11 +12,11 @@ import { Injectable } from '@angular/core';
export class DialogService {
/**
* Ask user to confirm an action. `message` explains the action and choices.
* Returns promise resolving to `true`=confirm or `false`=cancel
* Returns observable resolving to `true`=confirm or `false`=cancel
*/
confirm(message?: string) {
return new Promise<boolean>(resolve => {
return resolve(window.confirm(message || 'Is it OK?'));
});
confirm(message?: string): Observable<boolean> {
const confirmation = window.confirm(message || 'Is it OK?');
return Observable.of(confirmation);
};
}

View File

@ -4,6 +4,7 @@
import 'rxjs/add/operator/switchMap';
// #enddocregion rxjs-operator-import
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
// #docregion imports
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
// #enddocregion imports
@ -13,7 +14,7 @@ import { Hero, HeroService } from './hero.service';
@Component({
template: `
<h2>HEROES</h2>
<div *ngIf="hero">
<div *ngIf="hero$ | async as hero">
<h3>"{{ hero.name }}"</h3>
<div>
<label>Id: </label>{{ hero.id }}</div>
@ -28,7 +29,7 @@ import { Hero, HeroService } from './hero.service';
`
})
export class HeroDetailComponent implements OnInit {
hero: Hero;
hero$: Observable<Hero>;
// #docregion ctor
constructor(
@ -40,10 +41,9 @@ export class HeroDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.route.paramMap
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')))
.subscribe((hero: Hero) => this.hero = hero);
this.service.getHero(params.get('id')));
}
// #enddocregion ngOnInit

View File

@ -2,13 +2,14 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Hero, HeroService } from './hero.service';
@Component({
template: `
<h2>HEROES</h2>
<div *ngIf="hero">
<div *ngIf="hero$ | async as hero">
<h3>"{{ hero.name }}"</h3>
<div>
<label>Id: </label>{{ hero.id }}</div>
@ -23,7 +24,7 @@ import { Hero, HeroService } from './hero.service';
`
})
export class HeroDetailComponent implements OnInit {
hero: Hero;
hero$: Observable<Hero>;
constructor(
private route: ActivatedRoute,
@ -35,8 +36,7 @@ export class HeroDetailComponent implements OnInit {
ngOnInit() {
let id = this.route.snapshot.paramMap.get('id');
this.service.getHero(id)
.then((hero: Hero) => this.hero = hero);
this.hero$ = this.service.getHero(id);
}
// #enddocregion snapshot

View File

@ -4,6 +4,7 @@
import 'rxjs/add/operator/switchMap';
// #enddocregion rxjs-operator-import
import { Component, OnInit, HostBinding } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { slideInDownAnimation } from '../animations';
@ -13,7 +14,7 @@ import { Hero, HeroService } from './hero.service';
@Component({
template: `
<h2>HEROES</h2>
<div *ngIf="hero">
<div *ngIf="hero$ | async as hero">
<h3>"{{ hero.name }}"</h3>
<div>
<label>Id: </label>{{ hero.id }}</div>
@ -22,7 +23,7 @@ import { Hero, HeroService } from './hero.service';
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
<p>
<button (click)="gotoHeroes()">Back</button>
<button (click)="gotoHeroes(hero)">Back</button>
</p>
</div>
`,
@ -35,7 +36,7 @@ export class HeroDetailComponent implements OnInit {
@HostBinding('style.position') position = 'absolute';
// #enddocregion host-bindings
hero: Hero;
hero$: Observable<Hero>;
// #docregion ctor
constructor(
@ -47,16 +48,15 @@ export class HeroDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.route.paramMap
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')))
.subscribe((hero: Hero) => this.hero = hero);
this.service.getHero(params.get('id')));
}
// #enddocregion ngOnInit
// #docregion gotoHeroes
gotoHeroes() {
let heroId = this.hero ? this.hero.id : null;
gotoHeroes(hero: Hero) {
let heroId = hero ? hero.id : null;
// Pass along the hero id if available
// so that the HeroList component can select that hero.
// Include a junk 'foo' property for fun.

View File

@ -3,6 +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 { Hero, HeroService } from './hero.service';
@ -11,9 +12,12 @@ import { Hero, HeroService } from './hero.service';
template: `
<h2>HEROES</h2>
<ul class="items">
<li *ngFor="let hero of heroes | async"
(click)="onSelect(hero)">
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
<li *ngFor="let hero of heroes$ | async">
// #docregion nav-to-detail
<a [routerLink]="['/hero', hero.id]">
<span class="badge">{{ hero.id }}</span>{{ hero.name }}
</a>
// #enddocregion nav-to-detail
</li>
</ul>
@ -22,7 +26,7 @@ import { Hero, HeroService } from './hero.service';
// #enddocregion template
})
export class HeroListComponent implements OnInit {
heroes: Promise<Hero[]>;
heroes$: Observable<Hero[]>;
// #docregion ctor
constructor(
@ -32,16 +36,8 @@ export class HeroListComponent implements OnInit {
// #enddocregion ctor
ngOnInit() {
this.heroes = this.service.getHeroes();
this.heroes$ = this.service.getHeroes();
}
// #docregion select
onSelect(hero: Hero) {
// #docregion nav-to-detail
this.router.navigate(['/hero', hero.id]);
// #enddocregion nav-to-detail
}
// #enddocregion select
}
// #enddocregion

View File

@ -7,7 +7,7 @@ import { Observable } from 'rxjs/Observable';
// #enddocregion rxjs-imports
import { Component, OnInit } from '@angular/core';
// #docregion import-router
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { ActivatedRoute, ParamMap } from '@angular/router';
// #enddocregion import-router
import { Hero, HeroService } from './hero.service';
@ -17,10 +17,11 @@ import { Hero, HeroService } from './hero.service';
template: `
<h2>HEROES</h2>
<ul class="items">
<li *ngFor="let hero of heroes | async"
[class.selected]="isSelected(hero)"
(click)="onSelect(hero)">
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
<li *ngFor="let hero of heroes$ | async"
[class.selected]="hero.id === selectedId">
<a [routerLink]="['/hero', hero.id]">
<span class="badge">{{ hero.id }}</span>{{ hero.name }}
</a>
</li>
</ul>
@ -30,18 +31,17 @@ import { Hero, HeroService } from './hero.service';
})
// #docregion ctor
export class HeroListComponent implements OnInit {
heroes: Observable<Hero[]>;
heroes$: Observable<Hero[]>;
private selectedId: number;
constructor(
private service: HeroService,
private route: ActivatedRoute,
private router: Router
private route: ActivatedRoute
) {}
ngOnInit() {
this.heroes = this.route.paramMap
this.heroes$ = this.route.paramMap
.switchMap((params: ParamMap) => {
// (+) before `params.get()` turns the string into a number
this.selectedId = +params.get('id');
@ -49,16 +49,6 @@ export class HeroListComponent implements OnInit {
});
}
// #enddocregion ctor
// #docregion isSelected
isSelected(hero: Hero) { return hero.id === this.selectedId; }
// #enddocregion isSelected
// #docregion select
onSelect(hero: Hero) {
this.router.navigate(['/hero', hero.id]);
}
// #enddocregion select
// #docregion ctor
}
// #enddocregion

View File

@ -1,11 +1,14 @@
// #docregion
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
export class Hero {
constructor(public id: number, public name: string) { }
}
let HEROES = [
const HEROES = [
new Hero(11, 'Mr. Nice'),
new Hero(12, 'Narco'),
new Hero(13, 'Bombasto'),
@ -14,15 +17,13 @@ let HEROES = [
new Hero(16, 'RubberMan')
];
let heroesPromise = Promise.resolve(HEROES);
@Injectable()
export class HeroService {
getHeroes() { return heroesPromise; }
getHeroes() { return Observable.of(HEROES); }
getHero(id: number | string) {
return heroesPromise
return this.getHeroes()
// (+) before `id` turns the string into a number
.then(heroes => heroes.find(hero => hero.id === +id));
.map(heroes => heroes.find(hero => hero.id === +id));
}
}

View File

@ -0,0 +1,24 @@
// #docregion
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
const heroesRoutes: Routes = [
{ path: 'heroes', component: HeroListComponent },
// #docregion hero-detail-route
{ path: 'hero/:id', component: HeroDetailComponent }
// #enddocregion hero-detail-route
];
@NgModule({
imports: [
RouterModule.forChild(heroesRoutes)
],
exports: [
RouterModule
]
})
export class HeroRoutingModule { }
// #enddocregion

View File

@ -6,10 +6,10 @@ import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
const heroesRoutes: Routes = [
{ path: 'heroes', component: HeroListComponent },
// #docregion hero-detail-route
{ path: 'hero/:id', component: HeroDetailComponent }
// #enddocregion hero-detail-route
{ path: 'heroes', redirectTo: '/superheroes' },
{ path: 'hero/:id', redirectTo: '/superhero/:id' },
{ path: 'superheroes', component: HeroListComponent },
{ path: 'superhero/:id', component: HeroDetailComponent }
];
@NgModule({

View File

@ -35,7 +35,7 @@ export class HeroDetailComponent {
@Input() prefix = '';
// #docregion deleteRequest
// This component make a request but it can't actually delete a hero.
// This component makes a request but it can't actually delete a hero.
deleteRequest = new EventEmitter<Hero>();
delete() {

View File

@ -44,6 +44,7 @@ System.config({
map: {
'@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
'@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
'@angular/common/http/testing': 'npm:@angular/common/bundles/common-http-testing.umd.js',
'@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
'@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
'@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',

View File

@ -52,6 +52,10 @@ module.exports = function(config) {
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
// tslib (TS helper fns such as `__extends`)
{ pattern: 'node_modules/tslib/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/tslib/**/*.js.map', included: false, watched: false },
// Paths loaded via module imports:
// Angular itself
{ pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },

View File

@ -1,77 +0,0 @@
'use strict'; // necessary for es6 output in node
import { browser, element, by } from 'protractor';
describe('TypeScript to Javascript tests', function () {
beforeAll(function () {
browser.get('');
});
it('should display the basic component example', function () {
testTag('hero-view', 'Hero Detail: Windstorm');
});
it('should display the component example with lifecycle methods', function () {
testTag('hero-lifecycle', 'Hero: Windstorm');
});
it('should display component with DI example', function () {
testTag('hero-di', 'Hero: Windstorm');
});
it('should display component with DI using @Inject example', function () {
testTag('hero-di-inject', 'Hero: Windstorm');
});
it('should support optional, attribute, and query injections', function () {
let app = element(by.css('hero-di-inject-additional'));
let h1 = app.element(by.css('h1'));
let okMsg = app.element(by.css('p'));
expect(h1.getText()).toBe('Tour of Heroes');
app.element(by.buttonText('OK')).click();
expect(okMsg.getText()).toBe('OK!');
});
it('should support component with inputs and outputs', function () {
let app = element(by.css('hero-io'));
let confirmComponent = app.element(by.css('app-confirm'));
confirmComponent.element(by.buttonText('OK')).click();
expect(app.element(by.cssContainingText('span', 'OK clicked')).isPresent()).toBe(true);
confirmComponent.element(by.buttonText('Cancel')).click();
expect(app.element(by.cssContainingText('span', 'Cancel clicked')).isPresent()).toBe(true);
});
it('should support host bindings and host listeners', function() {
let app = element(by.css('hero-host'));
let h1 = app.element(by.css('h1'));
expect(app.getAttribute('class')).toBe('heading');
expect(app.getAttribute('title')).toContain('Tooltip');
h1.click();
expect(h1.getAttribute('class')).toBe('active');
h1.click();
browser.actions().doubleClick(h1.getWebElement()).perform();
expect(h1.getAttribute('class')).toBe('active');
});
it('should support content and view queries', function() {
let app = element(by.css('hero-queries'));
let windstorm = app.element(by.css('view-child:first-child'));
app.element(by.css('button')).click();
expect(windstorm.element(by.css('h2')).getAttribute('class')).toBe('active');
expect(windstorm.element(by.css('content-child')).getText()).toBe('Active');
});
function testTag(selector: string, expectedText: string) {
let component = element(by.css(selector));
expect(component.getText()).toBe(expectedText);
}
});

View File

@ -1,3 +0,0 @@
{
"build": "build:babel"
}

View File

@ -1,9 +0,0 @@
{
"description": "TypeScript to JavaScript",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"
],
"tags":["cookbook"]
}

View File

@ -1,6 +0,0 @@
{
"presets": [
"es2015",
"angular2"
]
}

View File

@ -1,14 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styles: [
// See hero-di-inject-additional.component
'hero-host, hero-host-meta { border: 1px dashed black; display: block; padding: 4px;}',
'.heading {font-style: italic}'
]
})
export class AppComponent {
title = 'ES6 JavaScript with Decorators';
}

View File

@ -1,31 +0,0 @@
<a id="toc"></a>
<h1>{{title}}</h1>
<a href="#class-metadata">Classes and Class Metadata</a><br>
<a href="#io-metadata">Input and Output Decorators</a><br>
<a href="#dependency-injection">Dependency Injection</a><br>
<a href="#host-metadata">Host Metadata</a><br>
<a href="#view-child-metadata">View and Child Metadata</a><br>
<hr>
<h4 id="class-metadata">Classes and Class Metadata</h4>
<hero-view></hero-view>
<hero-lifecycle></hero-lifecycle>
<hr>
<h4 id="io-metadata">Input and Output Metadata</h4>
<hero-io></hero-io>
<hr>
<h4 id="dependency-injection">Dependency Injection</h4>
<hero-di></hero-di>
<hero-di-inject></hero-di-inject>
<hero-di-inject-additional></hero-di-inject-additional>
<hr>
<h4 id="host-metadata">Host Metadata</h4>
<hero-host></hero-host>
<hero-host-meta></hero-host-meta>
<hr>
<h4 id="view-child-metadata">View and Child Metadata</h4>
<hero-queries></hero-queries>

View File

@ -1,55 +0,0 @@
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ConfirmComponent } from './confirm.component';
// #docregion appimport
import { HeroComponent } from './hero.component';
// #enddocregion appimport
import { HeroComponent as HeroDIComponent } from './hero-di.component';
import { HeroComponent as HeroDIInjectComponent } from './hero-di-inject.component';
import { HeroComponent as HeroDIInjectAdditionalComponent } from './hero-di-inject-additional.component';
import { HeroHostComponent } from './hero-host.component';
import { HeroHostMetaComponent } from './hero-host-meta.component';
import { HeroIOComponent } from './hero-io.component';
import { HeroComponent as HeroLifecycleComponent } from './hero-lifecycle.component';
import { HeroQueriesComponent, ViewChildComponent, ContentChildComponent } from './hero-queries.component';
import { HeroTitleComponent } from './hero-title.component';
import { DataService } from './data.service';
@NgModule({
imports: [
BrowserModule
],
declarations: [
AppComponent,
ConfirmComponent,
HeroComponent,
HeroDIComponent,
HeroDIInjectComponent,
HeroDIInjectAdditionalComponent,
HeroHostComponent, HeroHostMetaComponent,
HeroIOComponent,
HeroLifecycleComponent,
HeroQueriesComponent, ViewChildComponent, ContentChildComponent,
HeroTitleComponent
],
providers: [
DataService,
{ provide: 'heroName', useValue: 'Windstorm' }
],
bootstrap: [ AppComponent ],
// schemas: [ NO_ERRORS_SCHEMA ] // helpful for debugging
})
export class AppModule { }
/* tslint:disable no-unused-variable */
// #docregion ng2import
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import {
LocationStrategy,
HashLocationStrategy
} from '@angular/common';
// #enddocregion ng2import

View File

@ -1,21 +0,0 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
// #docregion
@Component({
selector: 'app-confirm',
templateUrl: './confirm.component.html'
})
export class ConfirmComponent {
@Input() okMsg = '';
@Input('cancelMsg') notOkMsg = '';
@Output() ok = new EventEmitter();
@Output('cancel') notOk = new EventEmitter();
onOkClick() {
this.ok.emit(true);
}
onNotOkClick() {
this.notOk.emit(true);
}
}
// #enddocregion

View File

@ -1,6 +0,0 @@
<button (click)="onOkClick()">
{{okMsg}}
</button>
<button (click)="onNotOkClick()">
{{notOkMsg}}
</button>

View File

@ -1,10 +0,0 @@
import { Injectable } from '@angular/core';
@Injectable()
export class DataService {
constructor() { }
getHeroName() {
return 'Windstorm';
}
}

View File

@ -1,7 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'hero-di-inject-additional',
template: `<hero-title title="Tour of Heroes"></hero-title>`
})
export class HeroComponent { }

View File

@ -1,13 +0,0 @@
import { Component, Inject } from '@angular/core';
// #docregion
@Component({
selector: 'hero-di-inject',
template: `<h1>Hero: {{name}}</h1>`
})
export class HeroComponent {
constructor(@Inject('heroName') name) {
this.name = name;
}
}
// #enddocregion

View File

@ -1,15 +0,0 @@
// #docregion
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'hero-di',
template: `<h1>Hero: {{name}}</h1>`
})
export class HeroComponent {
name = '';
constructor(dataService: DataService) {
this.name = dataService.getHeroName();
}
}
// #enddocregion

View File

@ -1,44 +0,0 @@
import { Component } from '@angular/core';
// #docregion
@Component({
selector: 'hero-host-meta',
template: `
<h1 [class.active]="active">Hero Host in Metadata</h1>
<div>Heading clicks: {{clicks}}</div>
`,
host: {
// HostBindings to the <hero-host-meta> element
'[title]': 'title',
'[class.heading]': 'headingClass',
// HostListeners on the entire <hero-host-meta> element
'(click)': 'clicked()',
'(mouseenter)': 'enter($event)',
'(mouseleave)': 'leave($event)'
},
// Styles within (but excluding) the <hero-host-meta> element
styles: ['.active {background-color: coral;}']
})
export class HeroHostMetaComponent {
title = 'Hero Host in Metadata Tooltip';
headingClass = true;
active = false;
clicks = 0;
clicked() {
this.clicks += 1;
}
enter(event: Event) {
this.active = true;
this.headingClass = false;
}
leave(event: Event) {
this.active = false;
this.headingClass = true;
}
}
// #enddocregion

View File

@ -1,39 +0,0 @@
import { Component, HostBinding, HostListener } from '@angular/core';
// #docregion
@Component({
selector: 'hero-host',
template: `
<h1 [class.active]="active">Hero Host in Decorators</h1>
<div>Heading clicks: {{clicks}}</div>
`,
// Styles within (but excluding) the <hero-host> element
styles: ['.active {background-color: yellow;}']
})
export class HeroHostComponent {
// HostBindings to the <hero-host> element
@HostBinding() title = 'Hero Host in Decorators Tooltip';
@HostBinding('class.heading') headingClass = true;
active = false;
clicks = 0;
// HostListeners on the entire <hero-host> element
@HostListener('click')
clicked() {
this.clicks += 1;
}
@HostListener('mouseenter', ['$event'])
enter(event: Event) {
this.active = true;
this.headingClass = false;
}
@HostListener('mouseleave', ['$event'])
leave(event: Event) {
this.active = false;
this.headingClass = true;
}
}
// #enddocregion

View File

@ -1,26 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'hero-io',
template: `
<app-confirm [okMsg]="'OK'"
[cancelMsg]="'Cancel'"
(ok)="onOk()"
(cancel)="onCancel()">
</app-confirm>
<span *ngIf="okClicked">OK clicked</span>
<span *ngIf="cancelClicked">Cancel clicked</span>
`
})
export class HeroIOComponent {
okClicked = false;
cancelClicked = false;
onOk() {
this.okClicked = true;
}
onCancel() {
this.cancelClicked = true;
}
}

View File

@ -1,14 +0,0 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'hero-lifecycle',
template: `<h1>Hero: {{name}}</h1>`
})
export class HeroComponent {
name = '';
ngOnInit() {
// todo: fetch from server async
setTimeout(() => this.name = 'Windstorm', 0);
}
}

View File

@ -1,81 +0,0 @@
import {
Component,
ContentChild,
Input,
QueryList,
ViewChildren
} from '@angular/core';
@Component({
selector: 'content-child',
template: `
<span class="content-child" *ngIf="active">
Active
</span>`
})
export class ContentChildComponent {
active = false;
activate() {
this.active = true;
}
}
////////////////////
// #docregion content
@Component({
selector: 'view-child',
template: `
<h2 [class.active]=active>
{{hero.name}}
<ng-content></ng-content>
</h2>`,
styles: ['.active {font-weight: bold; background-color: skyblue;}']
})
export class ViewChildComponent {
@Input() hero;
active = false;
@ContentChild(ContentChildComponent) content;
activate() {
this.active = !this.active;
this.content.activate();
}
}
// #enddocregion content
////////////////////
// #docregion view
@Component({
selector: 'hero-queries',
template: `
<view-child *ngFor="let hero of heroData" [hero]="hero">
<content-child></content-child>
</view-child>
<button (click)="activate()">{{buttonLabel}} All</button>
`
})
export class HeroQueriesComponent {
active = false;
heroData = [
{id: 1, name: 'Windstorm'},
{id: 2, name: 'LaughingGas'}
];
@ViewChildren(ViewChildComponent) views;
activate() {
this.active = !this.active;
this.views.forEach(
view => view.activate()
);
}
get buttonLabel() {
return this.active ? 'Deactivate' : 'Activate';
}
}
// #enddocregion view

View File

@ -1,25 +0,0 @@
import { Attribute, Component, Inject, Optional } from '@angular/core';
// #docregion
// #docregion templateUrl
@Component({
selector: 'hero-title',
templateUrl: './hero-title.component.html'
})
// #enddocregion templateUrl
export class HeroTitleComponent {
msg = '';
constructor(
@Inject('titlePrefix') @Optional() titlePrefix,
@Attribute('title') title
) {
this.titlePrefix = titlePrefix;
this.title = title;
}
ok() {
this.msg = 'OK!';
}
}
// #enddocregion

View File

@ -1,4 +0,0 @@
<!-- #docregion -->
<h1>{{titlePrefix}} {{title}}</h1>
<button (click)="ok()">OK</button>
<p>{{ msg }}</p>

View File

@ -1,15 +0,0 @@
// #docregion
// #docregion metadata
import { Component } from '@angular/core';
@Component({
selector: 'hero-view',
template: '<h1>{{title}}: {{getName()}}</h1>'
})
// #docregion appexport, class
export class HeroComponent {
title = 'Hero Detail';
getName() {return 'Windstorm'; }
}
// #enddocregion appexport, class
// #enddocregion metadata

View File

@ -1,26 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<base href="/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<title>TypeScript to JavaScript</title>
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('main.js').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>

View File

@ -1,4 +0,0 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -1,3 +0,0 @@
{
"build": "build:babel"
}

View File

@ -1,9 +0,0 @@
{
"description": "TypeScript to JavaScript",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"
],
"tags":["cookbook"]
}

View File

@ -1,5 +0,0 @@
{
"presets": [
"es2015"
]
}

View File

@ -1,19 +0,0 @@
import { Component } from '@angular/core';
export class AppComponent {
constructor() {
this.title = 'Plain ES6 JavaScript';
}
}
AppComponent.annotations = [
new Component({
selector: 'my-app',
templateUrl: './app.component.html',
styles: [
// See hero-di-inject-additional.component
'hero-host { border: 1px dashed black; display: block; padding: 4px;}',
'.heading {font-style: italic}'
]
})
];

View File

@ -1,30 +0,0 @@
<a id="toc"></a>
<h1>{{title}}</h1>
<a href="#class-metadata">Classes and Class Metadata</a><br>
<a href="#io-metadata">Input and Output Metadata</a><br>
<a href="#dependency-injection">Dependency Injection</a><br>
<a href="#host-metadata">Host Metadata</a><br>
<a href="#view-child-metadata">View and Child Metadata</a><br>
<hr>
<h4 id="class-metadata">Classes and Class Metadata</h4>
<hero-view></hero-view>
<hero-lifecycle></hero-lifecycle>
<hr>
<h4 id="io-metadata">Input and Output Metadata</h4>
<hero-io></hero-io>
<hr>
<h4 id="dependency-injection">Dependency Injection</h4>
<hero-di></hero-di>
<hero-di-inject></hero-di-inject>
<hero-di-inject-additional></hero-di-inject-additional>
<hr>
<h4 id="host-metadata">Host Metadata</h4>
<hero-host></hero-host>
<hr>
<h4 id="view-child-metadata">View and Child Metadata</h4>
<hero-queries></hero-queries>

View File

@ -1,56 +0,0 @@
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ConfirmComponent } from './confirm.component';
// #docregion appimport
import { HeroComponent } from './hero.component';
// #enddocregion appimport
import { HeroComponent as HeroDIComponent } from './hero-di.component';
import { HeroComponent as HeroDIInjectComponent } from './hero-di-inject.component';
import { HeroComponent as HeroDIInjectAdditionalComponent } from './hero-di-inject-additional.component';
import { HeroHostComponent } from './hero-host.component';
import { HeroIOComponent } from './hero-io.component';
import { HeroComponent as HeroLifecycleComponent } from './hero-lifecycle.component';
import { HeroQueriesComponent, ViewChildComponent, ContentChildComponent } from './hero-queries.component';
import { HeroTitleComponent } from './hero-title.component';
import { DataService } from './data.service';
export class AppModule { }
AppModule.annotations = [
new NgModule({
imports: [ BrowserModule],
declarations: [
AppComponent,
ConfirmComponent,
HeroComponent,
HeroDIComponent,
HeroDIInjectComponent,
HeroDIInjectAdditionalComponent,
HeroHostComponent,
HeroIOComponent,
HeroLifecycleComponent,
HeroQueriesComponent, ViewChildComponent, ContentChildComponent,
HeroTitleComponent
],
providers: [
DataService,
{ provide: 'heroName', useValue: 'Windstorm' }
],
bootstrap: [ AppComponent ],
// schemas: [ NO_ERRORS_SCHEMA ] // helpful for debugging
})
]
/* tslint:disable no-unused-variable */
// #docregion ng2import
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import {
LocationStrategy,
HashLocationStrategy
} from '@angular/common';
// #enddocregion ng2import

View File

@ -1,31 +0,0 @@
import { Component, EventEmitter } from '@angular/core';
// #docregion
export class ConfirmComponent {
constructor(){
this.ok = new EventEmitter();
this.notOk = new EventEmitter();
}
onOkClick() {
this.ok.emit(true);
}
onNotOkClick() {
this.notOk.emit(true);
}
}
ConfirmComponent.annotations = [
new Component({
selector: 'app-confirm',
templateUrl: './confirm.component.html',
inputs: [
'okMsg',
'notOkMsg: cancelMsg'
],
outputs: [
'ok',
'notOk: cancel'
]
})
];
// #enddocregion

View File

@ -1,6 +0,0 @@
<button (click)="onOkClick()">
{{okMsg}}
</button>
<button (click)="onNotOkClick()">
{{notOkMsg}}
</button>

View File

@ -1,13 +0,0 @@
import { Injectable } from '@angular/core';
export class DataService {
constructor() {
}
getHeroName() {
return 'Windstorm';
}
}
DataService.annotations = [
new Injectable()
];

View File

@ -1,10 +0,0 @@
import { Component } from '@angular/core';
export class HeroComponent { }
HeroComponent.annotations = [
new Component({
selector: 'hero-di-inject-additional',
template: `<hero-title title="Tour of Heroes"></hero-title>`
})
];

View File

@ -1,20 +0,0 @@
import { Component, Inject } from '@angular/core';
// #docregion
export class HeroComponent {
constructor(name) {
this.name = name;
}
}
HeroComponent.annotations = [
new Component({
selector: 'hero-di-inject',
template: `<h1>Hero: {{name}}</h1>`
})
];
HeroComponent.parameters = [
[new Inject('heroName')]
];
// #enddocregion

View File

@ -1,21 +0,0 @@
// #docregion
import { Component } from '@angular/core';
import { DataService } from './data.service';
export class HeroComponent {
constructor(dataService) {
this.name = dataService.getHeroName();
}
}
HeroComponent.annotations = [
new Component({
selector: 'hero-di',
template: `<h1>Hero: {{name}}</h1>`
})
];
HeroComponent.parameters = [
[DataService]
];
// #enddocregion

View File

@ -1,50 +0,0 @@
import { Component } from '@angular/core';
// #docregion
export class HeroHostComponent {
constructor() {
this.active = false;
this.clicks = 0;
this.headingClass = true;
this.title = 'Hero Host Tooltip';
}
clicked() {
this.clicks += 1;
}
enter(event) {
this.active = true;
this.headingClass = false;
}
leave(event) {
this.active = false;
this.headingClass = true;
}
}
// #docregion metadata
HeroHostComponent.annotations = [
new Component({
selector: 'hero-host',
template: `
<h1 [class.active]="active">Hero Host</h1>
<div>Heading clicks: {{clicks}}</div>
`,
host: {
// HostBindings to the <hero-host> element
'[title]': 'title',
'[class.heading]': 'headingClass',
'(click)': 'clicked()',
// HostListeners on the entire <hero-host> element
'(mouseenter)': 'enter($event)',
'(mouseleave)': 'leave($event)'
},
// Styles within (but excluding) the <hero-host> element
styles: ['.active {background-color: yellow;}']
})
];
// #enddocregion metadata
// #enddocregion

View File

@ -1,31 +0,0 @@
import { Component } from '@angular/core';
export class HeroIOComponent {
constructor() {
this.okClicked = false;
this.cancelClicked = false;
}
onOk() {
this.okClicked = true;
}
onCancel() {
this.cancelClicked = true;
}
}
HeroIOComponent.annotations = [
new Component({
selector: 'hero-io',
template: `
<app-confirm [okMsg]="'OK'"
[cancelMsg]="'Cancel'"
(ok)="onOk()"
(cancel)="onCancel()">
</app-confirm>
<span *ngIf="okClicked">OK clicked</span>
<span *ngIf="cancelClicked">Cancel clicked</span>
`
})
];

View File

@ -1,15 +0,0 @@
// #docregion
import { Component } from '@angular/core';
export class HeroComponent {
ngOnInit() {
// todo: fetch from server async
setTimeout(() => this.name = 'Windstorm', 0);
}
}
HeroComponent.annotations = [
new Component({
selector: 'hero-lifecycle',
template: `<h1>Hero: {{name}}</h1>`
})
];

View File

@ -1,97 +0,0 @@
import {
Component,
ContentChild,
Input,
QueryList,
ViewChildren
} from '@angular/core';
export class ContentChildComponent {
constructor() {
this.active = false;
}
activate() {
this.active = !this.active;
}
}
ContentChildComponent.annotations = [
new Component({
selector: 'content-child',
template: `
<span class="content-child" *ngIf="active">
Active
</span>`
})
];
////////////////////
// #docregion content
export class ViewChildComponent {
constructor() {
this.active = false;
}
activate() {
this.active = !this.active;
this.content.activate();
}
}
ViewChildComponent.annotations = [
new Component({
selector: 'view-child',
template: `<h2 [class.active]=active>
{{hero.name}}
<ng-content></ng-content>
</h2>`,
styles: ['.active {font-weight: bold; background-color: skyblue;}'],
inputs: ['hero'],
queries: {
content: new ContentChild(ContentChildComponent)
}
})
];
// #enddocregion content
////////////////////
// #docregion view
export class HeroQueriesComponent {
constructor(){
this.active = false;
this.heroData = [
{id: 1, name: 'Windstorm'},
{id: 2, name: 'LaughingGas'}
];
}
activate() {
this.active = !this.active;
this.views.forEach(
view => view.activate()
);
}
get buttonLabel() {
return this.active ? 'Deactivate' : 'Activate';
}
}
HeroQueriesComponent.annotations = [
new Component({
selector: 'hero-queries',
template: `
<view-child *ngFor="let hero of heroData" [hero]="hero">
<content-child></content-child>
</view-child>
<button (click)="activate()">{{buttonLabel}} All</button>
`,
queries: {
views: new ViewChildren(ViewChildComponent)
}
})
];
// #enddocregion view

View File

@ -1,28 +0,0 @@
import { Attribute, Component, Inject, Optional } from '@angular/core';
// #docregion
export class HeroTitleComponent {
constructor(titlePrefix, title) {
this.titlePrefix = titlePrefix;
this.title = title;
this.msg = '';
}
ok() {
this.msg = 'OK!';
}
}
// #docregion templateUrl
HeroTitleComponent.annotations = [
new Component({
selector: 'hero-title',
templateUrl: './hero-title.component.html'
})
];
// #enddocregion templateUrl
HeroTitleComponent.parameters = [
[new Optional(), new Inject('titlePrefix')],
[new Attribute('title')]
];

View File

@ -1,4 +0,0 @@
<!-- #docregion -->
<h1>{{titlePrefix}} {{title}}</h1>
<button (click)="ok()">OK</button>
<p>{{ msg }}</p>

View File

@ -1,21 +0,0 @@
// #docplaster
// #docregion
// #docregion metadata
import { Component } from '@angular/core';
// #docregion appexport, class
export class HeroComponent {
constructor() {
this.title = 'Hero Detail';
}
getName() {return 'Windstorm'; }
}
// #enddocregion appexport, class
HeroComponent.annotations = [
new Component({
selector: 'hero-view',
template: '<h1>{{title}}: {{getName()}}</h1>'
})
];
// #enddocregion metadata

View File

@ -1,26 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<base href="/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<title>TypeScript to JavaScript</title>
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('main.js').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>

View File

@ -1,4 +0,0 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -1,3 +0,0 @@
{
"build": "build:babel"
}

View File

@ -1,8 +0,0 @@
{
"description": "TypeScript to JavaScript",
"basePath": "src/",
"files":[
"!**/karma*.*"
],
"tags":["cookbook"]
}

View File

@ -1,47 +0,0 @@
<a id="toc"></a>
<h1>{{title}}</h1>
<a href="#class-metadata">Classes and Class Metadata</a><br>
<a href="#interfaces">Interfaces</a><br>
<a href="#io-metadata">Input and Output Metadata</a><br>
<a href="#dependency-injection">Dependency Injection</a><br>
<a href="#host-metadata">Host Metadata</a><br>
<a href="#view-child-metadata">View and Child Metadata</a><br>
<hr>
<h4 id="class-metadata">Classes and Class Metadata</h4>
<hero-view></hero-view>
<h4 id="class-metadata-dsl">Classes and Class Metadata (DSL)</h4>
<hero-view-dsl></hero-view-dsl>
<hr>
<h4 id="interfaces">Interfaces</h4>
<hero-lifecycle></hero-lifecycle>
<h4 id="interfaces-dsl">Interfaces (DSL)</h4>
<hero-lifecycle-dsl></hero-lifecycle-dsl>
<hr>
<h4 id="io-metadata">Input and Output Metadata</h4>
<hero-io></hero-io>
<h4 id="io-metadata-dsl">Input and Output Metadata (DSL)</h4>
<hero-io-dsl></hero-io-dsl>
<hr>
<h4 id="dependency-injection">Dependency Injection</h4>
<hero-di></hero-di>
<hero-di-inject></hero-di-inject>
<hero-di-inject-additional></hero-di-inject-additional>
<h4 id="dependency-injection-dsl">Dependency Injection (DSL)</h4>
<hero-di-dsl></hero-di-dsl>
<hero-di-inject-dsl></hero-di-inject-dsl>
<hero-di-inject-additional-dsl></hero-di-inject-additional-dsl>
<hr>
<h4 id="host-metadata">Host Metadata</h4>
<hero-host></hero-host>
<h4 id="host-metadata-dsl">Host Metadata (DSL)</h4>
<hero-host-dsl></hero-host-dsl>
<hr>
<h4 id="view-child-metadata">View and Child Metadata (DSL)</h4>
<hero-queries></hero-queries>

View File

@ -1,20 +0,0 @@
(function(app) {
app.AppComponent = AppComponent;
function AppComponent() {
this.title = 'ES5 JavaScript';
}
AppComponent.annotations = [
new ng.core.Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
styles: [
// See hero-di-inject-additional.component
'hero-host, hero-host-dsl { border: 1px dashed black; display: block; padding: 4px;}',
'.heading {font-style: italic}'
]
})
];
})(window.app = window.app || {});

View File

@ -1,46 +0,0 @@
(function(app) {
app.AppModule = AppModule;
function AppModule() { }
AppModule.annotations = [
new ng.core.NgModule({
imports: [ ng.platformBrowser.BrowserModule ],
declarations: [
app.AppComponent,
app.ConfirmComponent, app.ConfirmDslComponent,
app.HeroComponent, app.HeroDslComponent,
app.HeroDIComponent, app.HeroDIDslComponent,
app.HeroDIInjectComponent, app.HeroDIInjectDslComponent,
app.HeroDIInjectAdditionalComponent, app.HeroDIInjectAdditionalDslComponent,
app.HeroHostComponent, app.HeroHostDslComponent,
app.HeroIOComponent, app.HeroIODslComponent,
app.HeroLifecycleComponent, app.HeroLifecycleDslComponent,
app.heroQueries.HeroQueriesComponent, app.heroQueries.ViewChildComponent, app.heroQueries.ContentChildComponent,
app.HeroTitleComponent, app.HeroTitleDslComponent
],
providers: [
app.DataService,
{ provide: 'heroName', useValue: 'Windstorm' }
],
bootstrap: [ app.AppComponent ],
// schemas: [ ng.core.NO_ERRORS_SCHEMA ] // helpful for debugging!
})
]
})(window.app = window.app || {});
///// For documentation only /////
(function () {
// #docregion appimport
var HeroComponent = app.HeroComponent;
// #enddocregion appimport
// #docregion ng2import
var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic;
var LocationStrategy = ng.common.LocationStrategy;
var HashLocationStrategy = ng.common.HashLocationStrategy;
// #enddocregion ng2import
})

View File

@ -1,6 +0,0 @@
<button (click)="onOkClick()">
{{okMsg}}
</button>
<button (click)="onNotOkClick()">
{{notOkMsg}}
</button>

View File

@ -1,75 +0,0 @@
(function(app) {
// #docregion
app.ConfirmComponent = ConfirmComponent;
ConfirmComponent.annotations = [
new ng.core.Component({
selector: 'app-confirm',
templateUrl: 'app/confirm.component.html',
inputs: [
'okMsg',
'notOkMsg: cancelMsg'
],
outputs: [
'ok',
'notOk: cancel'
]
})
];
function ConfirmComponent() {
this.ok = new ng.core.EventEmitter();
this.notOk = new ng.core.EventEmitter();
}
ConfirmComponent.prototype.onOkClick = function() {
this.ok.emit(true);
}
ConfirmComponent.prototype.onNotOkClick = function() {
this.notOk.emit(true);
}
// #enddocregion
})(window.app = window.app || {});
/////// DSL version ////////
(function(app) {
var old = app.ConfirmComponent;
// #docregion dsl
app.ConfirmComponent = ng.core.Component({
selector: 'app-confirm-dsl',
templateUrl: 'app/confirm.component.html',
inputs: [
'okMsg',
'notOkMsg: cancelMsg'
],
outputs: [
'ok',
'notOk: cancel'
]
})
.Class({
constructor: function ConfirmComponent() {
this.ok = new ng.core.EventEmitter();
this.notOk = new ng.core.EventEmitter();
},
onOkClick: function() {
this.ok.emit(true);
},
onNotOkClick: function() {
this.notOk.emit(true);
}
});
// #enddocregion dsl
app.ConfirmDslComponent = app.ConfirmComponent;
app.ConfirmComponent = old;
})(window.app = window.app || {});

View File

@ -1,10 +0,0 @@
(function(app) {
app.DataService = DataService;
function DataService() { }
DataService.prototype.getHeroName = function() {
return 'Windstorm';
};
})(window.app = window.app || {});

View File

@ -1,36 +0,0 @@
(function(app) {
var old = app.HeroComponent;
app.HeroComponent = HeroComponent;
HeroComponent.annotations = [
new ng.core.Component({
selector: 'hero-di-inject-additional',
template: '<hero-title title="Tour of Heroes"></hero-title>'
})
];
function HeroComponent() {}
app.HeroDIInjectAdditionalComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});
////// DSL Version /////////
(function(app) {
var old = app.HeroComponent;
app.HeroComponent = ng.core.Component({
selector: 'hero-di-inject-additional-dsl',
template: '<hero-title-dsl title="Tour of Heroes"></hero-title-dsl>'
}).Class({
constructor: function HeroComponent() { }
});
app.HeroDIInjectAdditionalDslComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});

View File

@ -1,51 +0,0 @@
(function(app) {
var old = app.HeroComponent;
// #docregion
app.HeroComponent = HeroComponent;
HeroComponent.annotations = [
new ng.core.Component({
selector: 'hero-di-inject',
template: '<h1>Hero: {{name}}</h1>'
})
];
HeroComponent.parameters = [ 'heroName' ];
function HeroComponent(name) {
this.name = name;
}
// #enddocregion
app.HeroDIInjectComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});
/////// DSL version ////////
(function(app) {
var old = app.HeroComponent;
// #docregion dsl
app.HeroComponent = ng.core.Component({
selector: 'hero-di-inject-dsl',
template: '<h1>Hero: {{name}}</h1>'
})
.Class({
constructor: [
new ng.core.Inject('heroName'),
function HeroComponent(name) {
this.name = name;
}
]
});
// #enddocregion dsl
app.HeroDIInjectDslComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});

View File

@ -1,51 +0,0 @@
(function(app) {
var old = app.HeroComponent;
// #docregion
app.HeroComponent = HeroComponent;
HeroComponent.annotations = [
new ng.core.Component({
selector: 'hero-di',
template: '<h1>Hero: {{name}}</h1>'
})
];
HeroComponent.parameters = [ app.DataService ];
function HeroComponent(dataService) {
this.name = dataService.getHeroName();
}
// #enddocregion
app.HeroDIComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});
////// DSL Version /////
(function(app) {
var old = app.HeroComponent;
// #docregion dsl
app.HeroComponent = ng.core.Component({
selector: 'hero-di-dsl',
template: '<h1>Hero: {{name}}</h1>'
})
.Class({
constructor: [
app.DataService,
function HeroComponent(service) {
this.name = service.getHeroName();
}
]
});
// #enddocregion dsl
app.HeroDIDslComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});

View File

@ -1,107 +0,0 @@
(function(app) {
var old = app.HeroComponent
// #docregion
app.HeroComponent = HeroComponent;
HeroComponent.annotations = [
new ng.core.Component({
selector: 'hero-host',
template:
'<h1 [class.active]="active">Hero Host</h1>' +
'<div>Heading clicks: {{clicks}}</div>',
host: {
// HostBindings to the <hero-host> element
'[title]': 'title',
'[class.heading]': 'headingClass',
'(click)': 'clicked()',
// HostListeners on the entire <hero-host> element
'(mouseenter)': 'enter($event)',
'(mouseleave)': 'leave($event)'
},
// Styles within (but excluding) the <hero-host> element
styles: ['.active {background-color: yellow;}']
})
];
function HeroComponent() {
this.clicks = 0;
this.headingClass = true;
this.title = 'Hero Host Tooltip content';
}
HeroComponent.prototype.clicked = function() {
this.clicks += 1;
}
HeroComponent.prototype.enter = function(event) {
this.active = true;
this.headingClass = false;
}
HeroComponent.prototype.leave = function(event) {
this.active = false;
this.headingClass = true;
}
// #enddocregion
app.HeroHostComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});
//// DSL Version ////
(function(app) {
var old = app.HeroComponent;
// #docregion dsl
app.HeroComponent = ng.core.Component({
selector: 'hero-host-dsl',
template: `
<h1 [class.active]="active">Hero Host (DSL)</h1>
<div>Heading clicks: {{clicks}}</div>
`,
host: {
// HostBindings to the <hero-host-dsl> element
'[title]': 'title',
'[class.heading]': 'headingClass',
'(click)': 'clicked()',
// HostListeners on the entire <hero-host-dsl> element
'(mouseenter)': 'enter($event)',
'(mouseleave)': 'leave($event)'
},
// Styles within (but excluding) the <hero-host-dsl> element
styles: ['.active {background-color: coral;}']
})
.Class({
constructor: function HeroComponent() {
this.clicks = 0;
this.headingClass = true;
this.title = 'Hero Host Tooltip DSL content';
},
clicked() {
this.clicks += 1;
},
enter(event) {
this.active = true;
this.headingClass = false;
},
leave(event) {
this.active = false;
this.headingClass = true;
}
});
// #enddocregion dsl
app.HeroHostDslComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});

View File

@ -1,7 +0,0 @@
<app-confirm-dsl [okMsg]="'OK'"
[cancelMsg]="'Cancel'"
(ok)="onOk()"
(cancel)="onCancel()">
</app-confirm-dsl>
<span *ngIf="okClicked">OK clicked</span>
<span *ngIf="cancelClicked">Cancel clicked</span>

View File

@ -1,7 +0,0 @@
<app-confirm [okMsg]="'OK'"
[cancelMsg]="'Cancel'"
(ok)="onOk()"
(cancel)="onCancel()">
</app-confirm>
<span *ngIf="okClicked">OK clicked</span>
<span *ngIf="cancelClicked">Cancel clicked</span>

View File

@ -1,52 +0,0 @@
(function(app) {
var old = app.HeroComponent
app.HeroComponent = HeroComponent;
HeroComponent.annotations = [
new ng.core.Component({
selector: 'hero-io',
templateUrl: 'app/hero-io.component.html'
})
];
function HeroComponent() { }
HeroComponent.prototype.onOk = function() {
this.okClicked = true;
}
HeroComponent.prototype.onCancel = function() {
this.cancelClicked = true;
}
app.HeroIOComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});
///// DSL Version ////
(function(app) {
var old = app.HeroComponent
app.HeroComponent = ng.core.Component({
selector: 'hero-io-dsl',
templateUrl: 'app/hero-io-dsl.component.html'
})
.Class({
constructor: function HeroComponent() { },
onOk: function() {
this.okClicked = true;
},
onCancel: function() {
this.cancelClicked = true;
}
});
app.HeroIODslComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});

View File

@ -1,52 +0,0 @@
// #docplaster
(function(app) {
var old = app.HeroComponent;
// #docregion
app.HeroComponent = HeroComponent;
HeroComponent.annotations = [
new ng.core.Component({
selector: 'hero-lifecycle',
template: '<h1>Hero: {{name}}</h1>'
})
];
function HeroComponent() { }
HeroComponent.prototype.ngOnInit = function() {
// todo: fetch from server async
setTimeout(() => this.name = 'Windstorm', 0);
};
// #enddocregion
app.HeroLifecycleComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});
/////// DSL version ////
(function(app) {
var old = app.HeroComponent;
// #docregion dsl
app.HeroComponent = ng.core.Component({
selector: 'hero-lifecycle-dsl',
template: '<h1>Hero: {{name}}</h1>'
})
.Class({
constructor: function HeroComponent() { },
ngOnInit: function() {
// todo: fetch from server async
setTimeout(() => this.name = 'Windstorm', 0);
}
});
// #enddocregion dsl
app.HeroLifecycleDslComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});

View File

@ -1,92 +0,0 @@
(function(app) {
app.heroQueries = app.heroQueries || {};
app.heroQueries.ContentChildComponent = ng.core.Component({
selector: 'content-child',
template:
'<span class="content-child" *ngIf="active">' +
'Active' +
'</span>'
}).Class({
constructor: function ContentChildComponent() {
this.active = false;
},
activate: function() {
this.active = !this.active;
}
});
////////////////////
// #docregion content
app.heroQueries.ViewChildComponent = ng.core.Component({
selector: 'view-child',
template:
'<h2 [class.active]=active>' +
'{{hero.name}} ' +
'<ng-content></ng-content>' +
'</h2>',
styles: ['.active {font-weight: bold; background-color: skyblue;}'],
inputs: ['hero'],
queries: {
content: new ng.core.ContentChild(app.heroQueries.ContentChildComponent)
}
})
.Class({
constructor: function HeroQueriesHeroComponent() {
this.active = false;
},
activate: function() {
this.active = !this.active;
this.content.activate();
}
});
// #enddocregion content
////////////////////
// #docregion view
app.heroQueries.HeroQueriesComponent = ng.core.Component({
selector: 'hero-queries',
template:
'<view-child *ngFor="let hero of heroData" [hero]="hero">' +
'<content-child></content-child>' +
'</view-child>' +
'<button (click)="activate()">{{buttonLabel}} All</button>',
queries: {
views: new ng.core.ViewChildren(app.heroQueries.ViewChildComponent)
}
})
.Class({
constructor: function HeroQueriesComponent() {
this.active = false;
this.heroData = [
{id: 1, name: 'Windstorm'},
{id: 2, name: 'LaughingGas'}
];
},
activate: function() {
this.active = !this.active;
this.views.forEach(function(view) {
view.activate();
});
},
});
// #docregion defined-property
// add prototype property w/ getter outside the DSL
var proto = app.heroQueries.HeroQueriesComponent.prototype;
Object.defineProperty(proto, "buttonLabel", {
get: function () {
return this.active ? 'Deactivate' : 'Activate';
},
enumerable: true
});
// #enddocregion defined-property
// #enddocregion view
})(window.app = window.app || {});

View File

@ -1,4 +0,0 @@
<!-- #docregion -->
<h1>{{titlePrefix}} {{title}}</h1>
<button (click)="ok()">OK</button>
<p>{{ msg }}</p>

View File

@ -1,64 +0,0 @@
(function(app) {
// #docregion
app.HeroTitleComponent = HeroTitleComponent;
// #docregion templateUrl
HeroTitleComponent.annotations = [
new ng.core.Component({
selector: 'hero-title',
templateUrl: 'app/hero-title.component.html'
})
];
// #enddocregion templateUrl
function HeroTitleComponent(titlePrefix, title) {
this.titlePrefix = titlePrefix;
this.title = title;
this.msg = '';
}
HeroTitleComponent.prototype.ok = function() {
this.msg = 'OK!';
}
HeroTitleComponent.parameters = [
[new ng.core.Optional(), new ng.core.Inject('titlePrefix')],
[new ng.core.Attribute('title')]
];
// #enddocregion
})(window.app = window.app || {});
////////// DSL version ////////////
(function(app) {
var old = app.HeroTitleComponent;
// #docregion dsl
app.HeroTitleComponent = ng.core.Component({
selector: 'hero-title-dsl',
templateUrl: 'app/hero-title.component.html'
})
.Class({
constructor: [
[ new ng.core.Optional(), new ng.core.Inject('titlePrefix') ],
new ng.core.Attribute('title'),
function HeroTitleComponent(titlePrefix, title) {
this.titlePrefix = titlePrefix;
this.title = title;
this.msg = '';
}
],
ok: function() {
this.msg = 'OK!';
}
});
// #enddocregion dsl
app.HeroTitleDslComponent = app.HeroTitleComponent;
app.HeroTitleComponent = old;
})(window.app = window.app || {});

View File

@ -1,53 +0,0 @@
// #docplaster
(function(app) {
// #docregion
// #docregion appexport
// #docregion metadata
app.HeroComponent = HeroComponent; // "export"
HeroComponent.annotations = [
new ng.core.Component({
selector: 'hero-view',
template: '<h1>{{title}}: {{getName()}}</h1>'
})
];
// #docregion constructorproto
function HeroComponent() {
this.title = "Hero Detail";
}
HeroComponent.prototype.getName = function() { return 'Windstorm'; };
// #enddocregion constructorproto
// #enddocregion metadata
// #enddocregion appexport
// #enddocregion
})(window.app = window.app || {});
//////////// DSL version ///////////
(function(app) {
var old = app.HeroComponent;
// #docregion dsl
app.HeroComponent = ng.core.Component({
selector: 'hero-view-dsl',
template: '<h1>{{title}}: {{getName()}}</h1>',
})
.Class({
constructor: function HeroComponent() {
this.title = "Hero Detail";
},
getName: function() { return 'Windstorm'; }
});
// #enddocregion dsl
app.HeroDslComponent = app.HeroComponent;
app.HeroComponent = old;
})(window.app = window.app || {});

View File

@ -1,43 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<title>TypeScript to JavaScript</title>
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<!-- Angular and RxJS umd scripts -->
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/@angular/core/bundles/core.umd.js"></script>
<script src="node_modules/@angular/common/bundles/common.umd.js"></script>
<script src="node_modules/@angular/compiler/bundles/compiler.umd.js"></script>
<script src="node_modules/@angular/platform-browser/bundles/platform-browser.umd.js"></script>
<script src="node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js"></script>
<!-- Application scripts -->
<script src="app/app.component.js"></script>
<script src="app/confirm.component.js"></script>
<script src="app/data.service.js"></script>
<script src="app/hero.component.js"></script>
<script src="app/hero-io.component.js"></script>
<script src="app/hero-di.component.js"></script>
<script src="app/hero-di-inject.component.js"></script>
<script src="app/hero-di-inject-additional.component.js"></script>
<script src="app/hero-host.component.js"></script>
<script src="app/hero-lifecycle.component.js"></script>
<script src="app/hero-queries.component.js"></script>
<script src="app/hero-title.component.js"></script>
<script src="app/app.module.js"></script>
<script src="main.js"></script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>

View File

@ -1,9 +0,0 @@
(function(app) {
var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic;
document.addEventListener('DOMContentLoaded', function() {
platformBrowserDynamic().bootstrapModule(app.AppModule);
});
})(window.app = window.app || {});

View File

@ -1,9 +0,0 @@
{
"description": "TypeScript to JavaScript",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"
],
"tags":["cookbook"]
}

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