标签:
最初的源码来自:https://github.com/atian25/angular-lazyload/
但由于一些个人的原因(我有强迫症...)所以把代码的书写风格按照我平日的喜好修改了下
也顺便认真的阅读了一遍源码,按照自己的理解,把原来的英文注释替换成中文的了
毕竟不是原作者,对ng框架也不是特别的熟,注释中的用词可能有不少不正确的地方,欢迎指出
下面是我稍微修改了一下的代码:
/*
* angular-lazyLoad
* 一个angular项目的按需异步加载服务模块
* 支持 [Sea.js](http://seajs.org/) & [RequireJS](http://requirejs.org/)
*/
(function() {
‘use strict‘;
//定义 angular-lazyLoad 模块 & $lazyLoad 服务
angular.module(‘ngLazyLoad‘, [], [‘$controllerProvider‘, ‘$compileProvider‘, ‘$filterProvider‘, ‘$provide‘,
function ($controllerProvider, $compileProvider, $filterProvider, $provide) {
//定义 $lazyLoad 服务
$provide.factory(‘$lazyLoad‘, [‘$rootScope‘, ‘$q‘, function($rootScope, $q){
/*
* 在代码的运行后,你是无法使用 app.controller(...) 方式来定义控制器的
* 只能通过 $controllerProvider.register 方法来定义控制器
* 定义一个 register 对象缓存这些低阶方法,在构造 $lazyLoad 服务对象时作为参数传入
* */
var register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service,
decorator: $provide.decorator
};
return new LazyLoadProvider($rootScope, $q, register);
}]);
}
]);
/**
* $lazyload 服务类
*/
function LazyLoadProvider($rootScope, $q, register){
var _this = this;
_this.$$rootScope = $rootScope;
_this.$$q = $q;
_this.register = register;
//为 $rootScope 添加 safeApply 方法
_this.patchScope();
}
/**
* @param {Object} app 需要异步添加控制器的app主模块
* @param {Function/String} loader 加载器类型,取值范围如下:
* - ‘seaJS‘ : 默认值,使用 seaJS 去异步加载模块
* - ‘requireJS‘: 使用 requireJS 去异步加载模块
* - {Object} : 自定义加载器,此对象应该包含下面两个属性:
* - check {Function} 检测方法,检测路由切换后,是否需要异步加载模块
* - load {Function} 加载方法,应该包含三个参数:当前路由对象(用来获取controllerUrl属性的值),加载成功回调,加载失败回调
*/
LazyLoadProvider.prototype.init = function(app, loader){
//根据loader参数,来决定用什么加载器
var _this = this,
_loader = angular.isObject(loader) ? loader : this.loaders[loader] || this.loaders[‘seaJS‘];
//给app主模块添加register,以便可以使用低阶方法定义控制器
app.register = _this.register;
//监听 $routeChangeStart 事件
_this.$$rootScope.$on(‘$routeChangeStart‘, function(event, curRoute){
var route = curRoute && curRoute.$$route;
if(route){
if(typeof _loader.check == ‘function‘ && _loader.check(route)){
route.resolve = route.resolve || {};
/*
* 关键点:使用route的resolve对象
* 每当路由变更时,angular都会遍历route的resolve对象的各个属性
* 如果某个是指向一个函数,那么该函数就会被马上执行
*/
route.resolve.loadedModule = function(){
var defer = _this.$$q.defer();
_loader.load(route,
function(module){
_this.$$rootScope.safeApply(function(){
defer.resolve(angular.isFunction(module) ? module(app) : module);
});
},
function(module){
_this.$$rootScope.safeApply(function(){
defer.reject(module);
});
});
return defer.promise;
};
}
}
});
};
//为 $rootScope 增加 safeApply 方法, 安全的apply
LazyLoadProvider.prototype.patchScope = function(){
var _this = this;
_this.$$rootScope.safeApply = function(fn){
var phase = this.$root.$$phase;
if(phase == ‘$apply‘ || phase == ‘$digest‘){
if(fn && (typeof(fn) === ‘function‘)){
fn();
}
}else{
this.$apply(fn);
}
};
};
LazyLoadProvider.prototype.loaders = {};
LazyLoadProvider.prototype.loaders[‘seaJS‘] = {
check: function(route){
//当存在 controllerUrl 属性,且其类型为字符串时,路由变更后才执行异步加载方法
return typeof route.controllerUrl == ‘string‘
},
load: function(route, suc, fail){
seajs.use(route.controllerUrl, function(module){
if(angular.isUndefined(module)){
fail(module);
}else{
suc(module);
}
});
}
};
LazyLoadProvider.prototype.loaders[‘requireJS‘] = {
check: function(route){
//当存在 controllerUrl 属性,且其类型为字符串时,路由变更后才执行异步加载方法
return typeof route.controllerUrl == ‘string‘
},
load: function(route, suc, fail){
require(route.controllerUrl, function(module){
if(angular.isUndefined(module)){
fail(module);
}else{
suc(module);
}
});
}
};
})();
使用方法和原作也有一丝丝区别,其实只是省去了一行代码,这里也搬一下吧~
1.将代码引入到你的项目页面中去(下面几个基本上可以说是必备的了)
<script src="libs/angular.js"></script>
<script src="libs/angular-route.js"></script>
<script src="libs/angular-lazyLoad.js"></script>
<script src="libs/sea.js" id="seajsnode"></script>
2.手动执行angular.bootstrap
seajs.use("app", function(app){
angular.bootstrap(document, ["app"]);
});
3.将ngLazyLoad添加到你的主模块依赖中去
var app = angular.module("app", ["ngLazyLoad", "ngRoute"]);
4.在app.run方法中初始化
app.run(["$lazyLoad", function($lazyLoad){
$lazyLoad.init(app);
...
}]);
5.路由映射中,添加controllerUrl属性
$routeProvider
.when("/login", {
controller: "loginCtrl",
controllerUrl: "js/controllers/login.js",
templateUrl: "app/templates/login.html"
});
6.在你的模块里,通过 app.register.controller 方法来定义控制器
define(function(require, exports, module){
"use strict";
module.exports = function(app){
app.register.controller("loginCtrl", ["$scope", function($scope){
...
}]);
}
}
ngLazyLoad——让ng项目实现controllers按需异步加载
标签:
原文地址:http://www.cnblogs.com/czf-zone/p/4296676.html