$ocLazyload官网: https://oclazyload.readme.io/docs/getting-started
为什么要按需加载文件
当一个单页应用规模越来越大,一个ng-route或者ui-router要切换的路由或状态很多而且每个都有相对应的controller文件时,如果在index.html一开始就加载上百可能甚至上千个controller文件以及对应的css文件等外联文件时,网页速度往往会因为需要加载如此庞大的数据,加载时间会变得很冗长。我们有没有想过,一开始index.html的加载可能只需要一点点的数据处理,其他的能不能在切换到那个路由的时候,再加载那个路由所对应的所有相关文件,会省去很多页面加载的时间,这样也方便代码解读及后期维护。
$ocLazyLoad使用
今天这篇文章主要讲解一下$ocLazyLoad.js的使用,它实现了按需加载的功能,一般和ui-router组合使用的比较多。
安装
在git中,输入以下代码
bower install oclazyload
或者 npm install oclazyload
添加依赖
var app = angular.module("MyApp", ["oc.lazyLoad"]);
注意,这里依赖模块的名字是固定的,"oc.lazyLoad",切记不要写错。a
app.controller("MyController", function($ocLazyLoad) { $ocLazyLoad.load('testModule.js'); });
以上就是$ocLazyload的加载模块的简单例子。
$ocLazyLoad加载多种类型文件
$ocLazyLoad 可以加载模块,其他文件也是可以的, 比如controller、service、filter、css等与web app相关的文件都能加载。加载的时候要注意,你写的这些文件都是在已经存在的模块中,不然就加载不了。
$ocLazyLoad配置
angular.module('app', ['oc.lazyLoad']).config(['$ocLazyLoadProvider', function($ocLazyLoadProvider) { $ocLazyLoadProvider.config({ // ... }); }]);
选项 | 类型 | 默认值 |
---|---|---|
|
boolean |
false |
|
boolean |
false |
|
对象数组 |
undefined |
debug
:$ocLazyLoad 会返回一个promise对象,如果有报错时,promise对象会被拒绝(rejected), 也就是说,所有的errors不会显示。如果debug设为true,$ocLazyLoad会把所有的errors放在console上显示。
$ocLazyLoadProvider.config({ debug: true });
- events: 当你加载一个模块、js文件、css文件等时,$ocLazyLoad会广播一个事件,它默认是false,如果设为true时,则会激活它的功能。
这些事件有:
- ocLazyLoad.moduleLoaded
- ocLazyLoad.moduleReloaded
- ocLazyLoad.componentLoaded
- ocLazyLoad.fileLoaded
$ocLazyLoadProvider.config({ events: true });
$scope.$on('ocLazyLoad.moduleLoaded', function(e, module) { console.log('module loaded', module); });
- modules: 预定义一个模块,在之后用。再次之前,需要注册模块名字,及其文件地址。
$ocLazyLoadProvider.config({ modules: [{ name: 'TestModule', files: ['js/TestModule.js'] }] });
$ocLazyLoad.load('TestModule'); // will load the predefined configuration
$ocLazyLoad作为service
Parameter 针对本地加载器 | Type | Default value |
---|---|---|
|
Boolean |
true |
|
Boolean |
false |
|
Boolean |
false |
|
Boolean |
false |
|
Boolean |
undefined |
$ocLazyLoad.load({ cache: false, files: ['testModule.js', 'bower_components/bootstrap/dist/js/bootstrap.js'] });
reconfig: 如果重新加载模块,不会再次调用config代码块,这样可以手动操作再加载一次config代码
$ocLazyLoad.load({
reconfig: true,
files: ['testModule.js', 'bower_components/bootstrap/dist/js/bootstrap.js']
});
rerun: 重新运行块
$ocLazyLoad.load({
rerun: true,
files: ['testModule.js', 'bower_components/bootstrap/dist/js/bootstrap.js']
});
serie: 为true,打开平行加载文件功能
$ocLazyLoad.load({
serie: true,
files: [
'bower_components/angular-strap/dist/angular-strap.js',
'bower_components/angular-strap/dist/angular-strap.tpl.js'
]
});
insertBefore: 默认情况下,css文件会被加载在head元素中最后一个子元素之前插入文件,这里你可以写一个选择器重写它
$ocLazyLoad.load({
insertBefore: '#load_css_before',
files: ['bower_components/bootstrap/dist/css/bootstrap.css']
});
$ocLazyLoad作为directive
可以在tag中,输入指令,直接加载文件或者加载参数(文件路径已经放在了参数中)
<div oc-lazy-load="['js/testModule.js', 'partials/lazyLoadTemplate.html']"> <!-- Use a directive from TestModule --> <test-directive></test-directive> </div>
$scope.lazyLoadParams = [ 'js/testModule.js', 'partials/lazyLoadTemplate.html' ];
<div oc-lazy-load="lazyLoadParams"></div>
和ui-router一起使用
通常,$ocLazyLoad主要用于提前加载html模板所关联的文件,比如controller、css文件等,所以加载这些时,需要使用到resolve这个功能。resolve就是在这个路由或者状态被激活时,在html模板被加载之前,提前把需要的数据加载好。
$stateProvider.state('index', { url: "/", views: { "lazyLoadView": { controller: 'AppCtrl', templateUrl: 'partials/main.html' } }, resolve: { loadMyCtrl: ['$ocLazyLoad', function($ocLazyLoad) { return $ocLazyLoad.load('js/AppCtrl.js'); }] } });还有一点一定要记住的是,在加载模块后一定要写这些代码,不然达不到按需加载的效果, 报错ng-areq:
//配置动态加载
app.config(["$provide", "$compileProvider", "$controllerProvider", "$filterProvider",
function($provide, $compileProvider, $controllerProvider, $filterProvider) {
app.controller = $controllerProvider.register;
app.directive = $compileProvider.directive;
app.filter = $filterProvider.register;
app.factory = $provide.factory;
app.service = $provide.service;
app.constant = $provide.constant;
}
]);
具体原因还在查证。。。