一、AngularJs提供的常用的高级功能
(1)解耦应用逻辑、数据模型和视图
(2)Ajax服务
(3)依赖注入
(4)浏览历史(使书签和前进、后退按钮能够像在普通Web应用中一样工作)
(5)测试
二、AngularJs中的数据绑定
1. AS创建实时模板来代替视图,而不是将数据合并进模板之后更新DOM。任何一个独立视图组件中的值都是动态替换的
1.1 相关属性解释:
(1)ng-app:声明所有被其包含的内容都属于这个AS应用(只有被具有ng-app属性的DOM元素包含的元素才会受AS影响)
2.数据模型不需要同视图进行交互,只需要包含数据和操作视图的方法,控制器用来存放将二者绑在一起的业务逻辑
3.AS可以跟踪和响应应用变化的方式:
当AS认为某个值可能发生变化时,它会运行自己的事件循环来检查这个值是否变“脏”。如果该值从上次事件循环运行之后发生了变化,则该值被认为是“脏”值。-------这个过程被称为“脏检查”(是检查数据模型变化的有效手段)
这个事件循环会调用$digest()循环
4.AS使用$预定义对象-----为了表示内部和内置的库函数(在AS中只要遇到$符号,都可以只把它看做一个AS对象)
5.简单的数据绑定
5.1 相关名词的解释:
(1) $scope:数据模型对象,是一个简单的JS对象,其中的属性可以被视图访问,也可以同控制器进行交互
(2)双向数据绑定:如果视图改变了某个值,数据模型会通过脏检查观察到这个变化,而如果数据模型改变了某个值,视图也会依据变化重新渲染
(3)ng-controller:声明所有被它包含的元素都属于某个控制器,为当前DOM元素创建了一个新的$scope对象,并将它嵌套在$rootScope上
6.AS推荐在视图中通过对象的属性而非对象本身来进行引用绑定
三、AngularJs中的模块
1.在AS中,模块是定义应用最主要的方式。模块中包含了主要的应用代码。一个应用可以包含多个模块。每一个模块都包含了定义具体功能的代码
1.1 相关术语解释:
angular.module( 'myApp',[] ); //接收两个参数,第一个是模块的名称,第二个是依赖列表(可以被注入到模块中的对象列表)《======》相当于AS模块中的setter方法,用来定义模块的`
注:上述方法若只传递一个参数,就可以用它来引用模块,如下:
angular.module('myApp'); //这个方法用于获取应用 《======》相当于AS模块中的getter方法,用来获取对模块的引用
注:承上就可以在
angular.module('myApp');
返回的对象上创建我们所需要的应用了
温馨提示:开发大型应用时,我们会创建多个模块来承载业务逻辑。将复杂的功能分割成不同的模块,有助于单独为他们编写测试
四、作用域
1.作用域是应用状态的基础。基于动态绑定,我们可以依赖视图在修改数据时立刻更新$scope,也可以依赖$scope在其发生变化时立刻重新渲染视图
注:AS将$scope设计成和DOM类似的结构,因此$scope可以进行嵌套(我们可以引用父级$scope中的属性)
温馨提示:
(1)作用域提供了监视数据模型变化的能力。它允许开发者使用其中的apply机制,将数据模型的变化
在整个应用范围内进行通知。我们在作用域的上下文中定义和执行表达式,同时它也是将事件通知给另一个控制器和应用其他部分的中介
(2)将应用的业务逻辑都放在控制器中,而将相关的数据都放在控制器的作用域中
2.AS启动并生成视图时,会将根ng-app元素同$rootScope进行绑定,$rootScope是所有$scope对象的最上层
注:(1) $rootScope是AS中最接近全局作用域的对象,应避免在$rootScope上附加太多的业务逻辑(这与污染JS的全局作用域是一样的)
(2)$scope对象就像一个普通的JS对象,我们可以在其上随意修改或添加属性
(3)$scope对象在AS中充当数据模型,但与传统的数据模型不一样,$scope并不负责处理和操作数据,它只是视图和HTML之间的桥梁,是视图和控制器之间的胶水
(4)$scope的所有属性,都可以自动被视图访问到
3.在AS应用模板中常用的标记解释:
(1)指令:将DOM元素增强为可复用的DOM组件的属性和元素
(2)值绑定:模板语法 {{ }} 可将表达式绑定到视图上
(3)过滤器:可以在视图中使用的函数,用来进行格式化
(4)表单控件:用来检验用户输入的控件
注:AS中的指令通常不会创建自己的$scope,但也有例外,比如:ng-controller和ng-repeat,这两个指令会创建自己的子作用域并将他们附加到DOM元素上
五、控制器
1.控制器的作用:AS中的控制器是一个函数,用来向视图的作用域中添加额外的功能,可用它来给作用域对象设置初始状态并添加自定义行为。
注:AS同其他JS框架的区别:控制器并不适合用来执行DOM操作、格式化或数据操作,以及除存储数据模型之外的状态维护操作。它只是视图和$scope之间的桥梁
2.控制器的嵌套(作用域包含作用域)
2.1 名词解释:
(1)孤立作用域:在指令内部创建的作用域
注:(1)除了孤立作用域外,所有的作用域都是通过原型继承而来的 (他们都可以访问父级作用域)
(2)避免在控制器中进行DOM操作和数据操作,如下就是反例(不推荐):
angular.module('myApp', [])
.controller('MyController', function($scope) {
$scope.shouldShowLogin = true;
$scope.showLogin = function () {
$scope.shouldShowLogin = !$scope.shouldShowLogin;
};
$scope.clickButton = function() {
$('#btn span').html('Clicked');
}; //这是 反例 不推荐
$scope.onLogin = function(user) {
$http({
method: 'POST',
url: '/login',
data: {user: user}}
).success(function(data) {
// user});};
});
推荐:将复杂的逻辑放到指令和服务中。通过使用指令和服务,我们可以将控制器构成一个轻量且更易维护的形式,如下是推荐示例:
angular.module('myApp', [])
.controller('MyController', function($scope,UserSrv) {
// 内容可以被指令控制
$scope.onLogin = function(user) {
UserSrv.runLogin(user);
};
});
六、表达式
1.表达式和eval(javascript)非常相似,但由于表达式是由AS来处理,他们有以下显著不同的特性:
(1)所有表达式都在其所属的作用域的内部执行,并有访问本地$scope的权限
(2)如果表达式发生了typeError和referenceError并不会抛出异常
(3)不允许使用任何流程控制功能(条件控制,if/else)
(4)可以接受过滤器和过滤器链
2术语解释:
(1)$parse:这是一个内部服务,可以对表达式进行运算,这个服务能够访问当前所处的作用域-----表示未看懂
七、过滤器
1.过滤器的使用方式:
(1)直接写在HTML中,通过|分割
(2)在JS代码中通过$filter来调用过滤器,示例代码如下:
app.controller('DemoController', ['$scope', '$filter',
function($scope, $filter) {
$scope.name = $filter('lowercase')('Ari');
}]);
(3)使用filter过滤器
注:使用filter过滤器时可根据第一个参数可以分三种情况:
(1)字符串
(2)对象
(3)函数
2.表单验证
注:AS中的表达式验证,比如:模式匹配,只有在用户输入的符合正则表达式时才能获得其值,若输入的不正确则一直获取不到输入的值
如下是HTML代码:
<input type="type" placeholder="请输入手机号" ng-model="myTel" ng-pattern="/^1[3|4|5|7|8][0-9]{9}$/"/>
<span>我输入的是:{{ myTel }}</span>
如下是JS代码:
angular.module('myApp',[])
.controller('myCtrl',function($scope){
$scope.myTel='';
$scope.$watch('myTel',function(newVal,oldVal){
console.log('新值:'+newVal);
console.log('旧值:'+oldVal);
});
});
如下是运行截图:
相关文章的链接:http://www.cnblogs.com/rohelm/p/4033513.html
3.有关表达验证的综合案例(注:下述两个例子不是特别好,因为不简洁,AS1.3之后推荐ngMessages)
根据用户的输入进行实时验证(参考AngularJS权威教程.pdf 7.2节表单验证)
如下是HTML代码:
<!-- novalidate属性规定当提交表单时不对表单数据(输入)进行验证。 -->
<!-- ng-submit当提交表单时会调用signupForm函数 -->
<form name="signup_form" novalidate ng-submit="signupForm()">
<!-- fieldset标签会在相关表单元素周围绘制边框 -->
<fieldset>
<legend>Signup Form</legend>
<button type="submit" class="button radius">Submit</button>
<div class="row">
<div class="large-12 columns">
<label>Your Name</label>
<input type="text" placeholder="name" name="name" ng-model="signup.name" ng-minlength="3" ng-maxlength="20" required />
<div class="error" ng-show="signup_form.name.$dirty && signup_form.name.$invalid">
<small class="error" ng-show="signup_form.name.$error.required">
你的名字是必填的
</small>
<small class="error" ng-show="signup_form.name.$error.minlength">
你的名字至少为3个字符
</small>
<small class="error" ng-show="signup_form.name.$error.maxlength">
你的名字不能超过20个字符
</small>
</div>
</div>
</div>
</fieldset>
</form>
运行结果截图:
根据用户的输入进行失去焦点时的验证
对应的HTML代码:
<!-- novalidate属性规定当提交表单时不对表单数据(输入)进行验证。 -->
<!-- ng-submit当提交表单时会调用signupForm函数 -->
<form name="signup_form" novalidate ng-submit="signupForm()">
<!-- fieldset标签会在相关表单元素周围绘制边框 -->
<fieldset>
<legend>Signup Form</legend>
<button type="submit" class="button radius">Submit</button>
<div class="row">
<div class="large-12 columns">
<label>Your Name</label>
<!-- ng-class:用于给 HTML 元素动态绑定一个或多个 CSS 类,其值可以是对象,需要使用 key-value 对,key 为你想要添加的类名,value 是一个布尔值。只有在 value 为 true 时类才会被添加。 -->
<input type="text" ng-class="{error : signup_form.name.$dirty && signup_form.name.$invalid}" placeholder="name" name="name" ng-model="signup.name" ng-focus ng-minlength="3" ng-maxlength="20" required />
<div class="error" ng-show="signup_form.name.$dirty && signup_form.name.$invalid && !signup_form.name.$focused">
<small class="error" ng-show="signup_form.name.$error.required">
你的名字是必填的
</small>
<small class="error" ng-show="signup_form.name.$error.minlength">
你的名字至少为3个字符
</small>
<small class="error" ng-show="signup_form.name.$error.maxlength">
你的名字不能超过20个字符
</small>
</div>
</div>
</div>
</fieldset>
</form>
对应的JS代码:
angular.module('myApp',[])
/*ngFocus指令给表单输入字段的blur和focus添加了对应的行为,添加了一个名为ng-focus
ed的类,并将$focused的值设置为true。接下来,可以根据表单是否具有焦点来展示独立的错
误信息*/
.directive('ngFocus',[function(){
var FOCUS_CLASS='ng-focused';
return {
restrict:'A',
require:'ngModel',
link:function(scope,element,attrs,ctrl){
ctrl.$focused=false;
element.bind('focus',function(evt){
element.addClass(FOCUS_CLASS);
scope.$apply(function(){
ctrl.$focused=true;
});
}).bind('blur',function(evt){
element.removeClass(FOCUS_CLASS);
scope.$apply(function(){
ctrl.$focused=false;
});
});
}
}
}]);