angular使用requirejs/ui-router/angularAMD实现动态加载模块
来源:互联网 发布:南方电网待遇 知乎 编辑:程序博客网 时间:2024/06/05 18:52
最近在做angular项目,发现使用requirejs来加载模块的时候,它会根据已经建立好的依赖一次性把所有模块加载下来,而我们的项目中有两个不同的产品,我们希望进入每个产品时只加载该产品对应的模块。但是要结合ui-router来实现,网上的例子还实在少,好不容易有同事搜到类似的解决方案,试了半天终于成功了,原文章在这里:
http://christopherthielen.github.io/ui-router-extras/#/future
文章写的相当简洁,具体概念原理大家自己去看文章吧,这里就大家分享一下本项目中如何使用它的。。
1,首先需要引用一些库:
bower install angularAMD --save ---------angularAMD用来动态加载js文件和js模块,依赖于angular。这里我们使用angularAMD中的ngload来动态加载模块。
bower install ui-router-extra --save --------- ui-router-extra是ui-router的扩展包,主要是用到其中的futureState。futureState是在config时候定义,但真正跳转的时候会用一个full ui-router替换。这个full ui-router到时候会用$stateProvider。具体在例子里面解释。
2. 在require的config文件里面定义各种引用:
require.config({
baseUrl: '../',
paths: {
...
'angularUiRouterExtra':'xxx/ui-router-extras/release/ct-ui-router-extras.min', //for lazy load
'angularAMD':'xxx/angularAMD/angularAMD.min', //for lazy load
'ngload':'xxx/angularAMD/ngload.min', //for lazy load
},
shim: {
...
'angularAMD':{
deps:['angular']
},
'angularUiRouter': {
deps: ['angular']
},
'ngload':{
deps:['angularAMD']
},
'angularUiRouterExtra':{
deps:['angular']
}
...
}
});
require(['app'], function(app) { //init the application
app.init();
});
3. 定义futureState的声明
定义一个futureStates.json文件:
[{
"stateName": "module1", //future state name
"urlPrefix": "/module1", //url
"type": "ngload",
"src": "xxx/module1.js"
}...]
用一个json文件是为了便于管理到时候要lazy load的那些state
4. module1.js -----this is the module to lazy load
define(['angularAMD',
], function(angularAMD) {
'use strict';
var module1 = angular.module('module1',['ui.router']);
var mainState = { //this is the full ui-router state definition
name:'module1',
url:'/module1',
templateUrl:'xxx/test.html',
controller:function($scope){
$scope.test = "test";
}
};
module1.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state(rfxState); //use $stateProvider to register full ui-router state definition
}]);
return { mainState: mainState, module: module1 }; //这里一定要这样返回啊!跟以前直接返回一个module不一样哦!
});
5. app.js
define([
'angularAMD', //for lazy loading,replace angular with angularAMD
'angularUiRouter', //define
'angularUiRouterExtra', //for lazy loading
...
], function(angularAMD, _) {
'use strict';
var app = angular.module('app', [
'ui.router',
'ct.ui.router.extras',
...
]);
app.init = function() {
angularAMD.bootstrap(app); //replace angular.bootstrap(document, ['app']);
};
app.config(['$stateProvider', '$urlRouterProvider','$controllerProvider','$futureStateProvider',
function($stateProvider, $urlRouterProvider,$controllerProvider, $futureStateProvider) {
var loadAndRegisterFutureStates = function($http) {
return $http.get('xxx/futureStates.json').then(function (resp) {
angular.forEach(resp.data, function (fstate) {
// Register each state returned from $http.get() with $futureStateProvider
$futureStateProvider.futureState(fstate); //#1
// futureStates.json contains all the future states declaration
});
});
};
//#2
$futureStateProvider.stateFactory('ngload', ngloadStateFactory);// register AngularAMD ngload state factory
//#3
$futureStateProvider.addResolve(loadAndRegisterFutureStates);
}
]);
app.run(['$rootScope',
function($rootScope) {
$rootScope._ = _;
}
]);
return app;
function ngloadStateFactory($q, futureState) {
var ngloadDeferred = $q.defer();
require([ "ngload!" + futureState.src , 'ngload', 'angularAMD'],
function ngloadCallback(result, ngload, angularAMD) {
angularAMD.processQueue();
ngloadDeferred.resolve(result.entryState);
});
return ngloadDeferred.promise;
}
});
好了代码上完了,下面解释一下这些代码的工作流程和原理。
在以前的做法中,我们直接使用requirejs来建立app module对module1的依赖关系:
define([
...
’xxx/module1' //include module1.js file before loading app.js
...
], function(angular, _) {
'use strict';
var app = angular.module('app', [
...
'module1', //build the dependency of module1,
}
这样,在加载app module之前,根据requirejs建立的依赖关系,angular会先去加载module1模块
而现在,我们不在定义中建立这种依赖关系,当我们启动app模块时,module1模块还没有被加载进来。这时候如果我们通过ui访问module1 state时(比如点击module1的state或者href),但其实这个module1 state还不存在(还没加载进来),然后$futureStatesProvider会去futureState中看有没有module1 state的定义。(#1的code,futureStates.json里面的futureState定义,$futureStateProvider.futureState(fstate);)。当找到这个futureState(里面定义了type为ngload, 并且有url和src文件位置)时,ngloadStateFactory就起作用了。
#2的code,$futureStateProvider.stateFactory('ngload', ngloadStateFactory); 注册了type为ngload(动态加载模块)的factory, 该factory将会用build full Ui-Router module1。ngloadStateFactory的写法大家看代码,这里就不啰嗦了。
最后看#3的代码$futureStateProvider.addResolve
(resolveFunction
)。这个方法其实就是添加了一个resolve函数,这个函数返回的是个promise。具体概念自己去查,这里就不介绍了。。
总结:
发现把代码扒拉干净以后其实好简单,但里面有些概念和写法还是半知半解的。另外,原文里面的例子还提供了iframeStateFactory和lazyCtrlStateFactory,这里项目没有用到,也就没有去试,大家有兴趣可以自己去实现看看,实现以后记得共享一下哦
- angular使用requirejs/ui-router/angularAMD实现动态加载模块
- Angular-Ui-Router+ocLazyLoad动态加载脚本
- Angular+Requirejs实现模块按需加载
- angular+ui-router+requirejs整合demo
- angular 使用 ui-router(1)
- angular-ui/ui-router的使用
- angularJS+ui-router+requireJS异步加载controller、directive、filter
- angular 使用 ui-router 设计网页
- angular 使用 ui-router 设计网页
- angular 使用 ui-router 设计网页
- angular 路由,ui-router,ocLazyLoad的使用
- 使用angular ui-router的一点感受
- angular+ui-router+layui的使用心得
- angular 使用 ui-router 设计网页
- angular router ui 路由模块(父子)层级说明
- Angular-Ui-Router
- Angular路由:ui-router
- Angular ui-router 入门
- Apache Storm的由来与成功介绍
- 浅谈—分销系统管理
- 堆排序
- Table of results for Caltech 101 dataset
- How to display column values in a single cell in Web Intelligence using Oracle database ?
- angular使用requirejs/ui-router/angularAMD实现动态加载模块
- arm汇编指令中叹号作用
- php 获取上个月、下个月、本月的日期
- 【Java.IO】I/O 【字节/字符】【节点流】 - 之 - 【管道流】 - Piped*
- bind() to 0.0.0.0:80 failed (98: Address already in use)
- 第8周 项目4 个人所得税计算器
- POJ 1012 Joseph
- 【ThinkingInC++】73、深入理解模板
- MSChart 的常用属性、事件、数据源绑定