html5教程-AngularJS进阶(二十五)requirejs + angular + angular-route 浅谈HTML5单页面架构

发布时间:2018-12-14 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了html5教程-AngularJS进阶(二十五)requirejs + angular + angular-route 浅谈HTML5单页面架构脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

requirejs+Angular+angular-route浅谈HTML5单页面架构

众所周知,现在移动Webapp越来越多,例如天猫、京东、国美这些都是很好的例子。而在Webapp中,又要数单页面架构体验最好,更像原生app。简单来说,单页面App不需要频繁切换网页,可以局部刷新,整个加载流畅度会好很多。

废话就不多说了,直接到正题吧,浅谈一下我自己理解的几种单页面架构:

1、requirejs+angular+angular-route(+zepto)

最后这个zepto可有可无,主要是给团队中实在用不爽angular的同学,可以灵活修改一下页面某些内容。当然,严谨的项目不应该出现zepto。

2、requirejs+backbone+zepto+template

这个方案更灵活,MVC味道更浓,使用自定义的template模版库

3、requirejs+route+template

这个方案最灵活,看破红尘,针对简单的业务用最简单的方式,只需要路由和模版,不用MVC框架

4、react

个人感觉,react更偏向于view层的组件,更native,但实施难度略高

说到项目架构,往往要考虑很多方面:

方便:例如使用jquery,必然比没有使用jquery方便很多,所以大部分网站都接入类似的库;

性能优化:包括加载速度、渲染效率;

代码管理:大型项目需要考虑代码的模块化,模块间低耦合高内聚,目的就为了团队合作效率;

可扩展性:这个不用说了。

学习成本:一个框架再好,团队新成员难以掌握,学习难度大,结果很容易造成代码混乱。

而根据实际经验来看,方便是必然首要地位,除此之外,应该是代码管理了。团队合作过程中,各种协作,代码冲突等等,都会给一个优秀框架带来各种奇怪难题。所以,有好的框架还不够,我们还需要根据自身业务和团队的情况,按需裁剪或者修改框架,找到最佳的实施方案。

接下来,将分三个随笔分别介绍一下我心目中前三种架构的较好实施方案,而最后一种,跟前三种有种道不同不相为谋的感觉,加上自己道行不够,还是暂且不提了。

这一篇,先说说第一种:requirejs+angular+angular-route

移动端单页面Web相对多页面来说,模块化管理显得非常重要,因为如果没有模块化,页面初始化时就把所有的js和所有模版都加载进来,会导致首屏速度极慢。这一点,大家都理解的。

所以,requirejs或者类似的模块化框架是必不可少的。requirejs比较流行,配合grunt可以做好整套的自动化工具,我们就以这个为例子吧。

首先,来看看demo项目的整体架构。

除了类库外,业务代码都以模块划分目录,这样做便于实际开发中,按模块化合并js和htML,也利于多人并行开发,各自修改不同的模块,互不影响

另外,说说三个重点的根目录文件:

index.html,这个就是单页面唯一一个html了,其他都只是片段模版(tpl.html)。一般可以把这个html放到动态服务器上,保持零缓存,同时这里可以携带各种js版本控制信息和必要的用户数据。

main.js,这个是由requirejs引入的第一个业务js,主要是配置requirejs;

router.js,这个是整个网站/app的路由配置,在实际部署中,可以把main.js和router.js合并。

第一步,先看看index.html需要做什么变化

 

 

 

<script data-baseurl="./" data-main="main.js" src="libs/require.js" id="main"></script>

 

相对angular的写法,这里由于使用requirejs管理全部模块,所以index.html中不需要引入angular等,只是设置了一个带ng-view属性的p,用于充当整个App的视图区域。

data-baseurl是额外加入的属性,主要好处是可以轻松在html(0缓存)中对js的url进行修改。

data-main就是requirejs的标准写法了,跳过不说。

第二步,main.js,也就是requirejs的配置

 

 &#39;use strict'; (function (win) {     //配置baseUrl     VAR baseUrl = document.getElementById(';main').getAttribute('data-baseurl');     /*      * 文件依赖      */     var config = {         baseUrl: baseUrl,             // 依赖相对路径         paths: {                    // 如果某个前缀的依赖不是按照baseUrl拼接这么简单,就需要在这里指出             underscore: 'libs/underscore',             angular: 'libs/angular',             'angular-route': 'libs/angular-route',             text: 'libs/text'             // 用于requirejs导入html类型的依赖         },         shim: { //引入没有使用requirejs模块写法的类库。例如underscore这个类库,本来会有一个全局变量'_'。这里shim等于快速定义一个模块,把原来的全局变量'_'封装在局部,并导出为一个exports,变成跟普通requirejs模块一样             underscore: {                 exports: '_'             },             angular: {                 exports: 'angular'             },             'angular-route': {                 deps: ['angular'],   //依赖什么模块                 exports: 'ngRouteModule'             }         }     };     require.config(config);     require(['angular', 'router'], function(angular){         angular.bootstrap(document, ['webapp']);     }); })(window);

 

requirejs的语法,说来话长,简单在代码中做了注释。有兴趣了解详情的可以参考官网:http://requirejs.org/;

angular可以参考:https://docs.angularjs.org/guide/filter

这里配置好requirejs后,就做第一步工作,引入angular和angular的路由配置,然后用angular.bootstrap(document,[‘webapp’]);手工启动angular,这里webapp是router.js中定义的angularmodule。

第三步,配置这个router

 

 define(['angular', 'require', 'angular-route'], function (angular, require) {     var app = angular.module('webapp', ['ngRoute']);     app.config(['$routePRovider', '$controllerProvider',         function($routeProvider, $controllerProvider) {             $routeProvider.                 when('/module1', {                     templateUrl: 'module1/tpl.html',                     controller: 'module1Controller',                     resolve: {                         /*                         这个key值会被注入到controller中,对应的是后边这个function返回的值,或者promise最终resolve的值。函数的参数是所需的服务,angular会根据参数名自动注入对应controller写法(注意keyName):            controllers.controller('module2Controller', ['$scoPE', '$http', 'keyName',                              function($scope, $http, keyName) {                          }]);                          */                         keyName: function ($q) {                             var deferred = $q.defer();                             require(['module1/module1.js'], function (controller) {                                 $controllerProvider.register('module1Controller', controller);      //由于是动态加载的controller,所以要先注册,再使用                                 deferred.resolve();                             });                             return deferred.promise;                         }                     }                 }).                 otherwise({                     redirectTo: '/module1'      //angular就喜欢斜杠开头                 });         }]);     return app; });

 

上述代码看起来长,实际很短,因为有一堆绿色的注释,嘿嘿。。。

如果大家用过angular-route,这里的语法就很简单,如果没用过,则建议直接阅读angular-route代码中的注释,非常清晰。

简单而言,就是when函数配置一个路由规则,对应一个template和一个controller。otherwise就是默认路由,也就是遇到一个未定义路径的时候如何跳转。

如果没有使用requirejs,那么我们需要在路由配置前加载完全部controller。angular-route需要做的只是切换HTML模版,重新编译,绑定新的controller。

但是这里用了requirejs,事情就变化了。我们要按需加载,不可能页面刚加载就全部controller都load回来,这样得耗费多少流量。。。

所以,这里利用了angular-route提供的resolve功能,也就是路由更改html前先把resolve里边该做的事完成。

resolve的写法比较特殊,接受的是一个key:value对象,keyName将会导入到controller中(如果controller有注明依赖)。而value应该是一个函数,函数的写法类似controller,angular会自动根据参数名导入相应依赖的服务,例如$q、$route。

上述例子中,module1.js定义了模块1的controller,后续我们再看代码。

由于路由配置前还不存在这个controller,所以现在需要动态注册这个controller。也就是:

$controllerProvider.register('module1Controller',controller);

第四步,看看模块1的controller是怎么写的

 

 define(['angular'], function (angular) {     //angular会自动根据controller函数的参数名,导入相应的服务     return function($scope, $http, $interval){         $scope.info = 'kenko';      //向view/模版注入数据         //模拟请求cgi获取数据,数据返回后,自动修改界面,不需要碌$('#xxx').html(xxx)         $http.get('module2/tpl.html').success(function(data) {             $scope.info = 'vivi';         });         var i = 0;         //angularjs修改了原来的setTimeout和setInterval,要用这两个玩意,必须引入$timeout和$interval,否则无法修改angular范围内的东西         $interval(function () {             i++;             $scope.info = i;         }, 1000);     }; });

 

angular有太多牛逼的功能,但实际上我业务太简单,用不到。所以这里只演示了3种最简单的情况。

这里不得不说,由于双向绑定,拉cgi和修改dom这些操作就变得非常简单了。

貌似一切解决了?这样的模块化似乎已经很好,跳转到某个模块的时候才加载对应的html和controllerjs。

但是对于追求极致的团队来说,模块的html和js应该打包在一起,一次请求就拉回来,这样能大大减少HTTP请求的时间。而现在按照angular-route,只能利用templateUrl单独拉取一个html文件。

那么接下来,我们再动动歪脑筋,修改一下。

第五步,修改angular-route,实现HTML和js打包加载。

 

 function ngViewFillContentFactory($compile, $controller, $route) {   return {     restrict: 'ECA',     priorITy: -400,     link: function(scope, $element) {       var current = $route.current,           locals = current.locals;       $element.html(current.template);  //原来是locals.$template

 

首先,先修改一下angular-route的源代码,这个源代码非常精简,不用太纠结,狠狠的去修改就好了。

另外,想问我为什么知道或者想到在这修改?咳咳咳,我会大摇大摆的说我认识angular-route的作者么?。。。。。。。开玩笑,作者叫什么,我都没去找,还说认识作者。其实就是逐步调,稍加变量搜索,发现一些不对劲,就做了这个小刀。

再另外,有专家要拍板了,这样乱修改,肯定带来毛病。是的,我不得不说,我自己都没彻底的检查是否有问题,但按照实际情况来看,暂时没遇到问题。

然后,做一个新的when配置:

 

        when('/module2', {                     template: '',                     controller: 'module2Controller',                     resolve:{                         keyName: function ($route, $q) {                             var deferred = $q.defer();                             require(['module2/module2.js'], function (module2) {                                 $controllerProvider.register('module2Controller', module2.controller);                                 $route.current.template = module2.tpl;                                 deferred.resolve();                             });                             return deferred.promise;                         }                     }                 })

 

这里用Module2做例子,跟module1不同,这里初始设置的template是空字符串,然后在resolve中require回来后,动态修改$route.current.template。

因为我知道,这个修改能赶在angular-route修改HTML前,也就是小把戏能凑效。

相应,看看module2怎么写:

 

 define(['angular', 'text!module2/tpl.html'], function (angular, tpl) {     //angular会自动根据controller函数的参数名,导入相应的服务     return {         controller: function ($scope, $http, $interval) {             $scope.date = '2015-07-13';         },         tpl: tpl     }; });

 

大功告成,这样html模版就不由angular-route去接管了,而是由requirejs加载,我们可以控制的范围和灵活性就变大了。

不过,这里controller的函数写法可能会因为压缩混淆时丢失了原来的参数名,所以,我们也可以采用显式注入的方式:

 

  //也可以使用这样的显式注入方式,angular执行controller函数前,会先读取$inject     controller.$inject = ['$scope'];     function controller(s){         s.date = '2015-07-13';     }     return {controller:controller, tpl:tpl};

 

到这里,整个架构基本就成型了,webapp中每个模块都能非常独立,这样对网站打开速度和协同开发都非常有好处。

但是,路由表的配置还是略复杂,每次大家都要写一大堆代码,这不是我们想要的,那么可以抽取公用代码,再优化一下。

第六步,优化路由表,变成真正的配置化。

 

 define(['angular', 'require', 'angular-route'], function (angular, require) {     var app = angular.module('webapp', [         'ngRoute'     ]);     app.config(['$routeProvider', '$controllerProvider',         function($routeProvider, $controllerProvider) {             var routeMap = {                 '/module2': {                           //路由                     path: 'module2/module2.js',         //模块的代码路径                     controller: 'module2Controller'     //控制器名称                 }             };             var defaultRoute = '/module2';              //默认跳转到某个路由             $routeProvider.otherwise({redirectTo: defaultRoute});             for (var key in routeMap) {                 $routeProvider.when(key, {                     template: '',                     controller: routeMap[key].controller,                     resolve:{                      keyName:requireModule(routeMap[key].path, routeMap[key].controller)                     }                 });             }             function requireModule(path, controller) {                 return function ($route, $q) {                     var deferred = $q.defer();                     require([path], function (ret) {                         $controllerProvider.register(controller, ret.controller);                         $route.current.template = ret.tpl;                         deferred.resolve();                     });                     return deferred.promise;                 }             }         }]);     return app; });

routeMap可以由服务器直出,实现0缓存,彻底解耦,更便于团队合作。

最后最后,由于requirejs和angular都有模块管理,但两个概念又不一致,这里说说我的看法:

requirejs模块管理,不单单是代码模块化,还提供了模块加载的功能;

angular模块管理,更在乎的是代码逻辑上的模块化,避免全局变量污染,并不提供js文件层面的加载功能;

作为逻辑模块管理,其实用requirejs的模块管理就够了,所以我觉得除了angular原生的controller、service外,我们业务相关的公用库,用requirejs吧。

美文美图

html5教程-AngularJS进阶(二十五)requirejs + angular + angular-route 浅谈HTML5单页面架构

requirejs+angular+angular-route浅谈HTML5单页面架构

众所周知,现在移动Webapp越来越多,例如天猫、京东、国美这些都是很好的例子。而在Webapp中,又要数单页面架构体验最好,更像原生app。简单来说,单页面App不需要频繁切换网页,可以局部刷新,整个加载流畅度会好很多。

废话就不多说了,直接到正题吧,浅谈一下我自己理解的几种单页面架构:

1、requirejs+angular+angular-route(+zepto)

最后这个zepto可有可无,主要是给团队中实在用不爽angular的同学,可以灵活修改一下页面某些内容。当然,严谨的项目不应该出现zepto。

2、requirejs+backbone+zepto+template

这个方案更灵活,MVC味道更浓,使用自定义的template模版库

3、requirejs+route+template

这个方案最灵活,看破红尘,针对简单的业务用最简单的方式,只需要路由和模版,不用MVC框架

4、react

个人感觉,react更偏向于view层的组件,更native,但实施难度略高

说到项目架构,往往要考虑很多方面:

方便:例如使用jquery,必然比没有使用jquery方便很多,所以大部分网站都接入类似的库;

性能优化:包括加载速度、渲染效率;

代码管理:大型项目需要考虑代码的模块化,模块间低耦合高内聚,目的就为了团队合作效率;

可扩展性:这个不用说了。

学习成本:一个框架再好,团队新成员难以掌握,学习难度大,结果很容易造成代码混乱。

而根据实际经验来看,方便是必然首要地位,除此之外,应该是代码管理了。团队合作过程中,各种协作,代码冲突等等,都会给一个优秀框架带来各种奇怪难题。所以,有好的框架还不够,我们还需要根据自身业务和团队的情况,按需裁剪或者修改框架,找到最佳的实施方案。

接下来,将分三个随笔分别介绍一下我心目中前三种架构的较好实施方案,而最后一种,跟前三种有种道不同不相为谋的感觉,加上自己道行不够,还是暂且不提了。

这一篇,先说说第一种:requirejs+angular+angular-route

移动端单页面Web相对多页面来说,模块化管理显得非常重要,因为如果没有模块化,页面初始化时就把所有的js和所有模版都加载进来,会导致首屏速度极慢。这一点,大家都理解的。

所以,requirejs或者类似的模块化框架是必不可少的。requirejs比较流行,配合grunt可以做好整套的自动化工具,我们就以这个为例子吧。

首先,来看看demo项目的整体架构。

除了类库外,业务代码都以模块划分目录,这样做便于实际开发中,按模块化合并js和html,也利于多人并行开发,各自修改不同的模块,互不影响。

另外,说说三个重点的根目录文件:

index.html,这个就是单页面唯一一个html了,其他都只是片段模版(tpl.html)。一般可以把这个html放到动态服务器上,保持零缓存,同时这里可以携带各种js版本控制信息和必要的用户数据。

main.js,这个是由requirejs引入的第一个业务js,主要是配置requirejs;

router.js,这个是整个网站/app的路由配置,在实际部署中,可以把main.js和router.js合并。

第一步,先看看index.html需要做什么变化

 

 

 

<script data-baseurl="./" data-main="main.js" src="libs/require.js" id="main"></script>

 

相对angular的写法,这里由于使用requirejs管理全部模块,所以index.html中不需要引入angular等,只是设置了一个带ng-view属性的p,用于充当整个App的视图区域。

data-baseurl是额外加入的属性,主要好处是可以轻松在html(0缓存)中对js的url进行修改。

data-main就是requirejs的标准写法了,跳过不说。

第二步,main.js,也就是requirejs的配置

 

 'use strict'; (function (win) {     //配置baseUrl     var baseUrl = document.getElementById('main').getAttribute('data-baseurl');     /*      * 文件依赖      */     var config = {         baseUrl: baseUrl,             // 依赖相对路径         paths: {                    // 如果某个前缀的依赖不是按照baseUrl拼接这么简单,就需要在这里指出             underscore: 'libs/underscore',             angular: 'libs/angular',             'angular-route': 'libs/angular-route',             text: 'libs/text'             // 用于requirejs导入html类型的依赖         },         shim: { //引入没有使用requirejs模块写法的类库。例如underscore这个类库,本来会有一个全局变量'_'。这里shim等于快速定义一个模块,把原来的全局变量'_'封装在局部,并导出为一个exports,变成跟普通requirejs模块一样             underscore: {                 exports: '_'             },             angular: {                 exports: 'angular'             },             'angular-route': {                 deps: ['angular'],   //依赖什么模块                 exports: 'ngRouteModule'             }         }     };     require.config(config);     require(['angular', 'router'], function(angular){         angular.bootstrap(document, ['webapp']);     }); })(window);

 

requirejs的语法,说来话长,简单在代码中做了注释。有兴趣了解详情的可以参考官网:http://requirejs.org/;

angular可以参考:https://docs.angularjs.org/guide/filter

这里配置好requirejs后,就做第一步工作,引入angular和angular的路由配置,然后用angular.bootstrap(document,[‘webapp’]);手工启动angular,这里webapp是router.js中定义的angularmodule。

第三步,配置这个router

 

 define(['angular', 'require', 'angular-route'], function (angular, require) {     var app = angular.module('webapp', ['ngRoute']);     app.config(['$routeProvider', '$controllerProvider',         function($routeProvider, $controllerProvider) {             $routeProvider.                 when('/module1', {                     templateUrl: 'module1/tpl.html',                     controller: 'module1Controller',                     resolve: {                         /*                         这个key值会被注入到controller中,对应的是后边这个function返回的值,或者promise最终resolve的值。函数的参数是所需的服务,angular会根据参数名自动注入对应controller写法(注意keyName):            controllers.controller('module2Controller', ['$scope', '$http', 'keyName',                              function($scope, $http, keyName) {                          }]);                          */                         keyName: function ($q) {                             var deferred = $q.defer();                             require(['module1/module1.js'], function (controller) {                                 $controllerProvider.register('module1Controller', controller);      //由于是动态加载的controller,所以要先注册,再使用                                 deferred.resolve();                             });                             return deferred.promise;                         }                     }                 }).                 otherwise({                     redirectTo: '/module1'      //angular就喜欢斜杠开头                 });         }]);     return app; });

 

上述代码看起来长,实际很短,因为有一堆绿色的注释,嘿嘿。。。

如果大家用过angular-route,这里的语法就很简单,如果没用过,则建议直接阅读angular-route源代码中的注释,非常清晰。

简单而言,就是when函数配置一个路由规则,对应一个template和一个controller。otherwise就是默认路由,也就是遇到一个未定义路径的时候如何跳转。

如果没有使用requirejs,那么我们需要在路由配置前加载完全部controller。angular-route需要做的只是切换HTML模版,重新编译,绑定新的controller。

但是这里用了requirejs,事情就变化了。我们要按需加载,不可能页面刚加载就全部controller都load回来,这样得耗费多少流量。。。

所以,这里利用了angular-route提供的resolve功能,也就是路由更改html前先把resolve里边该做的事完成。

resolve的写法比较特殊,接受的是一个key:value对象,keyName将会导入到controller中(如果controller有注明依赖)。而value应该是一个函数,函数的写法类似controller,angular会自动根据参数名导入相应依赖的服务,例如$q、$route。

上述例子中,module1.js定义了模块1的controller,后续我们再看代码。

由于路由配置前还不存在这个controller,所以现在需要动态注册这个controller。也就是:

$controllerProvider.register('module1Controller',controller);

第四步,看看模块1的controller是怎么写的

 

 define(['angular'], function (angular) {     //angular会自动根据controller函数的参数名,导入相应的服务     return function($scope, $http, $interval){         $scope.info = 'kenko';      //向view/模版注入数据         //模拟请求cgi获取数据,数据返回后,自动修改界面,不需要碌$('#xxx').html(xxx)         $http.get('module2/tpl.html').success(function(data) {             $scope.info = 'vivi';         });         var i = 0;         //angularjs修改了原来的setTimeout和setInterval,要用这两个玩意,必须引入$timeout和$interval,否则无法修改angular范围内的东西         $interval(function () {             i++;             $scope.info = i;         }, 1000);     }; });

 

angular有太多牛逼的功能,但实际上我业务太简单,用不到。所以这里只演示了3种最简单的情况。

这里不得不说,由于双向绑定,拉cgi和修改dom这些操作就变得非常简单了。

貌似一切解决了?这样的模块化似乎已经很好,跳转到某个模块的时候才加载对应的html和controllerjs。

但是对于追求极致的团队来说,模块的html和js应该打包在一起,一次请求就拉回来,这样能大大减少HTTP请求的时间。而现在按照angular-route,只能利用templateUrl单独拉取一个html文件。

那么接下来,我们再动动歪脑筋,修改一下。

第五步,修改angular-route,实现HTML和js打包加载。

 

 function ngViewFillContentFactory($compile, $controller, $route) {   return {     restrict: 'ECA',     priority: -400,     link: function(scope, $element) {       var current = $route.current,           locals = current.locals;       $element.html(current.template);  //原来是locals.$template

 

首先,先修改一下angular-route的源代码,这个源代码非常精简,不用太纠结,狠狠的去修改就好了。

另外,想问我为什么知道或者想到在这修改?咳咳咳,我会大摇大摆的说我认识angular-route的作者么?。。。。。。。开玩笑,作者叫什么,我都没去找,还说认识作者。其实就是逐步调,稍加变量搜索,发现一些不对劲,就做了这个小刀。

再另外,有专家要拍板了,这样乱修改,肯定带来毛病。是的,我不得不说,我自己都没彻底的检查是否有问题,但按照实际情况来看,暂时没遇到问题。

然后,做一个新的when配置:

 

        when('/module2', {                     template: '',                     controller: 'module2Controller',                     resolve:{                         keyName: function ($route, $q) {                             var deferred = $q.defer();                             require(['module2/module2.js'], function (module2) {                                 $controllerProvider.register('module2Controller', module2.controller);                                 $route.current.template = module2.tpl;                                 deferred.resolve();                             });                             return deferred.promise;                         }                     }                 })

 

这里用module2做例子,跟module1不同,这里初始设置的template是空字符串,然后在resolve中require回来后,动态修改$route.current.template。

因为我知道,这个修改能赶在angular-route修改HTML前,也就是小把戏能凑效。

相应,看看module2怎么写:

 

 define(['angular', 'text!module2/tpl.html'], function (angular, tpl) {     //angular会自动根据controller函数的参数名,导入相应的服务     return {         controller: function ($scope, $http, $interval) {             $scope.date = '2015-07-13';         },         tpl: tpl     }; });

 

大功告成,这样html模版就不由angular-route去接管了,而是由requirejs加载,我们可以控制的范围和灵活性就变大了。

不过,这里controller的函数写法可能会因为压缩混淆时丢失了原来的参数名,所以,我们也可以采用显式注入的方式:

 

  //也可以使用这样的显式注入方式,angular执行controller函数前,会先读取$inject     controller.$inject = ['$scope'];     function controller(s){         s.date = '2015-07-13';     }     return {controller:controller, tpl:tpl};

 

到这里,整个架构基本就成型了,webapp中每个模块都能非常独立,这样对网站打开速度和协同开发都非常有好处。

但是,路由表的配置还是略复杂,每次大家都要写一大堆代码,这不是我们想要的,那么可以抽取公用代码,再优化一下。

第六步,优化路由表,变成真正的配置化。

 

 define(['angular', 'require', 'angular-route'], function (angular, require) {     var app = angular.module('webapp', [         'ngRoute'     ]);     app.config(['$routeProvider', '$controllerProvider',         function($routeProvider, $controllerProvider) {             var routeMap = {                 '/module2': {                           //路由                     path: 'module2/module2.js',         //模块的代码路径                     controller: 'module2Controller'     //控制器名称                 }             };             var defaultRoute = '/module2';              //默认跳转到某个路由             $routeProvider.otherwise({redirectTo: defaultRoute});             for (var key in routeMap) {                 $routeProvider.when(key, {                     template: '',                     controller: routeMap[key].controller,                     resolve:{                      keyName:requireModule(routeMap[key].path, routeMap[key].controller)                     }                 });             }             function requireModule(path, controller) {                 return function ($route, $q) {                     var deferred = $q.defer();                     require([path], function (ret) {                         $controllerProvider.register(controller, ret.controller);                         $route.current.template = ret.tpl;                         deferred.resolve();                     });                     return deferred.promise;                 }             }         }]);     return app; });

routeMap可以由服务器直出,实现0缓存,彻底解耦,更便于团队合作。

最后最后,由于requirejs和angular都有模块管理,但两个概念又不一致,这里说说我的看法:

requirejs模块管理,不单单是代码模块化,还提供了模块加载的功能;

angular模块管理,更在乎的是代码逻辑上的模块化,避免全局变量污染,并不提供js文件层面的加载功能;

作为逻辑模块管理,其实用requirejs的模块管理就够了,所以我觉得除了angular原生的controller、service外,我们业务相关的公用库,用requirejs吧。

美文美图

html5教程-AngularJS进阶(二十五)requirejs + angular + angular-route 浅谈HTML5单页面架构

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! html5教程,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的html5教程-AngularJS进阶(二十五)requirejs + angular + angular-route 浅谈HTML5单页面架构全部内容,希望文章能够帮你解决html5教程-AngularJS进阶(二十五)requirejs + angular + angular-route 浅谈HTML5单页面架构所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。