-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Lazy loading of states defined in child components
Gan Lu edited this page Oct 3, 2016
·
2 revisions
If you have states defined in a child component which is lazy loaded, the states are not available before the component is loaded. That means you cannot $state.go to the lazy loaded states or navigate to the URL corresponding to the state directly.
Consider the following scenario:
-- home/
---- posts/
------ posts.component.js
------ posts.js // defined the child state "home.posts", with URL "/home/posts".
---- profile/
------ profile.component.js
------ profile.js // defined the child state "home.profile", with URL "/home/profile".
---- home.component.js
---- home.js // defined the parent state "home".
Now that we added code splitting point in "home.js" and lazy loaded "posts" and "profile" with oclazyload, we cannot go to "/home/profile" directly in a browser since the state definition is not loaded yet.
To solve this problem we could use the Future State feature provided by ui-router-extras to implement the lazy loading of states with a few lines of code:
// home.js
import angular from 'angular';
import uiRouter from 'angular-ui-router';
import 'ui-router-extras/release/modular/ct-ui-router-extras.core';
import 'ui-router-extras/release/modular/ct-ui-router-extras.future';
import 'oclazyload';
let homeModule = angular.module('home', [
uiRouter,
"ct.ui.router.extras.future",
"oc.lazyLoad"
])
.config(($futureStateProvider, $compileProvider) => {
"ngInject";
$futureStateProvider.futureState({
'stateName': 'home',
'urlPrefix': '/home',
'type': 'homeState'
});
$futureStateProvider.stateFactory('homeState', ($q, $ocLazyLoad) => {
"ngInject";
let deferred = $q.defer();
// Webpack code splitting point
require.ensure([], function(require){
// In babel 6 ".default" must be manually added
let postsModule = require('./posts/posts').default;
let profileModule = require('./profile/profile').default;
let homeComponent = require('./home.component').default;
$ocLazyLoad
.inject([
postsModule,
profileModule
])
.then(() => {
$compileProvider.component('home', homeComponent);
})
.then(() => {
deferred.resolve({
name: 'home',
url: '/home',
component: 'home'
});
});
}, 'home');
return deferred.promise;
});
})
.name;
export default homeModule;