Sample code for on how to lazy load state for ui-router
-
-
Save marcoslin/b59cfa9a9a44bde04f9f to your computer and use it in GitHub Desktop.
ui-router: Lazy Loading State
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
h4 { | |
color: blue; | |
} | |
a { | |
padding-right: 20px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html ng-app="lazyapp"> | |
<head> | |
<title>Lazying Loading Routes</title> | |
<link rel="stylesheet" href="css_style.css"> | |
</head> | |
<body> | |
<h3>Lazying Loading Routes: <a href="https://gist.github.com/marcoslin/b59cfa9a9a44bde04f9f" target="_blank">Source</a></h3> | |
<div ui-view></div> | |
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js" type="text/javascript"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js" type="text/javascript"></script> | |
<script src="js_app.js" type="text/javascript"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!function() { | |
var app = angular.module("lazyapp", ['ui.router']), | |
config_injector; | |
/** | |
* Configure state in 2 steps: | |
* 1. `app.config` will create `home` that leads to `view1` and `view2` | |
* 2. `LazyRoute` will configure sub-state `view1.profile` and `view1.interest` | |
* | |
* `LazyRoute` should be invoked in `View1Ctrl` to simulate the delegation nature | |
* of `$state` configuration. | |
*/ | |
app.config(function($stateProvider, $urlRouterProvider, $injector) { | |
$stateProvider | |
.state('home', { | |
url: '/home', | |
templateUrl: 'view_home.html', | |
controller: 'HomeCtrl' | |
}) | |
.state('view1', { | |
url: '/view1', | |
templateUrl: 'view_view1.html', | |
controller: 'View1Ctrl' | |
}) | |
.state('view2', { | |
url: '/view2', | |
templateUrl: 'view_view2.html', | |
controller: 'View2Ctrl' | |
}); | |
$urlRouterProvider | |
.otherwise('/home'); | |
// Cache injector | |
config_injector = $injector; | |
}); | |
app.factory("LazyRoute", function ($log) { | |
config_injector.invoke(function ($stateProvider) { | |
$stateProvider | |
.state('view1.profile', { | |
url: '/profile', | |
templateUrl: 'view_view1_profile.html' | |
}) | |
.state('view1.interests', { | |
url: '/interest', | |
templateUrl: 'view_view1_interest.html' | |
}); | |
$log.log("Sub View1 state configured."); | |
}); | |
return {}; | |
}); | |
/** | |
* When going directly to sub-state, load the parent state first then go to the sub-state. | |
* E.g.: If going to `view1.profile` and it doesn't yet exists, attempt to go to `view1` | |
* first then go to `view1.profile` if it exists. | |
* | |
* Note: The code below only works one level down. Need to improve it to recursively go down | |
* the route. | |
*/ | |
app.run(function ($rootScope, $state, $log) { | |
// var scope = $rootScope.$new(); | |
console.log("$stateNotFound configured."); | |
$rootScope.$on('$stateNotFound', function(event, unfoundState, fromState, fromParams) { | |
$log.log("$stateNotFound event: ", event); | |
$log.log("$stateNotFound unfoundState: ", unfoundState); | |
$log.log("$stateNotFound fromState: ", fromState); | |
$log.log("$stateNotFound fromParams: ", fromParams); | |
var toState = unfoundState.to, | |
toStateParent = toState; | |
if (toState.indexOf(".")) { | |
// Check if parent state is a valid state | |
var firstToState = toState.split(".")[0]; | |
if ($state.get(firstToState)) { | |
$log.log("Parent state '" + firstToState + "' found for '" + toState + "'" ); | |
toStateParent = firstToState; | |
// Load first the parent state | |
$state.go(toStateParent).then(function (resolved) { | |
// Only go to final state if it exists. | |
if ($state.get(toState)) { | |
return $state.go(toState); | |
} else { | |
// Go back to calling state | |
$log.log("Going back to ", fromState); | |
return $state.go(fromState.name); | |
} | |
}); | |
event.preventDefault(); | |
} else { | |
$log.error(toState + " state not found."); | |
} | |
}; | |
}); | |
}); | |
/** | |
* Define controllers | |
*/ | |
app.controller("HomeCtrl", function ($scope) { | |
$scope.message = "Message from HomeCtrl"; | |
}); | |
app.controller("View1Ctrl", function ($scope, $state, LazyRoute, $log) { | |
$log.log("view1 controller called with scope id " + $scope.$id); | |
$scope.isState = $state.is; | |
$scope.message = "Message from View1Ctrl with state"; | |
}); | |
app.controller("View2Ctrl", function ($scope, $log) { | |
$log.log("view1 controller called with scope id " + $scope.$id); | |
$scope.message = "A View2Controller Message"; | |
}); | |
}(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h2>Home Page</h2> | |
<div>Message: {{message}}</div> | |
<hr> | |
<a ui-sref="view1">View 1</a> | |
<a ui-sref="view2">View 2</a> | |
<a ui-sref="view1.profile">View1Profile</a> | |
<a ui-sref="view1.notexists">View1NotExists</a> | |
<a ui-sref="view3">View3NotExists</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h2>View1</h2> | |
<div>View Message: {{message}}</div> | |
<h3>Detail</h3> | |
<div ui-view></div> | |
<h4 ng-show="isState('view1')">View 1 Main Page</h4> | |
<hr> | |
<a ui-sref="home">Home</a> | |
<a ui-sref="view1.profile">Profile</a> | |
<a ui-sref="view1.interests">Interests</a> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h4>Nested View: Interest</h4> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h4>Profile SubView</h4> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h2>View2</h2> | |
<div>View Message: {{message}}</div> | |
<hr> | |
<a ui-sref="home">Home</a> | |
<a ui-sref="view1.profile">View1Profile</a> | |
<a ui-sref="view1.notexists">View1NotExists</a> | |
<a ui-sref="view3">View3NotExists</a> |
Nice job! It really helped me, tnx for sharing it ;)
thank marcos 😄
@frankie .success is deprecated, you should be using .then/.catch
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Marcos,
I really appreciate this example! It's really helped me actually get something working for a lazy load for post authenticated user login. I am still uncertain of a few things and was wondering if you might know the answers?
Again, I really thank you for you sharing this code, it's helped me get really far.
I just needed to have the injected states be not so hard coded into the app and have a way to un-register the states.
Any ideas on removing a state after it's already loaded? Clearing it out of the apps config or registration?
Thanks a Ton Marcos!,
Frankie Loscavio