AngularJS最佳编码实践指南

AngularJS 是制作 SPA(单页面应用程序)和其它动态Web应用最广泛使用的框架之一。我认为程序员在使用AngularJS编码时有一个大的列表点应该记住,它会以这样或那样的方式帮助到你。下面是一些我遵守的最佳实践建议,同时也想推荐给你们。我坚信有更多的功能也应该是这份列表的一部分,我邀请你们都来提建议或者在下面评论,从而使这个成为完整的最佳实践指南。

一、依赖注入:

1. 依赖注入是AngularJS框架最好的特性之一,我们应该经常使用它。当我们需要对我们的应用程序进行测试用例覆盖时,它将真正的起到帮助。

2. 为依赖提供别名,这样他们不会在(JS代码)压缩过程中重命名,因为在AngularJS依赖是通过命名来实现的(注:AngularJS通过控制器构造函数的参数名字来推断依赖服务名称的)。

@H_301_51@

二、作用域

1. 在templates(模板)中scope(作用域)按只读对待。这就是说即使AngularJS允许我们在templates中编写代码修改scope,我们必须非常谨慎或者就不应该做。

2. 在controllers(控制器)中scope按只写对待。这就是说一个controllers负责使用另一个组件,就像一个服务,获取template将要显示的数据和把数据写到scope的一个对象中。

  • 作为一个经验法则,我们必须总是在绑定时使用”.“。这就是说我们应该绑定到scope的对象,而不是直接的属性,否则可能会在子$scope导致意外的行为,因为$scope基于Java-script的原型继承机制。
  • 下面的代码我们可以看到,superhero是scope上一个通过Superhero服务返回的对象,同时相同的对象被用来绑定在view(视图)上。
1
2
3
4
5
6
angular.module(‘myApp’).controller('MyController',['$scope','MyService',function($scope,MyService) {
// controller logic
}
]);
@H_301_51@
1
2
3
4
5
<divclass="form-group">
<labelclass="control-label"for="name">Super Power</label>
<divclass="controls">
<inputtype="text"data-ng-model="superhero.superPower">
</div>
@H_301_51@
  • Scope 的目的是引用 model,而不是成为 model。
  • Model是我们的JavaScript对象
@H_404_145@

三、验证

1. 在form(表单)标签中使用“novalidate”属性来使用AngularJS验证同时关闭HTML5验证。

1
2
3
$scope. superhero = Superheros.get({
superheroId: $stateParams.superheroId
)};
@H_301_51@

2. 我们可以使用angular classes(css类)来改变可见性和验证控件的状态。

1
<formname="reviewForm"ng-controller="ReviewController as reviewCtrl"ng-submit="reviewCtrl.addReview(product)"novalidate>
@H_301_51@

四、内存 – 任务管理

  • AngularJS在销毁一个scope和把一个scope从它的父级移除之前会广播一个$destroy事件。监听这个事件对清理任务和资源是至关重要的,否则可能会继续消耗内存或cpu。总是注册‘destroy‘事件来删除任何易于内存泄漏的代码

作为一个例子,下面的控制器在1秒的间隔不断更新一个mode(模型)l值,这些更新将永远持续,即使在controller对应view消失了或者scope从父级上移除。如果用户来回导航到一个view来加载这个controller,每次导航将添加另一个永远运行的计时器。

.ng-valid.ng-dirty{
border-color:#FA787E;
}
.ng-invalid.ng-dirty{
border-color:#FA787E;
}
@H_301_51@

监听$destroy事件是停止计时器的一个机会。一种方法是取消由$timeout返回的promise(承诺)。

1
2
3
4
5
6
7
8
9
module.controller("MyController",$timeout) {
varonMyTimeout =function() {
$scope.value += 1;
$timeout(onMyTimeout,100);
};
$timeout(onMyTimeout,100);
$scope.value = 0;
});
@H_301_51@

五、事件 顶级作用域

1. 我们应该只在当前屏幕的单页面应用程序的控制器中使用scope事件进行通信。如果我们只需要共享数据,那么我们应该考虑使用Services(服务)。

2. 当触发事件时,除非我们需要把事件通知到我们整个应用程序里的所有单个scope,否则我们不需要在$rootScope触发事件。如果我们只需要为子scope触发,则在当前的scope上$broadcast事件。父scope使用$emit获取当前scope事件。这也将缩短事件传播,而不是经过整个自上而下的流动。

3. Services是在$rootScope监听事件获取通知的不二选择。这是因为services在我们的应用程序中只初始化一次,并没有获取它们自己的scope,这将是很好。

4. 通常我们不应该在$rootScope注册事件监听(除了service)。这是导致AngularJS应用程序产生bug的一个普遍原因。这是因为当我们在一个controller的$scope上添加一个事件监听,而controller被销毁(我们导航离开页面,或关闭一个部分),监听同样被销毁。当我们将它添加到$rootScope,同时导航离开一个controller,监听会保留并保持活动和触发。所以我们必须从$rootScope手动取消监听,或者为了安全干脆就不在$rootScope上添加监听。但是如果我们必须为$rootScope添加一个事件,不要忘记在controller的scope中将其清除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.controller("TestController",$timeout) {varonTimeout =function() {
$scope.value += 1;
timer = $timeout(onTimeout,100);
};
vartimer = $timeout(onTimeout,100);
$scope.value = 0;
$scope.$on("$destroy",function() {
if(timer) {
$timeout.cancel(timer);
}
});
});
@H_301_51@

5. 如果我们知道只有一个监听器,而且你已经遇到了。我们可以通过在传递给事件监听函数的事件对象上调用event.stopPropagation()来停止进一步的事件传播。

六、构建业务逻辑

1. Controllers不应该引用DOM,而只是包含行为,使用Directives(指令)做DOM操作。

2. Services应该对view逻辑独立.

3. 不要与HTML打架,而是通过Directives扩展。

4. 最好是使用模块化的文件夹结构,这样我们可以创建可重用的/可分发的组件。

七、通用规则

1. 对images使用ng-src 替代src。

2. 使用promise来处理回调。AngularJS已经为它暴露了“$q”服务。许多AngularJSservices返回promises:$http,$interval,$timeout

3. 不要压缩angular.min.js 因为AngularJS团队已经通过预定义设置压缩了angular文件,如果我们再压缩可能会产生破坏。所以直接使用。

4. 如果template (模板)缓存是必需的,使用$templateCache缓存html template。

5. 总是把第三方API的回调包裹到$apply,用来通知AngularJS关于环境的变化。

6. 如果我们不想让用户在AngularJS加载之前显示HTML ,使用ng-cloakdirective。

<strong> </strong>
varmyEventHandler = $rootScope.$on('MyEvent',‘My Data’);
$scope.$on('$destroy',function() {
myEventHandler();
});
@H_301_51@

7. 为了阻止任何冲突,不要在我们自己的directives里使用“ng”前缀。创建你的自定义的。最好使用<my-component>,因为<my:component>在IE有时出错。

<divclass="session ng-cloak">..............content............</div>
.ng-cloak {
/* this will change to block when scope and angular is ready */
display:none;
}
@H_301_51@

8. 在应用程序中为全局相关的事件使用$broadcast(),$emit()$on()(比如用户身份验证或应用程序关闭)。如果我们需要特定于模块,服务或小部件的事件,我们应该选择Services,Directive Controllers等。

9. 不要使用自动关闭标签,因为有些浏览器不喜欢他们。使用“<product-title></product-title >”而不是“<product-title/>”。

相关文章

AngularJS 是一个JavaScript 框架。它可通过 注:建议把脚本放在 元素的底部。这会提高网页加载速度,因...
angluarjs中页面初始化的时候会出现语法{{}}在页面中问题,也即是页面闪烁问题。出现这个的原因是:由于...
AngularJS 通过被称为指令的新属性来扩展 HTML。AngularJS 指令AngularJS 指令是扩展的 HTML 属性,带有...
AngularJS 使用表达式把数据绑定到 HTML。AngularJS 表达式AngularJS 表达式写在双大括号内:{{ expres...
ng-repeat 指令可以完美的显示表格。在表格中显示数据 {{ x.Name }} {{ x.Country }} 使用 CSS 样式为了...
$http是 AngularJS 中的一个核心服务,用于读取远程服务器的数据。读取 JSON 文件下是存储在web服务器上...
1
2
<my-component>
<my:component>