失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Angular+Requirejs实现模块按需加载

Angular+Requirejs实现模块按需加载

时间:2019-12-18 13:10:20

相关推荐

Angular+Requirejs实现模块按需加载

Aangular作为前端开发利器,被广大前端研发人员所熟知,本人从接触到现在快有两年时间了,负责和Angular相关的产品也有10几个,有业务逻辑复杂的,有业务简单的,业务简单架构就简单,怎么搭建都行,只要开发效率快,维护成本低就可以,但是针对于复杂的业务逻辑,就会遇到很多问题,如果在初始化的时候进行互相依赖加载,那样首次加载,如果使用angular-ui-router进行路由管理,就需要将所有state依赖的的controller文件全部加载进来,由于业务复杂,controller文件有可能会有很多,还不包括资源类的请求,这样首次加载会非常缓慢,影响用户体验。

为了解决首次加载问题,首次加载只加载公共资源,并且将业务模块进行细化,每个路由状态对应相应的业务模块,首次加载只提供给用户的某一个模块,让首次加载更加轻量化,其他业务模块在路由状态切换时进行动态加载,也就是所谓的按需加载,最终选择方引用第三方组件angularAMD和ct-ui-router-extras来解决。

angularAMD是实现angular的controller、service异步加载的核心组件,ct-ui-router-extras是ui-router的扩展插件, 进行状态管理,它主要是监听路由状态变化,具体文档大家可以戳这里:http://christopherthielen.github.io/ui-router-extras/#/home,主要是用到其中的futureState,在应用启动时候在config中对futureState进行初始化,将所有的路由状态配置到 futureState中,在路由发生变化时,先判断路由状态是否存在,如果不存在,则会调用初始化时注册的angularAMD的ngload服务,实现对模块以及依赖的异步加载。

初始化配置

config(['$futureStateProvider','$locationProvider',function($futureStateProvider,$locationProvider) {var loadAndRegisterFutureStates = ['$http','lazyHerper',function ($http,lazyHerper) {return lazyHerper.getLazyModuleCfg().then(function(moduleCfg){angular.forEach(moduleCfg, function (cfg) {$futureStateProvider.futureState(cfg);});});}];$futureStateProvider.stateFactory('ngload', ngloadStateFactory); // register AngularAMD ngload state factory$futureStateProvider.stateFactory('iframe', iframeStateFactory); // register silly iframe state factory$futureStateProvider.stateFactory('requireCtrl', requireCtrlStateFactory); // Register state factory that registers controller via eval.$futureStateProvider.addResolve(loadAndRegisterFutureStates);}])

这个函数是按需加载的核心

function ngloadStateFactory($q, futureState) {var ngloadDeferred = $q.defer();require([ 'ngload!' + futureState.src , 'ngload', 'angularAMD'],function ngloadCallback(result, ngload, angularAMD) {angularAMD.processQueue();ngloadDeferred.resolve(undefined);});return ngloadDeferred.promise;}

懒加载路由配置文件

define([],function(){

return {

lazyCfg:[

{

“stateName”:”app.cloud”,

“urlPrefix”:”/cloud”,

“type”:”ngload”,

“src”:globalConfig.appPath+’cloud/app-cloud.module.js’

},

{

“stateName”:”work”,

“urlPrefix”:”/network”,

“type”:”ngload”,

“src”:globalConfig.appPath+’network/app-network.module.js’

}

]

}

})

这里有一点需要注意,就是在模块按需夹在的时候需要对响应的服务进行动态注册,否则会提示不能注册angular相关服务。

define([“utils/depResolve”],function(depResolve){

return function(routerConfig){

var self = this;

this.config([‘ stateProvider′,‘ urlRouterProvider’,

‘ locationProvider′,‘ controllerProvider’,

‘ compileProvider′,‘ filterProvider’,

‘ provide′,function( stateProvider, urlRouterProvider, locationProvider, controllerProvider, compileProvider, filterProvider, provide){

//多模块的异步加载时,无法满足模块controller、directive、service等动态定义

//也就是说在加载完module文件后,再动态加载相关的controller、directive、service等时

//提示controller、directive、service等未定义

//所以必须在加载module文件同时在模块的config中注入相应的provider服务进行动态注册。

self.controller = controllerProvider.register;self.directive= compileProvider.directive;

self.filter = filterProvider.register;self.factory= provide.factory;

self.service = $provide.service;

}]);}

})

以上是本人对angular开发的一些总结,希望对有需求的童鞋有一些帮助,有问题可以评论,大家互相讨论学习。demo地址是:/mazhaohai/angular-lazyload.git。

如果觉得《Angular+Requirejs实现模块按需加载》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。