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的代码量上肯定会有优势,所以一些不必要的东西就不用引入了.上面这些也是我在这段时间的项目中遇到并且做过的,已经实战过了,所以如果有类似需求的同学可以不必在此填坑.
Angular项目构建指南 - 不再为angular构建而犹豫不决(转)的更多相关文章
- Angular学习笔记—创建一个angular项目
开始项目前,你需要先安装node和npm,然后执行npm install -g @angular/cli安装Angular CLI. 如何安装node.js和npm npm使用介绍 1.安装angul ...
- 前后端分离之前端项目构建(grunt+require+angular)
前言 前段时间做了一个项目,前端开发页面,然后把代码给到后端同学,后端同学通过vm再来渲染页面.后来才发现,这种方式简直是太low了,因为前端代码在服务端同学那里,每次前端需要更改的时候都需要去到服务 ...
- [转]使用 Angular CLI 和 ng-packagr 构建一个标准的 Angular 组件库
使用 Angular CLI 构建 Angular 应用程序是最方便的方式之一. 项目目标 现在,我们一起创建一个简单的组件库. 首先,我们需要创建一个 header 组件.这没什么特别的,当然接下来 ...
- 再遇angular(angular4项目实战指南)
这两天看了看angular4的文档,发现他和angular1.X的差别真的是太大了,官方给出的那个管理英雄的Demo是一个非常好的入门项目,这里给出一个管理个人计划的小项目,从头至尾一步一步讲解如何去 ...
- angular项目中各个文件的作用
原文地址 https://www.jianshu.com/p/176ea79a7101 大纲 1.对angular项目中的一些文件的概述 2.对其中一些文件的详细描述 2.1.package.json ...
- 【阿里云产品公测】以开发者角度看ACE服务『ACE应用构建指南』
作者:阿里云用户mr_wid ,z)NKt# @I6A9do 如果感觉该评测对您有所帮助, 欢迎投票给本文: UO<claV RsfTUb)< 投票标题: 28.[阿里云 ...
- Webpack入门——使用Webpack打包Angular项目的一个例子
2016.1.22,对大多数人来说,这是一个非常平常的日子,但这却是我决定在博客园写博客的日子.虽然注册博客园的博客已有4年8个月,却一直没有动手写过一篇博客,原因是觉得自己水平不行,写不出好东西,所 ...
- 浅谈 Angular 项目实战
为什么使用 Angular 我不是 Angular 的布道者,但如今痴迷 Angular,使用 Angular 做项目让我有一种兴奋感.目前的三大主流前端框架都研究过,博客中也有三者的相关教程,最早接 ...
- [转]Angular项目目录结构详解
本文转自:https://blog.csdn.net/yuzhiqiang_1993/article/details/71191873 版权声明:本文为博主原创文章,转载请注明地址.如果文中有什么纰漏 ...
随机推荐
- ADT环境搭建手册
前言 笔者在搭建ADT环境之前一脸懵逼,甚至不知道ADT是什么,更别说与之相关的SDK.eclipse等,相信很多小伙伴跟我一样也是一脸茫然,所以在搭建环境之前有必要先了解一下它们是什么,有什么样的关 ...
- 5月28日 python学习总结 CSS学习(一)
1. CSS是什么 层叠样式表 --> 给HTML添加样式的 2. CSS的语法 选择器 { 属性1:值1; 属性2:值2; } 3. CSS引入方式 1. 直接写在HTMl标签里面 <p ...
- MSSQL得知密码后getshell
本文用了 sql server 2000和sql server 2008 MSSQL连接 连接MSSQL 2000 新建连接: 填写目的IP.目的端口.用户名.密码: 一直下一步,完成后,数据库导航窗 ...
- loj3161「NOI2019」I 君的探险(随机化,整体二分)
loj3161「NOI2019」I 君的探险(随机化,整体二分) loj Luogu 题解时间 对于 $ N \le 500 $ 的点,毫无疑问可以直接 $ O(n^2) $ 暴力询问解决. 考虑看起 ...
- RenderDoc图形调试器详细使用教程(基于DirectX11)
前言 由于最近Visual Studio的图形调试器老是抽风,不得不寻找一个替代品了. 对于图形程序开发者来说,学会使用RenderDoc图形调试器可以帮助你全面了解渲染管线绑定的资源和运行状态,从而 ...
- mq 的缺点 ?
系统可用性降低 系统引入的外部依赖越多,越容易挂掉,本来你就是 A 系统调用 BCD 三个系统的 接口就好了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整?MQ ...
- spring-boot中的AOP
public class User { private Integer id; private String username; private String note; public User(In ...
- Java 中,DOM 和 SAX 解析器有什么不同?
DOM 解析器将整个 XML 文档加载到内存来创建一棵 DOM 模型树,这样可以 更快的查找节点和修改 XML 结构,而 SAX 解析器是一个基于事件的解析器, 不会将整个 XML 文档加载到内存.由 ...
- SqlMapConfig.xml文件详解
SqlMapConfig.xml 是 mybatis 的全局配置文件,配置内容如下: properties(属性) settings(全局配置参数) typeAliases(类型别名) typeHan ...
- MySQL优化篇(一),我可以和面试官多聊几句吗?——SQL优化流程与优化数据库对象
我可以和面试官多聊几句吗?只是想偷点技能过来.MySQL优化篇(基于MySQL8.0测试验证),上部分:优化SQL语句.数据库对象,MyISAM表锁和InnoDB锁问题. MyISAM表锁和InnoD ...