详解angularjs利用ui-route异步加载组件
ui-route相比于angularjs的原生视图路由更好地支持了路由嵌套,状态转移等等。随着视图不断增加,打包的js体积也会越来越大,比如我在应用里面用到了wangeditor里面单独依赖的jquery就300多k。异步加载各个组件就很有必要。在这里我就以ui-route为框架来进行异步加载说明。
首先看一下路由加载文件
angular.module('webtrn-sns').config(['$stateProvider',function($stateProvider){ $stateProvider.state({ name:'home.message', url:'/message', abstract:true, templateProvider:['resources',function(resources){ returnresources.template }], controllerProvider:['resources',(resources)=>{ returnresources.controller }], onEnter:['resources',(resources)=>resources.css.use()], onExit:['resources',(resources)=>resources.css.unuse()], resolve:{ resources:()=>{ returnnewPromise( resolve=>{ require([],()=>{ resolve({ css:require('./css/message_box.css'), template:require('./html/message_box.html'), controller:require('./js/message_box.js') }) }) } ); } } } ).state({ name:'home.message.add_message', url:'/add_message?isReply&toUid&title', params:{isReply:null,toUid:null,title:null}, templateProvider:['resources',function(resources){ returnresources.template }], controllerProvider:['resources',(resources)=>{ returnresources.controller }], onEnter:['resources',(resources)=>resources.css.use()], onExit:['resources',(resources)=>resources.css.unuse()], resolve:{ resources:()=>{ returnnewPromise( resolve=>{ require(['./js/message.js'],()=>{ resolve({ css:require('./css/add_message.css'), template:require('./html/add_message.html'), controller:require('./js/add_message.js') }) }) } ); } } } ) }])
这个是路由状态的一个声明文件,name,url,param字段的方式不变,关键是看resolve这个部分。根据ui-route的resolve文档,resolve是为了给state或者controller进行自定义注入对象的。
下面是举出文档中关于resolve的例子:
$stateProvider.state('myState',{ resolve:{ //Exampleusingfunctionwithsimplereturnvalue. //Sinceit'snotapromise,itresolvesimmediately. simpleObj:function(){ return{value:'simple!'}; }, //Exampleusingfunctionwithreturnedpromise. //Thisisthetypicalusecaseofresolve. //Youneedtoinjectanyservicesthatyouare //using,e.g.$httpinthisexample promiseObj:function($http){ //$httpreturnsapromisefortheurldata return$http({method:'GET',url:'/someUrl'}); }, //Anotherpromiseexample.Ifyouneedtodosome //processingoftheresult,use.then,andyour //promiseischainedinforfree.Thisisanother //typicalusecaseofresolve. promiseObj2:function($http){ return$http({method:'GET',url:'/someUrl'}) .then(function(data){ returndoSomeStuffFirst(data); }); }, //Exampleusingaservicebynameasstring. //Thiswouldlookfora'translations'service //withinthemoduleandreturnit. //Note:Theservicecouldreturnapromiseand //itwouldworkjustliketheexampleabove translations:"translations", //Exampleshowinginjectionofserviceinto //resolvefunction.Servicethenreturnsa //promise.Tip:Inject$stateParamstoget //accesstourlparameters. translations2:function(translations,$stateParams){ //AssumethatgetLangisaservicemethod //thatuses$httptofetchsometranslations. //Alsoassumeoururlwas"/:lang/home". returntranslations.getLang($stateParams.lang); }, //Exampleshowingreturningofcustommadepromise greeting:function($q,$timeout){ vardeferred=$q.defer(); $timeout(function(){ deferred.resolve('Hello!'); },1000); returndeferred.promise; } }, //Thecontrollerwaitsforeveryoneoftheaboveitemstobe //completelyresolvedbeforeinstantiation.Forexample,the //controllerwillnotinstantiateuntilpromiseObj'spromisehas //beenresolved.Thenthoseobjectsareinjectedintothecontroller //andavailableforuse. controller:function($scope,simpleObj,promiseObj,promiseObj2,translations,translations2,greeting){ $scope.simple=simpleObj.value; //YoucanbesurethatpromiseObjisreadytouse! $scope.items=promiseObj.data.items; $scope.items=promiseObj2.items; $scope.title=translations.getLang("english").title; $scope.title=translations2.title; $scope.greeting=greeting; } })
我们可以看到resolve的对象是支持Promise的。
再回到我们之前的代码templateProvider和controllerProvider我们注入了resources的模板对象和controller对象,onEnter和onExit注入了css模块。
如果controller中依赖了服务怎么办的?
resolve:{ resources:()=>{ returnnewPromise( resolve=>{ require(['./js/message.js'],()=>{ resolve({ css:require('./css/add_message.css'), template:require('./html/add_message.html'), controller:require('./js/add_message.js') }) }) } ); } }
可以在require里面将服务注入,如代码中的message.js。而为了将服务进行异步加载我们不能用普通的.factory或者.service。而需要调用$provide.factory或者$provide.service
如果采用webpack进行编译打包的话就需要webpack.optimize.CommonsChunkPlugin的支持,这样可以对js进行拆分打包,达到异步加载js的目的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。