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 平时提交的变动 ...
随机推荐
- Red Gate系列之八 SQL Connect 1.1.1.19 Edition 数据库连接及操作工具 完全破解+使用教程
原文:Red Gate系列之八 SQL Connect 1.1.1.19 Edition 数据库连接及操作工具 完全破解+使用教程 Red Gate系列之八 SQL Connect 1.1.1.19 ...
- 使用Ratpack和Spring Boot打造高性能的JVM微服务应用
使用Ratpack和Spring Boot打造高性能的JVM微服务应用 这是我为InfoQ翻译的文章,原文地址:Build High Performance JVM Microservices wit ...
- wamp无法登录phpmyadmin问题
文章来源:PHP座谈会 地址:http://bbs.phpthinking.com/forum.php? mod=viewthread&tid=163 第一步.用navicat确认一下,自己的 ...
- 【LeetCode】Triangle 解决报告
[称号] Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjac ...
- WEB 3D SVG CAD 向量 几个实施
一.他们所有的发展.从地上爬起来 VML+SVG发展矢量地图.你并不需要导入第三方的图片作为背景,直接在地图编辑器可以在底图内容编辑,由于岩石.巷道.煤层.画水.础地图样子再在其上面画出智慧线等设备, ...
- PC2日记——坑爹的第一天2014/08/28
我不想安慰自己说今天是因为第一次将pc2用于实际的比赛经验不足而导致的今天出现种种问题,我想说的是自从我開始干后台我所做的每一件事都是第一次,所以这绝对不是让自己免去责怪的理由:我想说的是假设我今天是 ...
- ServiceStack.Hello——跨平台.net REST api服务搭建
ServiceStack.Hello--跨平台.net REST api服务搭建 自己创建: https://github.com/ServiceStack/ServiceStack/wiki/Cre ...
- A simple Test Client built on top of ASP.NET Web API Help Page
Step 1: Install the Test Client package Install the WebApiTestClient package from the NuGet Package ...
- React-Native入门
React-Native入门指导之iOS篇 React-Native 入门指导系列教程目录 一.准备工作 (已完成) 二.项目介绍与调试 三.CSS样式与Flex布局 四.常用UI控件的使用 五.JS ...
- lua基金会【五岁以下儿童】I/O文件操作
--[[ lua操作相关文件I/O ]]-- --件,假设该文件不存在的话, --lua会帮助我们在你规定的文件夹下创建这个文件,前提是该文件夹要存在 --[[ 同一时候我们应该掌握写入文件的模式: ...