Angular规范
只记录一些自己未曾用过,但觉得对以后的项目有帮助的规范
一 Javascript闭包
把Angular组件包装到一个立即调用函数表达式中(IIFE)。
为什么?:把变量从全局作用域中删除了,这有助于防止变量和函数声明比预期在全局作用域中有更长的生命周期,也有助于避免变量冲突。
为什么?:当你的代码为了发布而压缩了并且被合并到同一个文件中时,可能会有很多变量发生冲突,使用了IIFE(给每个文件提供了一个独立的作用域),你就不用担心这个了。
/* avoid */
// logger.js
angular
.module('app')
.factory('logger', logger); // logger function会被当作一个全局变量
function logger() { } // storage.js
angular
.module('app')
.factory('storage', storage); // storage function会被当作一个全局变量
function storage() { }
/**
* recommended
*
* 再也不存在全局变量了
*/ // logger.js
(function() {
'use strict'; angular
.module('app')
.factory('logger', logger); function logger() { }
})(); // storage.js
(function() {
'use strict'; angular
.module('app')
.factory('storage', storage); function storage() { }
})();
二 Modules
2.1 定义
不使用任何一个使用了setter语法的变量来定义modules。
为什么?:在一个文件只有一个组件的条件下,完全不需要为一个模块引入一个变量。
/* avoid */
var app = angular.module('app', [
'ngAnimate',
'ngRoute',
'app.shared',
'app.dashboard'
]);
你只需要用简单的setter语法来代替。
/* recommended */
angular
.module('app', [
'ngAnimate',
'ngRoute',
'app.shared',
'app.dashboard'
]);
2.2 Getters
使用module的时候,避免直接用一个变量,而是使用getter的链式语法。
为什么?:这将产生更加易读的代码,并且可以避免变量冲突和泄漏。
/* avoid */
var app = angular.module('app');
app.controller('SomeController', SomeController); function SomeController() { }
/* recommended */
angular
.module('app')
.controller('SomeController', SomeController); function SomeController() { }
2.3 Setting vs Getting
只能设置一次。
为什么?:一个module只能被创建一次,创建之后才能被检索到。
- 设置module,
angular.module('app', []);
- 获取module,
angular.module('app');
2.4命名函数 vs 匿名函数
回调函数使用命名函数,不要用匿名函数。
为什么?:易读,方便调试,减少嵌套回调函数的数量。
/* avoid */
angular
.module('app')
.controller('Dashboard', function() { })
.factory('logger', function() { });
/* recommended */ // dashboard.js
angular
.module('app')
.controller('Dashboard', Dashboard); function Dashboard () { }
// logger.js
angular
.module('app')
.factory('logger', logger); function logger () { }
三 Controllers
3.1 controllerAs在View中的语法
使用controllerAs
语法代替直接用经典的$scope定义的controller的方式。
为什么?:congtroller被构建的时候,就会有一个新的实例,controllerAs
的语法比经典的$scope语法
更接近JavaScript构造函数。
为什么?:这促进在View中对绑定到“有修饰”的对象的使用(例如用customer.name
代替name
),这将更有语境、更容易阅读,也避免了任何没有“修饰”而产生的引用问题。
为什么?:有助于避免在有嵌套的controllers的Views中调用 $parent
。
<!-- avoid -->
<div ng-controller="Customer">
{{ name }}
</div>
<!-- recommended -->
<div ng-controller="Customer as customer">
{{ customer.name }}
</div>
3.2 controllerAs在controller中的语法
使用
controllerAs
语法代替经典的$scope语法
语法。使用
controllerAs
时,controller中的$scope
被绑定到了this
上。为什么?:
controllerAs
是$scope
的语法修饰,你仍然可以绑定到View上并且访问$scope
的方法。为什么?:避免在controller中使用
$scope
,最好不用它们或是把它们移到一个factory中。factory中可以考虑使用$scope
,controller中只在需要时候才使用$scope
,例如当使用$emit
,$broadcast
,或者$on
来发布和订阅事件时,可以考虑把这些调用挪到factory当中,并从controller中调用。
/* avoid */
function Customer ($scope) {
$scope.name = {};
$scope.sendMessage = function() { };
}
/* recommended - but see next section */
function Customer () {
this.name = {};
this.sendMessage = function() { };
}
3.3 controllerAs with vm
使用controllerAs
语法时把this
赋值给一个可捕获的变量,选择一个有代表性的名称,例如vm
代表ViewModel。
为什么?:this
在不同的地方有不同的语义(就是作用域不同),在controller中的一个函数内部使用this
时可能会改变它的上下文。用一个变量来捕获this
的上下文从而可以避免遇到这样的坑。
/* avoid */
function Customer() {
this.name = {};
this.sendMessage = function() { };
}
/* recommended */
function Customer () {
var vm = this;
vm.name = {};
vm.sendMessage = function() { };
}
3.4 可绑定成员放到顶部
把可绑定的成员放到controller的顶部,按字母排序,并且不要通过controller的代码传播。
为什么?:易读,可以让你立即识别controller中的哪些成员可以在View中绑定和使用。
为什么?:虽然设置单行匿名函数很容易,但是当这些函数的代码超过一行时,这将极大降低代码的可读性。在可绑定成员下面定义函数(这些函数被提出来),把具体的实现细节放到下面,可绑定成员放到顶部,这会提高代码的可读性。
/* avoid */
function Sessions() {
var vm = this; vm.gotoSession = function() {
/* ... */
};
vm.refresh = function() {
/* ... */
};
vm.search = function() {
/* ... */
};
vm.sessions = [];
vm.title = 'Sessions';
/* recommended */
function Sessions() {
var vm = this; vm.gotoSession = gotoSession;
vm.refresh = refresh;
vm.search = search;
vm.sessions = [];
vm.title = 'Sessions'; //////////// function gotoSession() {
/* */
} function refresh() {
/* */
} function search() {
/* */
}
3.5 把Controller中的逻辑延迟到Service中
通过委派到service和factory中来延迟controller中的逻辑。
为什么?:把逻辑放到service中,并通过一个function暴露,就可以被多个controller重用。
为什么?:把逻辑放到service中将会使单元测试的时候更加容易地把它们分离,相反,如果在controller中调用逻辑就显得很二了。
为什么?:保持controller的简洁。
为什么?:从controller中删除依赖关系并且隐藏实现细节。
四 Factory
4.1 单一职责
factory应该是单一职责,这是由其上下文进行封装的。一旦一个factory将要处理超过单一的目的时,就应该创建一个新的factory
4.2 可访问的成员放到顶部
使用从显露模块模式派生出来的技术把service(它的接口)中可调用的成员暴露到顶部,
为什么?:易读,并且让你可以立即识别service中的哪些成员可以被调用,哪些成员必须进行单元测试(或者被别人嘲笑)。
为什么?:当文件内容很长时,这可以避免需要滚动才能看到暴露了哪些东西。
为什么?:虽然你可以随意写一个函数,但当函数代码超过一行时就会降低可读性并造成滚动。通过把实现细节放下面、可调用接口放到顶部的返回service的方式来定义可调用的接口,从而使代码更加易读。
/* avoid */
function dataService () {
var someValue = '';
function save () {
/* */
};
function validate () {
/* */
}; return {
save: save,
someValue: someValue,
validate: validate
};
}
/* recommended */
function dataService () {
var someValue = '';
var service = {
save: save,
someValue: someValue,
validate: validate
};
return service; //////////// function save () {
/* */
}; function validate () {
/* */
};
}
五 Data Services
5.1 独立的数据调用
把进行数据操作和数据交互的逻辑放到factory中,数据服务负责XHR请求、本地存储、内存存储和其它任何数据操作。
为什么?:controller的作用是查看视图和收集视图的信息,它不应该关心如何取得数据,只需要知道哪里需要用到数据。把取数据的逻辑放到数据服务中能够让controller更简单、更专注于对view的控制。
为什么?:方便测试。
为什么?:数据服务的实现可能有非常明确的代码来处理数据仓库,这可能包含headers、如何与数据交互或是其它service,例如$http
。把逻辑封装到单独的数据服务中,这隐藏了外部调用者(例如controller)对数据的直接操作,这样更加容易执行变更。
六 Directives
6.1 一个dirctive一个文件
一个文件中只创建一个directive,并依照directive来命名文件。
为什么?:虽然把所有directive放到一个文件中很简单,但是当一些directive是跨应用的,一些是跨模块的,一些仅仅在一个模块中使用时,想把它们独立出来就非常困难了。
为什么?:一个文件一个directive也更加容易维护。
注: "最佳实践:Angular文档中有提过,directive应该自动回收,当directive被移除后,你可以使用
element.on('$destroy', ...)
或者scope.$on('$destroy', ...)
来执行一个clearn-up函数。"
Angular规范的更多相关文章
- 基于 angular 规范的 commit
基于 angular 规范的 commit commit格式如下: <type>: <subject> <BLANK LINE> <body> type ...
- Commit message 的写法规范。本文介绍Angular 规范(
Commit message 的写法规范.本文介绍Angular 规范( http://www.ruanyifeng.com/blog/2016/01/commit_message_change_lo ...
- 使用 Commitizen 撰写 Angular 规范的 commit message
本文为原创文章,转载请标明出处 目录 安装及配置 使用 1. 安装及配置 npm install -g commitizen npm install -g cz-conventional-change ...
- git-commit Angular规范
commit message的格式 每次提交,Commit message 都包括三个部分:Header,Body 和 Footer. <type>(<scope>): < ...
- Angular指令(一)
Angular开发者手册重点翻译之指令(一) 创建自定义的指令 这个文章将解释什么需要在自己的angularjs应用中创建自己的指令,以及如何实现它. 什么是指令 在高的层面上讲,指令是DOM元素中的 ...
- 您必须知道的 Git 分支开发规范
Git 是目前最流行的源代码管理工具. 为规范开发,保持代码提交记录以及 git 分支结构清晰,方便后续维护,现规范 git 的相关操作. 分支管理 分支命名 master 分支 master 为主分 ...
- Angular开发者手册重点翻译之指令(一)
创建自定义的指令 这个文章将解释什么需要在自己的angularjs应用中创建自己的指令,以及如何实现它. 什么是指令 在高的层面上讲,指令是DOM元素中的标记(例如一个属性,一个节点名,注释或者CSS ...
- 后端必备的 Git 分支开发规范指南 转
原文链接 作者:稻草叔叔 http://juejin.im/post/5b4328bbf265da0fa21a6820 点击上方 "后端技术精选",选择 "置顶公众号&q ...
- commitizen规范代码提交
转载链接:https://www.jianshu.com/p/bd712e42f2e9 参考链接:https://segmentfault.com/a/1190000009048911 平时提交的变动 ...
随机推荐
- 将ACCESS数据库迁移到SQLSERVER数据库
原文:将ACCESS数据库迁移到SQLSERVER数据库 将ACCESS数据库迁移到SQLSERVER数据库 ACCESS2000文件 用ACCESS2007打开,并迁移到SQLSERVER2005里 ...
- C++ 哈希表 (hashtable) 用于保存简单的数据,及数据查找,数据删除
/*hashtable.h*/ #include<iostream> #include <string> #include<vector> using namesp ...
- CenOS下安装jdk
1. 安装JDK1.7.0 下载完成后在取得root权限后执行: [root@sea sea]# sudo rpm -ivh /目录/jdk-7-linux-x64.rpm 执行结果: Prepari ...
- Java Web整合开发(80) -- EJB & WebService
1. jdk-6u18-windows-i586-p.execlasspath: .;%JAVA_HOME%lib/tools.jar;%JAVA_HOME%lib/dt.jar;%JAVA_HOME ...
- Swift新手教程3-字符串String
原创blog,转载请注明出处 String 在swfit中,String兼容Unicode的方式.用法和C语言类似. 注意 在Cocoa和Cocoa touch中,Swift的String,和Fo ...
- java实现大数相加问题
闲来没事.写了个acm中常常遇到的大数加减问题的java 解决代码,我想说.用java的BigInteger 非常easy. 大爱java!! 比如: 实现多组输入的大数加减问题: import ja ...
- SPOJ PT07X Vertex Cover
题目意思: 一棵树,找到最少的点能覆盖到所有的边,(也就是每条边俩端 至少有一个在你找到的集合): 解法:每条边只能被俩个点中的一个,或全部覆盖所以我们有树形DP来解: DP[num][flag]// ...
- 在C#环境中动态调用IronPython脚本(二)
一.Python数据类型与C#数据类型的对应 Python中数据类型中的简单类型,例如int,float,string可以对应到C#环境中的int32,double,string,这些对应比较直观,P ...
- Android异步任务
本文主要探讨Android平台提供的各种异步载入机制,包括它们的适用场景.用法等. 1. AsynTask AsynTask适用于最长能够持续几秒钟的短时间的操作,对于长时间的操作,建议使用java. ...
- CSDN-markdown编者LaTex数学公式
LaTex什么? LaTeX(LATEX.音译"拉太和")它是基于ΤΕΧ排版系统,莱斯利由美国计算机科学家·兰伯特(Leslie Lamport)于20纪80年代初期开发,利用这样 ...