Compare commits
94 Commits
5.0.1
...
labs/eleme
Author | SHA1 | Date | |
---|---|---|---|
21bfaf2265 | |||
94526930b1 | |||
4d42d9adca | |||
c1c9083d04 | |||
bb9565d5a2 | |||
46280177b6 | |||
118e5a56a8 | |||
fb61771e3e | |||
3db7112b89 | |||
2ea76cce31 | |||
b8bb2dd0f5 | |||
27ae0f9475 | |||
171dceb010 | |||
1ebc0d1e33 | |||
1d8e0758fa | |||
cd55643f85 | |||
486b8e6f69 | |||
215d373ebd | |||
4038b42396 | |||
9ab1f4a9c9 | |||
e9afc59a81 | |||
83c826c3f9 | |||
abfc41d661 | |||
11fd7eaf63 | |||
54eba606cb | |||
3337865913 | |||
f24397c5d0 | |||
9d52bf27de | |||
19fbfbc371 | |||
6578b30b77 | |||
10c1c2ba5a | |||
e18bfd1f3d | |||
3c2ddbe9ab | |||
a149605c9f | |||
b396029d39 | |||
040b376052 | |||
175c872514 | |||
71291aa2c0 | |||
415e75716a | |||
3216abee2e | |||
327ad02a28 | |||
1df0c9e1b0 | |||
280dadaaad | |||
c30eff898a | |||
ca129ba549 | |||
171ae154c2 | |||
4426c0f14e | |||
901436e46f | |||
6fbc2b3be0 | |||
93d23ddcc8 | |||
548a809a05 | |||
a161b4ab6d | |||
60b91656cd | |||
1858d99559 | |||
3a8665409d | |||
005a78bd83 | |||
7553ce9dfe | |||
42bfe4477f | |||
3bdbb18c8b | |||
13f8648a00 | |||
b6abcb2500 | |||
f1a9e1e361 | |||
54480f7dfc | |||
951bd33b09 | |||
bf57df3e04 | |||
420852e2f5 | |||
04eb80cc2b | |||
308fc8e328 | |||
9bb2939d68 | |||
2f63899be2 | |||
22c66f0e02 | |||
00bc80bb37 | |||
394d951883 | |||
98b26381f6 | |||
31797d3b50 | |||
957be960d2 | |||
18e9d86a3b | |||
a869aeecd2 | |||
eca822b756 | |||
17142a778a | |||
5adb7c9669 | |||
703fcda590 | |||
f16a7cd7e3 | |||
fde5f2fa14 | |||
d56724659f | |||
56b18ff063 | |||
7bfeac746e | |||
c92efc15fb | |||
b51d57deb8 | |||
c357b40dca | |||
a0ae120093 | |||
d3211a2468 | |||
adab4f3e49 | |||
82fed62af2 |
@ -279,6 +279,14 @@ groups:
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
|
||||
elements:
|
||||
conditions:
|
||||
files:
|
||||
- "packages/elements/*"
|
||||
users:
|
||||
- mhevery #primary
|
||||
- IgorMinar #fallback
|
||||
|
||||
benchpress:
|
||||
conditions:
|
||||
files:
|
||||
|
@ -54,7 +54,6 @@ env:
|
||||
- CI_MODE=browserstack_optional
|
||||
- CI_MODE=aio_tools_test
|
||||
- CI_MODE=aio
|
||||
- CI_MODE=aio_optional
|
||||
- CI_MODE=aio_e2e AIO_SHARD=0
|
||||
- CI_MODE=aio_e2e AIO_SHARD=1
|
||||
- CI_MODE=bazel
|
||||
@ -64,7 +63,6 @@ matrix:
|
||||
allow_failures:
|
||||
- env: "CI_MODE=saucelabs_optional"
|
||||
- env: "CI_MODE=browserstack_optional"
|
||||
- env: "CI_MODE=aio_optional"
|
||||
|
||||
before_install:
|
||||
# source the env.sh script so that the exported variables are available to other scripts later on
|
||||
|
99
CHANGELOG.md
99
CHANGELOG.md
@ -1,17 +1,3 @@
|
||||
<a name="5.0.1"></a>
|
||||
## [5.0.1](https://github.com/angular/angular/compare/5.0.0...5.0.1) (2017-11-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** don't overwrite missingTranslation's value in JIT ([#19952](https://github.com/angular/angular/issues/19952)) ([799cbb9](https://github.com/angular/angular/commit/799cbb9))
|
||||
* **compiler:** report a reasonable error with invalid metadata ([#20062](https://github.com/angular/angular/issues/20062)) ([da22c48](https://github.com/angular/angular/commit/da22c48))
|
||||
* **compiler-cli:** don't report emit diagnostics when `--noEmitOnError` is off ([#20063](https://github.com/angular/angular/issues/20063)) ([8639995](https://github.com/angular/angular/commit/8639995))
|
||||
* **core:** `__symbol__` should return `__zone_symbol__` without zone.js loaded ([#19541](https://github.com/angular/angular/issues/19541)) ([678d1cf](https://github.com/angular/angular/commit/678d1cf))
|
||||
* **core:** should support event.stopImmediatePropagation ([#19222](https://github.com/angular/angular/issues/19222)) ([7083791](https://github.com/angular/angular/commit/7083791))
|
||||
* **platform-browser:** support Symbols in custom `jasmineToString()` method ([#19794](https://github.com/angular/angular/issues/19794)) ([5a6efa7](https://github.com/angular/angular/commit/5a6efa7))
|
||||
|
||||
|
||||
<a name="5.0.0"></a>
|
||||
# [5.0.0](https://github.com/angular/angular/compare/5.0.0-rc.9...5.0.0) pentagonal-donut (2017-11-01)
|
||||
|
||||
@ -22,6 +8,7 @@
|
||||
* **animations:** support :increment and :decrement transition aliases ([6f45519](https://github.com/angular/angular/commit/6f45519))
|
||||
* **animations:** support negative query limit values ([86ffacf](https://github.com/angular/angular/commit/86ffacf)), closes [#19259](https://github.com/angular/angular/issues/19259)
|
||||
* **common:** accept object map for HttpClient headers & params ([#18490](https://github.com/angular/angular/issues/18490)) ([1b1d5f1](https://github.com/angular/angular/commit/1b1d5f1))
|
||||
* **common:** add an empty DeprecatedI18NPipesModule module ([#18737](https://github.com/angular/angular/issues/18737)) ([83713dd](https://github.com/angular/angular/commit/83713dd))
|
||||
* **common:** drop use of the Intl API to improve browser support ([#18284](https://github.com/angular/angular/issues/18284)) ([079d884](https://github.com/angular/angular/commit/079d884)), closes [#10809](https://github.com/angular/angular/issues/10809) [#9524](https://github.com/angular/angular/issues/9524) [#7008](https://github.com/angular/angular/issues/7008) [#9324](https://github.com/angular/angular/issues/9324) [#7590](https://github.com/angular/angular/issues/7590) [#6724](https://github.com/angular/angular/issues/6724) [#3429](https://github.com/angular/angular/issues/3429) [#17576](https://github.com/angular/angular/issues/17576) [#17478](https://github.com/angular/angular/issues/17478) [#17319](https://github.com/angular/angular/issues/17319) [#17200](https://github.com/angular/angular/issues/17200) [#16838](https://github.com/angular/angular/issues/16838) [#16624](https://github.com/angular/angular/issues/16624) [#16625](https://github.com/angular/angular/issues/16625) [#16591](https://github.com/angular/angular/issues/16591) [#14131](https://github.com/angular/angular/issues/14131) [#12632](https://github.com/angular/angular/issues/12632) [#11376](https://github.com/angular/angular/issues/11376) [#11187](https://github.com/angular/angular/issues/11187)
|
||||
* **common:** generate `closure-locale.ts` to tree shake locale data ([#18907](https://github.com/angular/angular/issues/18907)) ([4878936](https://github.com/angular/angular/commit/4878936))
|
||||
* **common:** mark NgTemplateOutlet API as stable ([0a73e8d](https://github.com/angular/angular/commit/0a73e8d))
|
||||
@ -29,6 +16,7 @@
|
||||
* **compiler-cli:** lower metadata `useValue` and `data` literal fields ([#18905](https://github.com/angular/angular/issues/18905)) ([0e64261](https://github.com/angular/angular/commit/0e64261))
|
||||
* **compiler:** add representation of placeholders to xliff & xmb ([b3085e9](https://github.com/angular/angular/commit/b3085e9)), closes [#17345](https://github.com/angular/angular/issues/17345)
|
||||
* **compiler:** allow multiple exportAs names ([#18723](https://github.com/angular/angular/issues/18723)) ([7ec28fe](https://github.com/angular/angular/commit/7ec28fe))
|
||||
* **compiler:** deprecate i18n comments in favor of `ng-container` ([#18998](https://github.com/angular/angular/issues/18998)) ([66a5dab](https://github.com/angular/angular/commit/66a5dab))
|
||||
* **compiler:** enabled strict checking of parameters to an `@Injectable` ([#19412](https://github.com/angular/angular/issues/19412)) ([dfb8d21](https://github.com/angular/angular/commit/dfb8d21))
|
||||
* **compiler:** make `.ngsummary.json` files portable ([2572bf5](https://github.com/angular/angular/commit/2572bf5))
|
||||
* **compiler:** reuse the TypeScript typecheck for template typechecking. ([#19152](https://github.com/angular/angular/issues/19152)) ([996c7c2](https://github.com/angular/angular/commit/996c7c2))
|
||||
@ -44,6 +32,7 @@
|
||||
* **forms:** add updateOn blur option to FormControls ([#18408](https://github.com/angular/angular/issues/18408)) ([333a708](https://github.com/angular/angular/commit/333a708)), closes [#7113](https://github.com/angular/angular/issues/7113)
|
||||
* **forms:** add updateOn submit option to FormControls ([#18514](https://github.com/angular/angular/issues/18514)) ([f69561b](https://github.com/angular/angular/commit/f69561b))
|
||||
* **forms:** add updateOn support to ngModelOptions ([1cfa79c](https://github.com/angular/angular/commit/1cfa79c))
|
||||
* **http**: deprecate @angular/http in favor of @angular/common/http ([#18906](https://github.com/angular/angular/issues/18906)) ([72c7b6e](https://github.com/angular/angular/commit/72c7b6e))
|
||||
* **platform-server:** add an API to transfer state from server ([#19134](https://github.com/angular/angular/issues/19134)) ([cfd9ca0](https://github.com/angular/angular/commit/cfd9ca0))
|
||||
* **platform-server:** provide a DOM implementation on the server ([2f2d5f3](https://github.com/angular/angular/commit/2f2d5f3)), closes [#14638](https://github.com/angular/angular/issues/14638)
|
||||
* **platform-server:** provide a way to hook into renderModule* ([#19023](https://github.com/angular/angular/issues/19023)) ([8dfc3c3](https://github.com/angular/angular/commit/8dfc3c3))
|
||||
@ -70,15 +59,21 @@
|
||||
* **core:** Remove decorator DSL which depends on Reflect ([cac130e](https://github.com/angular/angular/commit/cac130e))
|
||||
* **core:** add option to remove blank text nodes from compiled templates ([d2c0d98](https://github.com/angular/angular/commit/d2c0d98))
|
||||
* **core:** use native addEventListener for faster rendering. ([#18107](https://github.com/angular/angular/issues/18107)) ([6279e50](https://github.com/angular/angular/commit/6279e50))
|
||||
* **core** switch angular to use StaticInjector instead of ReflectiveInjector ([fcadbf4](https://github.com/angular/angular/commit/fcadbf4)), closes [#18496](https://github.com/angular/angular/issues/18496)
|
||||
* latest tsickle to tree shake: abstract class methods & interfaces ([#18236](https://github.com/angular/angular/issues/18236)) ([b7a6f52](https://github.com/angular/angular/commit/b7a6f52))
|
||||
* switch angular to use StaticInjector instead of ReflectiveInjector ([fcadbf4](https://github.com/angular/angular/commit/fcadbf4)), closes [#18496](https://github.com/angular/angular/issues/18496)
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **compiler**: Angular now requires TypeScript 2.4.x.
|
||||
* **compiler**: split compiler and core. `@angular/platform-server` now additionally depends on `@angular/platform-browser-dynamic` as a peer dependency. ([#18683](https://github.com/angular/angular/issues/18683)) ([0cc77b4](https://github.com/angular/angular/commit/0cc77b4))
|
||||
* `platformXXXX()` no longer accepts providers which depend on reflection. Specifically the method signature went from `Provider[]` to `StaticProvider[]`.
|
||||
* compiler: The method `ngGetContentSelectors()`, deprecated in Angular 4.0, has been removed.
|
||||
Use `ComponentFactory.ngContentSelectors` instead.
|
||||
* - the Angular compiler now requires TypeScript 2.4.x.
|
||||
* router: `RouterOutlet` properties `locationInjector` and `locationFactoryResolver` have been removed as they were deprecated since v4.
|
||||
* compiler: the compiler option `enableLegacyTemplate` is now disabled by default as the `<template>` element has been deprecated since v4. Use `<ng-template>` instead. The option `enableLegacyTemplate` and the `<template>` element will both be removed in Angular v6.
|
||||
* core: `OpaqueToken` has been removed as it was deprecated since v4. Use `InjectionToken` instead.
|
||||
* `platformXXXX()` no longer accepts providers which depend on reflection.
|
||||
Specifically the method signature when from `Provider[]` to
|
||||
`StaticProvider[]`.
|
||||
|
||||
Example:
|
||||
Before:
|
||||
@ -183,27 +178,59 @@ Because of multiple bugs and browser inconsistencies, we have dropped the intl a
|
||||
|
||||
|
||||
### Deprecated code
|
||||
* **compiler**: The method `ngGetContentSelectors()` has been removed as it was deprecated since v4. Use `ComponentFactory.ngContentSelectors` instead.
|
||||
* **compiler**: the compiler option `enableLegacyTemplate` is now disabled by default as the `<template>` element was deprecated since v4. Use `<ng-template>` instead. The option `enableLegacyTemplate` and the `<template>` element will both be removed in Angular v6.
|
||||
* **compiler**: the option `useDebug` for the compiler has been removed as it had no effect and was deprecated since v4. ([#18778](https://github.com/angular/angular/issues/18778)) ([499d05d](https://github.com/angular/angular/commit/499d05d))
|
||||
* **compiler**: deprecate i18n comments in favor of `ng-container` ([#18998](https://github.com/angular/angular/issues/18998)) ([66a5dab](https://github.com/angular/angular/commit/66a5dab))
|
||||
* **common**: `NgFor` has been removed as it was deprecated since v4. Use `NgForOf` instead. This does not impact the use of `*ngFor` in your templates. ([#18758](https://github.com/angular/angular/issues/18758)) ([ec56760](https://github.com/angular/angular/commit/ec56760))
|
||||
* **common**: `NgTemplateOutlet#ngOutletContext` has been removed as it was deprecated since v4. Use `NgTemplateOutlet#ngTemplateOutletContext` instead. ([#18780](https://github.com/angular/angular/issues/18780)) ([7522987](https://github.com/angular/angular/commit/7522987))
|
||||
* **core**: `ErrorHandler` no longer takes a parameter as it was not used and deprecated since v4. ([#18759](https://github.com/angular/angular/issues/18759)) ([8f41326](https://github.com/angular/angular/commit/8f41326))
|
||||
* **core**: `ReflectiveInjector` is now deprecated. Use `Injector.create` as a replacement.
|
||||
* **core**: `Testability#findBindings` has been removed as it was deprecated since v4. Use `Testability#findProviders` instead. ([#18782](https://github.com/angular/angular/issues/18782)) ([f2a2a6b](https://github.com/angular/angular/commit/f2a2a6b))
|
||||
* **core**: `DebugNode#source` has been removed as it was deprecated since v4. ([#18779](https://github.com/angular/angular/issues/18779)) ([d61b902](https://github.com/angular/angular/commit/d61b902))
|
||||
* **core**: `OpaqueToken` has been removed as it was deprecated since v4. Use `InjectionToken` instead. ([#18971](https://github.com/angular/angular/issues/18971)) ([3c4eef8](https://github.com/angular/angular/commit/3c4eef8))
|
||||
* **core**: `DifferFactory.create` no longer takes ChangeDetectionRef as a first argument as it was not used and deprecated since v4. ([#18757](https://github.com/angular/angular/issues/18757)) ([be9713c](https://github.com/angular/angular/commit/be9713c))
|
||||
* **core**: `TrackByFn` has been removed because it was deprecated since v4. Use `TrackByFunction` instead. ([#18757](https://github.com/angular/angular/issues/18757)) ([596e9f4](https://github.com/angular/angular/commit/596e9f4))
|
||||
* **http**: deprecate @angular/http in favor of @angular/common/http ([#18906](https://github.com/angular/angular/issues/18906)) ([72c7b6e](https://github.com/angular/angular/commit/72c7b6e))
|
||||
* **router**: `RouterOutlet` properties `locationInjector` and `locationFactoryResolver` have been removed as they were deprecated since v4. ([#18781](https://github.com/angular/angular/issues/18781)) ([d1c4a94](https://github.com/angular/angular/commit/d1c4a94), [a9ef858](https://github.com/angular/angular/commit/a9ef858))
|
||||
* **router**: the values `true`, `false`, `legacy_enabled` and `legacy_disabled` for the router parameter `initialNavigation` have been removed as they were deprecated. Use `enabled` or `disabled` instead. ([#18781](https://github.com/angular/angular/issues/18781)) ([d76761b](https://github.com/angular/angular/commit/d76761b))
|
||||
* **platform-browser**: `NgProbeToken` has been removed from `@angular/platform-browser` as it was deprecated since v4. Import it from `@angular/core` instead. ([#18760](https://github.com/angular/angular/issues/18760)) ([d7f42bf](https://github.com/angular/angular/commit/d7f42bf))
|
||||
* **platform-webworker**: `PRIMITIVE` has been removed as it was deprecated since v4. Use `SerializerTypes.PRIMITIVE` instead. ([#18761](https://github.com/angular/angular/issues/18761)) ([a56468c](https://github.com/angular/angular/commit/a56468c))
|
||||
* router: `RouterOutlet` properties `locationInjector` and `locationFactoryResolver` have been removed as they were deprecated since v4.
|
||||
* common: `NgFor` has been removed as it was deprecated since v4. Use `NgForOf` instead. This does not impact the use of`*ngFor` in your templates.
|
||||
* common: `NgTemplateOutlet#ngOutletContext` has been removed as it was deprecated since v4. Use `NgTemplateOutlet#ngTemplateOutletContext` instead.
|
||||
* core: `Testability#findBindings` has been removed as it was deprecated since v4. Use `Testability#findProviders` instead.
|
||||
* core: `DebugNode#source` has been removed as it was deprecated since v4.
|
||||
* router: the values `true`, `false`, `legacy_enabled` and `legacy_disabled` for the router parameter `initialNavigation` have been removed as they were deprecated. Use `enabled` or `disabled` instead.
|
||||
* core: `DifferFactory.create` no longer takes ChangeDetectionRef as a first argument as it was not used and deprecated since v4.
|
||||
* core: `TrackByFn` has been removed because it was deprecated since v4. Use `TrackByFunction` instead.
|
||||
* platform-webworker: `PRIMITIVE` has been removed as it was deprecated since v4. Use `SerializerTypes.PRIMITIVE` instead.
|
||||
* platform-browser: `NgProbeToken` has been removed from `@angular/platform-browser` as it was deprecated since v4. Import it from `@angular/core` instead.
|
||||
* core: `ErrorHandler` no longer takes a parameter as it was not used and deprecated since v4.
|
||||
* compiler: the option `useDebug` for the compiler has been removed as it had no effect and was deprecated since v4.
|
||||
* common: remove deprecated `NgFor` ([#18758](https://github.com/angular/angular/issues/18758)) ([ec56760](https://github.com/angular/angular/commit/ec56760))
|
||||
* common: remove deprecated `NgTemplateOutlet#ngOutletContext` ([#18780](https://github.com/angular/angular/issues/18780)) ([7522987](https://github.com/angular/angular/commit/7522987))
|
||||
* compiler: remove option `useDebug` ([#18778](https://github.com/angular/angular/issues/18778)) ([499d05d](https://github.com/angular/angular/commit/499d05d))
|
||||
* compiler: split compiler and core ([#18683](https://github.com/angular/angular/issues/18683)) ([0cc77b4](https://github.com/angular/angular/commit/0cc77b4))
|
||||
* compiler: - `@angular/platform-server` now additionally depends on
|
||||
`@angular/platform-browser-dynamic` as a peer dependency.
|
||||
* core: remove deprecated `ChangeDetectionRef` argument in `DifferFactory#create` ([#18757](https://github.com/angular/angular/issues/18757)) ([be9713c](https://github.com/angular/angular/commit/be9713c))
|
||||
* core: remove deprecated `DebugNode#source` ([#18779](https://github.com/angular/angular/issues/18779)) ([d61b902](https://github.com/angular/angular/commit/d61b902))
|
||||
* core: remove deprecated `OpaqueToken` ([#18971](https://github.com/angular/angular/issues/18971)) ([3c4eef8](https://github.com/angular/angular/commit/3c4eef8))
|
||||
* core: remove deprecated `Testability#findBindings` ([#18782](https://github.com/angular/angular/issues/18782)) ([f2a2a6b](https://github.com/angular/angular/commit/f2a2a6b))
|
||||
* core: remove deprecated `TrackByFn` ([#18757](https://github.com/angular/angular/issues/18757)) ([596e9f4](https://github.com/angular/angular/commit/596e9f4))
|
||||
* core: remove deprecated parameter for `ErrorHandler` ([#18759](https://github.com/angular/angular/issues/18759)) ([8f41326](https://github.com/angular/angular/commit/8f41326))
|
||||
* platform-browser: remove deprecated `NgProbeToken` ([#18760](https://github.com/angular/angular/issues/18760)) ([d7f42bf](https://github.com/angular/angular/commit/d7f42bf))
|
||||
* platform-webworker: remove deprecated `PRIMITIVE` ([#18761](https://github.com/angular/angular/issues/18761)) ([a56468c](https://github.com/angular/angular/commit/a56468c))
|
||||
* router: remove deprecated `RouterOutlet` properties ([#18781](https://github.com/angular/angular/issues/18781)) ([d1c4a94](https://github.com/angular/angular/commit/d1c4a94))
|
||||
* router: remove deprecated `RouterOutlet` properties ([a9ef858](https://github.com/angular/angular/commit/a9ef858))
|
||||
* router: remove deprecated `initialNavigation` options ([#18781](https://github.com/angular/angular/issues/18781)) ([d76761b](https://github.com/angular/angular/commit/d76761b))
|
||||
- `ReflectiveInjector` is now deprecated as it will be remove. Use `Injector.create` as a replacement.
|
||||
|
||||
|
||||
|
||||
<a name="4.3.1"></a>
|
||||
## [4.3.1](https://github.com/angular/angular/compare/4.3.0...4.3.1) (2017-07-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** always camelcase style property names that contain auto styles ([383d896](https://github.com/angular/angular/commit/383d896)), closes [#17938](https://github.com/angular/angular/issues/17938)
|
||||
* **animations:** capture cancelled animation styles within grouped animations ([333ffd8](https://github.com/angular/angular/commit/333ffd8)), closes [#17170](https://github.com/angular/angular/issues/17170)
|
||||
* **animations:** do not crash animations if a nested component fires CD during CD ([4c1f32b](https://github.com/angular/angular/commit/4c1f32b)), closes [#18193](https://github.com/angular/angular/issues/18193)
|
||||
* **animations:** make sure @.disabled works in non-animation components ([a5c4bb5](https://github.com/angular/angular/commit/a5c4bb5))
|
||||
* **common:** send flushed body as error instead of null ([17b7bc3](https://github.com/angular/angular/commit/17b7bc3)), closes [#18181](https://github.com/angular/angular/issues/18181)
|
||||
* **compiler:** ensure jit external id arguments names are unique ([4671168](https://github.com/angular/angular/commit/4671168))
|
||||
* **compiler-cli:** don't generate empty `<target/>` when extracting xliff ([f0476fc](https://github.com/angular/angular/commit/f0476fc)), closes [#15754](https://github.com/angular/angular/issues/15754)
|
||||
* **platform-server:** provide XhrFactory for HttpClient ([4ce29f3](https://github.com/angular/angular/commit/4ce29f3))
|
||||
* **router:** canDeactivate guards should run from bottom to top ([1ac78bf](https://github.com/angular/angular/commit/1ac78bf)), closes [#15657](https://github.com/angular/angular/issues/15657)
|
||||
* **router:** should navigate to the same url when config changes ([4340bea](https://github.com/angular/angular/commit/4340bea)), closes [#15535](https://github.com/angular/angular/issues/15535)
|
||||
* **router:** should run resolvers for the same route concurrently ([ec89f37](https://github.com/angular/angular/commit/ec89f37)), closes [#14279](https://github.com/angular/angular/issues/14279)
|
||||
* **router:** terminal route in custom matcher ([5d275e9](https://github.com/angular/angular/commit/5d275e9))
|
||||
|
||||
|
||||
<a name="4.4.6"></a>
|
||||
## [4.4.6](https://github.com/angular/angular/compare/4.4.5...4.4.6) (2017-10-18)
|
||||
|
||||
|
@ -211,6 +211,7 @@ The following is the list of supported scopes:
|
||||
* **compiler**
|
||||
* **compiler-cli**
|
||||
* **core**
|
||||
* **elements**
|
||||
* **forms**
|
||||
* **http**
|
||||
* **language-service**
|
||||
|
27
aio/content/examples/aot-compiler/e2e-spec.ts
Normal file
27
aio/content/examples/aot-compiler/e2e-spec.ts
Normal file
@ -0,0 +1,27 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
/* tslint:disable:quotemark */
|
||||
describe('AOT Compilation', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should load page and click button', function (done: any) {
|
||||
let headingSelector = element.all(by.css('h1')).get(0);
|
||||
expect(headingSelector.getText()).toEqual('Hello Angular');
|
||||
|
||||
expect(element.all(by.xpath('//div[text()="Magneta"]')).get(0).isPresent()).toBe(true);
|
||||
expect(element.all(by.xpath('//div[text()="Bombasto"]')).get(0).isPresent()).toBe(true);
|
||||
expect(element.all(by.xpath('//div[text()="Magma"]')).get(0).isPresent()).toBe(true);
|
||||
expect(element.all(by.xpath('//div[text()="Tornado"]')).get(0).isPresent()).toBe(true);
|
||||
|
||||
let toggleButton = element.all(by.css('button')).get(0);
|
||||
toggleButton.click().then(function() {
|
||||
expect(headingSelector.isPresent()).toBe(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
4
aio/content/examples/aot-compiler/example-config.json
Normal file
4
aio/content/examples/aot-compiler/example-config.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"build": "build:aot",
|
||||
"projectType": "systemjs"
|
||||
}
|
33
aio/content/examples/aot-compiler/rollup-config.js
Normal file
33
aio/content/examples/aot-compiler/rollup-config.js
Normal file
@ -0,0 +1,33 @@
|
||||
// #docregion
|
||||
import nodeResolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import uglify from 'rollup-plugin-uglify';
|
||||
|
||||
// #docregion config
|
||||
export default {
|
||||
entry: 'src/main.js',
|
||||
dest: 'src/build.js', // output a single application bundle
|
||||
sourceMap: true,
|
||||
format: 'iife',
|
||||
onwarn: function(warning) {
|
||||
// Skip certain warnings
|
||||
|
||||
// should intercept ... but doesn't in some rollup versions
|
||||
if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }
|
||||
|
||||
// console.warn everything else
|
||||
console.warn( warning.message );
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve({jsnext: true, module: true}),
|
||||
// #docregion commonjs
|
||||
commonjs({
|
||||
include: 'node_modules/rxjs/**',
|
||||
}),
|
||||
// #enddocregion commonjs
|
||||
// #docregion uglify
|
||||
uglify()
|
||||
// #enddocregion uglify
|
||||
]
|
||||
};
|
||||
// #enddocregion config
|
@ -0,0 +1,7 @@
|
||||
<!-- #docregion -->
|
||||
<button (click)="toggleHeading()">Toggle Heading</button>
|
||||
<h1 *ngIf="showHeading">Hello Angular</h1>
|
||||
|
||||
<h3>List of Heroes</h3>
|
||||
<div *ngFor="let hero of heroes">{{hero}}</div>
|
||||
|
15
aio/content/examples/aot-compiler/src/app/app.component.ts
Normal file
15
aio/content/examples/aot-compiler/src/app/app.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
templateUrl: './app.component.html'
|
||||
})
|
||||
export class AppComponent {
|
||||
showHeading = true;
|
||||
heroes = ['Magneta', 'Bombasto', 'Magma', 'Tornado'];
|
||||
|
||||
toggleHeading() {
|
||||
this.showHeading = !this.showHeading;
|
||||
}
|
||||
}
|
12
aio/content/examples/aot-compiler/src/app/app.module.ts
Normal file
12
aio/content/examples/aot-compiler/src/app/app.module.ts
Normal file
@ -0,0 +1,12 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ AppComponent ],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
24
aio/content/examples/aot-compiler/src/index-jit.html
Normal file
24
aio/content/examples/aot-compiler/src/index-jit.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Ahead of time compilation (JIT)</title>
|
||||
<base href="/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<!-- #docregion jit -->
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
<script src="systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('main-jit.js').catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
<!-- #enddocregion jit -->
|
||||
</head>
|
||||
<body>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
</html>
|
20
aio/content/examples/aot-compiler/src/index.html
Normal file
20
aio/content/examples/aot-compiler/src/index.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Ahead of time compilation</title>
|
||||
<base href="/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
<!-- #docregion bundle -->
|
||||
<script src="build.js"></script>
|
||||
<!-- #enddocregion bundle -->
|
||||
</html>
|
6
aio/content/examples/aot-compiler/src/main-jit.ts
Normal file
6
aio/content/examples/aot-compiler/src/main-jit.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// #docregion
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
console.log('Running JIT compiled');
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
6
aio/content/examples/aot-compiler/src/main.ts
Normal file
6
aio/content/examples/aot-compiler/src/main.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// #docregion
|
||||
import { platformBrowser } from '@angular/platform-browser';
|
||||
import { AppModuleNgFactory } from './app/app.module.ngfactory';
|
||||
|
||||
console.log('Running AOT compiled');
|
||||
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
|
27
aio/content/examples/aot-compiler/tsconfig-aot.json
Normal file
27
aio/content/examples/aot-compiler/tsconfig-aot.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": ["es2015", "dom"],
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"typeRoots": [
|
||||
"./node_modules/@types/"
|
||||
]
|
||||
},
|
||||
|
||||
"files": [
|
||||
"src/app/app.module.ts",
|
||||
"src/main.ts"
|
||||
],
|
||||
|
||||
"angularCompilerOptions": {
|
||||
"annotationsAs": "decorators",
|
||||
"genDir": ".",
|
||||
"skipMetadataEmit" : true
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ describe('Component Style Tests', function () {
|
||||
let externalH1 = element(by.css('body > h1'));
|
||||
|
||||
// Note: sometimes webdriver returns the fontWeight as "normal",
|
||||
// other times as "400", both of which are equal in CSS terms.
|
||||
// othertimes as "400", both of which are equal in CSS terms.
|
||||
expect(componentH1.getCssValue('fontWeight')).toMatch(/normal|400/);
|
||||
expect(externalH1.getCssValue('fontWeight')).not.toMatch(/normal|400/);
|
||||
});
|
||||
|
@ -4,8 +4,7 @@
|
||||
"files": [
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.native.*",
|
||||
"!**/*.[1].*"
|
||||
"!**/*.native.*"
|
||||
],
|
||||
"tags": ["CSS"]
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
h1 {
|
||||
font-weight: normal;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import { Component, HostBinding } from '@angular/core';
|
||||
import { Hero } from './hero';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<h1>Tour of Heroes</h1>
|
||||
<app-hero-main [hero]="hero"></app-hero-main>
|
||||
`,
|
||||
styleUrls: ['./hero-app.component.css']
|
||||
})
|
||||
export class HeroAppComponent {
|
||||
// #enddocregion
|
||||
hero = new Hero(
|
||||
'Human Torch',
|
||||
['Mister Fantastic', 'Invisible Woman', 'Thing']
|
||||
);
|
||||
|
||||
@HostBinding('class') get themeClass() {
|
||||
return 'theme-light';
|
||||
}
|
||||
// #docregion
|
||||
}
|
||||
// #enddocregion
|
@ -6,8 +6,7 @@ import { Hero } from './hero';
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<h1>Tour of Heroes</h1>
|
||||
<app-hero-main [hero]="hero"></app-hero-main>
|
||||
`,
|
||||
<app-hero-main [hero]=hero></app-hero-main>`,
|
||||
styles: ['h1 { font-weight: normal; }']
|
||||
})
|
||||
export class HeroAppComponent {
|
||||
|
15
aio/content/examples/deployment/src/app/app.component.ts
Normal file
15
aio/content/examples/deployment/src/app/app.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: `
|
||||
<h1>Simple Deployment</h1>
|
||||
<nav>
|
||||
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
|
||||
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`
|
||||
})
|
||||
export class AppComponent { }
|
29
aio/content/examples/deployment/src/app/app.module.ts
Normal file
29
aio/content/examples/deployment/src/app/app.module.ts
Normal file
@ -0,0 +1,29 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { CrisisListComponent } from './crisis-list.component';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{ path: 'crisis-center', component: CrisisListComponent },
|
||||
{ path: 'heroes', component: HeroListComponent },
|
||||
|
||||
{ path: '', redirectTo: '/heroes', pathMatch: 'full' }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
RouterModule.forRoot(appRoutes)
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
CrisisListComponent,
|
||||
HeroListComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
@ -0,0 +1,9 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>CRISIS CENTER</h2>
|
||||
<p>Get your crisis here</p>`
|
||||
})
|
||||
export class CrisisListComponent { }
|
@ -0,0 +1,10 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>HEROES</h2>
|
||||
<p>Get your heroes here</p>
|
||||
`
|
||||
})
|
||||
export class HeroListComponent { }
|
38
aio/content/examples/deployment/src/index.html
Normal file
38
aio/content/examples/deployment/src/index.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Doesn't load from node_modules! -->
|
||||
|
||||
<!-- Set the base href -->
|
||||
<base href="/">
|
||||
<title>Simple Deployment</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<!-- #docregion node-module-scripts -->
|
||||
<!-- Polyfills -->
|
||||
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
|
||||
|
||||
<!-- Update these package versions as needed -->
|
||||
<script src="https://unpkg.com/zone.js@0.8.4?main=browser"></script>
|
||||
<script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>
|
||||
<!-- #enddocregion node-module-scripts -->
|
||||
|
||||
<!-- #docregion systemjs-config -->
|
||||
<!-- This SystemJS configuration loads umd packages from the web -->
|
||||
<script src="systemjs.config.server.js"></script>
|
||||
<!-- #enddocregion systemjs-config -->
|
||||
|
||||
<script>
|
||||
System.import('main.js')
|
||||
.catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<my-app></my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,12 +1,15 @@
|
||||
// #docregion
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
// #docregion enableProdMode
|
||||
import { enableProdMode } from '@angular/core';
|
||||
|
||||
// Enable production mode unless running locally
|
||||
if (!/localhost/.test(document.location.host)) {
|
||||
enableProdMode();
|
||||
}
|
||||
// #enddocregion enableProdMode
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
@ -0,0 +1,46 @@
|
||||
// #docregion
|
||||
/**
|
||||
* System configuration for deployment without installing node_modules
|
||||
* Loads umd packages from the web instead
|
||||
* Adjust as necessary for your application needs.
|
||||
*/
|
||||
(function (global) {
|
||||
System.config({
|
||||
// #docregion paths
|
||||
paths: {
|
||||
'npm:': 'https://unpkg.com/' // path serves as alias
|
||||
},
|
||||
// #enddocregion paths
|
||||
// map tells the System loader where to look for things
|
||||
map: {
|
||||
app: 'app', // location of transpiled app files
|
||||
|
||||
// angular minimized umd bundles
|
||||
'@angular/core': 'npm:@angular/core/bundles/core.umd.min.js',
|
||||
'@angular/common': 'npm:@angular/common/bundles/common.umd.min.js',
|
||||
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.min.js',
|
||||
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.min.js',
|
||||
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js',
|
||||
'@angular/http': 'npm:@angular/http/bundles/http.umd.min.js',
|
||||
'@angular/router': 'npm:@angular/router/bundles/router.umd.min.js',
|
||||
'@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.min.js',
|
||||
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.min.js',
|
||||
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.min.js',
|
||||
'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.min.js',
|
||||
|
||||
// other libraries
|
||||
'rxjs': 'npm:rxjs@5.0.1',
|
||||
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
|
||||
},
|
||||
// packages tells the System loader how to load when no filename and/or no extension
|
||||
packages: {
|
||||
app: {
|
||||
main: './main.js',
|
||||
defaultExtension: 'js'
|
||||
},
|
||||
rxjs: {
|
||||
defaultExtension: 'js'
|
||||
}
|
||||
}
|
||||
});
|
||||
})(this);
|
@ -1,7 +0,0 @@
|
||||
// #docregion import-locale-extra
|
||||
import { registerLocaleData } from '@angular/common';
|
||||
import localeFrCa from '@angular/common/locales/fr-CA';
|
||||
import localeFrCaExtra from '@angular/common/locales/extra/fr-CA';
|
||||
|
||||
registerLocaleData(localeFrCa, localeFrCaExtra);
|
||||
// #enddocregion import-locale-extra
|
@ -1,13 +0,0 @@
|
||||
// #docregion
|
||||
import { LOCALE_ID, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from '../src/app/app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ AppComponent ],
|
||||
providers: [ { provide: LOCALE_ID, useValue: 'fr' } ],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
@ -1,22 +0,0 @@
|
||||
// #docregion
|
||||
import { enableProdMode, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
// use the require method provided by webpack
|
||||
declare const require;
|
||||
// we use the webpack raw-loader to return the content as a string
|
||||
const translations = require(`raw-loader!./locale/messages.fr.xlf`);
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule, {
|
||||
providers: [
|
||||
{provide: TRANSLATIONS, useValue: translations},
|
||||
{provide: TRANSLATIONS_FORMAT, useValue: 'xlf'}
|
||||
]
|
||||
});
|
@ -1,13 +0,0 @@
|
||||
// #docregion
|
||||
import { MissingTranslationStrategy } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
// ...
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule, {
|
||||
missingTranslation: MissingTranslationStrategy.Error,
|
||||
providers: [
|
||||
// ...
|
||||
]
|
||||
});
|
@ -1,73 +0,0 @@
|
||||
<!-- The `messages.fr.xlf` after translation for documentation purposes -->
|
||||
<!-- #docregion -->
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<!-- #docregion translated-hello-before -->
|
||||
<trans-unit id="introductionHeader" datatype="html">
|
||||
<source>Hello i18n!</source>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
<note priority="1" from="meaning">User welcome</note>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translated-hello-before -->
|
||||
<!-- #docregion translated-hello -->
|
||||
<!-- #docregion custom-id -->
|
||||
<trans-unit id="introductionHeader" datatype="html">
|
||||
<!-- #enddocregion custom-id -->
|
||||
<source>Hello i18n!</source>
|
||||
<target>Bonjour i18n !</target>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
<note priority="1" from="meaning">User welcome</note>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translated-hello -->
|
||||
<!-- #docregion translated-other-nodes -->
|
||||
<!-- #docregion generated-id -->
|
||||
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
|
||||
<!-- #enddocregion generated-id -->
|
||||
<source>I don't output any element</source>
|
||||
<target>Je n'affiche aucun élément</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
|
||||
<source>Angular logo</source>
|
||||
<target>Logo d'Angular</target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translated-other-nodes -->
|
||||
<!-- #docregion translated-plural -->
|
||||
<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
|
||||
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
|
||||
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translated-plural -->
|
||||
<!-- #docregion translated-select -->
|
||||
<!-- #docregion translate-select-1 -->
|
||||
<trans-unit id="52515023fc70c216ef291086c1962ff135a9fe13" datatype="html">
|
||||
<source>The author is <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></source>
|
||||
<target>L'auteur est <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translate-select-1 -->
|
||||
<!-- #docregion translate-select-2 -->
|
||||
<trans-unit id="4e6fd3f2bb3477e8ad2088f03257f6e1b8b515a5" datatype="html">
|
||||
<source>{VAR_SELECT, select, m {male} f {female} o {other} }</source>
|
||||
<target>{VAR_SELECT, select, m {un homme} f {une femme} o {autre} }</target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translate-select-2 -->
|
||||
<!-- #enddocregion translated-select -->
|
||||
<!-- #docregion translate-nested -->
|
||||
<!-- #docregion translate-nested-1 -->
|
||||
<trans-unit id="f7a55c9ef7c5b37147825a9041263305063e63e9" datatype="html">
|
||||
<source>Updated: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></source>
|
||||
<target>Mis à jour: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translate-nested-1 -->
|
||||
<!-- #docregion translate-nested-2 -->
|
||||
<trans-unit id="80b5ac44661751e191225c0b1e000bceeeccb52c" datatype="html">
|
||||
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago by {VAR_SELECT, select, m {male} f {female} o {other} }} }</source>
|
||||
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes par {VAR_SELECT, select, m {un homme} f {une femme} o {autre} }} }</target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translate-nested-2 -->
|
||||
<!-- #enddocregion translate-nested -->
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
36
aio/content/examples/i18n/e2e-spec.ts
Normal file
36
aio/content/examples/i18n/e2e-spec.ts
Normal file
@ -0,0 +1,36 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('i18n E2E Tests', () => {
|
||||
|
||||
beforeEach(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should display i18n translated welcome: ¡Hola i18n!', function () {
|
||||
expect(element(by.css('h1')).getText()).toEqual('¡Hola i18n!');
|
||||
});
|
||||
|
||||
it('should display the node texts without elements', function () {
|
||||
expect(element(by.css('my-app')).getText()).toContain('No genero ningún elemento');
|
||||
});
|
||||
|
||||
it('should display the translated title attribute', function () {
|
||||
const title = element(by.css('img')).getAttribute('title');
|
||||
expect(title).toBe('Logo de Angular');
|
||||
});
|
||||
|
||||
it('should display the plural of: a horde of wolves', function () {
|
||||
expect(element.all(by.css('span')).get(0).getText()).toBe('ningún lobo');
|
||||
});
|
||||
|
||||
it('should display the select of gender', function () {
|
||||
expect(element.all(by.css('span')).get(1).getText()).toBe('El heroe es mujer');
|
||||
});
|
||||
|
||||
it('should display the nested expression', function() {
|
||||
expect(element.all(by.css('span')).get(2).getText()).toBe('Aquí tenemos: 3 mujeres');
|
||||
});
|
||||
|
||||
});
|
@ -1,45 +0,0 @@
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('i18n E2E Tests', () => {
|
||||
|
||||
beforeEach(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should display i18n translated welcome: Bonjour !', function () {
|
||||
expect(element(by.css('h1')).getText()).toEqual('Bonjour i18n !');
|
||||
});
|
||||
|
||||
it('should display the node texts without elements', function () {
|
||||
expect(element(by.css('app-root')).getText()).toContain(`Je n'affiche aucun élément`);
|
||||
});
|
||||
|
||||
it('should display the translated title attribute', function () {
|
||||
const title = element(by.css('img')).getAttribute('title');
|
||||
expect(title).toBe(`Logo d'Angular`);
|
||||
});
|
||||
|
||||
it('should display the ICU plural expression', function () {
|
||||
expect(element.all(by.css('span')).get(0).getText()).toBe(`Mis à jour à l'instant`);
|
||||
});
|
||||
|
||||
it('should display the ICU select expression', function () {
|
||||
const selectIcuExp = element.all(by.css('span')).get(1);
|
||||
expect(selectIcuExp.getText()).toBe(`L'auteur est une femme`);
|
||||
element.all(by.css('button')).get(2).click();
|
||||
expect(selectIcuExp.getText()).toBe(`L'auteur est un homme`);
|
||||
});
|
||||
|
||||
it('should display the nested expression', function() {
|
||||
const nestedExp = element.all(by.css('span')).get(2);
|
||||
const incBtn = element.all(by.css('button')).get(0);
|
||||
expect(nestedExp.getText()).toBe(`Mis à jour: à l'instant`);
|
||||
incBtn.click();
|
||||
expect(nestedExp.getText()).toBe(`Mis à jour: il y a une minute`);
|
||||
incBtn.click();
|
||||
incBtn.click();
|
||||
element.all(by.css('button')).get(4).click();
|
||||
expect(nestedExp.getText()).toBe(`Mis à jour: il y a 3 minutes par autre`);
|
||||
});
|
||||
|
||||
});
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"projectType": "i18n"
|
||||
}
|
||||
|
43
aio/content/examples/i18n/messages.xlf
Normal file
43
aio/content/examples/i18n/messages.xlf
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<trans-unit id="introductionHeader" datatype="html">
|
||||
<source>
|
||||
Hello i18n!
|
||||
</source>
|
||||
<target/>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
<note priority="1" from="meaning">User welcome</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
|
||||
<source>I don't output any element</source>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
|
||||
<source>Angular logo</source>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
<trans-unit id="6e22e74e8cbd3095560cfe08993c4fdfa3c50eb0" datatype="html">
|
||||
<source/>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
<trans-unit id="61cafedb85466ab789b3ae817bba1a545468ee1c" datatype="html">
|
||||
<source>The hero is <x id="ICU"/></source>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
<trans-unit id="14c7055d67771a3b7b6888d282ac092896be06b6" datatype="html">
|
||||
<source/>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
|
||||
<source>Here we have: <x id="ICU"/></source>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
|
||||
<source/>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
19
aio/content/examples/i18n/plnkr.json
Normal file
19
aio/content/examples/i18n/plnkr.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"description": "i18n",
|
||||
"basePath": "src/",
|
||||
"files": [
|
||||
"app/**/*.css",
|
||||
"app/**/*.html",
|
||||
"app/**/*.ts",
|
||||
"messages.xlf",
|
||||
"locale/messages.*.xlf",
|
||||
|
||||
"!**/*.[1].*",
|
||||
|
||||
"main.ts",
|
||||
"styles.css",
|
||||
"systemjs-text-plugin.js",
|
||||
"index.html"
|
||||
],
|
||||
"tags": ["i18n"]
|
||||
}
|
@ -29,3 +29,4 @@
|
||||
<!--#docregion i18n-title-->
|
||||
<img [src]="logo" title="Angular logo">
|
||||
<!--#enddocregion i18n-title-->
|
||||
Contact GitHub API Training Shop Blog About
|
@ -17,19 +17,19 @@
|
||||
<br>
|
||||
<button (click)="inc(1)">+</button> <button (click)="inc(-1)">-</button>
|
||||
<!--#docregion i18n-plural-->
|
||||
<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>
|
||||
<span i18n>{wolves, plural, =0 {no wolves} =1 {one wolf} =2 {two wolves} other {a wolf pack}}</span>
|
||||
<!--#enddocregion i18n-plural-->
|
||||
({{minutes}})
|
||||
({{wolves}})
|
||||
<br><br>
|
||||
<button (click)="male()">♂</button> <button (click)="female()">♀</button> <button (click)="other()">⚧</button>
|
||||
<button (click)="male()">♂</button> <button (click)="female()">♀</button>
|
||||
<!--#docregion i18n-select-->
|
||||
<span i18n>The author is {gender, select, m {male} f {female} o {other}}</span>
|
||||
<span i18n>The hero is {gender, select, m {male} f {female}}</span>
|
||||
<!--#enddocregion i18n-select-->
|
||||
<br><br>
|
||||
<!--#docregion i18n-nested-->
|
||||
<span i18n>Updated: {minutes, plural,
|
||||
=0 {just now}
|
||||
=1 {one minute ago}
|
||||
other {{{minutes}} minutes ago by {gender, select, m {male} f {female} o {other}}}}
|
||||
</span>
|
||||
<span i18n>Here we have: {count, plural,
|
||||
=0 {no one}
|
||||
=1 {one {gender, select, male {man} female {woman}}}
|
||||
other {{{heroes.length}} {gender, select, male {men} female {women}}}
|
||||
}</span>
|
||||
<!--#enddocregion i18n-nested-->
|
||||
|
@ -2,20 +2,20 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
selector: 'my-app',
|
||||
templateUrl: './app.component.html'
|
||||
})
|
||||
export class AppComponent {
|
||||
minutes = 0;
|
||||
wolves = 0;
|
||||
gender = 'f';
|
||||
fly = true;
|
||||
logo = 'https://angular.io/assets/images/logos/angular/angular.png';
|
||||
count = 3;
|
||||
heroes: string[] = ['Magneta', 'Celeritas', 'Dynama'];
|
||||
inc(i: number) {
|
||||
this.minutes = Math.min(5, Math.max(0, this.minutes + i));
|
||||
this.wolves = Math.min(5, Math.max(0, this.wolves + i));
|
||||
}
|
||||
male() { this.gender = 'm'; }
|
||||
male() { this.gender = 'm'; }
|
||||
female() { this.gender = 'f'; }
|
||||
other() { this.gender = 'o'; }
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
// #docregion import-locale-extra
|
||||
import { registerLocaleData } from '@angular/common';
|
||||
import localeEnGB from '@angular/common/locales/en-GB';
|
||||
import localeEnGBExtra from '@angular/common/locales/extra/en-GB';
|
||||
|
||||
registerLocaleData(localeEnGB, localeEnGBExtra);
|
||||
// #enddocregion import-locale-extra
|
@ -1,12 +1,13 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ AppComponent ],
|
||||
bootstrap: [ AppComponent ]
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
|
||||
export class AppModule { }
|
||||
|
41
aio/content/examples/i18n/src/app/i18n-providers.ts
Normal file
41
aio/content/examples/i18n/src/app/i18n-providers.ts
Normal file
@ -0,0 +1,41 @@
|
||||
// #docplaster
|
||||
// #docregion without-missing-translation
|
||||
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, MissingTranslationStrategy, StaticProvider } from '@angular/core';
|
||||
import { CompilerConfig } from '@angular/compiler';
|
||||
|
||||
export function getTranslationProviders(): Promise<StaticProvider[]> {
|
||||
|
||||
// Get the locale id from the global
|
||||
const locale = document['locale'] as string;
|
||||
|
||||
// return no providers if fail to get translation file for locale
|
||||
const noProviders: StaticProvider[] = [];
|
||||
|
||||
// No locale or U.S. English: no translation providers
|
||||
if (!locale || locale === 'en-US') {
|
||||
return Promise.resolve(noProviders);
|
||||
}
|
||||
|
||||
// Ex: 'locale/messages.es.xlf`
|
||||
const translationFile = `./locale/messages.${locale}.xlf`;
|
||||
|
||||
// #docregion missing-translation
|
||||
return getTranslationsWithSystemJs(translationFile)
|
||||
.then( (translations: string ) => [
|
||||
{ provide: TRANSLATIONS, useValue: translations },
|
||||
{ provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
|
||||
{ provide: LOCALE_ID, useValue: locale },
|
||||
// #enddocregion without-missing-translation
|
||||
{ provide: CompilerConfig, useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error }) }
|
||||
// #docregion without-missing-translation
|
||||
])
|
||||
.catch(() => noProviders); // ignore if file not found
|
||||
// #enddocregion missing-translation
|
||||
}
|
||||
|
||||
declare var System: any;
|
||||
|
||||
function getTranslationsWithSystemJs(file: string) {
|
||||
return System.import(file + '!text'); // relies on text plugin
|
||||
}
|
||||
// #enddocregion without-missing-translation
|
@ -1,14 +1,39 @@
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<!-- #docregion -->
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Angular i18n example</title>
|
||||
<base href="/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<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>
|
||||
|
||||
<!-- #docregion i18n -->
|
||||
<script>
|
||||
// Get the locale id somehow
|
||||
document.locale = 'es';
|
||||
|
||||
// Map to the text plugin
|
||||
System.config({
|
||||
map: {
|
||||
text: 'systemjs-text-plugin.js'
|
||||
}
|
||||
});
|
||||
|
||||
// Launch the app
|
||||
System.import('main.js').catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
<!-- #enddocregion i18n -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root>Loading...</app-root>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
</html>
|
||||
<!-- #enddocregion -->
|
||||
|
47
aio/content/examples/i18n/src/locale/messages.es.xlf
Normal file
47
aio/content/examples/i18n/src/locale/messages.es.xlf
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<trans-unit id="introductionHeader" datatype="html">
|
||||
<source>Hello i18n!</source>
|
||||
<target>¡Hola i18n!</target>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
<note priority="1" from="meaning">User welcome</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
|
||||
<source>I don't output any element</source>
|
||||
<target>No genero ningún elemento</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
|
||||
<source>Angular logo</source>
|
||||
<target>Logo de Angular</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="6e22e74e8cbd3095560cfe08993c4fdfa3c50eb0" datatype="html">
|
||||
<source/>
|
||||
<target>{wolves, plural, =0 {ningún lobo} =1 {un lobo} =2 {dos lobos} other {una horda de lobos}}</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="61cafedb85466ab789b3ae817bba1a545468ee1c" datatype="html">
|
||||
<source>The hero is <x id="ICU"/></source>
|
||||
<target>El heroe es <x id="ICU"/></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="14c7055d67771a3b7b6888d282ac092896be06b6" datatype="html">
|
||||
<source/>
|
||||
<target>{gender, select, m {hombre} f {mujer}}</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
|
||||
<source>Here we have: <x id="ICU"/></source>
|
||||
<target>Aquí tenemos: <x id="ICU"/></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
|
||||
<source/>
|
||||
<target>
|
||||
{count, plural,
|
||||
=0 { nadie }
|
||||
=1 {{gender, select, m {un hombre} f {una mujer}}}
|
||||
other {{{heroes.length}} {gender, select, m {hombres} f {mujeres}}}
|
||||
}
|
||||
</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
80
aio/content/examples/i18n/src/locale/messages.es.xlf.html
Normal file
80
aio/content/examples/i18n/src/locale/messages.es.xlf.html
Normal file
@ -0,0 +1,80 @@
|
||||
<!-- The `messages.es.xlf` after translation for documentation purposes -->
|
||||
<!-- #docregion -->
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<!-- #docregion translated-hello -->
|
||||
<!-- #docregion custom-id -->
|
||||
<trans-unit id="introductionHeader" datatype="html">
|
||||
<!-- #enddocregion custom-id -->
|
||||
<source>Hello i18n!</source>
|
||||
<target>¡Hola i18n!</target>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
<note priority="1" from="meaning">User welcome</note>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translated-hello -->
|
||||
<!-- #docregion translated-other-nodes -->
|
||||
<!-- #docregion generated-id -->
|
||||
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
|
||||
<!-- #enddocregion generated-id -->
|
||||
<source>I don't output any element</source>
|
||||
<target>No genero ningún elemento</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
|
||||
<source>Angular logo</source>
|
||||
<target>Logo de Angular</target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translated-other-nodes -->
|
||||
<!-- #docregion translated-plural -->
|
||||
<trans-unit id="6e22e74e8cbd3095560cfe08993c4fdfa3c50eb0" datatype="html">
|
||||
<source/>
|
||||
<target>{wolves, plural, =0 {ningún lobo} =1 {un lobo} =2 {dos lobos} other {una horda de lobos}}</target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translated-plural -->
|
||||
<!-- #docregion translated-select -->
|
||||
<!-- #docregion translate-select-1 -->
|
||||
<trans-unit id="61cafedb85466ab789b3ae817bba1a545468ee1c" datatype="html">
|
||||
<source>The hero is <x id="ICU"/></source>
|
||||
<target>El heroe es <x id="ICU"/></target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translate-select-1 -->
|
||||
<!-- #docregion translate-select-2 -->
|
||||
<trans-unit id="14c7055d67771a3b7b6888d282ac092896be06b6" datatype="html">
|
||||
<source/>
|
||||
<target>{gender, select, m {hombre} f {mujer}}</target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translate-select-2 -->
|
||||
<!-- #enddocregion translated-select -->
|
||||
<trans-unit id="db04527df562d12c8607eab2b5723ef6e2066ba0" datatype="html">
|
||||
<source>Here we have: <x id="ICU"/></source>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
<trans-unit id="000058be4e6f08b685d1d0a70f9da68067df7379" datatype="html">
|
||||
<source/>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
<!-- #docregion translate-nested -->
|
||||
<!-- #docregion translate-nested-1 -->
|
||||
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
|
||||
<source>Here we have: <x id="ICU"/></source>
|
||||
<target>Aquí tenemos: <x id="ICU"/></target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translate-nested-1 -->
|
||||
<!-- #docregion translate-nested-2 -->
|
||||
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
|
||||
<source/>
|
||||
<target>
|
||||
{count, plural,
|
||||
=0 { nadie }
|
||||
=1 {{gender, select, m {un hombre} f {una mujer}}}
|
||||
other {{{heroes.length}} {gender, select, m {hombres} f {mujeres}}}
|
||||
}
|
||||
</target>
|
||||
</trans-unit>
|
||||
<!-- #enddocregion translate-nested-2 -->
|
||||
<!-- #enddocregion translate-nested -->
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1,87 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<trans-unit id="introductionHeader" datatype="html">
|
||||
<source>
|
||||
Hello i18n!
|
||||
</source>
|
||||
<target>
|
||||
Bonjour i18n !
|
||||
</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">4</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
<note priority="1" from="meaning">User welcome</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
|
||||
<source>I don't output any element</source>
|
||||
<target>Je n'affiche aucun élément</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">10</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
|
||||
<source>Angular logo</source>
|
||||
<target>Logo d'Angular</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d69f6b42305f49332026fef24b40227f02e34594" datatype="html">
|
||||
<source>Updated <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></source>
|
||||
<target>Mis à jour <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">21</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
|
||||
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
|
||||
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">21</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="52515023fc70c216ef291086c1962ff135a9fe13" datatype="html">
|
||||
<source>The author is <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></source>
|
||||
<target>L'auteur est <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">27</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4e6fd3f2bb3477e8ad2088f03257f6e1b8b515a5" datatype="html">
|
||||
<source>{VAR_SELECT, select, m {male} f {female} o {other} }</source>
|
||||
<target>{VAR_SELECT, select, m {un homme} f {une femme} o {autre} }</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">27</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f7a55c9ef7c5b37147825a9041263305063e63e9" datatype="html">
|
||||
<source>Updated: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/>
|
||||
</source>
|
||||
<target>Mis à jour: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/>
|
||||
</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">31</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="80b5ac44661751e191225c0b1e000bceeeccb52c" datatype="html">
|
||||
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago by {VAR_SELECT, select, m {male} f {female} o {other} }} }</source>
|
||||
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes par {VAR_SELECT, select, m {un homme} f {une femme} o {autre} }} }</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">31</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -1,75 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<trans-unit id="introductionHeader" datatype="html">
|
||||
<source>
|
||||
Hello i18n!
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">4</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">An introduction header for this sample</note>
|
||||
<note priority="1" from="meaning">User welcome</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
|
||||
<source>I don't output any element</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">10</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
|
||||
<source>Angular logo</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d69f6b42305f49332026fef24b40227f02e34594" datatype="html">
|
||||
<source>Updated <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">21</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
|
||||
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">21</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="52515023fc70c216ef291086c1962ff135a9fe13" datatype="html">
|
||||
<source>The author is <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">27</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4e6fd3f2bb3477e8ad2088f03257f6e1b8b515a5" datatype="html">
|
||||
<source>{VAR_SELECT, select, m {male} f {female} o {other} }</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">27</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f7a55c9ef7c5b37147825a9041263305063e63e9" datatype="html">
|
||||
<source>Updated: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/>
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">31</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="80b5ac44661751e191225c0b1e000bceeeccb52c" datatype="html">
|
||||
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago by {VAR_SELECT, select, m {male} f {female} o {other} }} }</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">app\app.component.ts</context>
|
||||
<context context-type="linenumber">31</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
6
aio/content/examples/i18n/src/main.1.ts
Normal file
6
aio/content/examples/i18n/src/main.1.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// #docregion
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
@ -1,12 +1,10 @@
|
||||
// #docregion
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { getTranslationProviders } from './app/i18n-providers';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
getTranslationProviders().then(providers => {
|
||||
const options = { providers };
|
||||
platformBrowserDynamic().bootstrapModule(AppModule, options);
|
||||
});
|
||||
|
14
aio/content/examples/i18n/src/systemjs-text-plugin.js
Normal file
14
aio/content/examples/i18n/src/systemjs-text-plugin.js
Normal file
@ -0,0 +1,14 @@
|
||||
// #docregion
|
||||
/*
|
||||
SystemJS Text plugin from
|
||||
https://github.com/systemjs/plugin-text/blob/master/text.js
|
||||
*/
|
||||
exports.translate = function (load) {
|
||||
if (this.builder && this.transpiler) {
|
||||
load.metadata.format = 'esm';
|
||||
return 'exp' + 'ort var __useDefault = true; exp' + 'ort default ' + JSON.stringify(load.source) + ';';
|
||||
}
|
||||
|
||||
load.metadata.format = 'amd';
|
||||
return 'def' + 'ine(function() {\nreturn ' + JSON.stringify(load.source) + ';\n});';
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"files":[
|
||||
"!dist/",
|
||||
"!**/*.d.ts",
|
||||
"!src/**/*.js",
|
||||
"!doc-files/**/*",
|
||||
"**/*.xlf"
|
||||
],
|
||||
"removeSystemJsConfig": true,
|
||||
"type": "i18n"
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Tour of Heroes', () => {
|
||||
beforeEach(() => {
|
||||
return browser.get('/');
|
||||
});
|
||||
|
||||
it('should display "Tour of Heroes"', () => {
|
||||
let title = element(by.css('app-root h1')).getText();
|
||||
expect(title).toEqual('Tour of Heroes');
|
||||
});
|
||||
});
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"description": "Tour of Heroes: Part 0",
|
||||
"basePath": "src/",
|
||||
"files":[
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.[1].*"
|
||||
],
|
||||
"tags": ["tutorial", "tour", "heroes"]
|
||||
}
|
@ -1 +0,0 @@
|
||||
<h1>{{title}}</h1>
|
@ -1,32 +0,0 @@
|
||||
import { TestBed, async } from '@angular/core/testing';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
it('should create the app', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
|
||||
it(`should have as title 'app'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('app');
|
||||
}));
|
||||
|
||||
it('should render title in a h1 tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
|
||||
}));
|
||||
});
|
@ -1,12 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
// #docregion set-title
|
||||
title = 'Tour of Heroes';
|
||||
// #enddocregion set-title
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
@ -1,14 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tour of Heroes</title>
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
44
aio/content/examples/toh-pt1/app/app.component.1.ts
Normal file
44
aio/content/examples/toh-pt1/app/app.component.1.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
let t = {
|
||||
// #docregion show-hero
|
||||
template: `<h1>{{title}}</h1><h2>{{hero}} details!</h2>`
|
||||
// #enddocregion show-hero
|
||||
};
|
||||
|
||||
t = {
|
||||
// #docregion show-hero-2
|
||||
template: `<h1>{{title}}</h1><h2>{{hero.name}} details!</h2>`
|
||||
// #enddocregion show-hero-2
|
||||
};
|
||||
|
||||
t = {
|
||||
// #docregion multi-line-strings
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<h2>{{hero.name}} details!</h2>
|
||||
<div><label>id: </label>{{hero.id}}</div>
|
||||
<div><label>name: </label>{{hero.name}}</div>
|
||||
`
|
||||
// #enddocregion multi-line-strings
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
// #docregion name-input
|
||||
<div>
|
||||
<label>name: </label>
|
||||
<input [(ngModel)]="hero.name" placeholder="name">
|
||||
</div>
|
||||
// #enddocregion name-input
|
||||
*/
|
||||
|
||||
/////////////////
|
||||
|
||||
@Component(t)
|
||||
// #docregion app-component-1
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
hero = 'Windstorm';
|
||||
}
|
||||
// #enddocregion app-component-1
|
@ -4,7 +4,7 @@ import { browser, element, by, ElementFinder } from 'protractor';
|
||||
import { promise } from 'selenium-webdriver';
|
||||
|
||||
const expectedH1 = 'Tour of Heroes';
|
||||
const expectedTitle = `${expectedH1}`;
|
||||
const expectedTitle = `Angular ${expectedH1}`;
|
||||
|
||||
class Hero {
|
||||
id: number;
|
||||
@ -49,7 +49,7 @@ describe('Tutorial part 1', () => {
|
||||
let page = getPageElts();
|
||||
let hero = await Hero.fromDetail(page.heroDetail);
|
||||
expect(hero.id).toEqual(expectedHero.id);
|
||||
expect(hero.name).toEqual(expectedHero.name.toUpperCase());
|
||||
expect(hero.name).toEqual(expectedHero.name);
|
||||
});
|
||||
|
||||
it(`shows updated hero name`, async () => {
|
||||
@ -58,13 +58,13 @@ describe('Tutorial part 1', () => {
|
||||
let hero = await Hero.fromDetail(page.heroDetail);
|
||||
let newName = expectedHero.name + nameSuffix;
|
||||
expect(hero.id).toEqual(expectedHero.id);
|
||||
expect(hero.name).toEqual(newName.toUpperCase());
|
||||
expect(hero.name).toEqual(newName);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function getPageElts() {
|
||||
return {
|
||||
heroDetail: element(by.css('app-root'))
|
||||
heroDetail: element(by.css('my-app'))
|
||||
};
|
||||
}
|
@ -4,8 +4,7 @@
|
||||
"files":[
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.[1].*",
|
||||
"!**/dummy.module.ts"
|
||||
"!**/*.[1].*"
|
||||
],
|
||||
"tags": ["tutorial", "tour", "heroes"]
|
||||
}
|
||||
|
@ -1,2 +0,0 @@
|
||||
<h1>{{title}}</h1>
|
||||
<app-heroes></app-heroes>
|
@ -1,10 +1,33 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion hero-class-1
|
||||
export class Hero {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
// #enddocregion hero-class-1
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
selector: 'my-app',
|
||||
// #docregion editing-Hero
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<h2>{{hero.name}} details!</h2>
|
||||
<div><label>id: </label>{{hero.id}}</div>
|
||||
<div>
|
||||
<label>name: </label>
|
||||
<input [(ngModel)]="hero.name" placeholder="name">
|
||||
</div>
|
||||
`
|
||||
// #enddocregion editing-Hero
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
// #docregion hero-property-1
|
||||
hero: Hero = {
|
||||
id: 1,
|
||||
name: 'Windstorm'
|
||||
};
|
||||
// #enddocregion hero-property-1
|
||||
}
|
||||
|
@ -1,30 +1,18 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
// #docregion formsmodule-js-import
|
||||
import { FormsModule } from '@angular/forms'; // <-- NgModel lives here
|
||||
// #enddocregion formsmodule-js-import
|
||||
import { FormsModule } from '@angular/forms'; // <-- NgModel lives here
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
// #docregion heroes-import
|
||||
import { HeroesComponent } from './heroes/heroes.component';
|
||||
// #enddocregion heroes-import
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
// #docregion declarations
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HeroesComponent
|
||||
],
|
||||
// #enddocregion declarations
|
||||
// #docregion ng-imports
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule
|
||||
FormsModule // <-- import the FormsModule before binding with [(ngModel)]
|
||||
],
|
||||
// #enddocregion ng-imports
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
@ -1,4 +0,0 @@
|
||||
export class Hero {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<!-- #docregion show-hero-1 -->
|
||||
{{hero}}
|
||||
<!-- #enddocregion show-hero-1 -->
|
||||
|
||||
<!-- #docregion show-hero-2 -->
|
||||
<h2>{{ hero.name }} Details</h2>
|
||||
<div><span>id: </span>{{hero.id}}</div>
|
||||
<div><span>name: </span>{{hero.name}}</div>
|
||||
<!-- #enddocregion show-hero-2 -->
|
||||
|
||||
<!-- #docregion name-input -->
|
||||
<div>
|
||||
<label>name:
|
||||
<input [(ngModel)]="hero.name" placeholder="name">
|
||||
</label>
|
||||
</div>
|
||||
<!-- #enddocregion name-input -->
|
@ -1,10 +0,0 @@
|
||||
<!-- #docregion -->
|
||||
<!-- #docregion pipe -->
|
||||
<h2>{{ hero.name | uppercase }} Details</h2>
|
||||
<!-- #enddocregion pipe -->
|
||||
<div><span>id: </span>{{hero.id}}</div>
|
||||
<div>
|
||||
<label>name:
|
||||
<input [(ngModel)]="hero.name" placeholder="name">
|
||||
</label>
|
||||
</div>
|
@ -1,25 +0,0 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HeroesComponent } from './heroes.component';
|
||||
|
||||
describe('HeroesComponent', () => {
|
||||
let component: HeroesComponent;
|
||||
let fixture: ComponentFixture<HeroesComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ HeroesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(HeroesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -1,35 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion, v1
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
// #enddocregion v1
|
||||
import { Hero } from '../hero';
|
||||
// #docregion v1
|
||||
|
||||
@Component({
|
||||
selector: 'app-heroes',
|
||||
templateUrl: './heroes.component.html',
|
||||
styleUrls: ['./heroes.component.css']
|
||||
})
|
||||
export class HeroesComponent implements OnInit {
|
||||
// #enddocregion, v1
|
||||
/*
|
||||
// #docregion add-hero
|
||||
hero = 'Windstorm';
|
||||
// #enddocregion add-hero
|
||||
*/
|
||||
// #docregion
|
||||
// #docregion hero-property-1
|
||||
hero: Hero = {
|
||||
id: 1,
|
||||
name: 'Windstorm'
|
||||
};
|
||||
// #enddocregion hero-property-1
|
||||
// #docregion v1
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
// #enddocregion, v1
|
@ -1,14 +1,13 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tour of Heroes</title>
|
||||
<base href="/">
|
||||
<head>
|
||||
<title>Angular Tour of Heroes</title>
|
||||
<base href="/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
<body>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -4,7 +4,7 @@ import { browser, element, by, ElementFinder } from 'protractor';
|
||||
import { promise } from 'selenium-webdriver';
|
||||
|
||||
const expectedH1 = 'Tour of Heroes';
|
||||
const expectedTitle = `${expectedH1}`;
|
||||
const expectedTitle = `Angular ${expectedH1}`;
|
||||
const expectedH2 = 'My Heroes';
|
||||
const targetHero = { id: 16, name: 'RubberMan' };
|
||||
const nameSuffix = 'X';
|
||||
@ -85,7 +85,7 @@ function selectHeroTests() {
|
||||
let page = getPageElts();
|
||||
let hero = await Hero.fromDetail(page.heroDetail);
|
||||
expect(hero.id).toEqual(targetHero.id);
|
||||
expect(hero.name).toEqual(targetHero.name.toUpperCase());
|
||||
expect(hero.name).toEqual(targetHero.name);
|
||||
});
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ function updateHeroTests() {
|
||||
let hero = await Hero.fromDetail(page.heroDetail);
|
||||
let newName = targetHero.name + nameSuffix;
|
||||
expect(hero.id).toEqual(targetHero.id);
|
||||
expect(hero.name).toEqual(newName.toUpperCase());
|
||||
expect(hero.name).toEqual(newName);
|
||||
});
|
||||
|
||||
it(`shows updated hero name in list`, async () => {
|
||||
@ -126,8 +126,8 @@ function expectHeading(hLevel: number, expectedText: string): void {
|
||||
|
||||
function getPageElts() {
|
||||
return {
|
||||
heroes: element.all(by.css('app-root li')),
|
||||
selected: element(by.css('app-root li.selected')),
|
||||
heroDetail: element(by.css('app-root > div, app-root > app-heroes > div'))
|
||||
heroes: element.all(by.css('my-app li')),
|
||||
selected: element(by.css('my-app li.selected')),
|
||||
heroDetail: element(by.css('my-app > div, my-app > hero-detail > div'))
|
||||
};
|
||||
}
|
69
aio/content/examples/toh-pt2/src/app/app.component.1.html
Normal file
69
aio/content/examples/toh-pt2/src/app/app.component.1.html
Normal file
@ -0,0 +1,69 @@
|
||||
<!-- #docregion ng-for -->
|
||||
<li *ngFor="let hero of heroes">
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
<!-- #enddocregion ng-for -->
|
||||
|
||||
<!-- #docregion heroes-styled -->
|
||||
<h2>My Heroes</h2>
|
||||
<ul class="heroes">
|
||||
<li *ngFor="let hero of heroes">
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
<!-- #enddocregion heroes-styled -->
|
||||
|
||||
<!-- #docregion selectedHero-click -->
|
||||
<li *ngFor="let hero of heroes" (click)="onSelect(hero)">
|
||||
...
|
||||
</li>
|
||||
<!-- #enddocregion selectedHero-click -->
|
||||
|
||||
<!-- #docregion selectedHero-details -->
|
||||
<h2>{{selectedHero.name}} details!</h2>
|
||||
<div><label>id: </label>{{selectedHero.id}}</div>
|
||||
<div>
|
||||
<label>name: </label>
|
||||
<input [(ngModel)]="selectedHero.name" placeholder="name"/>
|
||||
</div>
|
||||
<!-- #enddocregion selectedHero-details -->
|
||||
|
||||
<!-- #docregion ng-if -->
|
||||
<div *ngIf="selectedHero">
|
||||
<h2>{{selectedHero.name}} details!</h2>
|
||||
<div><label>id: </label>{{selectedHero.id}}</div>
|
||||
<div>
|
||||
<label>name: </label>
|
||||
<input [(ngModel)]="selectedHero.name" placeholder="name"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- #enddocregion ng-if -->
|
||||
|
||||
<!-- #docregion hero-array-1 -->
|
||||
heroes = HEROES;
|
||||
<!-- #enddocregion hero-array-1 -->
|
||||
|
||||
<!-- #docregion heroes-template-1 -->
|
||||
<h2>My Heroes</h2>
|
||||
<ul class="heroes">
|
||||
<li>
|
||||
<!-- each hero goes here -->
|
||||
</li>
|
||||
</ul>
|
||||
<!-- #enddocregion heroes-template-1 -->
|
||||
|
||||
<!-- #docregion heroes-ngfor-1 -->
|
||||
<li *ngFor="let hero of heroes">
|
||||
<!-- #enddocregion heroes-ngfor-1 -->
|
||||
|
||||
<!-- #docregion class-selected-1 -->
|
||||
[class.selected]="hero === selectedHero"
|
||||
<!-- #enddocregion class-selected-1 -->
|
||||
|
||||
<!-- #docregion class-selected-2 -->
|
||||
<li *ngFor="let hero of heroes"
|
||||
[class.selected]="hero === selectedHero"
|
||||
(click)="onSelect(hero)">
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
<!-- #enddocregion class-selected-2 -->
|
@ -1,2 +0,0 @@
|
||||
<h1>{{title}}</h1>
|
||||
<app-heroes></app-heroes>
|
@ -1,10 +1,109 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
export class Hero {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
// #docregion hero-array
|
||||
const HEROES: Hero[] = [
|
||||
{ id: 11, name: 'Mr. Nice' },
|
||||
{ id: 12, name: 'Narco' },
|
||||
{ id: 13, name: 'Bombasto' },
|
||||
{ id: 14, name: 'Celeritas' },
|
||||
{ id: 15, name: 'Magneta' },
|
||||
{ id: 16, name: 'RubberMan' },
|
||||
{ id: 17, name: 'Dynama' },
|
||||
{ id: 18, name: 'Dr IQ' },
|
||||
{ id: 19, name: 'Magma' },
|
||||
{ id: 20, name: 'Tornado' }
|
||||
];
|
||||
// #enddocregion hero-array
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
selector: 'my-app',
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<h2>My Heroes</h2>
|
||||
<ul class="heroes">
|
||||
<li *ngFor="let hero of heroes"
|
||||
[class.selected]="hero === selectedHero"
|
||||
(click)="onSelect(hero)">
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
<div *ngIf="selectedHero">
|
||||
<h2>{{selectedHero.name}} details!</h2>
|
||||
<div><label>id: </label>{{selectedHero.id}}</div>
|
||||
<div>
|
||||
<label>name: </label>
|
||||
<input [(ngModel)]="selectedHero.name" placeholder="name"/>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
// #docregion styles
|
||||
styles: [`
|
||||
.selected {
|
||||
background-color: #CFD8DC !important;
|
||||
color: white;
|
||||
}
|
||||
.heroes {
|
||||
margin: 0 0 2em 0;
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
width: 15em;
|
||||
}
|
||||
.heroes li {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
left: 0;
|
||||
background-color: #EEE;
|
||||
margin: .5em;
|
||||
padding: .3em 0;
|
||||
height: 1.6em;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.heroes li.selected:hover {
|
||||
background-color: #BBD8DC !important;
|
||||
color: white;
|
||||
}
|
||||
.heroes li:hover {
|
||||
color: #607D8B;
|
||||
background-color: #DDD;
|
||||
left: .1em;
|
||||
}
|
||||
.heroes .text {
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
.heroes .badge {
|
||||
display: inline-block;
|
||||
font-size: small;
|
||||
color: white;
|
||||
padding: 0.8em 0.7em 0 0.7em;
|
||||
background-color: #607D8B;
|
||||
line-height: 1em;
|
||||
position: relative;
|
||||
left: -1px;
|
||||
top: -4px;
|
||||
height: 1.8em;
|
||||
margin-right: .8em;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
`]
|
||||
// #enddocregion styles
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
heroes = HEROES;
|
||||
// #docregion selected-hero
|
||||
selectedHero: Hero;
|
||||
// #enddocregion selected-hero
|
||||
|
||||
// #docregion on-select
|
||||
onSelect(hero: Hero): void {
|
||||
this.selectedHero = hero;
|
||||
}
|
||||
// #enddocregion on-select
|
||||
}
|
||||
|
@ -1,20 +1,18 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { HeroesComponent } from './heroes/heroes.component';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HeroesComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
@ -1,4 +0,0 @@
|
||||
export class Hero {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<!-- #docregion list -->
|
||||
<h2>My Heroes</h2>
|
||||
<ul class="heroes">
|
||||
<li>
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
<!-- #enddocregion list -->
|
||||
|
||||
<!-- #docregion li -->
|
||||
<li *ngFor="let hero of heroes">
|
||||
<!-- #enddocregion li -->
|
||||
|
||||
<!-- #docregion selectedHero-click -->
|
||||
<li *ngFor="let hero of heroes" (click)="onSelect(hero)">
|
||||
<!-- #enddocregion selectedHero-click -->
|
||||
|
||||
<!-- #docregion class-selected -->
|
||||
[class.selected]="hero === selectedHero"
|
||||
<!-- #enddocregion class-selected -->
|
@ -1,27 +0,0 @@
|
||||
<!-- #docregion -->
|
||||
<h2>My Heroes</h2>
|
||||
<ul class="heroes">
|
||||
<!-- #docregion li -->
|
||||
<li *ngFor="let hero of heroes"
|
||||
[class.selected]="hero === selectedHero"
|
||||
(click)="onSelect(hero)">
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
<!-- #enddocregion li -->
|
||||
</ul>
|
||||
|
||||
<!-- #docregion ng-if -->
|
||||
<div *ngIf="selectedHero">
|
||||
|
||||
<!-- #docregion selectedHero-details -->
|
||||
<h2>{{ selectedHero.name | uppercase }} Details</h2>
|
||||
<div><span>id: </span>{{selectedHero.id}}</div>
|
||||
<div>
|
||||
<label>name:
|
||||
<input [(ngModel)]="selectedHero.name" placeholder="name">
|
||||
</label>
|
||||
</div>
|
||||
<!-- #enddocregion selectedHero-details -->
|
||||
|
||||
</div>
|
||||
<!-- #enddocregion ng-if -->
|
@ -1,25 +0,0 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HeroesComponent } from './heroes.component';
|
||||
|
||||
describe('HeroesComponent', () => {
|
||||
let component: HeroesComponent;
|
||||
let fixture: ComponentFixture<HeroesComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ HeroesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(HeroesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -1,36 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Hero } from '../hero';
|
||||
// #docregion import-heroes
|
||||
import { HEROES } from '../mock-heroes';
|
||||
// #enddocregion import-heroes
|
||||
|
||||
// #docplaster
|
||||
// #docregion metadata
|
||||
@Component({
|
||||
selector: 'app-heroes',
|
||||
templateUrl: './heroes.component.html',
|
||||
styleUrls: ['./heroes.component.css']
|
||||
})
|
||||
// #enddocregion metadata
|
||||
export class HeroesComponent implements OnInit {
|
||||
|
||||
// #docregion heroes
|
||||
heroes = HEROES;
|
||||
// #enddocregion heroes
|
||||
|
||||
// #docregion on-select
|
||||
selectedHero: Hero;
|
||||
|
||||
// #enddocregion on-select
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
// #docregion on-select
|
||||
onSelect(hero: Hero): void {
|
||||
this.selectedHero = hero;
|
||||
}
|
||||
// #enddocregion on-select
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { Hero } from './hero';
|
||||
|
||||
export const HEROES: Hero[] = [
|
||||
{ id: 11, name: 'Mr. Nice' },
|
||||
{ id: 12, name: 'Narco' },
|
||||
{ id: 13, name: 'Bombasto' },
|
||||
{ id: 14, name: 'Celeritas' },
|
||||
{ id: 15, name: 'Magneta' },
|
||||
{ id: 16, name: 'RubberMan' },
|
||||
{ id: 17, name: 'Dynama' },
|
||||
{ id: 18, name: 'Dr IQ' },
|
||||
{ id: 19, name: 'Magma' },
|
||||
{ id: 20, name: 'Tornado' }
|
||||
];
|
@ -1,14 +1,13 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tour of Heroes</title>
|
||||
<base href="/">
|
||||
<head>
|
||||
<title>Angular Tour of Heroes</title>
|
||||
<base href="/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
<body>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<h1>{{title}}</h1>
|
||||
<h2>My Heroes</h2>
|
||||
|
||||
<ul class="heroes">
|
||||
<li *ngFor="let hero of heroes"
|
||||
[class.selected]="hero === selectedHero"
|
||||
@ -7,7 +7,6 @@
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- #docregion hero-detail-binding -->
|
||||
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
|
||||
<hero-detail [hero]="selectedHero"></hero-detail>
|
||||
<!-- #enddocregion hero-detail-binding -->
|
35
aio/content/examples/toh-pt3/app/hero-detail.component.1.ts
Normal file
35
aio/content/examples/toh-pt3/app/hero-detail.component.1.ts
Normal file
@ -0,0 +1,35 @@
|
||||
// #docplaster
|
||||
// #docregion v1
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #enddocregion v1
|
||||
// #docregion hero-import
|
||||
import { Hero } from './hero';
|
||||
// #enddocregion hero-import
|
||||
|
||||
// #docregion v1
|
||||
@Component({
|
||||
selector: 'hero-detail',
|
||||
// #enddocregion v1
|
||||
// #docregion template
|
||||
template: `
|
||||
<div *ngIf="hero">
|
||||
<h2>{{hero.name}} details!</h2>
|
||||
<div><label>id: </label>{{hero.id}}</div>
|
||||
<div>
|
||||
<label>name: </label>
|
||||
<input [(ngModel)]="hero.name" placeholder="name"/>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
// #enddocregion template
|
||||
// #docregion v1
|
||||
})
|
||||
export class HeroDetailComponent {
|
||||
// #enddocregion v1
|
||||
// #docregion hero
|
||||
hero: Hero;
|
||||
// #enddocregion hero
|
||||
// #docregion v1
|
||||
}
|
||||
// #enddocregion v1
|
@ -4,7 +4,7 @@ import { browser, element, by, ElementFinder } from 'protractor';
|
||||
import { promise } from 'selenium-webdriver';
|
||||
|
||||
const expectedH1 = 'Tour of Heroes';
|
||||
const expectedTitle = `${expectedH1}`;
|
||||
const expectedTitle = `Angular ${expectedH1}`;
|
||||
const expectedH2 = 'My Heroes';
|
||||
const targetHero = { id: 16, name: 'RubberMan' };
|
||||
const nameSuffix = 'X';
|
||||
@ -85,7 +85,7 @@ function selectHeroTests() {
|
||||
let page = getPageElts();
|
||||
let hero = await Hero.fromDetail(page.heroDetail);
|
||||
expect(hero.id).toEqual(targetHero.id);
|
||||
expect(hero.name).toEqual(targetHero.name.toUpperCase());
|
||||
expect(hero.name).toEqual(targetHero.name);
|
||||
});
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ function updateHeroTests() {
|
||||
let hero = await Hero.fromDetail(page.heroDetail);
|
||||
let newName = targetHero.name + nameSuffix;
|
||||
expect(hero.id).toEqual(targetHero.id);
|
||||
expect(hero.name).toEqual(newName.toUpperCase());
|
||||
expect(hero.name).toEqual(newName);
|
||||
});
|
||||
|
||||
it(`shows updated hero name in list`, async () => {
|
||||
@ -126,8 +126,8 @@ function expectHeading(hLevel: number, expectedText: string): void {
|
||||
|
||||
function getPageElts() {
|
||||
return {
|
||||
heroes: element.all(by.css('app-root li')),
|
||||
selected: element(by.css('app-root li.selected')),
|
||||
heroDetail: element(by.css('app-root > div, app-root > app-heroes > app-hero-detail > div'))
|
||||
heroes: element.all(by.css('my-app li')),
|
||||
selected: element(by.css('my-app li.selected')),
|
||||
heroDetail: element(by.css('my-app > div, my-app > hero-detail > div'))
|
||||
};
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
<h1>{{title}}</h1>
|
||||
<app-heroes></app-heroes>
|
@ -1,10 +1,95 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion hero-import
|
||||
import { Hero } from './hero';
|
||||
// #enddocregion hero-import
|
||||
|
||||
const HEROES: Hero[] = [
|
||||
{ id: 11, name: 'Mr. Nice' },
|
||||
{ id: 12, name: 'Narco' },
|
||||
{ id: 13, name: 'Bombasto' },
|
||||
{ id: 14, name: 'Celeritas' },
|
||||
{ id: 15, name: 'Magneta' },
|
||||
{ id: 16, name: 'RubberMan' },
|
||||
{ id: 17, name: 'Dynama' },
|
||||
{ id: 18, name: 'Dr IQ' },
|
||||
{ id: 19, name: 'Magma' },
|
||||
{ id: 20, name: 'Tornado' }
|
||||
];
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
selector: 'my-app',
|
||||
// #docregion hero-detail-template
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<h2>My Heroes</h2>
|
||||
<ul class="heroes">
|
||||
<li *ngFor="let hero of heroes"
|
||||
[class.selected]="hero === selectedHero"
|
||||
(click)="onSelect(hero)">
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
<hero-detail [hero]="selectedHero"></hero-detail>
|
||||
`,
|
||||
// #enddocregion hero-detail-template
|
||||
styles: [`
|
||||
.selected {
|
||||
background-color: #CFD8DC !important;
|
||||
color: white;
|
||||
}
|
||||
.heroes {
|
||||
margin: 0 0 2em 0;
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
width: 15em;
|
||||
}
|
||||
.heroes li {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
left: 0;
|
||||
background-color: #EEE;
|
||||
margin: .5em;
|
||||
padding: .3em 0;
|
||||
height: 1.6em;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.heroes li.selected:hover {
|
||||
background-color: #BBD8DC !important;
|
||||
color: white;
|
||||
}
|
||||
.heroes li:hover {
|
||||
color: #607D8B;
|
||||
background-color: #DDD;
|
||||
left: .1em;
|
||||
}
|
||||
.heroes .text {
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
.heroes .badge {
|
||||
display: inline-block;
|
||||
font-size: small;
|
||||
color: white;
|
||||
padding: 0.8em 0.7em 0 0.7em;
|
||||
background-color: #607D8B;
|
||||
line-height: 1em;
|
||||
position: relative;
|
||||
left: -1px;
|
||||
top: -4px;
|
||||
height: 1.8em;
|
||||
margin-right: .8em;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
`]
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
heroes = HEROES;
|
||||
selectedHero: Hero;
|
||||
|
||||
onSelect(hero: Hero): void {
|
||||
this.selectedHero = hero;
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,24 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { HeroesComponent } from './heroes/heroes.component';
|
||||
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
|
||||
import { AppComponent } from './app.component';
|
||||
// #docregion hero-detail-import
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
// #enddocregion hero-detail-import
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HeroesComponent,
|
||||
HeroDetailComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
// #docregion declarations
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HeroDetailComponent
|
||||
],
|
||||
// #enddocregion declarations
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
@ -0,0 +1,29 @@
|
||||
// #docregion
|
||||
// #docregion import-input
|
||||
import { Component, Input } from '@angular/core';
|
||||
// #enddocregion import-input
|
||||
|
||||
import { Hero } from './hero';
|
||||
// #docregion template
|
||||
@Component({
|
||||
selector: 'hero-detail',
|
||||
template: `
|
||||
<div *ngIf="hero">
|
||||
<h2>{{hero.name}} details!</h2>
|
||||
<div><label>id: </label>{{hero.id}}</div>
|
||||
<div>
|
||||
<label>name: </label>
|
||||
<input [(ngModel)]="hero.name" placeholder="name"/>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
// #enddocregion template
|
||||
// #docregion class
|
||||
export class HeroDetailComponent {
|
||||
// #docregion hero
|
||||
@Input() hero: Hero;
|
||||
// #enddocregion hero
|
||||
}
|
||||
// #enddocregion class
|
||||
|
@ -1,11 +0,0 @@
|
||||
<div *ngIf="hero">
|
||||
|
||||
<h2>{{ hero.name | uppercase }} Details</h2>
|
||||
<div><span>id: </span>{{hero.id}}</div>
|
||||
<div>
|
||||
<label>name:
|
||||
<input [(ngModel)]="hero.name" placeholder="name"/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
@ -1,24 +0,0 @@
|
||||
// #docregion
|
||||
// #docregion import-input
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
// #enddocregion import-input
|
||||
// #docregion import-hero
|
||||
import { Hero } from '../hero';
|
||||
// #enddocregion import-hero
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-detail',
|
||||
templateUrl: './hero-detail.component.html',
|
||||
styleUrls: ['./hero-detail.component.css']
|
||||
})
|
||||
export class HeroDetailComponent implements OnInit {
|
||||
// #docregion input-hero
|
||||
@Input() hero: Hero;
|
||||
// #enddocregion input-hero
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user