




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
概览目录结构由于一个大型的AngularJS应用有较多组成部分,所以最好通过分层的目录结构来组织。 有两个主流的组织方式: 按照类型优先,业务功能其次的组织方式这种方式的目录结构看起来如下:. app app.js controllers home FirstCtrl.js SecondCtrl.js about ThirdCtrl.js directives home directive1.js about directive2.js directive3.js filters home about services CommonService.js cache Cache1.js Cache2.js models Model1.js Model2.js partials lib test 按照业务功能优先,类型其次的组织方式如下:. app app.js common controllers directives filters services home controllers FirstCtrl.js SecondCtrl.js directives directive1.js filters filter1.js filter2.js services service1.js service2.js about controllers ThirdCtrl.js directives directive2.js directive3.js filters filter3.js services service3.js partials lib test 当目录里有多个单词时, 使用 lisp-case 语法:app app.js my-complex-module controllers directives filters services 在创建指令时,合适的做法是将相关的文件放到同一目录下 (如:模板文件, CSS/SASS 文件, JavaScript文件)。如果你在整个项目周期都选择这种组织方式,app directives directive1 directive1.html directive1.js directive1.sass directive2 directive2.html directive2.js directive2.sass那么,上述的两种目录结构均能适用。 组件的单元测试应与组件放置在同一目录下下。在这种方式下,当改变组件时,更加容易找到对应的测试。同时,单元测试也充当了文档和示例。services cache cache1.js cache1.spec.js models model1.js model1.spec.js app.js文件包含路由定义、配置和启动说明(如果需要的话)。 每一个 JavaScript 文件应该仅包含一个组件。文件名应该以组件名命名。 使用 Angular 项目模板,如Yeoman,ng-boilerplate.组件命名的约定可以在每个组件中看到。标记太长慎读把script标签放在文档底部。 MyApp 保持标签的简洁并把AngularJS的标签放在标准HTML属性后面。这样提高了代码可读性。标准HTML属性和AngularJS的属性没有混到一起,提高了代码的可维护性。 其它的HTML标签应该遵循下面的指南的建议标记下表展示了各个Angular元素的命名约定元素命名风格实例用途ModuleslowerCamelCaseangularAppControllersFunctionality + CtrlAdminCtrlDirectiveslowerCamelCaseuserInfoFilterslowerCamelCaseuserFilterServicesUpperCamelCaseUserconstructorServiceslowerCamelCasedataFactoryothers其他 使用: $timeout替代setTimeout $intervalinstead ofsetInterval $window替代window $document替代document $http替代$.ajax这将使你更易于在测试时处理代码异常 (例如:你在setTimeout中忘记$scope.$apply)使用如下工具自动化你的工作流 *Yeoman*Gulp*Grunt*Bower 使用 promise ($q) 而非回调。这将使你的代码更加优雅、直观,并且免于回调地狱。 尽可能使用$resource而非$http。更高的抽象可以避免冗余。 使用AngularJS的预压缩版 (像ngmin或ng-annotate) 避免在压缩之后出现问题。 不要使用全局变量或函数。通过依赖注入解决所有依赖,这可以减少 bug ,规避很多测试时的麻烦。 为避免使用全局变量或函数,可以借助 Grunt 或 Gulp 把你的代码放到一个立即执行的函数表达式(IIFE)中。可用的插件有grunt-wrap或gulp-wrap。下面是 Gulp 的示例:gulp.src(./src/*.js) .pipe(wrap(function()nuse strict;nn)();) .pipe(gulp.dest(./dist); 不要污染$scope。仅添加与视图相关的函数和变量。 使用 controllers 而非ngInit。ngInit只有在一种情况下的使用是合适的:用来给ngRepeat的特殊属性赋予一个别名。除此之外, 你应该使用 controllers 而不是ngInit来初始化scope变量。ngInit中的表达式会传递给 Angular 的$parse服务,通过词法分析,语法分析,求值等过程。这会导致: 对性能的巨大影响,因为解释器由 Javascript 写成 多数情况下,$parse服务中对表达式的缓存基本不起作用,因为ngInit表达式经常只有一次求值 很容易出错,因为是模板中写字符串,没有针对表达式的语法高亮和进一步的编辑器支持 不会抛出运行时错误 不要使用$前缀来命名变量, 属性和方法. 这种前缀是预留给 AngularJS 来使用的. 当使用 DI 机制来解决依赖关系, 要根据他们的类型进行排序 - AngularJS 内建的依赖要优先, 之后才是你自定义的:module.factory(Service, function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) return /Something ;);模块 模块应该用驼峰式命名。为表明模块b是模块a的子模块, 可以用点号连接:a.b。有两种常见的组织模块的方式: 按照功能组织 按照组件类型组织当前并无太大差别,但前者更加清晰。同时,如果 lazy-loading modules 被实现的话 (当前并未列入 AngularJS 的路线图),这种方式将改善应用的性能。控制器 不要在控制器里操作 DOM,这会让你的控制器难以测试,而且违背了关注点分离原则。应该通过指令操作 DOM。 通过控制器完成的功能命名控制器 (如:购物卡,主页,控制板),并以字符串Ctrl结尾。 控制器是纯 Javascript构造函数,所以应该用首字母大写的驼峰命名法(HomePageCtrl,ShoppingCartCtrl,AdminPanelCtrl, 等等)。 控制器不应该在全局中定义 (尽管 AngularJS 允许,但污染全局命名空间是个糟糕的实践)。 使用以下语法定义控制器: function MyCtrl(dependency1, dependency2, ., dependencyn) / . module.controller(MyCtrl, MyCtrl);为了避免在压缩代码时产生问题,你可以使用工具自动生成标准的数组定义式语法,如:ng-annotate(还有 grunt 任务grunt-ng-annotate) 使用controller as语法: main.title app.controller(MainCtrl, MainCtrl); function MainCtrl () this.title = Some title;使用controller as主要的优点是: 创建了一个“独立”的组件绑定的属性不属于$scope原型链。这是一个很好的实践,因为$scope原型继承有一些重要的缺点(这可能是为什么它在 Angular 2 中被移除了): Scope值的改变会在你不注意的地方有影响。 难以重构。 dot rule. 当你不需要做必须由$scope完成的操作(比如$scope.$broadcast)时,移除掉了$scope,就是为 Angular2 做好准备。 语法上更接近于普通的 JavaScript 构造函数。想深入了解controller as,请看:digging-into-angulars-controller-as-syntax 如果使用数组定义语法声明控制器,使用控制器依赖的原名。这将提高代码的可读性: function MyCtrl(s) / . module.controller(MyCtrl, $scope, MyCtrl);下面的代码更易理解function MyCtrl($scope) / .module.controller(MyCtrl, $scope, MyCtrl);对于包含大量代码的需要上下滚动的文件尤其适用。这可能使你忘记某一变量是对应哪一个依赖。 尽可能的精简控制器。将通用函数抽象为独立的服务。 不要再控制器中写业务逻辑。把业务逻辑交给模型层的服务。 举个例子: / 这是把业务逻辑放在控制器的常见做法 angular.module(Store, ) .controller(OrderCtrl, function ($scope) $scope.items = ; $scope.addToOrder = function (item) $scope.items.push(item);/-控制器中的业务逻辑 ; $scope.removeFromOrder = function (item) $scope.items.splice($scope.items.indexOf(item), 1);/-控制器中的业务逻辑 ; $scope.totalPrice = function () return $scope.items.reduce(function (memo, item) return memo + (item.qty * item.price);/-控制器中的业务逻辑 , 0); ;);当你把业务逻辑交给模型层的服务,控制器看起来就会想这样:(关于 service-model 的实现,参看 use services as your Model):/ Order 在此作为一个 modelangular.module(Store, ).controller(OrderCtrl, function (Order) $scope.items = Order.items; $scope.addToOrder = function (item) Order.addToOrder(item); ; $scope.removeFromOrder = function (item) Order.removeFromOrder(item); ; $scope.totalPrice = function () return Order.total(); ;);为什么控制器不应该包含业务逻辑和应用状态? 控制器会在每个视图中被实例化,在视图被销毁时也要同时销毁 控制器是不可重用的它与视图有耦合 Controllers are not meant to be injected 需要进行跨控制器通讯时,通过方法引用(通常是子控制器到父控制器的通讯)或者$emit,$broadcast及$on方法。发送或广播的消息应该限定在最小的作用域。 制定一个通过$emit,$broadcast发送的消息列表并且仔细的管理以防命名冲突和bug。Example:/ app.js/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *Custom events: - authorization-message - description of the message - user, role, action - data format - user - a string, which contains the username - role - an ID of the role the user has - action - specific ation the user tries to perform* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 在需要格式化数据时将格式化逻辑封装成过滤器并将其声明为依赖: function myFormat() return function () / . ; module.filter(myFormat, myFormat); function MyCtrl($scope, myFormatFilter) / . module.controller(MyCtrl, MyCtrl); 有内嵌的控制器时使用 内嵌作用域 (controllerAs语法):app.jsmodule.config(function ($routeProvider) $routeProvider .when(/route, templateUrl: partials/template.html, controller: HomeCtrl, controllerAs: home ););HomeCtrlfunction HomeCtrl() this.bindingValue = 42;template.html指令 使用小写字母开头的驼峰法命名指令。 在 link function 中使用scope而非$scope。在 compile 中, 你已经定义参数的 post/pre link functions 将在函数被执行时传递, 你无法通过依赖注入改变他们。这种方式同样应用在 AngularJS 项目中。 为你的指令添加自定义前缀以免与第三方指令冲突。 不要使用ng或ui前缀,因为这些备用于 AngularJS 和 AngularJS UI。 DOM 操作只通过指令完成。 为你开发的可复用组件创建独立作用域。 以属性和元素形式使用指令,而不是注释和 class。这会使你的代码可读性更高。 使用scope.$on($destroy, fn)来清除。这点在使用第三方指令的时候特别有用。 处理不可信的数据时,不要忘记使用$sce。过滤器 使用小写字母开头的驼峰法命名过滤器。 尽可能使过滤器精简。过滤器在$digestloop 中被频繁调用,过于复杂的过滤器将使得整个应用缓慢。 在过滤器中只做一件事。更加复杂的操作可以用 pipe 串联多个过滤器来实现。服务这个部分包含了 AngularJS 服务组件的相关信息。下面提到的东西与定义服务的具体方式(.provider,.factory,.service等)无关,除非有特别提到。 用驼峰法命名服务。 用首字母大写的驼峰法命名你自己的服务, 把服务写成构造函数的形式,例如: function MainCtrl($scope, User) $scope.user = new User(foo, 42); module.controller(MainCtrl, MainCtrl); function User(name, age) = name; this.age = age; module.factory(User, function () return User;); 用首字母小写的驼峰法命名其它所有的服务。 把业务逻辑封装到服务中,把业务逻辑抽象为服务作为你的model。例如: /Order is the model angular.module(Store) .factory(Order, function () var add = function (item) this.items.push (item); ; var remove = function (item) if (this.items.indexOf(item) -1) this.items.splice(this.items.indexOf(item), 1); ; var total = function () return this.items.reduce(function (memo, item) return memo + (item.qty * item.price); , 0); ; return items: , addToOrder: add, removeFromOrder: remove, totalPrice: total ;);如果需要例子展现如何在控制器中使用服务,请参考 Avoid writing business logic inside controllers。 将业务逻辑封装成service而非factory,这样我们可以更容易在服务间实现“经典式”继承: function Human() /body Htotype.talk = function () return Im talking; ; function Developer() /body Dtotype = Object.create(Htotype); Dtotype.code = function () return Im coding; ; myModule.service(human, Human); myModule.service(developer, Developer); 使用$cacheFactory进行会话级别的缓存,缓存网络请求或复杂运算的结果。 如果给定的服务需要配置,把配置相关代码放在config回调里,就像这样: angular.module(demo, ) .config(function ($provide) $vider(sample, function () var foo = 42; return setFoo: function (f) foo = f; , $get: function () return foo: foo ; ; ); ); var demo = angular.module(demo); demo.config(function (sampleProvider) samplePro
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 电影获奖发言稿
- 中班认识苗族课件
- 人体发育学课件
- 2025版房产中介公司知识产权保护合作协议
- 二零二五年毛石石材批发市场合作协议
- 二零二五年度新能源设备维修保养与能源管理协议
- 二零二五年度汽车后市场零部件代理合同
- 二零二五年度专业舞台灯光音响租赁合同样本
- 二零二五年度锻件制造企业节能减排技术改造合同
- 2025版智能家居家居装修工程绿色施工安全协议
- 广西2025年公需科目学习考试试题及答案4
- 代加工板材合同协议书范本
- 2025-2026学年新七年级上学期开学摸底考试语文试卷(广东专用)
- 2025年事业单位工勤技能-湖南-湖南地质勘查员二级(技师)历年参考题库含答案解析(5卷)
- 早期诊断技术优化-第1篇-洞察及研究
- 2025 慢阻肺合并肺心病诊疗查房课件
- 2025二手房个人购房合同范本
- AI初级复习试题附答案
- 检验科生物安全工作总结模版
- 电网工程设备材料信息参考价(2024年第四季度)
- NB-T32036-2017光伏发电工程达标投产验收规程
评论
0/150
提交评论