- Notifications
You must be signed in to change notification settings - Fork77
Upgrade an ng1 UI-Router app to a ng1+ng2 hybrid using ng-upgrade
License
ui-router/angular-hybrid
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This module providesngUpgrade integration with UI-Router.It enables UI-Router to route to both AngularJS components (and/or templates) and Angular components.
Your app will be hosted by AngularJS while you incrementally upgrade it to Angular.With@uirouter/angular-hybrid you can use either an Angular component or an AngularJS component/template as the view in a state definition.
import{Ng2AboutComponentClass}from"./about.ng2.component";/// ...$stateProvider.state({name:'home',url:'/home',component:'ng1HomeComponent'// AngularJS component or directive name}).state({name:'about',url:'/about',component:Ng2AboutComponentClass// Angular component class reference});.state({name:'other',url:'/other',template:'<h1>Other</h1>',// AngularJS template/controllercontroller:function($scope){/* do stuff */}})
When routing to an Angular component, that component uses the standardAngular directives (ui-view and uiSref) from@uirouter/angular.
When routing to an AngularJS component or template, that component uses the standardAngularJS directives (ui-view and ui-sref) from@uirouter/angularjs.
See thehybrid sample app for a full example.
Removeangular-ui-router (or@uirouter/angularjs) from your AngularJS app's package.json and replace it with@uirouter/angular-hybrid.Add the@angular/* dependencies.
dependencies: { ... "@angular/common": "^6.0.0", "@angular/compiler": "^6.0.0", "@angular/core": "^6.0.0", "@angular/platform-browser": "^6.0.0", "@angular/platform-browser-dynamic": "^6.0.0", "@angular/upgrade": "^6.0.0", ... "@uirouter/angular-hybrid": "^6.0.0", ...}Remove anyng-app attributes from your main HTML file.We need to use manual AngularJS bootstrapping mode.
- Add 'ui.router.upgrade' to your AngularJS app module's depedencies
letng1module=angular.module('myApp',['ui.router','ui.router.upgrade']);
- Import the
BrowserModule,UpgradeModule, and aUIRouterUpgradeModule.forRoot()module. - Add
providersentry for any AngularJS services you want to expose to Angular. - The module should have a
ngDoBootstrapmethod which calls theUpgradeModule'sbootstrapmethod.
exportfunctiongetDialogService($injector){return$injector.get('DialogService');}@NgModule({imports:[BrowserModule,// Provide angular upgrade capabilitiesUpgradeModule,// Provides the@uirouter/angular directives and registers// the future state for the lazy loaded contacts moduleUIRouterUpgradeModule.forRoot({states:[contactsFutureState]}),],providers:[// Provide the SystemJsNgModuleLoader when using Angular lazy loading{provide:NgModuleFactoryLoader,useClass:SystemJsNgModuleLoader},// Register some AngularJS services as Angular providers{provide:'DialogService',deps:['$injector'],useFactory:getDialogService},{provide:'Contacts',deps:['$injector'],useFactory:getContactsService},]})exportclassSampleAppModuleAngular{constructor(privateupgrade:UpgradeModule){}ngDoBootstrap(){this.upgrade.bootstrap(document.body,[sampleAppModuleAngularJS.name],{strictDi:true});}}
Tell UI-Router that it should wait until all bootstrapping is complete before doing the initial URL synchronization.
ngmodule.config(['$urlServiceProvider',($urlService:UrlService)=>$urlService.deferIntercept()]);
- Bootstrap Angular
- Angular runs ngDoBootstrap() which bootstraps AngularJS
- Chain off
bootstrapModule()and tell UIRouter to synchronize the URL and listen for further URL changes- Do this in the Angular Zone to avoid "digest already in progress" errors.
platformBrowserDynamic().bootstrapModule(SampleAppModuleAngular).then((platformRef)=>{// Intialize the Angular Module// get() the UIRouter instance from DI to initialize the routerconsturlService:UrlService=platformRef.injector.get(UIRouter).urlService;// Instruct UIRouter to listen to URL changesfunctionstartUIRouter(){urlService.listen();urlService.sync();}platformRef.injector.get<NgZone>NgZone.run(startUIRouter);});
Your existing AngularJS routes work the same as before.
var foo = { name: 'foo', url: '/foo', component: 'fooComponent'};$stateProvider.state(foo);var bar = { name: 'foo.bar', url: '/bar', templateUrl: '/bar.html', controller: 'BarController'};$stateProvider.state(bar);Register states using either Angular or AngularJS code.Usecomponent: in your state declaration.
var leaf = { name: 'foo.bar.leaf', url: '/leaf', component: MyNg2CommponentClass};$stateProvider.state(leaf);@NgModule({imports:[UIRouterUpgradeModule.forChild({states:[featureState1,featureState2],}),],declarations:[FeatureComponent1,FeatureComponent2],})exportclassMyFeatureModule{}
Add the feature module to the root NgModule imports
@NgModule({imports:[BrowserModule,UIRouterUpgradeModule.forChild({ states}),MyFeatureModule],})classSampleAppModule{}
We currently support routing either Angular (2+) or AngularJS (1.x) components into an AngularJS (1.x)ui-view.However, we do not support routing AngularJS (1.x) components into an Angular (2+)ui-view.
If you create an Angular (2+)ui-view, then any nestedui-view must also be Angular (2+).
Because of this, apps should be migrated starting from leaf states/views and work up towards the root state/view.
Resolve blocks on state definitions are always injected using AngularJS style string injection tokens.
- UI-Router for AngularJS injects objects using string tokens, such as
'$transition$','$state', or'currentUser'.
resolve:{ roles:($authService,currentUser)=>$authService.fetchRoles(currentUser);}
- UI-Router for Angular uses theTransition.injector() API.The resolve function receives the
Transitionobject as the first argument.
// In Angular, the first argument to a resolve is always the Transition object// The resolver (usually) must be exportedexportconstrolesResolver=(transition)=>{constauthService=transition.injector().get(AuthService);constcurrentUser=transition.injector().get('currentUser');returnauthService.fetchRoles(currentUser);}...resolve:{roles:rolesResolver}
In UI-Router for Angular/AngularJS hybrid mode,all resolves are injected using AngularJS style.If you need to inject Angular services by class, or need to use some other token-based injection such as anInjectionToken,access them by injecting the$transition$ object using string-based injection.Then, use theTransition.injector() API to access your services and values.
import{AuthService,UserToken}from'./auth.service';// Notice that the `Transition` object is first injected// into the resolver using the '$transition$' string tokenexportconstrolesResolver=function($transition$){// Get the AuthService using a class tokenconstauthService:AuthService=transition.injector().get(AuthService);// Get the user object using an InjectionTokenconstuser=transition.injector().get(UserToken);returnauthService.fetchRoles(user).then((resp)=>resp.roles);};exportconstNG2_STATE={name:'ng2state',url:'/ng2state',component:Ng2Component,resolve:{roles:rolesResolver,},};
When a state has anonEnter,onExit, oronRetain, they are always injected (AngularJS style),even if the state uses Angular 2+ components or is added to anUIRouterUpgradeModuleNgModule.
exportfunctionng2StateOnEnter(transition:Transition,svc:MyService){console.log(transition.to().name+svc.getThing());}ng2StateOnEnter.$inject=[Transition,'MyService'];exportconstNG2_STATE={name:'ng2state',url:'/ng2state',onEnter:ng2StateOnEnter,};
The minimal example of@uirouter/angular-hybrid can be found here:https://github.com/ui-router/angular-hybrid/tree/master/example
A minimal example can also be found on stackblitz:https://stackblitz.com/edit/ui-router-angular-hybrid
A large sample application example with lazy loaded modules can be found here:https://github.com/ui-router/sample-app-angular-hybrid
The same sample application can be live-edited using Angular CLI and StackBlitz here:https://stackblitz.com/github/ui-router/sample-app-angular-hybrid/tree/angular-cli
Version 2.0.0 of@uirouter/angular-hybrid only supportsUpgradeAdapter, which works fine but is no longer in development.Version 3.0.0+ of@uirouter/angular-hybrid only supportsUpgradeModule from@angular/upgrade/static, which is what the Angular team actively supports for hybrid mode.Because we dropped support forUpgradeAdapter, current users of@uirouter/angular-hybrid 2.x will have to switch toUpgradeModule when upgrading to 3.x.
About
Upgrade an ng1 UI-Router app to a ng1+ng2 hybrid using ng-upgrade
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.