-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathangular-lazyload.js
142 lines (133 loc) · 4.83 KB
/
angular-lazyload.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*! angular-lazyload - v0.4.0 - https://github.com/atian25/angular-lazyload - 2013-10-28 */
/**
* A lazyload service for angular projects, only load-on-demand, support seajs/requirejs/custom.
* support [Sea.js](http://seajs.org/) & [RequireJS](http://requirejs.org/)
*
* @author TZ <[email protected]>
* @home https://github.com/atian25/angular-lazyload
*/
(function(global, undefined) {
'use strict';
/**
* register `angular-lazyload` module & `$lazyload` service
*/
angular.module('angular-lazyload', [], ['$controllerProvider', '$compileProvider', '$filterProvider', '$provide',
function ($controllerProvider, $compileProvider, $filterProvider, $provide) {
//register `$lazyload` service
$provide.factory('$lazyload', ['$rootScope', '$q', function($rootScope, $q){
//hold provide's refs, because after ng bootstrap, you can't use `app.controller` to dynamic register controller.
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 Service
*/
function LazyLoadProvider($rootScope, $q, register){
//patch the $rootScope, add `safeApply` function.
patchScope($rootScope);
/**
* hold provide's refs, because after ng bootstrap, you can't use `app.controller` to dynamic register controller.
*/
this.register = register;
/**
* @param {Object} params This will pass to the lazy load module
* @param {String} eventName Default to `$routeChangeStart`, //TODO: support `ui-route`
* @param {Function/String} loaderType The loader function: //FIXME: only support `seajs` current.
* - 'seajs' : default value, use [Sea.js](http://seajs.org/) to async load modules
* - 'requirejs': use [RequireJS](http://requirejs.org/) to async load modules
* - {Object} : custom loader:
* - check {Function} Optional , check whether need to load by loader
* - load {Function}
* - route : current route item
* - register: register refs object
* - callback : callback function when async load success
*/
this.init = function(params, loaderType){
//get loaderFn: if loaderType is function, then just use it, else use build in loader by loaderType, default to seajs
var loader = angular.isObject(loaderType) ? loaderType : this.loaders[loaderType] || this.loaders['seajs'];
//listen to route change event to hook
$rootScope.$on('$routeChangeStart', function(e, target){
//console.debug(e, '|', target);
var route = target && target.$$route;
if(route){
// if loader provide check(), then check it
if(!angular.isFunction(loader.check) || loader.check(route)){
route.resolve = route.resolve || {};
//keypoint: use `route.resolve`
route.resolve.loadedModule = function(){
var defer = $q.defer();
loader.load(route, function(m){
$rootScope.safeApply(function(){
defer.resolve(angular.isFunction(m) ? m(params, register) : m);
});
}, function(m){
$rootScope.safeApply(function(){
defer.reject(m);
});
});
return defer.promise;
}
}
}
});
}
}
/**
* build-in loaders
*/
LazyLoadProvider.prototype.loaders = {};
LazyLoadProvider.prototype.loaders['seajs'] = {
check: function(route){
//if exsit `controllerUrl` then trigger seajs async load.
return typeof route.controllerUrl == 'string'
},
load: function(route, suc, fail){
seajs.use(route.controllerUrl, function(m){
if(angular.isUndefined(m)){
fail(m);
}else{
suc(m);
}
});
}
}
LazyLoadProvider.prototype.loaders['requirejs'] = {
check: function(route){
//if exsit `controllerUrl` then trigger requirejs async load.
return typeof route.controllerUrl == 'string'
},
load: function(route, suc, fail){
require(route.controllerUrl, function(m){
if(angular.isUndefined(m)){
fail(m);
}else{
suc(m);
}
});
}
}
/**
* 为$rootScope增加safeApply方法, 安全的apply
*/
function patchScope($rootScope){
$rootScope.safeApply = function(fn){
var phase = this.$root.$$phase;
if(phase == '$apply' || phase == '$digest') {
if(fn && (typeof(fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
};
}
})(this);