Angular-ui-router + oclazyload + requirejs實現資源隨route懶加載


本文主要說明在用AngularJS開發web應用中如何實現lazyload,使用AngularJS需要在前端實現路由功能,本文就介紹利用此點實現前端資源的懶加載。

問題

目前大部分AngularJS的應用用requirJS組織模塊,但是很多都沒有使用lazyload功能,在app.js中啟動時將全部依賴加載進來,在模塊功能較少,前端資源少的情況下沒問題。那么問題來了,依賴資源過多時怎么辦?

  1. build時利用grunt-contrib-requirejs提取合並文件,減少http請求,但是存在問題:build后文件大;線上調試不方便,尤其在html2js后問題更明顯。
  2. 開發中盡量在原有文件里進行新業務添加,不增加額外的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,強大的多。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM