介绍
AngularJS是如今最受欢迎的JS框架之一,简化开发过程是它的目标之一,这使得它非常适合于元型较小的apps的开发,但也扩展到具有全部特征的客户端应用的开发。易于开发、较多的特征及较好的效果导致了较多的应用,伴随而来的是一些陷阱。本文列举了AngularJS的一些共同的易于也问题的地方,尤其是在开发一个app的时候。
1. MVC目录结构
AngularJS是一个缺乏较好的term的MVC框架,其models不像backbone.js中那样做为一个框架来定义,但其结构模式仍匹配的较好。当在一个MVC框架中作业时,基于文件类型将文件组合在一起是其共同的要求:templates/
_login.html
_feed.html
app/
app.js
controllers/
LoginController.js
FeedController.js
directives/
FeedEntryDirective.js
services/
LoginService.js
FeedService.js
filters/
CapatalizeFilter.js这样的布局, 尤其是对那些有 Rails 背景的人来说, 看起来挺合理. 可是当 app 变得越来越庞大的时候, 这样的布局结构会导致每次都会打开一堆文件夹. 无论你是用 Sublime, Visual Studio, 还是 Vim with Nerd Tree, 每次都要花上很多时间滑动滚动条浏览这个目录树来查找文件.如果我们根据每个文件隶属的功能模块来对文件分组, 而不是根据它隶属的层:app/
app.js
Feed/
_feed.html
FeedController.js
FeedEntryDirective.js
FeedService.js
Login/
_login.html
LoginController.js
LoginService.js
Shared/
CapatalizeFilter.js那么查找某个功能模块的文件就要容易得多, 自然可以提高开发的速度. 也许把 html 文件跟 js 文件放在混合放在一起做法不是每个人都能认同. 但是起码它省下宝贵的时间.
2、模块分组
一开始就将主模块中所有子模块展示出来是通常的做法。但是开始做一个小应用还好,但是做大了就不好管理了。var app = angular.module("app",[]);app.service("MyService", function(){
//service code});app.controller("MyCtrl", function($scope, MyService){
//controller code});一个比较好的办法是将相似类型的子模块分组:var services = angular.module("services",[]);services.service("MyService", function(){
//service code});var controllers = angular.module("controllers",["services"]);controllers.controller("MyCtrl", function($scope, MyService){
//controller code});var app = angular.module("app",["controllers", "services"]);这个方法与上面那个方法效果差不多,但是也不很大。运用要分组的思想将使工作更容易。var sharedServicesModule = angular.module("sharedServices",[]);
sharedServices.service("NetworkService", function($http){});
var loginModule = angular.module("login",["sharedServices"]);
loginModule.service("loginService", function(NetworkService){});
loginModule.controller("loginCtrl", function($scope, loginService){});
var app = angular.module("app", ["sharedServices", "login"]);当创建一个大的应用时,所有模块可能不会放在一页里,但是将模块根据类型进行分组将使模块的重用能力更强。3 依赖注入依赖注入是AngularJS最棒的模式之一。它使测试变得更加方便,也让它所依赖的对象变的更加清楚明白。AngularJS 对于注入是非常灵活的。一个最简单的方式只需要为模块将依赖的名字传入函数中:var app = angular.module("app",[]);app.controller("MainCtrl", function($scope, $timeout){
$timeout(function(){
console.log($scope);
}, 1000);});这里,很清楚的是MainCtrl依赖于$scope和$timeout。直到你准备投入生产并压缩你的代码。使用UglifyJS,上面的例子会变成:var app=angular.module("app",[]);
app.controller("MainCtrl",function(e,t){t(function(){console.log(e)},1e3)})现在AngularJS怎么知道MainCtrl依赖什么?AngularJS提供了一个非常简单的解决方案:把依赖作为一个字符串数组传递,而数组的最后一个元素是一个把所有依赖作为参数的函数。app.controller("MainCtrl", ["$scope", "$timeout", function($scope, $timeout){
$timeout(function(){
console.log($scope);
}, 1000);}]);接下来在压缩的代码中AngularJS也可以知道如何找到依赖:app.controller("MainCtrl",["$scope","$timeout",function(e,t){t(function(){console.log(e)},1e3)}])希望你喜欢,并分享我的工作~
带你走近AngularJS系列:
- 带你走近AngularJS - 基本功能介绍 http://www.linuxidc.com/Linux/2014-05/102140.htm
- 带你走近AngularJS - 体验指令实例 http://www.linuxidc.com/Linux/2014-05/102141.htm
- 带你走近AngularJS - 创建自定义指令 http://www.linuxidc.com/Linux/2014-05/102142.htm
如何在 AngularJS 中对控制器进行单元测试 http://www.linuxidc.com/Linux/2013-12/94166.htm在 AngularJS 应用中通过 JSON 文件来设置状态 http://www.linuxidc.com/Linux/2014-07/104083.htmAngularJS 之 Factory vs Service vs Provider http://www.linuxidc.com/Linux/2014-05/101475.htmAngularJS —— 使用 ngResource、RESTful APIs 和 Spring MVC 框架提交数据 http://www.linuxidc.com/Linux/2014-07/104402.htm
3.1 全局依赖
通常在写AngularJS应用时会有一个对象作为依赖绑定到全局作用域中。这意味着它在任何AngularJS的代码中都可用,但这打破了依赖注入模型同时带来一些问题,特别是在测试中。AngularJS把这些全局变量封装到模块中,这样它们可以像标准AngularJS模块一样被注入。Underscore.js是很棒的库,它把Javascript代码简化成了函数模式,并且它可以被转化成一个模块:var underscore = angular.module("underscore", []);underscore.factory("_", function() {
return window._; //Underscore must already be loaded on the page});var app = angular.module("app", ["underscore"]);app.controller("MainCtrl", ["$scope", "_", function($scope, _) {
init = function() {
_.keys($scope);
}
init();}]);它允许应用继续用AngularJS依赖注入的风格,也让underscore在测试的时候被交换出来。这或许看上去不重要,像是一个无关紧要的工作,但如果你的代码正在使用use strict(应该使用),那么这就变得有必要了。
更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2014-10/107783p2.htm