Angular项目构建指南 - 不再为angular构建而犹豫不决(转)

如果你不知道什么是Angular或者根本没听说过,那么我接下来所说的对你来说毫无益处,不过如果你打算以后会接触Angular或者干脆要涨涨姿势~读下去还是有点用的.

    Angular和它之前所出现的其余前端框架最大的不同,在于它的核心不再是DOM,而是数据,是model.我们惯用的不管是单纯的jQuery还是MVC的Backbone,它们本质仍是让我们更方便更有条理的操作DOM,但是Angular不是.通过一系列魔术般的手法,它将一切的重心转移到数据上.以开发应用而不是操作节点的方式去开发Web,一切以数据为中心,数据的变化驱动了一切,包括行为.

    文本主题,如何构建一个angular项目?

    坦白说最开始构建一个项目的时候,虽然很小但是很纠结.我本身是有点完美主义的,所以虽然一开始什么都没有也想做到尽善尽美.因为听过很多前辈的经验,说如果框架基础没搭好,等到后来不管是重构还是维护都是一场噩梦.所以一开始小心意义,希望能将项目尽量搭建的结实并且益于维护和开发.

    在搭建伊始首先遇到的一个问题,就是到底要不要引入requirejs或者seajs这类依赖管理的工具?

    我本身没有多少语言或者技术的上的情节,对于各个大神也没有多少膜拜的憧憬(更多的是我根本不清楚谁是大神,也从没去找过).所以对于我来讲不管是requirejs的AMD还是seajs的CMD,从实现的角度上来讲都是做了同一个工作.在考虑一个Angular应用到底需不需要这种工具的时候,我也在网上看了很多人的说法.我总结一句就是,基本都和没说一样,也就是用不用随便,看情况.

    那么我能有什么好的答案,其实我现在的答案就是:"可以不用".怎么说是可以不用呢,如果你不用requirejs也能满足项目的开发以及各种需求,那么就别用了.angular本身的模块已经做到了依赖注入,所以我们不需要通过requirejs进行异步加载也可以很好的用下去.

    当然,如果你开发过程中发觉还是有些地方需要,那么也可以加上去.本文里我会详细说明这两种方式的构建方法.但是这里我的观点已经表明了:在不需要的情况下,不要用.

    (1) 不用requirejs直接构建Angular

    之所以不使用requirejs就直接构建angular,因为angular对于依赖的管理以及angular的使用场景完全可以做到这一点.首先在以来上,angular的依赖注入是个好东西,不了解的同学可以去搜一下资料.我这里简单的说,就是当我需要一个module的时候,我不用管它在哪,它是什么.我只要知道它的名字然后告诉angular就可以了,至于怎么将它的对象传递过来,怎么找到的,angular自己会去处理.

?
1
2
3
angular.module( 'myApp' , [
   'ngRoute' ,
]);

 

    例如这里的ngRoute,我需要知道ngRoute怎么来的,在哪里.只要有一个模块定义为ngRoute我就可以直接拿来用.

    鉴于Angular如此的给力,剩下的事情就好办了.我们只需要从功能和业务两方面将文件划分成module就可以了,然后将所有的库文件在页面上通过script标签引用,再将所有的业务文件也即是我们自己写的js合并为一个all.js加载到页面上即可.

    这里文件的划分遵循angular官方的推荐方式:

?
1
2
3
4
5
6
7
8
9
10
|--js
    |--app.js                      // app启动文件,用于app配置
    |--controllers.js           // controllers也就是存放我们自己的业务文件
    |--directives.js             // 指令文件(指令可共用)
    |--fliters.js                   // 过滤器文件(过滤器可共用)
    |--services.js              //  服务文件(可共用,一般是与服务器交互的服务)
|--partials
    |--html1.html  
    |--html2.html
|--index.html

 

    app.js

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'use strict' ;
 
 
// Declare app level module which depends on filters, and services
angular.module( 'myApp' , [
   'ngRoute' ,
   'myApp.filters' ,
   'myApp.services' ,
   'myApp.directives' ,
   'myApp.controllers'
]).
config([ '$routeProvider' function ($routeProvider) {
   $routeProvider.when( '/view1' , {templateUrl:  'partials/partial1.html' , controller:  'MyCtrl1' });
   $routeProvider.when( '/view2' , {templateUrl:  'partials/partial2.html' , controller:  'MyCtrl2' });
   $routeProvider.otherwise({redirectTo:  '/view1' });
}]);

 

    controllers.js

?
1
2
3
4
5
6
7
8
9
10
11
'use strict' ;
 
/* Controllers */
 
angular.module( 'myApp.controllers' , [])
   .controller( 'MyCtrl1' , [ '$scope' function ($scope) {
 
   }])
   .controller( 'MyCtrl2' , [ '$scope' function ($scope) {
 
   }]);

 

    directives.js

?
1
2
3
4
5
6
7
8
9
10
11
'use strict' ;
 
/* Directives */
 
 
angular.module( 'myApp.directives' , []).
   directive( 'appVersion' , [ 'version' function (version) {
     return  function (scope, elm, attrs) {
       elm.text(version);
     };
   }]);

 

    filters.js

?
1
2
3
4
5
6
7
8
9
10
'use strict' ;
 
/* Filters */
 
angular.module( 'myApp.filters' , []).
   filter( 'interpolate' , [ 'version' function (version) {
     return  function (text) {
       return  String(text).replace(/\%VERSION\%/mg, version);
     };
   }]);

 

    services.js

?
1
2
3
4
5
6
7
8
9
'use strict' ;
 
/* Services */
 
 
// Demonstrate how to register services
// In this case it is a simple value service.
angular.module( 'myApp.services' , []).
   value( 'version' '0.1' );

 

    index.html

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<!--[ if  lt IE 7]>      <html ng-app= "myApp"  class = "no-js lt-ie9 lt-ie8 lt-ie7" > <![endif]-->
<!--[ if  IE 7]>         <html ng-app= "myApp"  class = "no-js lt-ie9 lt-ie8" > <![endif]-->
<!--[ if  IE 8]>         <html ng-app= "myApp"  class = "no-js lt-ie9" > <![endif]-->
<!--[ if  gt IE 8]><!--> <html ng-app= "myApp" > <!--<![endif]-->
<head>
   <meta charset= "utf-8" >
   <meta http-equiv= "X-UA-Compatible"  content= "IE=edge" >
   <title>My AngularJS App</title>
   <meta name= "description"  content= "" >
   <meta name= "viewport"  content= "width=device-width, initial-scale=1" >
   <link rel= "stylesheet"  href= "bower_components/html5-boilerplate/css/normalize.css" >
   <link rel= "stylesheet"  href= "bower_components/html5-boilerplate/css/main.css" >
   <link rel= "stylesheet"  href= "css/app.css" />
   <script src= "bower_components/html5-boilerplate/js/vendor/modernizr-2.6.2.min.js" ></script>
</head>
<body>
   <ul>
     <li><a href= "#/view1" >view1</a></li>
     <li><a href= "#/view2" >view2</a></li>
   </ul>
 
   <!--[ if  lt IE 7]>
       <p>You are using an <strong>outdated</strong> browser. Please <a href= "http://browsehappy.com/" >upgrade your browser</a> to improve your experience.</p>
   <![endif]-->
 
   <div ng-view></div>
 
   <div>Angular seed app: v<span app-version></span></div>
 
   <!-- In production use:
   <script src= "//ajax.googleapis.com/ajax/libs/angularjs/x.x.x/angular.min.js" ></script>
   -->
   <script src= "bower_components/angular/angular.js" ></script>
   <script src= "bower_components/angular-route/angular-route.js" ></script>
   <script src= "js/app.js" ></script>
   <script src= "js/services.js" ></script>
   <script src= "js/controllers.js" ></script>
   <script src= "js/filters.js" ></script>
   <script src= "js/directives.js" ></script>
</body>
</html>

 

    如此在不使用requirejs的情景下,项目就构建完成了.还有几个补充点就是其一你可以将controllers继续拆分为多个controller模块,这里可以完全按照你的业务进行划分.比如user目录下userController等等.然后将所有这些我们自己写的文件通过grunt或者gulp进行合并为一个单独的总的文件all.js这样在页面中除了库文件只要这一个文件就行了.angular的module所带来的好处就是这样合并的文件,不用在乎js合并的顺序,因为它是通过angular依赖注入的.

    (2) 通过requirejs构建

    这种方式的构建可能对于某些人来讲更加清晰,结构和上面的基本一样,多了一个man.js用来配置requirejs,单独拆分出routes.js以及一个controller文件夹通过requirejs将controller一个个拆分出来,按需的异步加载.

    index.html

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!doctype html>
<html ng-app>
<head>
<title>Angular-RequireJS sample app</title>
<meta name= "viewport"  content= "width=device-width, initial-scale=1.0" >
<link rel= "stylesheet"  type= "text/css"  media= "all"  href= "app/css/app.css"  />
</head>
<body >
<h1>AngularJS + RequireJS</h1>
<ul>
<li><a href= "#/view1" >View 1</a></li>
<li><a href= "#/view2" >View 2</a></li>
</ul>
<div ng-view></div>
<script data-main= "app/js/main"  src= "/bower_components/requirejs/require.js" ></script>
</body>
</html>

 

    main.js

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
require.config({
     paths: {
         angular:  '../../bower_components/angular/angular' ,
         angularRoute:  '../../bower_components/angular-route/angular-route' ,
         angularMocks:  '../../bower_components/angular-mocks/angular-mocks' ,
         text:  '../../bower_components/requirejs-text/text'
     },
     shim: {
         'angular'  : { 'exports'  'angular' },
         'angularRoute' : [ 'angular' ],
         'angularMocks' : {
             deps:[ 'angular' ],
             'exports' : 'angular.mock'
         }
     },
     priority: [
         "angular"
     ]
});
 
//http://code.angularjs.org/1.2.1/docs/guide/bootstrap#overview_deferred-bootstrap
window.name =  "NG_DEFER_BOOTSTRAP!" ;
 
require( [
     'angular' ,
     'app' ,
     'routes'
],  function (angular, app, routes) {
     'use strict' ;
     var  $html = angular.element(document.getElementsByTagName( 'html' )[0]);
 
     angular.element().ready( function () {
         angular.resumeBootstrap([app[ 'name' ]]);
     });
});

 

    app.js

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
define([
     'angular' ,
     'filters' ,
     'services' ,
     'directives' ,
     'controllers' ,
     'angularRoute' ,
     ],  function  (angular, filters, services, directives, controllers) {
         'use strict' ;
 
         // Declare app level module which depends on filters, and services
         
         return  angular.module( 'myApp' , [
             'ngRoute' ,
             'myApp.controllers' ,
             'myApp.filters' ,
             'myApp.services' ,
             'myApp.directives'
         ]);
});

 

    controllers.js

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
define([ 'angular' 'services' ],  function  (angular) {
     'use strict' ;
 
     /* Controllers */
     
     return  angular.module( 'myApp.controllers' , [ 'myApp.services' ])
         // Sample controller where service is being used
         .controller( 'MyCtrl1' , [ '$scope' 'version' function  ($scope, version) {
             $scope.scopedAppVersion = version;
         }])
         // More involved example where controller is required from an external file
         .controller( 'MyCtrl2' , [ '$scope' '$injector' function ($scope, $injector) {
             require([ 'controllers/myctrl2' ],  function (myctrl2) {
                 // injector method takes an array of modules as the first argument
                 // if you want your controller to be able to use components from
                 // any of your other modules, make sure you include it together with 'ng'
                 // Furthermore we need to pass on the $scope as it's unique to this controller
                 $injector.invoke(myctrl2,  this , {'$scope': $scope});
             });
         }]);
});

 

    directives.js

?
1
2
3
4
5
6
7
8
9
10
11
12
define([ 'angular' 'services' ],  function (angular, services) {
     'use strict' ;
 
   /* Directives */
 
     angular.module( 'myApp.directives' , [ 'myApp.services' ])
         .directive( 'appVersion' , [ 'version' function (version) {
             return  function (scope, elm, attrs) {
                 elm.text(version);
         };
     }]);
});

 

    filters.js

?
1
2
3
4
5
6
7
8
9
10
11
12
define([ 'angular' 'services' ],  function  (angular, services) {
     'use strict' ;
 
     /* Filters */
   
     angular.module( 'myApp.filters' , [ 'myApp.services' ])
         .filter( 'interpolate' , [ 'version' function (version) {
             return  function (text) {
                 return  String(text).replace(/\%VERSION\%/mg, version);
             };
     }]);
});

 

    routes.js

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
define([ 'angular' 'app' ],  function (angular, app) {
     'use strict' ;
 
     return  app.config([ '$routeProvider' function ($routeProvider) {
         $routeProvider.when( '/view1' , {
             templateUrl:  'app/partials/partial1.html' ,
             controller:  'MyCtrl1'
         });
         $routeProvider.when( '/view2' , {
             templateUrl:  'app/partials/partial2.html' ,
             controller:  'MyCtrl2'
         });
         $routeProvider.otherwise({redirectTo:  '/view1' });
     }]);
 
});

 

    services.js

?
1
2
3
4
5
6
7
8
9
10
define([ 'angular' ],  function  (angular) {
     'use strict' ;
     
   /* Services */
 
   // Demonstrate how to register services
   // In this case it is a simple value service.
     angular.module( 'myApp.services' , [])
         .value( 'version' '0.1' );
});

 

    controllers文件夹中一个单独controlle文件,myCtrl2.js

?
1
2
3
4
5
6
7
8
9
10
11
define([],  function () {
     return  [ '$scope' '$http' function ($scope, $http) {
         // You can access the scope of the controller from here
         $scope.welcomeMessage =  'hey this is myctrl2.js!' ;
 
         // because this has happened asynchroneusly we've missed
         // Angular's initial call to $apply after the controller has been loaded
         // hence we need to explicityly call it at the end of our Controller constructor
         $scope.$apply();
     }];
});

 

    结尾

    写到这应该差不多了,就快超字数了.通常情况下Angular应用的构建这样就可以了,因为比起传统框架angular的代码量上肯定会有优势,所以一些不必要的东西就不用引入了.上面这些也是我在这段时间的项目中遇到并且做过的,已经实战过了,所以如果有类似需求的同学可以不必在此填坑.

转载于:https://www.cnblogs.com/GoodPingGe/p/4507722.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值