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: commit17c7e15467
Author: Filipe Silva <filipematossilva@gmail.com> Date: Mon Nov 14 23:11:37 2016 +0000 chore: update to 2.2.0 (#2797) commit1e5facfb98
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 commit5c4cc9a3c8
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 commit43457e9765
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) commit1afe5dc97d
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 commitdb0fac94c9
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 commita423a5abc7
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. commitd63b1ccea3
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) commitf627706779
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 commit75464d585c
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 commit78e25840b2
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 commit182493f877
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 commit53f5538859
Author: Ward Bell <wardbell@hotmail.com> Date: Sun Nov 13 14:09:28 2016 -0800 docs(cb-ts-to-js): refactor sample code commit9e9666b2cc
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. commit5dcffd69dc
Author: Patrice Chalin <pchalin@gmail.com> Date: Sun Nov 13 19:37:13 2016 -0800 docs: dart glossary - fix misnamed Jade block commit6680acc513
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.) commit3b03573f34
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.) commit470426d5e0
Author: Patrice Chalin <pchalin@gmail.com> Date: Mon Nov 14 05:25:36 2016 -0800 update _cache commitc12d75a477
Author: Patrice Chalin <pchalin@gmail.com> Date: Mon Nov 14 05:23:35 2016 -0800 remove redundant headings commit85062c47ca
Author: Patrice Chalin <pchalin@gmail.com> Date: Mon Nov 14 04:56:12 2016 -0800 chore(util.js): getExampleName - support optional .html suffix commit02f55592b2
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`. commit14db838f8b
Author: Naomi Black <naomitraveller@gmail.com> Date: Sun Nov 13 21:48:52 2016 -0500 news(nov): Some news and a blog post update commiteff32ecbdd
Author: Naomi Black <naomitraveller@gmail.com> Date: Sun Nov 13 21:48:37 2016 -0500 chore(bios): update some bios for leads commit3ee36fbba2
Author: koyner <markburrett@gmail.com> Date: Sun Nov 13 22:59:59 2016 +0100 docs(forms): grammar fix (#2764) commitb11438f211
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 commit33b61977b2
Author: Ward Bell <wardbell@hotmail.com> Date: Thu Nov 3 01:37:55 2016 -0700 docs(ts-to-js): ward's edits (incomplete) commit12eb19fa3c
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 commit64a8754386
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) commit7619cdf4a4
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) commit0161d9db39
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 commitf92983cc6f
Author: Jesús Rodríguez <Foxandxss@gmail.com> Date: Thu Nov 10 23:44:51 2016 +0100 docs(ngmodule): fix plunkers (#2786) commit03db4bbc48
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) commit60565a5cf1
Author: Pavol Pitonak <pavol@pitonak.com> Date: Wed Nov 9 17:42:57 2016 +0100 docs(testing): configureTestModule -> configureTestingModule (#2767) commitec471974a7
Author: Catalin Zalog <xxxxxcata@yahoo.com> Date: Wed Nov 9 18:41:56 2016 +0200 docs(style-guide): fix missing *.ts (#2763) commit234e468d5d
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. commit6b37da78e4
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 commitc24dd074a6
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 commit2808878c36
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. commit2649647ecb
Author: Jesus Rodriguez <Foxandxss@gmail.com> Date: Sat Nov 5 00:37:47 2016 +0100 chore: add upgrade/static to API reference commit850814097f
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 commit37f93bc0cb
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 commitb1c2c27d36
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
|
@ -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');
|
|
@ -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…
Reference in New Issue