最近帮朋友写了个小项目的前端,用到了angular.js,由于最近在学习vue.js,暂时没有时间学习angular.js 2.x版本,暂时就使用了angular.js 1.x版本。项目目录暂时通过功能划分,新闻模块/个人中心模块/后台管理模块,如下:

AngularJS + RequireJS 项目整合-实现js文件懒加载和文件合并-Rome-Web 前端开发博客

css使用less编译,闲言少叙,进入正题。该项目有一个发布文章和投稿的需求,用到了百度UEditor,重新写了theme中的主题样式,美化了一下,去掉了不常用的功能,由于该插件ueditor.all.js文件过大,即使使用cdn资源,加载速度还是很耗时间,由于require.js的amd规范,直接在首页加载了全部的文件,但是首页展示的是基本的新闻列表,不需要加载类似发布文章功能的js文件,这就需要使用angular.js配合require.js实现按需加载,具体项目修改如下:

首页引入require.js,配置主文件入口:

<script data-main="js/main" src="js/libs/require.min.js" ></script>//上线修改为cdn资源

配置main.js,文件为默认加载的js文件:

require.config({
  baseUrl : '/js',//配置基本路径
  paths: { //上线换为cdn资源,直接可以使用http或者https协议,angularJS会识别这两个协议进行加载
    'angular': '/libs/angular.min',
    'uiRoute': '/libs/angular-ui-router',
    'routes': 'routes'
  },
  waitSeconds: 0, //设置等待加载时间
  shim: {
    'angular': {
      'exports': 'angular'
    },
    'uiRoute': {
      deps: ['angular']
    }
  },
  priority: [
    "angular"
  ],
  urlArgs: 'v=' + (new Date()).getTime() //调试的时候加版本号,防止读取缓冲
});

require(['angular',
  'app',
  'routes',
  'uiRoute'
], function(angular) {
  angular.bootstrap(document, ['app']);
});

配置angular.js的应用主模块:

define(['angular', 'uiRoute'], function(angular) {
  return angular.module('app', ['ui.router']);
});

配置angular-ui-router,实现按需加载,通过router阻塞js文件的加载:

define(['app'], function(app) {
  app.config(function($stateProvider, $urlRouterProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
    app.register = {
      Controller : $controllerProvider.controller, //注册控制器controller
      Directive : $compileProvider.directive, // 注册指令directive
      Filter : $filterProvider.register, // 注册过滤器filter
      Factory : $provide.factory, // 注册服务factory
      Service : $provide.service // 注册服务service
    };
    app.asyncjs = function(js) {
      return function($rootScope, $q) {
        var def = $q.defer(),
          deps = [];
        angular.isArray(js) ? (deps = js) : deps.push(js);
        require(deps, function() {
          $rootScope.$apply(function() {
            def.resolve();
          });
        });
        return def.promise;
      };
    };
    $urlRouterProvider.otherwise('/index'); //默认加载路径
    $stateProvider.state('index', {
      url: '/index',
      templateUrl: 'views/index.html',
      controller: 'indexCtrl',
      resolve: {
        deps: app.asyncjs(['js/controller/indexCtrl','js/directive/directive']) //实现index.html加载index的indexCtrl.js和测试的指令文件directive.js
      }
    });
    $stateProvider.state('page', {
      url: '/page',
      templateUrl: 'tpls/page.html',
      controller: 'pageCtrl',
      resolve: {
        deps: app.asyncjs(['js/controller/pageCtrl','js/filter/filter'])//实现page.html加载index的pageCtrl.js和测试的过滤器文件filter.js
      }
    });
  });
});

controller文件的注册如下:

define(['app'], function(app) {
  //注册控制器
  app.register.Controller 'indexCtrl', ['$scope', function($scope) {
    $scope.title = 'Test';
  }]);
});

测试指令directive文件,多个文件可以合并为一个文件,如果不用$compileProvider注册,合并到一个文件,指令就会覆盖,也是指令合并到一个问题,多个指令注册如下:

define(['app'], function(app) {
  //注册指令一
  app.register.Directive('directiveOne', ['$rootScope', '$globalVar', 'httpPost', '$http', function($rootScope, $globalVar, httpPost, $http) {
    return {
      restrict: 'A',
      scope: false,
      replace: false,
      link: function($scope, $element, $attrs) {
        console.log('Directive One');
      },
    };
  }]);

  //注册指令二
  app.register.Directive('directiveTwo', ['$rootScope', '$globalVar', 'httpPost', '$http', function($rootScope, $globalVar, httpPost, $http) {
    return {
      restrict: 'A',
      scope: false,
      replace: false,
      link: function($scope, $element, $attrs) {
        console.log('Directive Two');
      },
    };
  }]);
});

多个过滤器注册类似于directive,如下:

define(['app'], function(app) {
  //注册测试过滤器一
  app.register.Filter('filterOne', function() {
    return function(data) {
      return data;
    };
  });

  //注册测试过滤器二
  app.register.Filter('filterTwo', function() {
    return function(data) {
      return data;
    };
  });
});

其他服务指令注册方式同上,合并方式类似,这里就不加列举,该实例实现懒加载的方式,就在于router中的js文件阻塞,通过$urlRouterProvider的依赖项进行加载,仅作参考,错误之处,请大家指正留言。