AngularJS是为了克服HTML在构建应用上的不足而设计的。HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了,所以AngularJS做了一些工作来来解决静态网页技术在构建动态应用上的不足。
AngularJS的初衷是为了简化web APP开发,精髓是简单。但是国内外有很多AngularJS的教程,都着重讲AngularJS的强大之处,从而增加了AngularJS学习的难度,本教程试图用通俗的语言讲解最为基础、最为实用的内容,简化学习进程、降低学习难度是本教程的初衷。
本系列教程以翻译Chris Smith的Angualr Basics为梗概,融合博主自己的理解,为大家提供一个简单明了的学习教程。
本文为系列教程第7篇模块,翻译自Modules。
总的来说,模块(modules)的目的是通过定义公共APIs、限制行为(功能)和数据(属性和变量)的可视化实现关注点分离(separation of concerns,soc)。大部分的编程平台内置了对模块化的支持,以致于我们会觉得理所当然而无所察觉。但是客户端javascript没有支持,对附加的解决方案(例如CommonJS、AMD)的好处和坏处也进行了诸多争论。
需要注意的是,Angular的模块化系统不是模块化加载(它不从文件或internet加载源码),Angular提供的是内置的、私有的模块化方案工作原理类似于其内置的、私有的依赖注入方案,两个系统提供了令人印象深刻的通用基础设施。尽管使用模块化功能是每个开发者的需要掌握的内在能力,但问题是,为什么我们需要?
尽管模块化和依赖注入通常是必要命题,但是其实Angular允许我们不使用模块实现很多事情。截止目前,我们已经完成了一系列通过构造函数(在全局作用域定义和控制器一样名称的函数)不用模块的案例。通过一点简单的设置,ng-controller指令在全局范围和模块化系统中查找控制器函数,允许我们使用简化的方法使用Angular,但仅仅是一定程度上。
为了我们可以在Angular基础特性之后走的更远,我们需要精通它的模块化系统。相对于JS对象的管理复杂性问题来说,我们应该使用简单的方法解决问题,寻找您自己的最佳实践,因此本书不想详细介绍模块化和依赖注入的本质特性,只介绍跟Angular使用密切相关的模块和依赖注入的内容。
因此,让我们审视下必须使用Angular模块的重要特性:
下一章我们讲服务,主要演示如何为自定义JS组件定义提供支持。本章讲解如何定义控制器加载外部模块,同时为您讲解模块系统的基础。
一个Angular应用通常起始于一个根模块,在我们的案例中这个模块名字叫做app,注意,这个名字虽说常见,很多时候就是简单起见,未必是最好的选择。
/* module.js */
angular.module(‘app‘, []);
在上面的案例中,需要特别注意module的第二个参数,尽管它看起来只是一个空的数组,但是它是非常重要的,如果您忽略它,angular.module
的行为将产生根本改变。考虑到API的合理性设计, 当你指定第二个参数调用angular.module时,该方法处于创建模式,如果名为app的模块不存在,将创建一个名字为app的模块。但是调用angular.module
时不指定第二个参数,它处于寻找模式,如果给定名称的模块存在将返回该模块,如果不存在将抛出错误,提醒我们注意第二个参数。该案例我们使用了正确的方式,但我们需要明白代码中的重要区别。这个参数用于导入外部模块,我们将会在angular动画模块时通过案例说明这一点。
在承载应用的HTML文档中,我们需要通过传递模块名称作为参数给ng-app
指令告诉Angular加载应用模块。
<!-- index.html -->
<body ng-app="app">
<!-- Other examples to be inserted here. -->
</body>
我们添加到应用模块中的任何组件都可以使用,让我们来看看如何使用模块定义一个控制器(不在使用全局的scope)。
module
API里面包含了定义特殊Angular组件的一些方法,截至目前我们比较熟悉的controller
方法,我们使用controller
方法创建控制器。首先我们需要取得一个应用模块的引用,同时我们需要给angular.module
不指定第二个参数让它处于查询模式(主要是因为我们上文已经创建过应用模块了)。
/* message-controller.js */
var app = angular.module(‘app‘);
app.controller(‘MessageController‘, function($scope) {
$scope.message = "This is a model.";
});
然后我们需要在调用ng-app
的元素里面的某个位置,使用ng-controller
调用我们的控制器。
<!-- message-controller.html -->
<p ng-controller="MessageController">
{{message}}
</p>
编译结果为:This is a model.
您已经看到了,使用模块定义控制器比全局scope的方式稍微麻烦点,但不至于太糟。
假设我们需要定义如下的两个控制器
<!-- another-message-controller.html -->
<p ng-controller="MessageController">
{{message}}
</p>
<p ng-controller="AnotherMessageController">
{{message}}
</p>
module
的定义方法可以是链式操作,这样我们可以在一个语句里定义两个控制器。
/* chained-controllers.js */
angular.module(‘app‘)
.controller(‘MessageController‘, function($scope) {
$scope.message = "This is a model.";
})
.controller(‘AnotherMessageController‘, function($scope) {
$scope.message = "This is another model.";
});
编译结果为:
This is a model.
This is another model.
注意,第一个控制器的声明语句没有用分号结束。
如果你不喜欢链式操作风格,你可以随时检索调用模块,当然也可以存储在一个变量里(如下面代码所示)。如果您使用了变量,最好能够在IIFE(立即调用函数表达式)或者其他闭包里避免污染全局变量。
/* separate-controllers.js */
var app = angular.module(‘app‘);
app.controller(‘MessageController‘, function($scope) {
$scope.message = "This is a model.";
});
app.controller(‘AnotherMessageController‘, function($scope) {
$scope.message = "This is another model.";
});
选择哪种风格由您决定,不过链式风格更加流行些。
Animation
是Angular的一个新增特性,是一个名字叫做ngAnimate
的独立模块。使用animations的第一步是引入包含模块,源文件中是Angular的核心部分,但是分发的时候以一个单独文件分发,如下所示。
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-animate.js"></script>
<!-- 以上被墙,国内用另一个cdn -->
<script src="//cdn.bootcss.com/angular.js/1.3.14/angular.js"></script>
<script
src="//cdn.bootcss.com/angular.js/1.3.14//angular-animate.js"></script>
是时候我们使用module方法的第二个数组参数了,前面的案例我们只是传递了一个空参数, 这次我们声明模块的依赖性。
/* ng-animate-module.js */
angular.module(‘app‘, [‘ngAnimate‘]);
这样,我们在应用中引入了ngAnimate。 模板中的ng-show、ng-hide、ng-class等指令将会在css和js里检测JS animation,也许会应用在类似于add、enter、leave、move、remove等DOM事件中 。在DOM事件中应用animation无需模板做任何改变(感觉像透明一样), 如果动画代码没有呈现, 或者作为css或者作为js通过[module.animation](http://docs.angularjs.cn/api/ng/type/angular.Module)
注册,指令代码还是普通代码。
<!-- ng-animate.html -->
<input type="checkbox" ng-model="showMessage">
Check the box to show the message
<h2 ng-show="showMessage">
The secret message.
</h2>
编译结果为:
单击上面的复选框,我们能够看到元素之间的显示与隐藏式立刻进行的,因为我们没有在css或js中添加动画。接下来,我们使用css(通过声明式风格创建一般动画的较好选择),当然使用jQuery的animate方法也不错,Angular的module.animation能够兼容这些方法。
控制淡入淡出需要四个额外的css类,ng-hide-add、ng-hide-add-active、ng-hide-remove、ng-hide-remove-active等。
/* ng-animate.css */
.ng-hide-add,
.ng-hide-remove {
transition: all linear 1s;
display: block !important;
}
.ng-hide-add.ng-hide-add-active,
.ng-hide-remove {
opacity: 0;
}
.ng-hide-add,
.ng-hide-remove.ng-hide-remove-active {
opacity: 1;
}
这次的编译结果如下所示。
Depending on your site’s users, you may need to add vendor-prefixed properties for certain browsers, such as -webkit-transition for iOS Safari 6. (The site caniuse.com is a good reference for browser compatibility with HTML5 and CSS3.) Please also note that as written, this animation will applied to every usage of ng-show and ng-hide in our application. For better control, we can add a custom CSS class to both the element and the CSS selectors, for example .my-class.ng-hide-add, .my-class.ng-hide-remove, and so on.
根据您的网站的用户需要,你可能需要给特定的css属性增加浏览器引擎前缀(vendor-prefix),例如针对iOS Safari6增加-webkit-transition(caniuse.com是一个比较好的html5、css3浏览器兼容性网站)。注意这个动画将附加到任何一次ng-show、ng-hide使用中,为了做更好的控制,我们可以在元素和选择器上增加自定义css类,例如.my-class.ng-hide-add
和.my-class.ng-hide-remove
等等。
添加ngAnimate
的案例我想让您确信理解Angular 模块系统的重要性。而且,令人高兴的是,ngAnimate
只是使用Angular附件模块的开始,除了可以使用官方提供的模块资源外,大家还可以到github之类的网站上寻找更多的第三方开源模块。最流行的一个项目是AngularUI,提供了UI Router、UI Bootstrap等强大的模块,这些模块可以方便地使用Bower进行安装,当您上手Angular之后,您也可以在Github和Bower发布您的Angular模块,等你哟!
ngAnimate
模块演示一个如何使用附件模块发挥强大功能的案例,但是因为它特殊的嵌入方式,没有使用依赖注入。因为模块和依赖注入需要相互协作,下一章我们将讲解依赖注入。
前端开发whqet,关注前端开发,分享相关资源。csdn专家博客,王海庆希望能对您有所帮助,限于作者水平有限,出错难免,欢迎拍砖!
欢迎任何形式的转载,烦请注明装载,保留本段文字。
本文原文链接,http://blog.csdn.net/whqet/article/details/45074873
欢迎大家访问独立博客http://whqet.github.io
原文地址:http://blog.csdn.net/whqet/article/details/45074873