標籤:
本文主要說明在用AngularJS開發web應用中如何?lazyload,使用AngularJS需要在前端實現路由功能,本文就介紹利用此點實現前端資源的懶載入。
問題
目前大部分AngularJS的應用用requirJS組織模組,但是很多都沒有使用lazyload功能,在app.js中啟動時將全部依賴載入進來,在模組功能較少,前端資源少的情況下沒問題。那麼問題來了,依賴資源過多時怎麼辦?
- build時利用grunt-contrib-requirejs提取合并檔案,減少http請求,但是存在問題:build後檔案大;線上調試不方便,尤其在html2js後問題更明顯。
- 開發中盡量在原有檔案裡進行新業務添加,不增加額外的http請求壓力,但是存在問題:多人合作時需要經常處理代碼衝突;單個檔案(control,directive等)很大,看的是眼花繚亂,容易出問題。
解決問題
基本思路:在路由切換時載入所需要資源。
工具:Angular-ui-router,oclazyload,requirejs。
- 配置oclazyload
在引入oclazyload檔案後配置主要參數項 app.config([‘$ocLazyLoadProvider‘,function($ocLazyLoadProvider){ $ocLazyLoadProvider.config({ loadedModules: [‘monitorApp‘],//主模組名,和ng.bootstrap(document, [‘monitorApp‘])相同 jsLoader: requirejs, //使用requirejs去負載檔案 files: [‘modules/summary‘,‘modules/appEngine‘,‘modules/alarm‘,‘modules/database‘], //主模組需要的資源,這裡主要子模組的聲明檔案 debug: true }); }]);
- 配置ui-route
利用angularjs-ui-route配置路由跳轉的基本規則和需要懶負載檔案 app.config([‘$stateProvider‘, ‘$urlRouterProvider‘,function($stateProvider, $urlRouterProvider){ var lazyDeferred; /** * 路由切換時調用 * @param param.file 懶負載檔案數組 * @param tpl 子模組view視圖 * @param module 子模組名 */ function resovleDep(param,tpl,module){ var resolves = { loadMyCtrl: [‘$ocLazyLoad‘, ‘$templateCache‘, ‘$q‘, function($ocLazyLoad,$templateCache,$q) { lazyDeferred = $q.defer(); return $ocLazyLoad.load({ name : module, cache: false, files: param.files }).then(function() { lazyDeferred.resolve($templateCache.get(tpl)); }); }] }; return resolves; }; $urlRouterProvider.otherwise(‘/summary‘); //路由配置 $stateProvider .state(‘module1‘, { url:‘/module1‘, templateProvider: function() { return lazyDeferred.promise; }, controller: ‘module1Controller‘, resolve : resovleDep({files:[ ‘controllers/module1Ctrl‘, ‘services/module1Service‘, ‘directives/module1Directive‘ ]}, ‘views/module1.html‘, ‘app.module1‘) }) .state(‘module2‘, { abstract: true, url: ‘/module2‘, templateUrl: ‘views/module2.html‘ }) .state(‘module2.list‘, { url: ‘‘, templateProvider: function() { return lazyDeferred.promise; }, controller: ‘module2Controller‘, resolve : resovleDep({files:[ ‘controllers/module2ListCtrl‘, ‘services/module2Service‘ ]}, ‘views/list.html‘, ‘app.module1‘) }) .state(‘module1.detail‘, { url: ‘/:id‘, templateProvider: function() { return lazyDeferred.promise; }, controller: ‘detailController‘, resolve : resovleDep({files:[ ‘controllers/detailCtrl‘, ‘services/detailService‘ ]}, ‘views/detail.html‘, ‘app.module2‘) }); }]);
結束
ok,至此就可以在路由切換時方便的載入子模組和依賴資源,oclazyload和ui-router還有很多可挖掘的,大家可參考api滿足需求。
ps:最初用angular-route+oclazyload做時出現:
multiple directives asking for isolated scope on
multiple asking for template
等問題,不好用,建議使用ui-route,強大的多。
Angular-ui-router + oclazyload + requirejs實現資源隨route懶載入