docs(upgrade): Use NgUpgrade static (#2781)
* re-enable upgrade-adapter and upgrade-phonecat-1 tests * re-enable upgrade-phonecat-2 tests * add hybrid toggle switch to helpers * use 2.2.0-rc.0 * revert change to browser.ignoreSynchronization * convert 1-2-hybrid-bootstrap to upgrade/static * remove shared adapter example * add systemjs config extras to all indexes * update upgrade-static * update upgrade-io example * update downgrade-static * update downgrade-io * update 1-to-2-projection * update 2-to-1-transclusion * update 1-to-2-providers * update 2-to-1-providers * cleanup upgrade-adapter e2e test * re-enable upgrade-adapter tests * change HeroDetailComponent to HeroDetailDirective * fix missing systemjs.config.extras * add typing to UpgradeModule DI * update upgrade-phonecat-2-hybrid * update upgrade-adapter's prose * rename upgrade-adapter example to upgrade-module * improve angular1 type declaration in hybrid apps * remove unused imports in protractor-helpers * update phonecat-hybrid bootstrap prose * update phonecat-hybrid service and components * update phonecat-final prose * update e2e prose * update systemjs.config.js to have @angular/upgrade/static by default * add aot (WIP) * remove wip aot changes from test run * change let to const in bootstrap * elaborate upgraded component alert * use 2.2.0 versions instead of rc0 * Squashed commit of the following: commit 17c7e154672dbf5feeeb971ed3b594d318703748 Author: Filipe Silva <filipematossilva@gmail.com> Date: Mon Nov 14 23:11:37 2016 +0000 chore: update to 2.2.0 (#2797) commit 1e5facfb980b85313d51559b3272950f662ce20c Merge: 5c4cc9a db0fac9 Author: Ward Bell <wardbell@hotmail.com> Date: Mon Nov 14 12:44:51 2016 -0800 Merge pull request #2799 from IdeaBlade/docs-changelog-2.2.0 chore(changelog): update docs changelog for Ng v.2.2.0 commit 5c4cc9a3c8b2718b71ab7c3d1b5dd02bfdd5f1fc Merge: 43457e9 1afe5dc Author: Ward Bell <wardbell@hotmail.com> Date: Mon Nov 14 12:43:09 2016 -0800 docs(router): Updated usage of observables in router tutorial and developer guide (#2696) Moved route configuration into separate variable for consistency Added async pipe to handle subscriptions for list items commit 43457e9765c63b3889ab449959fe295327390315 Merge: a423a5a 2649647 Author: Jesús Rodríguez <Foxandxss@gmail.com> Date: Mon Nov 14 21:38:49 2016 +0100 chore: add upgrade/static to API reference (#2755) commit 1afe5dc97d457e045adb6c0e03d27023aa97eea5 Author: Brandon Roberts <robertsbt@gmail.com> Date: Sat Oct 29 16:08:54 2016 -0500 docs(router): Updated usage of observables in router tutorial and developer guide Moved route configuration into separate variable for consistency Added async pipe to handle subscriptions for list items commit db0fac94c980c99d9575a90d4b6bb15f572f9161 Author: Ward Bell <wardbell@hotmail.com> Date: Mon Nov 14 10:48:09 2016 -0800 chore(changelog): update docs changelog for Ng v.2.2.0 commit a423a5abc704280794b6dea69cf1c9e76bbc9da1 Author: ikilled <ikilled@users.noreply.github.com> Date: Mon Nov 14 18:39:46 2016 +0000 clicking on Books & Training sends user to Education (#2701) When user clicks in Books & Training item in footer the website should take them to Education section (anchor) in the middle of the page, not to the top where Development section is. commit d63b1ccea36f4cf52333c846184b8e6876284a0a Merge: f627706 8508140 Author: Ward Bell <wardbell@hotmail.com> Date: Mon Nov 14 10:35:48 2016 -0800 docs(router): fixed verbiage about router-outlet (#2746) commit f627706779c418ca8357aacd52aba5b5b7d05cb0 Author: Ward Bell <wardbell@hotmail.com> Date: Mon Nov 14 10:26:13 2016 -0800 docs(cookbook-aot-compiler): improve Ahead-of-Time compilation cookbook (#2798) closes #2790 commit 75464d585cac944e3cffb4401663e4c1185b7cb5 Merge: 78e2584 02f5559 Author: Ward Bell <wardbell@hotmail.com> Date: Mon Nov 14 09:34:36 2016 -0800 Merge pull request #2794 from IdeaBlade/chalin-guide-misc-fix-1113 docs: guide/index misc Jade fixes commit 78e25840b229b0fe345feacf786f34e62b2cb963 Merge: 182493f 85062c4 Author: Ward Bell <wardbell@hotmail.com> Date: Mon Nov 14 09:33:55 2016 -0800 Merge pull request #2795 from IdeaBlade/chalin-util-js-getExampleName-1114 chore(util.js): getExampleName - support optional .html suffix commit 182493f8779fa37422dd942813fc5681dbdac55f Merge: 9e9666b 53f5538 Author: Ward Bell <wardbell@hotmail.com> Date: Mon Nov 14 09:28:40 2016 -0800 feat(cb-ts-to-js): add es6 examples (#2606) * feat(cb-ts-to-js): add es6 examples update docshredder to shred .es6 optimized focus gulp task convert imports and metadate sections add DI section add host and query metadata section add intro fix capitalization and grammar * docs(ts-to-js): ward's edits (incomplete) * docs(ts-to-js): add separate template files for some components * docs(cb-ts-to-js): refactor sample code commit 53f5538859c4d243552d288872e8c8fc8156f446 Author: Ward Bell <wardbell@hotmail.com> Date: Sun Nov 13 14:09:28 2016 -0800 docs(cb-ts-to-js): refactor sample code commit 9e9666b2cc3ce57cac172894e935f0c6b9f7d6f4 Author: Patrice Chalin <chalin@users.noreply.github.com> Date: Mon Nov 14 08:34:10 2016 -0800 docs(template-syntax/dart): updates to match TS (#2751) * docs(template-syntax): refresh _cache * docs(template-syntax/dart): updates to match TS - Propagates TS-side changes: - update #2639 - new two-way binding section, and - fix #2687 - invalid attr syntax - Fixes - #1898 - currency symbols - #2748 - Dart template-syntax e2e is failing - #2749 - deprecated `[className]` * updated _cache file following Kathy's post-review edits * Post Ward's review w/ cache updated - Keep `my-` and `my` prefixes on selectors (for components and directives, respectively). - Drop `my-` from file names. - Drop `My` as component class prefix. commit 5dcffd69dc09b48d99af4acd0dd06b029416e103 Author: Patrice Chalin <pchalin@gmail.com> Date: Sun Nov 13 19:37:13 2016 -0800 docs: dart glossary - fix misnamed Jade block commit 6680acc513a0178bb522f5bc99d66f366542d33c Merge: 14db838 3b03573 Author: Kathy Walrath <kathyw@google.com> Date: Mon Nov 14 08:31:11 2016 -0800 docs(toh): avoid dup header title (#2796) * remove redundant headings * update _cache * misc: make block comment a Jade comment (This prevents the text from appearing in the generated HTML as an HTML comment.) commit 3b03573f340cc7fc43e2642bdf52fb1bae61aff0 Author: Patrice Chalin <pchalin@gmail.com> Date: Mon Nov 14 05:30:05 2016 -0800 misc: make block comment a Jade comment (This prevents the text from appearing in the generated HTML as an HTML comment.) commit 470426d5e03829442449cb59c0528811c6011c37 Author: Patrice Chalin <pchalin@gmail.com> Date: Mon Nov 14 05:25:36 2016 -0800 update _cache commit c12d75a477a1e33ea37886c0bd5942ddb9c955b3 Author: Patrice Chalin <pchalin@gmail.com> Date: Mon Nov 14 05:23:35 2016 -0800 remove redundant headings commit 85062c47cac44d63b06b97ae86b2a4f596889ad6 Author: Patrice Chalin <pchalin@gmail.com> Date: Mon Nov 14 04:56:12 2016 -0800 chore(util.js): getExampleName - support optional .html suffix commit 02f55592b232618407a3a8fce70845589ee78978 Author: Patrice Chalin <pchalin@gmail.com> Date: Mon Nov 14 04:29:17 2016 -0800 docs: guide/index misc Jade fixes - Eliminate use of deprecated `clear=“all”` in `<br>`. - No need for local `langName`; use global `_Lang` var instead. - Remove duplicate id `learning-path`. commit 14db838f8b76309597140d9857acb92c76c864f6 Author: Naomi Black <naomitraveller@gmail.com> Date: Sun Nov 13 21:48:52 2016 -0500 news(nov): Some news and a blog post update commit eff32ecbdd5a52d2240afd5ad4e14bdab21c9a8f Author: Naomi Black <naomitraveller@gmail.com> Date: Sun Nov 13 21:48:37 2016 -0500 chore(bios): update some bios for leads commit 3ee36fbba211d115414d322b17a67626ed90d450 Author: koyner <markburrett@gmail.com> Date: Sun Nov 13 22:59:59 2016 +0100 docs(forms): grammar fix (#2764) commit b11438f211ed7009335bc18f5cbf2950fc4014fa Author: Ward Bell <wardbell@hotmail.com> Date: Fri Nov 11 19:44:00 2016 -0800 docs(ts-to-js): add separate template files for some components commit 33b61977b2cd0bc35b257ce526d5dd2fd460cd10 Author: Ward Bell <wardbell@hotmail.com> Date: Thu Nov 3 01:37:55 2016 -0700 docs(ts-to-js): ward's edits (incomplete) commit 12eb19fa3c34bb48b28da8bd33d94d7cc0526cf5 Author: Filipe Silva <filipematossilva@gmail.com> Date: Thu Oct 13 17:59:00 2016 +0100 feat(cb-ts-to-js): add es6 examples update docshredder to shred .es6 optimized focus gulp task convert imports and metadate sections add DI section add host and query metadata section add intro fix capitalization and grammar commit 64a8754386c0aa727e61d140d86bd31b6891ea99 Author: Patrice Chalin <chalin@users.noreply.github.com> Date: Thu Nov 10 20:01:36 2016 -0800 example(template-syntax): follow style-guide and other updates (#2750) commit 7619cdf4a4ac592d74c25a372234c2d3964355dc Author: Jesús Rodríguez <Foxandxss@gmail.com> Date: Thu Nov 10 23:47:30 2016 +0100 chore: ability to open a plunker on a specific file (#2778) commit 0161d9db39b08be6a29e5a00b362c1eff12bf6b9 Author: Filipe Silva <filipematossilva@gmail.com> Date: Thu Nov 10 22:45:22 2016 +0000 chore: ignore debug.log file (#2785) This file is generated when running `gulp e2e` and often enough committed by mistake. /cc @foxandxss commit f92983cc6f7a895b751a6023791a283bb2e41073 Author: Jesús Rodríguez <Foxandxss@gmail.com> Date: Thu Nov 10 23:44:51 2016 +0100 docs(ngmodule): fix plunkers (#2786) commit 03db4bbc4873d8b68d08ef32bfa1b2b43cf46224 Author: Martin Eckardt <m.eckardt@outlook.com> Date: Wed Nov 9 17:43:40 2016 +0100 docs(a1-a2): fix link to Filter/Pipes (#2770) commit 60565a5cf1dfa7e43cb18b448c7d61c5f765f0de Author: Pavol Pitonak <pavol@pitonak.com> Date: Wed Nov 9 17:42:57 2016 +0100 docs(testing): configureTestModule -> configureTestingModule (#2767) commit ec471974a776dc208b2c56115cf1105fa39c8f88 Author: Catalin Zalog <xxxxxcata@yahoo.com> Date: Wed Nov 9 18:41:56 2016 +0200 docs(style-guide): fix missing *.ts (#2763) commit 234e468d5d6a11782e306901f80546d8989f17b3 Author: Patrice Chalin <pchalin@gmail.com> Date: Tue Nov 8 08:21:02 2016 -0800 docs: intra-site links should be relative Contributes to #2772. commit 6b37da78e4901a57b6ebf77720ec4796f2bb5f5f Author: Patrice Chalin <pchalin@gmail.com> Date: Tue Nov 8 09:27:10 2016 -0800 docs(forms/dart): remove mention of FORM_DIRECTIVES Fixes #2752 commit c24dd074a6acbceb87f8e973969c9bd94f769d8f Author: Patrice Chalin <chalin@users.noreply.github.com> Date: Tue Nov 8 14:48:03 2016 -0800 docs(toh-5/dart): use routerLink in dashboard (#2744) * docs(toh-5/dart): use routerLink in dashboard * minor edits to TS jade * remove dart/toh-pt5 from bad-code-excerpt-skip-patterns commit 2808878c36d7429611e4f0584323e99c9b83219e Author: Patrice Chalin <pchalin@gmail.com> Date: Tue Nov 8 07:41:27 2016 -0800 chore(deploy): don't name project in firebase deploy Naming the project would sometimes cause gulp to report `An unexpected error has occurred` with exit code 2. commit 2649647ecb14a28932405d6b0bc22afd1f931089 Author: Jesus Rodriguez <Foxandxss@gmail.com> Date: Sat Nov 5 00:37:47 2016 +0100 chore: add upgrade/static to API reference commit 850814097f9908781ce954d13878d20eed779c87 Merge: 37f93bc b1c2c27 Author: Adrian Irwin <mr.irwin@gmail.com> Date: Thu Nov 3 17:27:43 2016 -0700 Merge branch 'router' of https://github.com/adrianirwin/angular.io into router commit 37f93bc0cbc2a766846b7715b1d8ddeeec43de39 Author: Adrian Irwin <mr.irwin@gmail.com> Date: Thu Nov 3 17:25:55 2016 -0700 docs(router): fixed verbiage and example of how routed views are related to the router outlet commit b1c2c27d365186d4231a470945a0975482df58e9 Author: Adrian Irwin <adrianirwin@kpmg.com> Date: Thu Nov 3 16:57:56 2016 -0700 docs(router): fixed verbiage and example of how routed views are related to the router outlet * deactivate bugged tests
This commit is contained in:
commit
52f6693f91
1
public/docs/_examples/.gitignore
vendored
1
public/docs/_examples/.gitignore
vendored
@ -17,5 +17,6 @@ _test-output
|
||||
|
||||
!**/*e2e-spec.js
|
||||
!systemjs.config.1.js
|
||||
!**/systemjs.config.extras.js
|
||||
!_boilerplate/*
|
||||
_boilerplate/a2docs.css
|
||||
|
@ -23,6 +23,7 @@
|
||||
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
|
||||
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
|
||||
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
|
||||
'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
|
||||
|
||||
// other libraries
|
||||
'rxjs': 'npm:rxjs',
|
||||
|
@ -50,6 +50,7 @@
|
||||
'@angular/router': 'ng:router-builds/master/bundles/router.umd.js',
|
||||
'@angular/forms': 'ng:forms-builds/master/bundles/forms.umd.js',
|
||||
'@angular/upgrade': 'ng:upgrade-builds/master/bundles/upgrade.umd.js',
|
||||
'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
|
||||
|
||||
// angular testing umd bundles (overwrite the shim mappings)
|
||||
'@angular/core/testing': 'ng:core-builds/master/bundles/core-testing.umd.js',
|
||||
|
@ -47,6 +47,7 @@
|
||||
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
|
||||
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
|
||||
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
|
||||
'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
|
||||
|
||||
// other libraries
|
||||
'rxjs': 'npm:rxjs',
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { browser } from 'protractor';
|
||||
|
||||
export var appLang = {
|
||||
appIsTs: false,
|
||||
appIsJs: false,
|
||||
@ -21,16 +23,13 @@ export function itIf(cond: boolean, name: string, func: (done: DoneFn) => void):
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Jesus - figure out what's needed here for the new upgrade chapters
|
||||
// Allow changing bootstrap mode to NG1 for upgrade tests
|
||||
// protractor.config.js is set to ng2 mode by default, so we must manually
|
||||
// change it for upgradeAdapter tests
|
||||
export function setProtractorToNg1Mode(): void {
|
||||
// browser.rootEl = 'body';
|
||||
|
||||
// let disableNgAnimate = function() {
|
||||
// angular.module('disableNgAnimate', []).run(['$animate', function($animate: any) {
|
||||
// $animate.enabled(false);
|
||||
// }]);
|
||||
// };
|
||||
|
||||
// browser.addMockModule('disableNgAnimate', disableNgAnimate);
|
||||
browser.rootEl = 'body';
|
||||
}
|
||||
|
||||
export function setProtractorToHybridMode() {
|
||||
setProtractorToNg1Mode();
|
||||
browser.ng12Hybrid = true;
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
declare var angular: any;
|
||||
// #docregion ngmodule
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ]
|
||||
})
|
||||
export class AppModule {}
|
||||
// #enddocregion ngmodule
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
||||
});
|
||||
|
||||
|
||||
// #docregion bootstrap
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
|
||||
// #enddocregion bootstrap
|
||||
|
||||
// This blank is expected to trigger the docplaster
|
||||
|
||||
// #docregion bootstrap
|
||||
|
||||
const upgradeAdapter = new UpgradeAdapter(AppModule);
|
||||
|
||||
upgradeAdapter.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
// #enddocregion bootstrap
|
@ -1,16 +0,0 @@
|
||||
// #docregion bootstrap
|
||||
import { upgradeAdapter } from './upgrade_adapter';
|
||||
|
||||
// #enddocregion bootstrap
|
||||
|
||||
declare var angular: any;
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
||||
});
|
||||
|
||||
// #docregion bootstrap
|
||||
|
||||
upgradeAdapter.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
// #enddocregion bootstrap
|
@ -1,16 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
||||
});
|
||||
|
||||
// #docregion
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
export const upgradeAdapter = new UpgradeAdapter(AppModule);
|
@ -1,25 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
|
||||
import { MainController } from './main.controller';
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroDetailComponent ]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
declare var angular: any;
|
||||
const upgradeAdapter = new UpgradeAdapter(AppModule);
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainController', MainController)
|
||||
.directive('heroDetail', upgradeAdapter.downgradeNg2Component(HeroDetailComponent));
|
||||
|
||||
upgradeAdapter.bootstrap(
|
||||
document.querySelector('hero-app'),
|
||||
['heroApp'],
|
||||
{strictDi: true}
|
||||
);
|
@ -1,21 +0,0 @@
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
import { HeroesService } from './heroes.service';
|
||||
import { upgradeAdapter } from './upgrade_adapter';
|
||||
|
||||
declare var angular: any;
|
||||
|
||||
// #docregion register
|
||||
angular.module('heroApp', [])
|
||||
.service('heroes', HeroesService)
|
||||
.directive('heroDetail',
|
||||
upgradeAdapter.downgradeNg2Component(HeroDetailComponent));
|
||||
|
||||
upgradeAdapter.upgradeNg1Provider('heroes');
|
||||
|
||||
// #enddocregion register
|
||||
|
||||
upgradeAdapter.bootstrap(
|
||||
document.querySelector('hero-app'),
|
||||
['heroApp'],
|
||||
{strictDi: true}
|
||||
);
|
@ -1,19 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroDetailComponent ]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
||||
});
|
||||
|
||||
// #docregion
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
export const upgradeAdapter = new UpgradeAdapter(AppModule);
|
@ -1,17 +0,0 @@
|
||||
import { heroDetailComponent } from './hero-detail.component';
|
||||
import { Heroes } from './heroes';
|
||||
import { upgradeAdapter } from './upgrade_adapter';
|
||||
|
||||
declare var angular: any;
|
||||
|
||||
// #docregion register
|
||||
angular.module('heroApp', [])
|
||||
.factory('heroes', upgradeAdapter.downgradeNg2Provider(Heroes))
|
||||
.component('heroDetail', heroDetailComponent);
|
||||
// #enddocregion register
|
||||
|
||||
upgradeAdapter.bootstrap(
|
||||
document.querySelector('hero-app'),
|
||||
['heroApp'],
|
||||
{strictDi: true}
|
||||
);
|
@ -1,19 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
// #docregion ngmodule
|
||||
import { Heroes } from './heroes';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
providers: [ Heroes ]
|
||||
})
|
||||
export class AppModule {}
|
||||
// #enddocregion ngmodule
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
||||
});
|
||||
|
||||
// #docregion
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
export const upgradeAdapter = new UpgradeAdapter(AppModule);
|
@ -1,15 +0,0 @@
|
||||
import { ContainerComponent } from './container.component';
|
||||
import { heroDetailComponent } from './hero-detail.component';
|
||||
import { upgradeAdapter } from './upgrade_adapter';
|
||||
|
||||
declare var angular: any;
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.directive('myContainer', upgradeAdapter.downgradeNg2Component(ContainerComponent))
|
||||
.component('heroDetail', heroDetailComponent);
|
||||
|
||||
upgradeAdapter.bootstrap(
|
||||
document.querySelector('hero-app'),
|
||||
['heroApp'],
|
||||
{strictDi: true}
|
||||
);
|
@ -1,12 +0,0 @@
|
||||
// #docregion
|
||||
export const heroDetailComponent = {
|
||||
bindings: {
|
||||
hero: '='
|
||||
},
|
||||
template: `
|
||||
<h2>{{$ctrl.hero.name}}</h2>
|
||||
<div>
|
||||
<ng-transclude></ng-transclude>
|
||||
</div>
|
||||
`
|
||||
};
|
@ -1,20 +0,0 @@
|
||||
// #docregion
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
import { NgModule, forwardRef } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { ContainerComponent } from './container.component';
|
||||
|
||||
export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule));
|
||||
const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail');
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ ContainerComponent, HeroDetail ]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
||||
});
|
@ -1,33 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { MainController } from './main.controller';
|
||||
// #docregion downgradecomponent
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
// #enddocregion downgradecomponent
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroDetailComponent ]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
|
||||
const upgradeAdapter = new UpgradeAdapter(AppModule);
|
||||
|
||||
// #docregion downgradecomponent
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainController', MainController)
|
||||
.directive('heroDetail', upgradeAdapter.downgradeNg2Component(HeroDetailComponent));
|
||||
|
||||
// #enddocregion downgradecomponent
|
||||
|
||||
upgradeAdapter.bootstrap(
|
||||
document.querySelector('hero-app'),
|
||||
['heroApp'],
|
||||
{strictDi: true}
|
||||
);
|
||||
// #enddocregion bootstrap
|
@ -1,30 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion downgradecomponent, ngmodule
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
// #enddocregion downgradecomponent
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroDetailComponent ]
|
||||
})
|
||||
export class AppModule {}
|
||||
// #enddocregion ngmodule
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
|
||||
const upgradeAdapter = new UpgradeAdapter(AppModule);
|
||||
|
||||
// #docregion downgradecomponent
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.directive('heroDetail', upgradeAdapter.downgradeNg2Component(HeroDetailComponent));
|
||||
|
||||
// #enddocregion downgradecomponent
|
||||
|
||||
upgradeAdapter.bootstrap(
|
||||
document.querySelector('hero-app'),
|
||||
['heroApp'],
|
||||
{strictDi: true}
|
||||
);
|
||||
// #enddocregion bootstrap
|
@ -1,16 +0,0 @@
|
||||
import { heroDetail } from './hero-detail.component';
|
||||
import { ContainerComponent } from './container.component';
|
||||
import { upgradeAdapter } from './upgrade_adapter';
|
||||
|
||||
|
||||
declare var angular: any;
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.component('heroDetail', heroDetail)
|
||||
.directive('myContainer', upgradeAdapter.downgradeNg2Component(ContainerComponent));
|
||||
|
||||
upgradeAdapter.bootstrap(
|
||||
document.querySelector('hero-app'),
|
||||
['heroApp'],
|
||||
{strictDi: true}
|
||||
);
|
@ -1,17 +0,0 @@
|
||||
// #docregion
|
||||
export const heroDetail = {
|
||||
bindings: {
|
||||
hero: '<',
|
||||
deleted: '&'
|
||||
},
|
||||
template: `
|
||||
<h2>{{$ctrl.hero.name}} details!</h2>
|
||||
<div><label>id: </label>{{$ctrl.hero.id}}</div>
|
||||
<button ng-click="$ctrl.onDelete()">Delete</button>
|
||||
`,
|
||||
controller: function() {
|
||||
this.onDelete = () => {
|
||||
this.deleted(this.hero);
|
||||
};
|
||||
}
|
||||
};
|
@ -1,20 +0,0 @@
|
||||
// #docregion
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
import { NgModule, forwardRef } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { ContainerComponent } from './container.component';
|
||||
|
||||
export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule));
|
||||
const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail');
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ ContainerComponent, HeroDetail ]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
||||
});
|
@ -1,16 +0,0 @@
|
||||
import { heroDetail } from './hero-detail.component';
|
||||
import { ContainerComponent } from './container.component';
|
||||
import { upgradeAdapter } from './upgrade_adapter';
|
||||
|
||||
|
||||
declare var angular: any;
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.component('heroDetail', heroDetail)
|
||||
.directive('myContainer', upgradeAdapter.downgradeNg2Component(ContainerComponent));
|
||||
|
||||
upgradeAdapter.bootstrap(
|
||||
document.querySelector('hero-app'),
|
||||
['heroApp'],
|
||||
{strictDi: true}
|
||||
);
|
@ -1,9 +0,0 @@
|
||||
// #docregion
|
||||
export const heroDetail = {
|
||||
template: `
|
||||
<h2>Windstorm details!</h2>
|
||||
<div><label>id: </label>1</div>
|
||||
`,
|
||||
controller: function() {
|
||||
}
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
// #docregion
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
import { NgModule, forwardRef } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { ContainerComponent } from './container.component';
|
||||
|
||||
export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule));
|
||||
|
||||
// #docregion heroupgrade
|
||||
const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail');
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ ContainerComponent, HeroDetail ]
|
||||
})
|
||||
export class AppModule {}
|
||||
// #enddocregion heroupgrade
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
||||
});
|
@ -1,28 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Angular 2 Upgrade</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
|
||||
|
||||
<!-- Polyfills for older browsers -->
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="node_modules/reflect-metadata/Reflect.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
<script src="systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('app/1-2-hybrid-shared-adapter-bootstrap/app.module')
|
||||
.then(null, console.error.bind(console));
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="message" ng-controller="MainCtrl as mainCtrl">{{ mainCtrl.message }}</div>
|
||||
</body>
|
||||
</html>
|
@ -1,24 +1,18 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
import { setProtractorToHybridMode } from '../protractor-helpers';
|
||||
|
||||
describe('Upgrade Tests', function () {
|
||||
|
||||
// Protractor doesn't support the UpgradeAdapter's asynchronous
|
||||
// bootstrap with Angular 1 at the moment. Get around it by
|
||||
// waiting for an element to get `ng-scope` class.
|
||||
function waitForNg1AsyncBootstrap() {
|
||||
browser.ignoreSynchronization = true;
|
||||
browser.driver.wait(function() {
|
||||
return element(by.css('.ng-scope')).isPresent();
|
||||
}, 5000);
|
||||
}
|
||||
beforeAll(function () {
|
||||
setProtractorToHybridMode();
|
||||
});
|
||||
|
||||
describe('NG1 Auto-bootstrap', function() {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-ng-app.html');
|
||||
setProtractorToNg1Mode();
|
||||
});
|
||||
|
||||
it('bootstraps as expected', function () {
|
||||
@ -31,7 +25,6 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-bootstrap.html');
|
||||
setProtractorToNg1Mode();
|
||||
});
|
||||
|
||||
it('bootstraps as expected', function () {
|
||||
@ -44,20 +37,6 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-1-2-hybrid-bootstrap.html');
|
||||
setProtractorToNg1Mode();
|
||||
});
|
||||
|
||||
it('bootstraps as expected', function () {
|
||||
expect(element(by.css('#message')).getText()).toEqual('Hello world');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('NG1-2 Hybrid Bootstrap with Shared UpgradeAdapter', function() {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-1-2-hybrid-shared-adapter-bootstrap.html');
|
||||
setProtractorToNg1Mode();
|
||||
});
|
||||
|
||||
it('bootstraps as expected', function () {
|
||||
@ -70,8 +49,6 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-upgrade-static.html');
|
||||
setProtractorToNg1Mode();
|
||||
waitForNg1AsyncBootstrap();
|
||||
});
|
||||
|
||||
it('renders', function () {
|
||||
@ -85,8 +62,6 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-upgrade-io.html');
|
||||
setProtractorToNg1Mode();
|
||||
waitForNg1AsyncBootstrap();
|
||||
});
|
||||
|
||||
it('has inputs', function () {
|
||||
@ -105,8 +80,6 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-downgrade-static.html');
|
||||
setProtractorToNg1Mode();
|
||||
waitForNg1AsyncBootstrap();
|
||||
});
|
||||
|
||||
it('renders', function () {
|
||||
@ -119,15 +92,13 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-downgrade-io.html');
|
||||
setProtractorToNg1Mode();
|
||||
waitForNg1AsyncBootstrap();
|
||||
});
|
||||
|
||||
it('has inputs', function () {
|
||||
expect(element.all(by.css('h2')).first().getText()).toEqual('Windstorm details!');
|
||||
});
|
||||
|
||||
it('has outputs', function () {
|
||||
xit('has outputs', function () {
|
||||
element.all(by.buttonText('Delete')).first().click();
|
||||
expect(element.all(by.css('h2')).first().getText()).toEqual('Ex-Windstorm details!');
|
||||
});
|
||||
@ -143,8 +114,6 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-1-to-2-projection.html');
|
||||
setProtractorToNg1Mode();
|
||||
waitForNg1AsyncBootstrap();
|
||||
});
|
||||
|
||||
it('can be transcluded into', function () {
|
||||
@ -158,8 +127,6 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-2-to-1-transclusion.html');
|
||||
setProtractorToNg1Mode();
|
||||
waitForNg1AsyncBootstrap();
|
||||
});
|
||||
|
||||
it('can be projected into', function () {
|
||||
@ -173,8 +140,6 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-1-to-2-providers.html');
|
||||
setProtractorToNg1Mode();
|
||||
waitForNg1AsyncBootstrap();
|
||||
});
|
||||
|
||||
it('works', function () {
|
||||
@ -188,8 +153,6 @@ describe('Upgrade Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('/index-2-to-1-providers.html');
|
||||
setProtractorToNg1Mode();
|
||||
waitForNg1AsyncBootstrap();
|
||||
});
|
||||
|
||||
it('works', function () {
|
@ -0,0 +1,29 @@
|
||||
declare var angular: angular.IAngularStatic;
|
||||
// #docregion ngmodule
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeModule } from '@angular/upgrade/static';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
UpgradeModule
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
ngDoBootstrap() {}
|
||||
}
|
||||
// #enddocregion ngmodule
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
||||
});
|
||||
|
||||
// #docregion bootstrap
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
});
|
||||
// #enddocregion bootstrap
|
@ -1,5 +1,3 @@
|
||||
declare var angular: any;
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
@ -1,5 +1,3 @@
|
||||
declare var angular: any;
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainCtrl', function() {
|
||||
this.message = 'Hello world';
|
@ -0,0 +1,36 @@
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { NgModule } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
import { MainController } from './main.controller';
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
UpgradeModule
|
||||
],
|
||||
declarations: [
|
||||
HeroDetailComponent
|
||||
],
|
||||
entryComponents: [
|
||||
HeroDetailComponent
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
ngDoBootstrap() {}
|
||||
}
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainController', MainController)
|
||||
.directive('heroDetail', downgradeComponent({
|
||||
component: HeroDetailComponent,
|
||||
inputs: ['hero']
|
||||
}) as angular.IDirectiveFactory);
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
});
|
@ -0,0 +1,46 @@
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { NgModule } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
import { HeroesService } from './heroes.service';
|
||||
|
||||
// #docregion register
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
UpgradeModule
|
||||
],
|
||||
providers: [{
|
||||
provide: 'heroes',
|
||||
useFactory: (i: any) => i.get('heroes'),
|
||||
deps: ['$injector']
|
||||
}],
|
||||
// #enddocregion register
|
||||
declarations: [
|
||||
HeroDetailComponent
|
||||
],
|
||||
entryComponents: [
|
||||
HeroDetailComponent
|
||||
]
|
||||
// #docregion register
|
||||
})
|
||||
export class AppModule {
|
||||
ngDoBootstrap() {}
|
||||
}
|
||||
// #enddocregion register
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.service('heroes', HeroesService)
|
||||
.directive(
|
||||
'heroDetail',
|
||||
downgradeComponent({component: HeroDetailComponent}) as angular.IDirectiveFactory
|
||||
);
|
||||
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
});
|
@ -0,0 +1,34 @@
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { NgModule } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeModule } from '@angular/upgrade/static';
|
||||
|
||||
import { heroDetailComponent } from './hero-detail.component';
|
||||
|
||||
// #docregion ngmodule
|
||||
import { Heroes } from './heroes';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
UpgradeModule
|
||||
],
|
||||
providers: [ Heroes ]
|
||||
})
|
||||
export class AppModule {
|
||||
ngDoBootstrap() {}
|
||||
}
|
||||
// #enddocregion ngmodule
|
||||
// #docregion register
|
||||
import { downgradeInjectable } from '@angular/upgrade/static';
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.factory('heroes', downgradeInjectable(Heroes))
|
||||
.component('heroDetail', heroDetailComponent);
|
||||
// #enddocregion register
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
});
|
@ -0,0 +1,39 @@
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { NgModule } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
import { heroDetail, HeroDetailDirective } from './hero-detail.component';
|
||||
import { ContainerComponent } from './container.component';
|
||||
|
||||
// #docregion heroupgrade
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
UpgradeModule
|
||||
],
|
||||
declarations: [
|
||||
ContainerComponent,
|
||||
HeroDetailDirective
|
||||
],
|
||||
entryComponents: [
|
||||
ContainerComponent
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
ngDoBootstrap() {}
|
||||
}
|
||||
// #enddocregion heroupgrade
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.component('heroDetail', heroDetail)
|
||||
.directive(
|
||||
'myContainer',
|
||||
downgradeComponent({component: ContainerComponent}) as angular.IDirectiveFactory
|
||||
);
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
});
|
@ -0,0 +1,28 @@
|
||||
// #docregion
|
||||
export const heroDetail = {
|
||||
bindings: {
|
||||
hero: '='
|
||||
},
|
||||
template: `
|
||||
<h2>{{$ctrl.hero.name}}</h2>
|
||||
<div>
|
||||
<ng-transclude></ng-transclude>
|
||||
</div>
|
||||
`
|
||||
};
|
||||
// #enddocregion
|
||||
|
||||
import { Directive, ElementRef, Injector, Input } from '@angular/core';
|
||||
import { UpgradeComponent } from '@angular/upgrade/static';
|
||||
import { Hero } from '../hero';
|
||||
|
||||
@Directive({
|
||||
selector: 'hero-detail'
|
||||
})
|
||||
export class HeroDetailDirective extends UpgradeComponent {
|
||||
@Input() hero: Hero;
|
||||
|
||||
constructor(elementRef: ElementRef, injector: Injector) {
|
||||
super('heroDetail', elementRef, injector);
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { NgModule } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
import { MainController } from './main.controller';
|
||||
|
||||
// #docregion downgradecomponent
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
// #enddocregion downgradecomponent
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
UpgradeModule
|
||||
],
|
||||
declarations: [
|
||||
HeroDetailComponent
|
||||
],
|
||||
entryComponents: [
|
||||
HeroDetailComponent
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
ngDoBootstrap() {}
|
||||
}
|
||||
// #docregion downgradecomponent
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.controller('MainController', MainController)
|
||||
.directive('heroDetail', downgradeComponent({
|
||||
component: HeroDetailComponent,
|
||||
inputs: ['hero'],
|
||||
outputs: ['deleted']
|
||||
}) as angular.IDirectiveFactory);
|
||||
|
||||
// #enddocregion downgradecomponent
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
});
|
@ -0,0 +1,42 @@
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { NgModule } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeModule } from '@angular/upgrade/static';
|
||||
|
||||
// #docregion downgradecomponent, ngmodule
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
// #enddocregion downgradecomponent
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
UpgradeModule
|
||||
],
|
||||
declarations: [
|
||||
HeroDetailComponent
|
||||
],
|
||||
entryComponents: [
|
||||
HeroDetailComponent
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
ngDoBootstrap() {}
|
||||
}
|
||||
// #enddocregion ngmodule
|
||||
// #docregion downgradecomponent
|
||||
|
||||
import { downgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.directive(
|
||||
'heroDetail',
|
||||
downgradeComponent({component: HeroDetailComponent}) as angular.IDirectiveFactory
|
||||
);
|
||||
|
||||
// #enddocregion downgradecomponent
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
});
|
@ -8,6 +8,4 @@ import { Component } from '@angular/core';
|
||||
<div><label>id: </label>1</div>
|
||||
`
|
||||
})
|
||||
export class HeroDetailComponent {
|
||||
|
||||
}
|
||||
export class HeroDetailComponent { }
|
@ -0,0 +1,39 @@
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { NgModule } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
import { heroDetail, HeroDetailDirective } from './hero-detail.component';
|
||||
import { ContainerComponent } from './container.component';
|
||||
|
||||
// #docregion heroupgrade
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
UpgradeModule
|
||||
],
|
||||
declarations: [
|
||||
ContainerComponent,
|
||||
HeroDetailDirective
|
||||
],
|
||||
entryComponents: [
|
||||
ContainerComponent
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
ngDoBootstrap() {}
|
||||
}
|
||||
// #enddocregion heroupgrade
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.component('heroDetail', heroDetail)
|
||||
.directive(
|
||||
'myContainer',
|
||||
downgradeComponent({component: ContainerComponent}) as angular.IDirectiveFactory
|
||||
);
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
});
|
@ -0,0 +1,37 @@
|
||||
// #docregion
|
||||
// #docregion hero-detail-io
|
||||
export const heroDetail = {
|
||||
bindings: {
|
||||
hero: '<',
|
||||
deleted: '&'
|
||||
},
|
||||
template: `
|
||||
<h2>{{$ctrl.hero.name}} details!</h2>
|
||||
<div><label>id: </label>{{$ctrl.hero.id}}</div>
|
||||
<button ng-click="$ctrl.onDelete()">Delete</button>
|
||||
`,
|
||||
controller: function() {
|
||||
this.onDelete = () => {
|
||||
this.deleted(this.hero);
|
||||
};
|
||||
}
|
||||
};
|
||||
// #enddocregion hero-detail-io
|
||||
|
||||
// #docregion hero-detail-io-upgrade
|
||||
import { Directive, ElementRef, Injector, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { UpgradeComponent } from '@angular/upgrade/static';
|
||||
import { Hero } from '../hero';
|
||||
|
||||
@Directive({
|
||||
selector: 'hero-detail'
|
||||
})
|
||||
export class HeroDetailDirective extends UpgradeComponent {
|
||||
@Input() hero: Hero;
|
||||
@Output() deleted: EventEmitter<Hero>;
|
||||
|
||||
constructor(elementRef: ElementRef, injector: Injector) {
|
||||
super('heroDetail', elementRef, injector);
|
||||
}
|
||||
}
|
||||
// #enddocregion hero-detail-io-upgrade
|
@ -0,0 +1,41 @@
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { NgModule } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
import { heroDetail, HeroDetailDirective } from './hero-detail.component';
|
||||
import { ContainerComponent } from './container.component';
|
||||
|
||||
// #docregion hero-detail-upgrade
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
UpgradeModule
|
||||
],
|
||||
declarations: [
|
||||
HeroDetailDirective,
|
||||
// #enddocregion hero-detail-upgrade
|
||||
ContainerComponent
|
||||
],
|
||||
entryComponents: [
|
||||
ContainerComponent
|
||||
// #docregion hero-detail-upgrade
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
ngDoBootstrap() {}
|
||||
}
|
||||
// #enddocregion hero-detail-upgrade
|
||||
|
||||
angular.module('heroApp', [])
|
||||
.component('heroDetail', heroDetail)
|
||||
.directive(
|
||||
'myContainer',
|
||||
downgradeComponent({component: ContainerComponent}) as angular.IDirectiveFactory
|
||||
);
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true});
|
||||
});
|
@ -8,6 +8,4 @@ import { Component } from '@angular/core';
|
||||
<hero-detail></hero-detail>
|
||||
`
|
||||
})
|
||||
export class ContainerComponent {
|
||||
|
||||
}
|
||||
export class ContainerComponent { }
|
@ -0,0 +1,25 @@
|
||||
// #docregion
|
||||
// #docregion hero-detail
|
||||
export const heroDetail = {
|
||||
template: `
|
||||
<h2>Windstorm details!</h2>
|
||||
<div><label>id: </label>1</div>
|
||||
`,
|
||||
controller: function() {
|
||||
}
|
||||
};
|
||||
// #enddocregion hero-detail
|
||||
|
||||
// #docregion hero-detail-upgrade
|
||||
import { Directive, ElementRef, Injector } from '@angular/core';
|
||||
import { UpgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
@Directive({
|
||||
selector: 'hero-detail'
|
||||
})
|
||||
export class HeroDetailDirective extends UpgradeComponent {
|
||||
constructor(elementRef: ElementRef, injector: Injector) {
|
||||
super('heroDetail', elementRef, injector);
|
||||
}
|
||||
}
|
||||
// #enddocregion hero-detail-upgrade
|
@ -1,14 +1,15 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
import { setProtractorToHybridMode } from '../protractor-helpers';
|
||||
|
||||
// Angular E2E Testing Guide:
|
||||
// https://docs.angularjs.org/guide/e2e-testing
|
||||
|
||||
describe('PhoneCat Application', function() {
|
||||
|
||||
beforeAll(function() {
|
||||
setProtractorToNg1Mode();
|
||||
beforeAll(function () {
|
||||
setProtractorToHybridMode();
|
||||
});
|
||||
|
||||
it('should redirect `index.html` to `index.html#!/phones', function() {
|
||||
@ -16,7 +17,7 @@ describe('PhoneCat Application', function() {
|
||||
expect(browser.getLocationAbsUrl()).toBe('/phones');
|
||||
});
|
||||
|
||||
describe('View: Phone list', function() {
|
||||
xdescribe('View: Phone list', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
browser.get('index.html#!/phones');
|
||||
@ -68,13 +69,13 @@ describe('PhoneCat Application', function() {
|
||||
query.sendKeys('nexus');
|
||||
|
||||
element.all(by.css('.phones li a')).first().click();
|
||||
browser.refresh(); // Not sure why this is needed but it is. The route change works fine.
|
||||
browser.sleep(200); // Not sure why this is needed but it is. The route change works fine.
|
||||
expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('View: Phone detail', function() {
|
||||
xdescribe('View: Phone detail', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
browser.get('index.html#!/phones/nexus-s');
|
3
public/docs/_examples/upgrade-phonecat-2-hybrid/ts/.gitignore
vendored
Normal file
3
public/docs/_examples/upgrade-phonecat-2-hybrid/ts/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
**/*.js
|
||||
aot/**/*.ts
|
||||
!rollup-config.js
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"port": 8000,
|
||||
"files": ["./aot/**/*.{html,htm,css,js}"],
|
||||
"server": { "baseDir": "./aot" }
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Angular Tour of Heroes</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
|
||||
<script src="https://code.angularjs.org/1.5.5/angular.js"></script>
|
||||
<script src="https://code.angularjs.org/1.5.5/angular-animate.js"></script>
|
||||
<script src="https://code.angularjs.org/1.5.5/angular-resource.js"></script>
|
||||
<script src="https://code.angularjs.org/1.5.5/angular-route.js"></script>
|
||||
|
||||
<script src="app.module.ng1.js"></script>
|
||||
<script src="app.config.js"></script>
|
||||
<script src="app.animations.js"></script>
|
||||
<script src="core/core.module.js"></script>
|
||||
<script src="core/phone/phone.module.js"></script>
|
||||
<script src="phone-list/phone-list.module.js"></script>
|
||||
<script src="phone-detail/phone-detail.module.js"></script>
|
||||
|
||||
<script src="shim.min.js"></script>
|
||||
<script src="zone.min.js"></script>
|
||||
<!-- #docregion moduleId -->
|
||||
<script>window.module = 'aot';</script>
|
||||
<!-- #enddocregion moduleId -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
<script src="dist/build.js"></script>
|
||||
</html>
|
@ -3,6 +3,9 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
// #enddocregion bare
|
||||
// #docregion upgrademodule
|
||||
import { UpgradeModule } from '@angular/upgrade/static';
|
||||
// #enddocregion upgrademodule
|
||||
// #docregion httpmodule
|
||||
import { HttpModule } from '@angular/http';
|
||||
// #enddocregion httpmodule
|
||||
@ -22,18 +25,20 @@ import { PhoneListComponent } from './phone-list/phone-list.component';
|
||||
import { PhoneDetailComponent } from './phone-detail/phone-detail.component';
|
||||
// #enddocregion phonedetail
|
||||
|
||||
// #docregion bare, httpmodule, phone, phonelist, phonedetail, checkmarkpipe
|
||||
// #docregion bare, upgrademodule, httpmodule, phone, phonelist, phonedetail, checkmarkpipe
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
// #enddocregion bare
|
||||
UpgradeModule,
|
||||
// #enddocregion upgrademodule
|
||||
HttpModule,
|
||||
// #enddocregion httpmodule, phone
|
||||
FormsModule,
|
||||
// #docregion bare, httpmodule, phone
|
||||
// #docregion bare, upgrademodule, httpmodule, phone
|
||||
],
|
||||
// #enddocregion bare, httpmodule, phone
|
||||
// #enddocregion bare, upgrademodule, httpmodule, phone
|
||||
declarations: [
|
||||
PhoneListComponent,
|
||||
// #enddocregion phonelist
|
||||
@ -42,10 +47,35 @@ import { PhoneDetailComponent } from './phone-detail/phone-detail.component';
|
||||
CheckmarkPipe
|
||||
// #docregion phonelist, phonedetail
|
||||
],
|
||||
// #docregion phone
|
||||
providers: [ Phone ]
|
||||
// #docregion bare, httpmodule, phonelist
|
||||
entryComponents: [
|
||||
PhoneListComponent,
|
||||
// #enddocregion phonelist
|
||||
PhoneDetailComponent
|
||||
// #enddocregion phonedetail
|
||||
],
|
||||
// #docregion phone, routeparams
|
||||
providers: [
|
||||
Phone,
|
||||
// #enddocregion phone
|
||||
{
|
||||
provide: '$routeParams',
|
||||
useFactory: routeParamsFactory,
|
||||
deps: ['$injector']
|
||||
}
|
||||
// #docregion phone
|
||||
]
|
||||
// #enddocregion routeparams
|
||||
// #docregion bare, upgrademodule, httpmodule, phone, phonelist
|
||||
})
|
||||
export class AppModule {}
|
||||
// #enddocregion httpmodule, phone, phonelist, phonedetail, checkmarkpipe
|
||||
// #enddocregion bare
|
||||
export class AppModule {
|
||||
// #enddocregion bare
|
||||
ngDoBootstrap() {}
|
||||
// #docregion bare
|
||||
}
|
||||
// #enddocregion bare, upgrademodule, httpmodule, phone, phonelist, phonedetail, checkmarkpipe
|
||||
|
||||
// #docregion routeparams
|
||||
export function routeParamsFactory(i: any) {
|
||||
return i.get('$routeParams');
|
||||
}
|
||||
// #enddocregion routeparams
|
||||
|
@ -3,6 +3,11 @@ import { Injectable } from '@angular/core';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
// #docregion downgrade-injectable
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { downgradeInjectable } from '@angular/upgrade/static';
|
||||
// #enddocregion downgrade-injectable
|
||||
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
// #docregion phonedata-interface
|
||||
@ -14,10 +19,10 @@ export interface PhoneData {
|
||||
// #enddocregion phonedata-interface
|
||||
|
||||
// #docregion fullclass
|
||||
// #docregion classdef
|
||||
// #docregion classdef, downgrade-injectable
|
||||
@Injectable()
|
||||
export class Phone {
|
||||
// #enddocregion classdef
|
||||
// #enddocregion classdef, downgrade-injectable
|
||||
constructor(private http: Http) { }
|
||||
query(): Observable<PhoneData[]> {
|
||||
return this.http.get(`phones/phones.json`)
|
||||
@ -27,7 +32,11 @@ export class Phone {
|
||||
return this.http.get(`phones/${id}.json`)
|
||||
.map((res: Response) => res.json());
|
||||
}
|
||||
// #docregion classdef
|
||||
// #docregion classdef, downgrade-injectable
|
||||
}
|
||||
// #enddocregion classdef
|
||||
// #enddocregion fullclass
|
||||
|
||||
angular.module('core.phone')
|
||||
.factory('phone', downgradeInjectable(Phone));
|
||||
// #enddocregion downgrade-injectable
|
||||
|
@ -0,0 +1,11 @@
|
||||
// #docregion bootstrap
|
||||
import { platformBrowser } from '@angular/platform-browser';
|
||||
import { UpgradeModule } from '@angular/upgrade/static';
|
||||
|
||||
import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory';
|
||||
|
||||
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.documentElement, ['phonecatApp']);
|
||||
});
|
||||
// #enddocregion bootstrap
|
@ -1,51 +1,11 @@
|
||||
// #docregion import-adapter
|
||||
import { UpgradeAdapter } from '@angular/upgrade';
|
||||
declare var angular: any;
|
||||
// #docregion bootstrap
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { UpgradeModule } from '@angular/upgrade/static';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
// #enddocregion import-adapter
|
||||
// #docregion phone-service
|
||||
import { Phone } from './core/phone/phone.service';
|
||||
|
||||
// #enddocregion phone-service
|
||||
// #docregion phone-list
|
||||
import { PhoneListComponent } from './phone-list/phone-list.component';
|
||||
|
||||
// #enddocregion phone-list
|
||||
// #docregion phone-detail
|
||||
import { PhoneDetailComponent } from './phone-detail/phone-detail.component';
|
||||
|
||||
// #enddocregion phone-detail
|
||||
// #docregion init-adapter
|
||||
let upgradeAdapter = new UpgradeAdapter(AppModule);
|
||||
// #enddocregion init-adapter
|
||||
|
||||
// #docregion routeparams
|
||||
upgradeAdapter.upgradeNg1Provider('$routeParams');
|
||||
// #enddocregion routeparams
|
||||
|
||||
// #docregion phone-service
|
||||
|
||||
angular.module('core.phone')
|
||||
.factory('phone', upgradeAdapter.downgradeNg2Provider(Phone));
|
||||
// #enddocregion phone-service
|
||||
// #docregion phone-list
|
||||
|
||||
angular.module('phoneList')
|
||||
.directive(
|
||||
'phoneList',
|
||||
upgradeAdapter.downgradeNg2Component(PhoneListComponent) as angular.IDirectiveFactory
|
||||
);
|
||||
// #enddocregion phone-list
|
||||
// #docregion phone-detail
|
||||
|
||||
angular.module('phoneDetail')
|
||||
.directive(
|
||||
'phoneDetail',
|
||||
upgradeAdapter.downgradeNg2Component(PhoneDetailComponent) as angular.IDirectiveFactory
|
||||
);
|
||||
// #enddocregion phone-detail
|
||||
|
||||
// #docregion bootstrap
|
||||
upgradeAdapter.bootstrap(document.documentElement, ['phonecatApp']);
|
||||
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
|
||||
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.documentElement, ['phonecatApp']);
|
||||
});
|
||||
// #enddocregion bootstrap
|
||||
|
@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { Phone, PhoneData } from '../core/phone/phone.service';
|
||||
declare var angular: any;
|
||||
|
||||
class PhoneDetailController {
|
||||
phone: PhoneData;
|
||||
|
@ -1,4 +1,8 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { downgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
// #docregion initialclass
|
||||
import { Component, Inject } from '@angular/core';
|
||||
|
||||
@ -19,9 +23,7 @@ export class PhoneDetailComponent {
|
||||
phone: PhoneData;
|
||||
mainImageUrl: string;
|
||||
|
||||
constructor(@Inject('$routeParams')
|
||||
$routeParams: angular.route.IRouteParamsService,
|
||||
phone: Phone) {
|
||||
constructor(@Inject('$routeParams') $routeParams: any, phone: Phone) {
|
||||
phone.get($routeParams['phoneId']).subscribe(phone => {
|
||||
this.phone = phone;
|
||||
this.setImage(phone.images[0]);
|
||||
@ -33,3 +35,9 @@ export class PhoneDetailComponent {
|
||||
}
|
||||
}
|
||||
// #enddocregion initialclass
|
||||
|
||||
angular.module('phoneDetail')
|
||||
.directive(
|
||||
'phoneDetail',
|
||||
downgradeComponent({component: PhoneDetailComponent}) as angular.IDirectiveFactory
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { Phone, PhoneData } from '../core/phone/phone.service';
|
||||
declare var angular: any;
|
||||
|
||||
class PhoneListController {
|
||||
phones: PhoneData[];
|
||||
|
@ -1,14 +1,21 @@
|
||||
// #docplaster
|
||||
// #docregion downgrade-component
|
||||
declare var angular: angular.IAngularStatic;
|
||||
import { downgradeComponent } from '@angular/upgrade/static';
|
||||
|
||||
// #enddocregion downgrade-component
|
||||
|
||||
// #docregion initialclass
|
||||
import { Component } from '@angular/core';
|
||||
import { Phone, PhoneData } from '../core/phone/phone.service';
|
||||
|
||||
// #docregion downgrade-component
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'phone-list',
|
||||
templateUrl: 'phone-list.template.html'
|
||||
})
|
||||
export class PhoneListComponent {
|
||||
// #enddocregion downgrade-component
|
||||
phones: PhoneData[];
|
||||
query: string;
|
||||
orderProp: string;
|
||||
@ -54,6 +61,13 @@ export class PhoneListComponent {
|
||||
return phones;
|
||||
}
|
||||
// #enddocregion getphones
|
||||
// #docregion initialclass
|
||||
// #docregion initialclass, downgrade-component
|
||||
}
|
||||
// #enddocregion initialclass
|
||||
|
||||
angular.module('phoneList')
|
||||
.directive(
|
||||
'phoneList',
|
||||
downgradeComponent({component: PhoneListComponent}) as angular.IDirectiveFactory
|
||||
);
|
||||
// #enddocregion downgrade-component
|
||||
|
@ -0,0 +1,21 @@
|
||||
// #docregion
|
||||
import rollup from 'rollup'
|
||||
import nodeResolve from 'rollup-plugin-node-resolve'
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import uglify from 'rollup-plugin-uglify'
|
||||
|
||||
//paths are relative to the execution path
|
||||
export default {
|
||||
entry: 'app/main-aot.js',
|
||||
dest: 'aot/dist/build.js', // output a single application bundle
|
||||
sourceMap: true,
|
||||
sourceMapFile: 'aot/dist/build.js.map',
|
||||
format: 'iife',
|
||||
plugins: [
|
||||
nodeResolve({jsnext: true, module: true}),
|
||||
commonjs({
|
||||
include: ['node_modules/rxjs/**']
|
||||
}),
|
||||
uglify()
|
||||
]
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
|
||||
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
|
||||
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
|
||||
'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
|
||||
|
||||
// other libraries
|
||||
'rxjs': 'npm:rxjs',
|
||||
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"removeComments": false,
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"typeRoots": [
|
||||
"../../node_modules/@types/"
|
||||
]
|
||||
},
|
||||
|
||||
"files": [
|
||||
"app/app.module.ts",
|
||||
"app/main-aot.ts"
|
||||
],
|
||||
|
||||
"angularCompilerOptions": {
|
||||
"genDir": "aot",
|
||||
"skipMetadataEmit" : true
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
@ -67,11 +67,7 @@ describe('PhoneCat Application', function() {
|
||||
// #docregion links
|
||||
it('should render phone specific links', function() {
|
||||
let query = element(by.css('input'));
|
||||
// https://github.com/angular/protractor/issues/2019
|
||||
let str = 'nexus';
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
query.sendKeys(str.charAt(i));
|
||||
}
|
||||
query.sendKeys('nexus');
|
||||
element.all(by.css('.phones li a')).first().click();
|
||||
browser.getCurrentUrl().then(function(url: string) {
|
||||
expect(url.endsWith('/phones/nexus-s')).toBe(true);
|
||||
|
@ -27,8 +27,8 @@ include ../_util-fns
|
||||
2. [Using a Module Loader](#using-a-module-loader)
|
||||
3. [Migrating to TypeScript](#migrating-to-typescript)
|
||||
4. [Using Component Directives](#using-component-directives)
|
||||
2. [Upgrading with The Upgrade Adapter](#upgrading-with-the-upgrade-adapter)
|
||||
1. [How The Upgrade Adapter Works](#how-the-upgrade-adapter-works)
|
||||
2. [Upgrading with The Upgrade Module](#upgrading-with-the-upgrade-module)
|
||||
1. [How The Upgrade Module Works](#how-the-upgrade-module-works)
|
||||
2. [Bootstrapping hybrid Angular 1+2 Applications](#bootstrapping-hybrid-angular-1-2-applications)
|
||||
3. [Using Angular 2 Components from Angular 1 Code](#using-angular-2-components-from-angular-1-code)
|
||||
4. [Using Angular 1 Component Directives from Angular 2 Code](#using-angular-1-component-directives-from-angular-2-code)
|
||||
@ -181,7 +181,7 @@ include ../_util-fns
|
||||
An Angular 1 component directive that is fully aligned with the Angular 2
|
||||
architecture may look something like this:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/hero-detail.directive.ts')
|
||||
+makeExample('upgrade-module/ts/app/hero-detail.directive.ts')
|
||||
|
||||
:marked
|
||||
Angular 1.5 introduces the [component API](https://docs.angularjs.org/api/ng/type/angular.Module)
|
||||
@ -195,7 +195,7 @@ include ../_util-fns
|
||||
The component directive example from above looks like this when expressed
|
||||
using the component API:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/upgrade-io/hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/upgrade-io/hero-detail.component.ts')
|
||||
|
||||
:marked
|
||||
Controller lifecycle hook methods `$onInit()`, `$onDestroy()`, and `$onChanges()`
|
||||
@ -205,7 +205,7 @@ include ../_util-fns
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
# Upgrading with The Upgrade Adapter
|
||||
# Upgrading with The Upgrade Module
|
||||
|
||||
The `upgrade` module in Angular 2 is a very useful tool for upgrading
|
||||
anything but the smallest of applications. With it we can mix and match
|
||||
@ -214,13 +214,13 @@ include ../_util-fns
|
||||
since there's a natural coexistence between the two frameworks during the
|
||||
transition period.
|
||||
|
||||
## How The Upgrade Adapter Works
|
||||
## How The Upgrade Module Works
|
||||
|
||||
The primary tool provided by the upgrade module is called the `UpgradeAdapter`.
|
||||
The primary tool provided by the upgrade module is called the `UpgradeModule`.
|
||||
This is a service that can bootstrap and manage hybrid applications that support
|
||||
both Angular 2 and Angular 1 code.
|
||||
|
||||
When we use `UpgradeAdapter`, what we're really doing is *running both versions
|
||||
When we use `UpgradeModule`, what we're really doing is *running both versions
|
||||
of Angular at the same time*. All Angular 2 code is running in the Angular 2
|
||||
framework, and Angular 1 code in the Angular 1 framework. Both of these are the
|
||||
actual, fully featured versions of the frameworks. There is no emulation going on,
|
||||
@ -260,7 +260,7 @@ table
|
||||
|
||||
:marked
|
||||
Even accounting for these differences we can still have dependency injection
|
||||
interoperability. The `UpgradeAdapter` resolves the differences and makes
|
||||
interoperability. The `UpgradeModule` resolves the differences and makes
|
||||
everything work seamlessly:
|
||||
|
||||
* We can make Angular 1 services available for injection to Angular 2 code
|
||||
@ -283,7 +283,7 @@ figure.image-display
|
||||
What we'll find in the DOM of a hybrid application are components and
|
||||
directives from both Angular 1 and Angular 2. These components
|
||||
communicate with each other by using the input and output bindings
|
||||
of their respective frameworks, which the `UpgradeAdapter` bridges
|
||||
of their respective frameworks, which the `UpgradeModule` bridges
|
||||
together. They may also communicate through shared injected dependencies,
|
||||
as described above.
|
||||
|
||||
@ -311,7 +311,7 @@ figure.image-display
|
||||
using an Angular 2 component, or an Angular 2 template using an
|
||||
Angular 1 component.
|
||||
2. By transcluding or projecting content from the other framework. The
|
||||
`UpgradeAdapter` bridges the related concepts of Angular 1 transclusion
|
||||
`UpgradeModule` bridges the related concepts of Angular 1 transclusion
|
||||
and Angular 2 content projection together.
|
||||
|
||||
figure.image-display
|
||||
@ -351,13 +351,13 @@ figure.image-display
|
||||
change detection. The code itself doesn't have to call `scope.$apply()`
|
||||
or anything like it.
|
||||
|
||||
In the case of hybrid applications, the `UpgradeAdapter` bridges the
|
||||
In the case of hybrid applications, the `UpgradeModule` bridges the
|
||||
Angular 1 and Angular 2 approaches. Here's what happens:
|
||||
|
||||
* Everything that happens in the application runs inside the Angular 2 zone.
|
||||
This is true whether the event originated in Angular 1 or Angular 2 code.
|
||||
The zone triggers Angular 2 change detection after every event.
|
||||
* The `UpgradeAdapter` will invoke the Angular 1 `$rootScope.$apply()` after
|
||||
* The `UpgradeModule` will invoke the Angular 1 `$rootScope.$apply()` after
|
||||
every turn of the Angular zone. This also triggers Angular 1 change
|
||||
detection after every event.
|
||||
|
||||
@ -367,7 +367,7 @@ figure.image-display
|
||||
:marked
|
||||
What this means in practice is that we do not need to call `$apply()` in
|
||||
our code, regardless of whether it is in Angular 1 on Angular 2. The
|
||||
`UpgradeAdapter` does it for us. We *can* still call `$apply()` so there
|
||||
`UpgradeModule` does it for us. We *can* still call `$apply()` so there
|
||||
is no need to remove such calls from existing code. Those calls just don't
|
||||
have any effect in a hybrid application.
|
||||
|
||||
@ -386,7 +386,7 @@ figure.image-display
|
||||
as regular Angular 2 inputs and set onto the scope (or controller) when
|
||||
they change.
|
||||
|
||||
## Using the Upgrade Adapter with Angular 2 _NgModules_
|
||||
## Using UpgradeModule with Angular 2 _NgModules_
|
||||
|
||||
Both Angular 1 and Angular 2 have their own concept of modules
|
||||
to help organize an application into cohesive blocks of funcionality.
|
||||
@ -398,8 +398,8 @@ figure.image-display
|
||||
|
||||
In a hybrid application we run both versions of Angular at the same time.
|
||||
That means that we need at least one module each from both Angular 1 and Angular 2.
|
||||
We will give the Angular 2 module to the `UpgradeAdapter` while we use the
|
||||
Angular 1 module for bootstrapping. Let's see how.
|
||||
We will import `UpgradeModule` inside our Angular 2 module, and then use it for
|
||||
bootstrapping our Angular 1 module. Let's see how.
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
@ -408,7 +408,7 @@ figure.image-display
|
||||
:marked
|
||||
## Bootstrapping Hybrid Angular 1+2 Applications
|
||||
|
||||
The first step to upgrading an application using the `UpgradeAdapter` is
|
||||
The first step to upgrading an application using the `UpgradeModule` is
|
||||
always to bootstrap it as a hybrid that supports both Angular 1 and
|
||||
Angular 2.
|
||||
|
||||
@ -422,14 +422,14 @@ figure.image-display
|
||||
|
||||
Say we have an `ng-app` driven bootstrap such as this one:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/index-ng-app.html', null, null, {otl: /(ng-app.*ng-strict-di)/})
|
||||
+makeExample('upgrade-module/ts/index-ng-app.html', null, null, {otl: /(ng-app.*ng-strict-di)/})
|
||||
|
||||
:marked
|
||||
We can remove the `ng-app` and `ng-strict-di` directives from the HTML
|
||||
and instead switch to calling `angular.bootstrap` from JavaScript, which
|
||||
will result in the same thing:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-bootstrap/app.module.ts', 'bootstrap')
|
||||
+makeExample('upgrade-module/ts/app/1-bootstrap/app.module.ts', 'bootstrap')
|
||||
|
||||
:marked
|
||||
Now introduce Angular 2 to the project. Inspired by instructions in
|
||||
@ -438,40 +438,25 @@ figure.image-display
|
||||
|
||||
Next, create an `app.module.ts` file and add the following `NgModule` class:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts', 'ngmodule')
|
||||
+makeExample('upgrade-module/ts/app/1-2-hybrid-bootstrap/app.module.ts', 'ngmodule')
|
||||
|
||||
:marked
|
||||
This bare minimum `NgModule` imports `BrowserModule`, the module every Angular browser-based app must have.
|
||||
|
||||
Import and instantiate the `UpgradeAdapter` with the new `AppModule` and call its `bootstrap` method.
|
||||
That method takes the exact same arguments as [angular.bootstrap](https://docs.angularjs.org/api/ng/function/angular.bootstrap):
|
||||
It also imports `UpgradeModule` from `@angular/upgrade/static`, and adds an override to prevent
|
||||
Angular 2 from bootstrapping itself in the form of the `ngDoBootstrap` empty class method.
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts', 'bootstrap')
|
||||
Now we bootstrap `AppModule` using `platformBrowserDynamic`'s `bootstrapModule` method.
|
||||
Then we use dependency injection to get a hold of the `UpgradeModule` instance in `AppModule`,
|
||||
and use it to bootstrap our Angular 1 app.
|
||||
The `upgrade.bootstrap` method takes the exact same arguments as [angular.bootstrap](https://docs.angularjs.org/api/ng/function/angular.bootstrap):
|
||||
|
||||
+makeExample('upgrade-module/ts/app/1-2-hybrid-bootstrap/app.module.ts', 'bootstrap')
|
||||
|
||||
:marked
|
||||
Congratulations! You're running a hybrid Angular 1+2 application! The
|
||||
existing Angular 1 code works as before _and_ you're ready to run Angular 2 code.
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
Note that, unlike `angular.bootstrap`, the `upgradeAdapter.bootstrap` runs *asynchronously*.
|
||||
The application is not launched immediately. Some time must pass after the bootstrap call returns.
|
||||
|
||||
:marked
|
||||
As we begin to migrate components to Angular 2, we'll be using the
|
||||
`UpgradeAdapter` for more than just bootstrapping. It'll be important
|
||||
to use the **same** instance of the adapter across the whole application,
|
||||
because it stores internal information about what's going on in the application.
|
||||
It'll be useful to have a module for a shared `UpgradeAdapter` instance in
|
||||
the project:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/upgrade_adapter.ts', null, 'upgrade_adapter.ts')
|
||||
|
||||
:marked
|
||||
This shared instance can then be pulled in to all the modules that need it:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/app.module.ts', 'bootstrap')
|
||||
|
||||
:marked
|
||||
## Using Angular 2 Components from Angular 1 Code
|
||||
figure
|
||||
@ -484,19 +469,24 @@ figure
|
||||
|
||||
Say we have a simple Angular 2 component that shows information about a hero:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/downgrade-static/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/downgrade-static/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
|
||||
:marked
|
||||
If we want to use this component from Angular 1, we need to *downgrade* it
|
||||
using the upgrade adapter. What we get when we do that is an Angular 1
|
||||
using the `downgradeComponent()` method. What we get when we do that is an Angular 1
|
||||
*directive*, which we can then register into our Angular 1 module:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/downgrade-static/app.module.ts', 'downgradecomponent')
|
||||
+makeExample('upgrade-module/ts/app/downgrade-static/app.module.ts', 'downgradecomponent')
|
||||
|
||||
:marked
|
||||
Because `HeroDetailComponent` is an Angular 2 component, we must also add it to the `declarations` in the `AppModule`.
|
||||
Because `HeroDetailComponent` is an Angular 2 component, we must also add it to the
|
||||
`declarations` in the `AppModule`.
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/downgrade-static/app.module.ts', 'ngmodule')
|
||||
And because this component is being used from the Angular 1 module, and is an entry point into
|
||||
our Angular 2 application, we also need to add it to the `entryComponents` for our
|
||||
Angular 2 module.
|
||||
|
||||
+makeExample('upgrade-module/ts/app/downgrade-static/app.module.ts', 'ngmodule')
|
||||
.l-sub-section
|
||||
:marked
|
||||
All Angular 2 components, directives and pipes must be declared in an NgModule.
|
||||
@ -505,7 +495,7 @@ figure
|
||||
The net resulit is an Angular 1 directive called `heroDetail`, that we can
|
||||
use like any other directive in our Angular 1 templates.
|
||||
|
||||
+makeExample('upgrade-adapter/ts/index-downgrade-static.html', 'usecomponent')
|
||||
+makeExample('upgrade-module/ts/index-downgrade-static.html', 'usecomponent')
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
@ -520,13 +510,15 @@ figure
|
||||
Angular 2 hero detail component with inputs and outputs might look
|
||||
like this:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/downgrade-io/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/downgrade-io/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
|
||||
:marked
|
||||
These inputs and outputs can be supplied from the Angular 1 template, and the
|
||||
`UpgradeAdapter` takes care of bridging them over:
|
||||
`downgradeComponent()` method takes care of bridging them over via the `inputs`
|
||||
and `outputs` arrays:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/index-downgrade-io.html', 'usecomponent')
|
||||
+makeExample('upgrade-module/ts/app/downgrade-io/app.module.ts', 'downgradecomponent')
|
||||
+makeExample('upgrade-module/ts/index-downgrade-io.html', 'usecomponent')
|
||||
|
||||
:marked
|
||||
Note that even though we are in an Angular 1 template, **we're using Angular 2
|
||||
@ -555,7 +547,7 @@ figure
|
||||
directives on the element, even though it has Angular 2 binding attributes on it.
|
||||
For example, we can easily make multiple copies of the component using `ng-repeat`:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/index-downgrade-io.html', 'userepeatedcomponent')
|
||||
+makeExample('upgrade-module/ts/index-downgrade-io.html', 'userepeatedcomponent')
|
||||
|
||||
:marked
|
||||
## Using Angular 1 Component Directives from Angular 2 Code
|
||||
@ -566,7 +558,7 @@ figure
|
||||
code. This is very useful when we start our migration from lower-level
|
||||
components and work our way up. But in some cases it is more convenient
|
||||
to do things in the opposite order: To start with higher-level components
|
||||
and work our way down. This too can be done using the `UpgradeAdapter`.
|
||||
and work our way down. This too can be done using the `UpgradeModule`.
|
||||
We can *upgrade* Angular 1 component directives and then use them from
|
||||
Angular 2.
|
||||
|
||||
@ -580,20 +572,23 @@ figure
|
||||
A simple example of an upgradable component is one that just has a template
|
||||
and a controller:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/upgrade-static/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/upgrade-static/hero-detail.component.ts', 'hero-detail', 'hero-detail.component.ts')
|
||||
|
||||
:marked
|
||||
We can *upgrade* this component to Angular 2 using the `UpgradeAdapter`'s
|
||||
`upgradeNg1Component` method. It takes the name of an Angular 1 component
|
||||
directive and returns an Angular 2 **component class**.
|
||||
Declare it in an `NgModule` as with other Angular 2 components:
|
||||
We can *upgrade* this component to Angular 2 using the `UpgradeComponent` class.
|
||||
By creating a new Angular 2 **directive** that extends `UpgradeComponent` and doing a `super` call
|
||||
inside it's constructor, we have a fully upgrade Angular 1 component to be used inside Angular 2.
|
||||
All that is left is to add it to `AppModule`'s `declarations` array.
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/upgrade-static/upgrade_adapter.ts', 'heroupgrade', 'app.module.ts')
|
||||
+makeExample('upgrade-module/ts/app/upgrade-static/hero-detail.component.ts', 'hero-detail-upgrade', 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/upgrade-static/app.module.ts', 'hero-detail-upgrade', 'hero-detail.component.ts')
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
Upgraded components always have an element selector, which is based
|
||||
on the original name of the original Angular 1 component directive.
|
||||
Upgraded componentes are Angular 2 **directives**, instead of **components**, because Angular 2
|
||||
is unaware that Angular 1 will create elements under it. As far as Angular 2 knows, the upgraded
|
||||
component is just a directive - a tag - and Angular 2 doesn't have to concern itself with
|
||||
it's children.
|
||||
|
||||
:marked
|
||||
An upgraded component may also have inputs and outputs, as defined by
|
||||
@ -646,13 +641,14 @@ table
|
||||
As an example, say we have a hero detail Angular 1 component directive
|
||||
with one input and one output:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/upgrade-io/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/upgrade-io/hero-detail.component.ts', 'hero-detail-io', 'hero-detail.component.ts')
|
||||
|
||||
:marked
|
||||
We can upgrade this component to Angular 2, and then provide the input
|
||||
and output using Angular 2 template syntax:
|
||||
We can upgrade this component to Angular 2, annotate inputs and outputs in the upgrade directive,
|
||||
and then provide the input and output using Angular 2 template syntax:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/upgrade-io/container.component.ts', null, 'container.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/upgrade-io/hero-detail.component.ts', 'hero-detail-io-upgrade', 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/upgrade-io/container.component.ts', null, 'container.component.ts')
|
||||
|
||||
|
||||
:marked
|
||||
@ -663,20 +659,20 @@ figure
|
||||
When we are using a downgraded Angular 2 component from an Angular 1
|
||||
template, the need may arise to *transclude* some content into it. This
|
||||
is also possible. While there is no such thing as transclusion in Angular 2,
|
||||
there is a very similar concept called *content projection*. The `UpgradeAdapter`
|
||||
there is a very similar concept called *content projection*. The `UpgradeModule`
|
||||
is able to make these two features interoperate.
|
||||
|
||||
Angular 2 components that support content projection make use of an `<ng-content>`
|
||||
tag within them. Here's an example of such a component:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-to-2-projection/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/1-to-2-projection/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
|
||||
:marked
|
||||
When using the component from Angular 1, we can supply contents for it. Just
|
||||
like they would be transcluded in Angular 1, they get projected to the location
|
||||
of the `<ng-content>` tag in Angular 2:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/index-1-to-2-projection.html', 'usecomponent')
|
||||
+makeExample('upgrade-module/ts/index-1-to-2-projection.html', 'usecomponent')
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
@ -696,7 +692,7 @@ figure
|
||||
the `ng-transclude` directive in its template to mark the transclusion
|
||||
point:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/2-to-1-transclusion/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/2-to-1-transclusion/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
@ -708,7 +704,7 @@ figure
|
||||
If we upgrade this component and use it from Angular 2, we can populate
|
||||
the component tag with contents that will then get transcluded:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/2-to-1-transclusion/container.component.ts', null, 'container.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/2-to-1-transclusion/container.component.ts', null, 'container.component.ts')
|
||||
|
||||
:marked
|
||||
## Making Angular 1 Dependencies Injectable to Angular 2
|
||||
@ -722,19 +718,18 @@ figure
|
||||
Angular 2. This makes it possible to then inject it somewhere in Angular 2
|
||||
code. For example, we might have a service called `HeroesService` in Angular 1:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-to-2-providers/heroes.service.ts', null, 'heroes.service.ts')
|
||||
+makeExample('upgrade-module/ts/app/1-to-2-providers/heroes.service.ts', null, 'heroes.service.ts')
|
||||
|
||||
:marked
|
||||
We can upgrade the service using the `UpgradeAdapter`'s `upgradeNg1Provider` method
|
||||
by giving it the name of the service. This adds the service into Angular 2's root injector.
|
||||
We can upgrade the service using a Angular 2 [Factory provider](../guide/dependency-injection.html#!#factory-providers)
|
||||
that requests the service from the Angular 1 `$injector`. The name of the Angular 2 dependency is up to you:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-to-2-providers/app.module.ts', 'register', 'app.module.ts')
|
||||
+makeExample('upgrade-module/ts/app/1-to-2-providers/app.module.ts', 'register', 'app.module.ts')
|
||||
|
||||
:marked
|
||||
We can then inject it in Angular 2 using a string token that matches
|
||||
its original name in Angular 1:
|
||||
We can then inject it in Angular 2 using a string token:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-to-2-providers/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/1-to-2-providers/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
@ -754,24 +749,24 @@ figure
|
||||
|
||||
For example, we might have an Angular 2 service called `Heroes`:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/2-to-1-providers/heroes.ts', null, 'heroes.ts')
|
||||
+makeExample('upgrade-module/ts/app/2-to-1-providers/heroes.ts', null, 'heroes.ts')
|
||||
|
||||
:marked
|
||||
Again, as with Angular 2 components, register the provider with the `NgModule` by adding it to the module's `providers` list.
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/2-to-1-providers/upgrade_adapter.ts', 'ngmodule', 'app.module.ts')
|
||||
+makeExample('upgrade-module/ts/app/2-to-1-providers/app.module.ts', 'ngmodule', 'app.module.ts')
|
||||
|
||||
:marked
|
||||
Now wrap the Angular 2 `Heroes` in an *Angular 1 factory function* using `upgradeAdapter.downgradeNg2Provider()`.
|
||||
Now wrap the Angular 2 `Heroes` in an *Angular 1 factory function* using `downgradeInjectable()`.
|
||||
and plug the factory into an Angular 1 module.
|
||||
The name of the Angular 1 dependency is up to you:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/2-to-1-providers/app.module.ts', 'register', 'app.module.ts')
|
||||
+makeExample('upgrade-module/ts/app/2-to-1-providers/app.module.ts', 'register', 'app.module.ts')
|
||||
|
||||
:marked
|
||||
After this, the service is injectable anywhere in our Angular 1 code:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/2-to-1-providers/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
+makeExample('upgrade-module/ts/app/2-to-1-providers/hero-detail.component.ts', null, 'hero-detail.component.ts')
|
||||
|
||||
|
||||
|
||||
@ -1018,7 +1013,7 @@ code-example(format="").
|
||||
|
||||
Having completed our preparation work, let's get going with the Angular 2
|
||||
upgrade of PhoneCat. We'll do this incrementally with the help of the
|
||||
[upgrade module](#upgrading-with-the-upgrade-adapter) that comes with Angular 2.
|
||||
[upgrade module](#upgrading-with-the-upgrade-module) that comes with Angular 2.
|
||||
By the time we're done, we'll be able to remove Angular 1 from the project
|
||||
completely, but the key is to do this piece by piece without breaking the application.
|
||||
|
||||
@ -1092,36 +1087,19 @@ code-example(format="").
|
||||
that supports both Angular 1 and Angular 2 components. Once we've done that
|
||||
we can start converting the individual pieces to Angular 2.
|
||||
|
||||
To bootstrap a hybrid application, we first need to initialize an `UpgradeAdapter`,
|
||||
which [provides the glue](#upgrading-with-the-upgrade-adapter) that joins the two
|
||||
versions of the framework together. Let's import the `UpgradeAdapter` class into a
|
||||
new file `app/main.ts`. This file has been configured as the application entrypoint
|
||||
in `systemjs.config.js`, so it is already being loaded by the browser.
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'import-adapter', 'app/main.ts')
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
### Why declare _angular_ as _any_?
|
||||
|
||||
A strongly typed `angular` reference to Angular 1 would be great.
|
||||
But we can't import its <a href="https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#support-for-umd-module-definitions" target="_blank">UMD typings</a>
|
||||
library, `@types/angular`, without also importing Angular 1 itself via `import * as angular from 'angular'`.
|
||||
|
||||
Angular 1 is currently loaded by a script tag in `index.html` and
|
||||
switching to an ES6 import at this time is not worth the considerable effort.
|
||||
Instead we declare `angular` as an untyped `any` to avoid typing errors.
|
||||
|
||||
:marked
|
||||
We can then make an adapter by instantiating the class:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'init-adapter')
|
||||
To [bootstrap a hybrid application](#bootstrapping-hybrid-angular-1-2-applications),
|
||||
we first need to import `UpgradeModule` in our `AppModule`, and override it's bootstrap method:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ts', 'upgrademodule', 'app/app.module.ts')
|
||||
|
||||
:marked
|
||||
Our application is currently bootstrapped using the Angular 1 `ng-app` directive
|
||||
attached to the `<html>` element of the host page. This will no longer work with
|
||||
Angular 2. We should switch to a JavaScript-driven bootstrap instead. So, remove the
|
||||
`ng-app` attribute from `index.html`, and instead add this to `main.ts`:
|
||||
Angular 2. We should switch to a JavaScript-driven bootstrap instead.
|
||||
|
||||
So, remove the `ng-app` attribute from `index.html`, and instead boostrap via `app/main.ts`.
|
||||
This file has been configured as the application entrypoint in `systemjs.config.js`,
|
||||
so it is already being loaded by the browser.
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'bootstrap')
|
||||
|
||||
@ -1129,13 +1107,32 @@ code-example(format="").
|
||||
The arguments used here are the root element of the application (which is
|
||||
the same element we had `ng-app` on earlier), and the Angular 1.x modules
|
||||
that we want to load. Since we're bootstrapping the app through
|
||||
an `UpgradeAdapter`, we're actually now running the app as a hybrid Angular 1+2
|
||||
an `UpgradeModule`, we're actually now running the app as a hybrid Angular 1+2
|
||||
app.
|
||||
|
||||
This means we are now running both Angular 1 and 2 at the same time. That's pretty
|
||||
exciting! We're not running any actual Angular 2 components yet though,
|
||||
so let's do that next.
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
### Why declare _angular_ as _angular.IAngularStatic_?
|
||||
|
||||
`@types/angular` is declared as a UMD module, and due to the way
|
||||
<a href="https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#support-for-umd-module-definitions" target="_blank">UMD typings</a>
|
||||
work, once you have an ES6 `import` statement in a file all UMD typed modules must also be
|
||||
imported via `import` statements instead of being globally available.
|
||||
|
||||
Angular 1 is currently loaded by a script tag in `index.html`, which means that the whole app
|
||||
has access to it as a global and uses the same instance of the `angular` variable.
|
||||
If we used `import * as angular from 'angular'` instead we would also need to overhaul how we
|
||||
load every file in our Angular 1 app to use ES6 modules in order to ensure Angular 1 was being
|
||||
loaded correctly.
|
||||
|
||||
This is a considerable effort and it often isn't worth it, especially since we are in the
|
||||
process of moving our our to Angular 2 already.
|
||||
Instead we declare `angular` as `angular.IAngularStatic` to indicate it is a global variable
|
||||
and still have full typing support.
|
||||
|
||||
:marked
|
||||
## Upgrading the Phone service
|
||||
@ -1183,6 +1180,12 @@ code-example(format="").
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts', 'phonedata-interface', 'app/core/phone/phone.service.ts (interface)')(format='.')
|
||||
|
||||
:marked
|
||||
`@angular/upgrade/static` has a `downgradeInjectable` method for the purpose of making
|
||||
Angular 2 services available to Angular 1 code. Use it to plug in the `Phone` service:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts', 'downgrade-injectable', 'app/core/phone/phone.service.ts (downgrade)')(format='.')
|
||||
|
||||
:marked
|
||||
Here's the full, final code for the service:
|
||||
|
||||
@ -1197,11 +1200,6 @@ code-example(format="").
|
||||
Because it's an Angular 2 service, we register it with the `NgModule` providers:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ts', 'phone', 'app.module.ts')
|
||||
:marked
|
||||
`UpgradeAdapter` has a `downgradeNg2Provider` method for the purpose of making
|
||||
Angular 2 services available to Angular 1 code. Use it to plug in the `Phone` service:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'phone-service', 'app/main.ts (excerpt)')(format='.')
|
||||
|
||||
:marked
|
||||
Now that we are loading `phone.service.ts` through an import that is resolved
|
||||
@ -1275,29 +1273,29 @@ code-example(format="").
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ts', 'getphones', 'app/phone-list/phone-list.component.ts')
|
||||
|
||||
:marked
|
||||
Now we need to downgrade our Angular 2 component so we can use it in Angular 1.
|
||||
Instead of registering a component, we register a `phoneList` *directive*,
|
||||
a downgraded version of the Angular 2 component.
|
||||
|
||||
The `as angular.IDirectiveFactory` cast tells the TypeScript compiler
|
||||
that the return value of the `downgradeComponent` method is a directive factory.
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ts', 'downgrade-component', 'app/phone-list/phone-list.component.ts')
|
||||
|
||||
:marked
|
||||
The new `PhoneListComponent` uses the Angular 2 `ngModel` directive, located in the `FormsModule`.
|
||||
Add the `FormsModule` to `NgModule` imports and declare the new `PhoneListComponent` :
|
||||
Add the `FormsModule` to `NgModule` imports, declare the new `PhoneListComponent` and
|
||||
finally add it to `entryComponents` since we downgraded it:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ts', 'phonelist', 'app.module.ts')
|
||||
|
||||
:marked
|
||||
In the entrypoint file `main.ts` we'll plug this component into the Angular 1 module.
|
||||
|
||||
Instead of registering a component, we register a `phoneList` *directive*, a downgraded version of the Angular 2 component.
|
||||
The `UpgradeAdapter` creates the bridge between the two:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'phone-list', 'app/main.ts (excerpt)')(format='.')
|
||||
|
||||
:marked
|
||||
The `as angular.IDirectiveFactory` cast tells the TypeScript compiler
|
||||
that the return value of the downgrade method is a directive factory.
|
||||
|
||||
Remove the <script> tag for the phone list component from `index.html`.
|
||||
|
||||
Now set the remaining `phone-detail.component.ts` as follows:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ts', 'initialclass', 'app/phone-detail/phone-detail.component.ts')
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ts', null, 'app/phone-detail/phone-detail.component.ts')
|
||||
|
||||
:marked
|
||||
This is similar to the phone list component.
|
||||
@ -1308,14 +1306,11 @@ code-example(format="").
|
||||
We intend to inject it into the new `PhoneDetailsComponent`.
|
||||
|
||||
Unfortunately, Angular 1 dependencies are not automatically available to Angular 2 components.
|
||||
We must use the `UpgradeAdapter` to make the `$routeParams` an Angular 2 provider.
|
||||
Do that in `main.ts`:
|
||||
We must use a [Factory provider](#making-angular-1-dependencies-injectable-to-angular-2)
|
||||
to make `$routeParams` an Angular 2 provider.
|
||||
Do that in `app.module.ts`:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'routeparams', 'app/main.ts ($routeParms)')(format='.')
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
Do not register an upgraded Angular 1 provider in the `NgModule`.
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ts', 'routeparams', 'app/app.module.ts ($routeParms)')(format='.')
|
||||
|
||||
:marked
|
||||
Convert the phone detail component template into Angular 2 syntax as follows:
|
||||
@ -1342,26 +1337,19 @@ code-example(format="").
|
||||
when we try to refer to properties on undefined objects. We need to be explicit
|
||||
about cases where this is expected.
|
||||
|
||||
Add this component to the `NgModule` _declarations_:
|
||||
Add `PhoneDetailComponent` component to the `NgModule` _declarations_ and _entryComponents_:
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ts', 'phonedetail', 'app.module.ts')
|
||||
|
||||
:marked
|
||||
In `main.ts` we'll now register a `phoneDetail` directive instead of a
|
||||
component. The directive is a downgraded version of the `PhoneDetail` Angular 2
|
||||
component.
|
||||
|
||||
+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'phone-detail', 'app/main.ts (excerpt)')(format='.')
|
||||
|
||||
:marked
|
||||
We should now also remove the phone detail component <script> tag from `index.html`.
|
||||
|
||||
### Add the _CheckmarkPipe_
|
||||
|
||||
The Angular 1 directive had a `checkmark` _filter_.
|
||||
Turn that into an Angular 2 **pipe**.
|
||||
Let's turn that into an Angular 2 **pipe**.
|
||||
|
||||
There is no upgrade adapter method to convert filters into pipes.
|
||||
There is no upgrade method to convert filters into pipes.
|
||||
You won't miss it.
|
||||
It's easy to turn the filter function into an equivalent Pipe class.
|
||||
The implementation is the same as before, repackaged in the `transform` method.
|
||||
@ -1462,10 +1450,12 @@ code-example(format="").
|
||||
|
||||
Now switch the bootstrap method of the application from the `UpgradeAdapter`
|
||||
to the Angular 2 way.
|
||||
Because this is a browser application, compiled with the Just-in-Time (JiT) compiler,
|
||||
use the `platformBrowserDynamic` function to bootstrap the `AppModule`:
|
||||
|
||||
Now we can drop `upgrade.bootstrap` from our application bootstrap, and remove the
|
||||
`ngDoBootstrap()` override from `app.module.ts`
|
||||
|
||||
+makeExample('upgrade-phonecat-3-final/ts/app/main.ts', null, 'main.ts')
|
||||
+makeExample('upgrade-phonecat-3-final/ts/app/app.module.ts', null, 'app.module.ts')
|
||||
|
||||
:marked
|
||||
You are now running a pure Angular 2 application!
|
||||
@ -1476,18 +1466,16 @@ code-example(format="").
|
||||
its new life as a pure, shiny Angular 2 app. The remaining tasks all have to
|
||||
do with removing code - which of course is every programmer's favorite task!
|
||||
|
||||
If you haven't already, remove all references to the `UpgradeAdapter` from `main.ts`.
|
||||
Also remove the Angular 1 bootstrap code.
|
||||
|
||||
When you're done, this is what `main.ts` should look like:
|
||||
|
||||
+makeExample('upgrade-phonecat-3-final/ts/app/main.ts', null, 'app/main.ts')
|
||||
If you haven't already, remove all references to the `UpgradeModule` from `app.module.ts`,
|
||||
as well as any [Factory provider](#making-angular-1-dependencies-injectable-to-angular-2) for Angular 1 services.
|
||||
Also remove any `downgradeComponent()` you find, together with the associated Angular 1
|
||||
directive declarations.
|
||||
|
||||
:marked
|
||||
You may also completely remove the following files. They are Angular 1
|
||||
module configuration files and not needed in Angular 2:
|
||||
|
||||
* `app/app.module.ts`
|
||||
* `app/app.module.ng1.ts`
|
||||
* `app/app.config.ts`
|
||||
* `app/core/core.module.ts`
|
||||
* `app/core/phone/phone.module.ts`
|
||||
@ -1498,7 +1486,7 @@ code-example(format="").
|
||||
we still need are for Jasmine and Angular 2 polyfills.
|
||||
|
||||
code-example(format="").
|
||||
npm uninstall @types/angular --save-dev
|
||||
npm uninstall @types/angular @types/angular-animate @types/angular-cookies @types/angular-mocks @types/angular-resource @types/angular-route @types/angular-sanitize --save-dev
|
||||
|
||||
:marked
|
||||
Finally, from `index.html`, remove all references to
|
||||
@ -1533,10 +1521,17 @@ code-example(format="").
|
||||
we don't change how the application behaves from the user's point of view.
|
||||
|
||||
During TypeScript conversion, there is nothing we have to do to keep E2E tests
|
||||
working. It is only when we start to upgrade components and their template to Angular 2
|
||||
that we need to make some changes. This is because the E2E tests have matchers
|
||||
that are specific to Angular 1. For PhoneCat we need to make the following changes
|
||||
in order to make things work with Angular 2:
|
||||
working. It is only when we change our bootstrap to that of an Hybrid app that we need to
|
||||
make some changes.
|
||||
|
||||
The following change is needed in `protractor-conf.js` to sync with hybrid apps:
|
||||
code-example(format="").
|
||||
ng12Hybrid: true
|
||||
|
||||
:marked
|
||||
The next set of changes is when we start to upgrade components and their template to Angular 2.
|
||||
This is because the E2E tests have matchers that are specific to Angular 1.
|
||||
For PhoneCat we need to make the following changes in order to make things work with Angular 2:
|
||||
|
||||
table
|
||||
tr
|
||||
@ -1596,11 +1591,13 @@ table
|
||||
|
||||
|
||||
:marked
|
||||
When the bootstrap method is switched from that of `UpgradeAdapter` to
|
||||
When the bootstrap method is switched from that of `UpgradeModule` to
|
||||
pure Angular 2, Angular 1 ceases to exist on the page completely.
|
||||
At this point we need to tell Protractor that it should not be looking for
|
||||
an Angular 1 app anymore, but instead it should find *Angular 2 apps* from
|
||||
the page. The following change is then needed in `protractor-conf.js`:
|
||||
the page.
|
||||
|
||||
Replace the `ng12Hybrid` previously added with the following in `protractor-conf.js`:
|
||||
|
||||
code-example(format="").
|
||||
useAllAngular2AppRoots: true,
|
||||
|
Loading…
x
Reference in New Issue
Block a user