Angular项目构建指南 - 不再为angular构建而犹豫不决(转)
如果你不知道什么是Angular或者根本沒聽說過,那么我接下來所說的對(duì)你來說毫無益處,不過如果你打算以后會(huì)接觸Angular或者干脆要漲漲姿勢(shì)~讀下去還是有點(diǎn)用的.
????Angular和它之前所出現(xiàn)的其余前端框架最大的不同,在于它的核心不再是DOM,而是數(shù)據(jù),是model.我們慣用的不管是單純的jQuery還是MVC的Backbone,它們本質(zhì)仍是讓我們更方便更有條理的操作DOM,但是Angular不是.通過一系列魔術(shù)般的手法,它將一切的重心轉(zhuǎn)移到數(shù)據(jù)上.以開發(fā)應(yīng)用而不是操作節(jié)點(diǎn)的方式去開發(fā)Web,一切以數(shù)據(jù)為中心,數(shù)據(jù)的變化驅(qū)動(dòng)了一切,包括行為.
????文本主題,如何構(gòu)建一個(gè)angular項(xiàng)目?
????坦白說最開始構(gòu)建一個(gè)項(xiàng)目的時(shí)候,雖然很小但是很糾結(jié).我本身是有點(diǎn)完美主義的,所以雖然一開始什么都沒有也想做到盡善盡美.因?yàn)槁犨^很多前輩的經(jīng)驗(yàn),說如果框架基礎(chǔ)沒搭好,等到后來不管是重構(gòu)還是維護(hù)都是一場(chǎng)噩夢(mèng).所以一開始小心意義,希望能將項(xiàng)目盡量搭建的結(jié)實(shí)并且益于維護(hù)和開發(fā).
????在搭建伊始首先遇到的一個(gè)問題,就是到底要不要引入requirejs或者seajs這類依賴管理的工具?
????我本身沒有多少語言或者技術(shù)的上的情節(jié),對(duì)于各個(gè)大神也沒有多少膜拜的憧憬(更多的是我根本不清楚誰是大神,也從沒去找過).所以對(duì)于我來講不管是requirejs的AMD還是seajs的CMD,從實(shí)現(xiàn)的角度上來講都是做了同一個(gè)工作.在考慮一個(gè)Angular應(yīng)用到底需不需要這種工具的時(shí)候,我也在網(wǎng)上看了很多人的說法.我總結(jié)一句就是,基本都和沒說一樣,也就是用不用隨便,看情況.
????那么我能有什么好的答案,其實(shí)我現(xiàn)在的答案就是:"可以不用".怎么說是可以不用呢,如果你不用requirejs也能滿足項(xiàng)目的開發(fā)以及各種需求,那么就別用了.angular本身的模塊已經(jīng)做到了依賴注入,所以我們不需要通過requirejs進(jìn)行異步加載也可以很好的用下去.
????當(dāng)然,如果你開發(fā)過程中發(fā)覺還是有些地方需要,那么也可以加上去.本文里我會(huì)詳細(xì)說明這兩種方式的構(gòu)建方法.但是這里我的觀點(diǎn)已經(jīng)表明了:在不需要的情況下,不要用.
????(1) 不用requirejs直接構(gòu)建Angular
????之所以不使用requirejs就直接構(gòu)建angular,因?yàn)閍ngular對(duì)于依賴的管理以及angular的使用場(chǎng)景完全可以做到這一點(diǎn).首先在以來上,angular的依賴注入是個(gè)好東西,不了解的同學(xué)可以去搜一下資料.我這里簡(jiǎn)單的說,就是當(dāng)我需要一個(gè)module的時(shí)候,我不用管它在哪,它是什么.我只要知道它的名字然后告訴angular就可以了,至于怎么將它的對(duì)象傳遞過來,怎么找到的,angular自己會(huì)去處理.
?| 1 2 3 | angular.module('myApp',?[ ??'ngRoute', ]); |
?
????例如這里的ngRoute,我需要知道ngRoute怎么來的,在哪里.只要有一個(gè)模塊定義為ngRoute我就可以直接拿來用.
????鑒于Angular如此的給力,剩下的事情就好辦了.我們只需要從功能和業(yè)務(wù)兩方面將文件劃分成module就可以了,然后將所有的庫(kù)文件在頁面上通過script標(biāo)簽引用,再將所有的業(yè)務(wù)文件也即是我們自己寫的js合并為一個(gè)all.js加載到頁面上即可.
????這里文件的劃分遵循angular官方的推薦方式:
?| 1 2 3 4 5 6 7 8 9 10 | |--js ???|--app.js?????????????????????//?app啟動(dòng)文件,用于app配置 ???|--controllers.js??????????//?controllers也就是存放我們自己的業(yè)務(wù)文件 ???|--directives.js????????????//?指令文件(指令可共用) ???|--fliters.js??????????????????//?過濾器文件(過濾器可共用) ???|--services.js?????????????//??服務(wù)文件(可共用,一般是與服務(wù)器交互的服務(wù)) |--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的情景下,項(xiàng)目就構(gòu)建完成了.還有幾個(gè)補(bǔ)充點(diǎn)就是其一你可以將controllers繼續(xù)拆分為多個(gè)controller模塊,這里可以完全按照你的業(yè)務(wù)進(jìn)行劃分.比如user目錄下userController等等.然后將所有這些我們自己寫的文件通過grunt或者gulp進(jìn)行合并為一個(gè)單獨(dú)的總的文件all.js這樣在頁面中除了庫(kù)文件只要這一個(gè)文件就行了.angular的module所帶來的好處就是這樣合并的文件,不用在乎js合并的順序,因?yàn)樗峭ㄟ^angular依賴注入的.
????(2) 通過requirejs構(gòu)建
????這種方式的構(gòu)建可能對(duì)于某些人來講更加清晰,結(jié)構(gòu)和上面的基本一樣,多了一個(gè)man.js用來配置requirejs,單獨(dú)拆分出routes.js以及一個(gè)controller文件夾通過requirejs將controller一個(gè)個(gè)拆分出來,按需的異步加載.
????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文件夾中一個(gè)單獨(dú)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(); ????}]; }); |
?
????結(jié)尾
????寫到這應(yīng)該差不多了,就快超字?jǐn)?shù)了.通常情況下Angular應(yīng)用的構(gòu)建這樣就可以了,因?yàn)楸绕饌鹘y(tǒng)框架angular的代碼量上肯定會(huì)有優(yōu)勢(shì),所以一些不必要的東西就不用引入了.上面這些也是我在這段時(shí)間的項(xiàng)目中遇到并且做過的,已經(jīng)實(shí)戰(zhàn)過了,所以如果有類似需求的同學(xué)可以不必在此填坑.
轉(zhuǎn)載于:https://www.cnblogs.com/GoodPingGe/p/4507722.html
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Angular项目构建指南 - 不再为angular构建而犹豫不决(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android自动化测试Uiautoma
- 下一篇: 网站架构之架构演化