angularjs 前端开发总结

angularjs开发前端好处|angularjs 前端开发工具|nodejs开发前端应用应用

一、数据绑定和第一个Angularjs

1.一个简单的示例
html 代码

<!DOCTYPE html>
<html ng-app>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    </p>
    <p>
        <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    </p>
    <p>
</head>
<body>
    <input ng-model=”name” type=”text” placeholder=”Your name”>
    <h1>Hello {{ name }}</h1>
</body>
</html>

*使用ng-model进行简单数据绑定,ng-app属性声明所有被其宝航的内容都属于这个AngularJs应用

二、模块

AngularJS允许我们使用angular.module()方法来声明模块,这个方法能够接受两个参数,第一个是模块的名称,第二个是依赖列表,也就是可以被注入到模块中的对象列表。
angular.module('myApp', []);

三、作用域

1.视图和$scope的世界
AngularJS启动并生成视图时,会将根ng-app元素同$rootScope进行绑定。$rootScope是所有$scope对象的最上层。$scope对象就是一个普通的JavaScript对象,我们可以在其上随意修改或添加属性。$scope对象在AngularJS中充当数据模型,但与传统的数据模型不一样,$scope并不负责处理和操作数据,它只是视图和HTML之间的桥梁,它是视图和控制器之间的胶水。
 **html 代码**
<div ng-app=”myApp”>
    <h1>Hello {{ name }}</h1>
    </div>
angular.module(‘myApp’, [])
    .run(function($rootScope) {
        $rootScope.name = “World”;
    });

2.作用域能做什么
作用域包含了渲染视图时所需的功能和数据,它是所有视图的唯一源头。可以将作用域理解成视图模型(view model)。
html 代码

//在$rootScope中设置了一个name变量并在视图中引用了它:
angular.module(‘myApp’, [])
.run(function($rootScope) {
$rootScope.name = “World”;
});
//在视图中可以引用这个name属性并将它展示给用户:
<div ng-app=”myApp”>
<h1>Hello {{ name }}</h1>
</div>
//我们可以不将变量设置在$rootScope上,而是用控制器显式创建一个隔离的子$scope对象,
把它设置到这个子对象上。使用ng-controller指令可以将一个控制器对象附加到DOM元素上
<div ng-app=”myApp”>
<div ng-controller=”MyController”>
<h1>Hello {{ name }}</h1>
</div>
</div>
//我们可以创建一个控制器来管理与其相关的变量,
//而不用将name变量直接放在$rootScope上:
angular.module(“myApp”, [])
.controller(‘MyController’,
function($scope) {
$scope.name = “Ari”;
});
//ng-controller指令为这个DOM元素创建了一个新的$scope对象,并将它嵌套在$rootScope中。

3.$scope的生命周期
$scope对象的生命周期处理有四个不同阶段。
html 代码

1:创建
在创建控制器或指令时,AngularJS会用$injector创建一个新的作用域,并在这个新建的控
制器或指令运行时将作用域传递进去。
2:链接
当Angular开始运行时,所有的$scope对象都会附加或者链接到视图中。所有创建$scope对
象的函数也会将自身附加到视图中。这些作用域将会注册当Angular应用上下文中发生变化时需
要运行的函数。(这些函数被称为$watch函数,Angular通过这些函数获知何时启动事件循环)
3:更新
当事件循环运行时,它通常执行在顶层$scope对象上(被称作$rootScope),每个子作用域
都执行自己的脏值检测。每个监控函数都会检查变化。如果检测到任意变化,$scope对象就会触
发指定的回调函数。
4:销毁
当一个$scope在视图中不再需要时,这个作用域将会清理和销毁自己。
尽管永远不会需要清理作用域(因为Angular会为你处理),但是知道是谁创建了这个作用域
还是有用的,因为你可以使用这个$scope上叫做$destory()的方法来清理这个作用域。

四、控制器

1.控制器
AngularJS中的控制器是一个函数,用来向视图的作用域中添加额外的功能。我们用它来给作用域对象设置初始状态,并添加自定义行为。当我们在页面上创建一个新的控制器时,AngularJS会生成并传递一个新的$scope给这个控制器。可以在这个控制器里初始化$scope。由于AngularJS会负责处理控制器的实例化过程,我们只需编写构造函数即可。
html 代码

//按钮和链接都被绑定在了内部$scope的一个操作上,当点击任何一个元素时AngularJS都会
调用相应的方法。注意,当设置调用哪个函数时,会同时用括号传递一个参数(add(1))。
<div ng-controller=”FirstController”>
<h4>The simplest adding machine ever</h4>
<buttonng-click=”add(1)”class=”button”>Add</button>
<ang-click=”subtract(1)”class=”button alert”>Subtract</a>
<h4>Current count: {{ counter }}</h4>
</div>
app.controller(‘FirstController’, function($scope) {
$scope.counter = 0;
$scope.add = function(amount) { $scope.counter += amount; };
$scope.subtract = function(amount) { $scope.counter -= amount; };
});
//AngularJS同其他JavaScript框架最主要的一个区别就是,控制器并不适合用来执行DOM操
作、格式化或数据操作,以及除存储数据模型之外的状态维护操作。它只是视图和$scope之间的
桥梁。
//AngularJS允许在$scope上设置包括对象在内的任何类型的数据,并且在视图中还可以展示
对象的属性。
e.g:
app.controller(‘MyController’, function($scope) {
$scope.person = {
name: ‘Ari Lerner’
};
});
//在拥有ng-controller=’MyController’这个属性的元素内部的任何子元素中,都可以访问
person对象,因为它是定义在$scope上的。

2.控制器嵌套(作用域包含作用域)
AngularJS应用的任何一个部分,无论它渲染在哪个上下文中,都有父级作用域存在。对于ng-app所处的层级来讲,它的父级作用域就是$rootScope。有一个例外:在指令内部创建的作用域被称作孤立作用域。除了孤立作用域外,所有的作用域都通过原型继承而来,也就是说它们都可以访问父级作用域。
html 代码

//如果我们将ChildController置于ParentController内部,那ChildController的$scope
对象的父级作用域就是ParentController的$scope对象。根据原型继承的机制,我们可以在子
作用域中访问ParentController的$scope对象。
<div ng-controller=”ParentController”>
<div ng-controller=”ChildController”>
<a ng-click=”sayHello()”>Say hello</a>
</div>
{{ person }}
</div>
app.controller(‘ParentController’, function($scope) {
$scope.person = {greeted: false};
});
app.controller(‘ChildController’, function($scope) {
$scope.sayHello = function() {
$scope.person.name = ‘Ari Lerner’;
};
});

五、表达式

1.解析AngularJS表达式
AngularJS通过$parse这个内部服务来进行表达式的运算,这个服务能够访问当前所处的作用域。这个过程允许我们访问定义在$scope上的原始JavaScript数据和函数。
html 代码

六、过滤器

1.过滤器
html 代码

1. currency:可以将一个数值格式化为货币格式。用{{ 123 | currency }}来将123转化
成货币格式。
2.date:可以将日期格式化成需要的格式。AngularJS中内置了几种日期格式,如果没有指定
使用任何格式,默认会采用mediumDate格式
3.filter:可以从给定数组中选择一个子集,并将其生成一个新数组返回。(字符串、
对象、函数)第二个参数可以是以下三种情况之一
1)true:用angular.equals(expected, actual)对两个值进行严格比较。
2)false:进行区分大小写的子字符串比较
3)函数:运行这个函数,如果返回真值就接受这个元素。
4.json:json过滤器可以将一个JSON或JavaScript对象转换成字符串。
这种转换对调试非常有帮助
5.limitTo 会根据传入的参数生成一个新的数组或字符串,新的数组或字符串的长度取
决于传入的参数,通过传入参数的正负值来控制从前面还是从后面开始截取。(
如果传入的长度值大于被操作数组或字符串的长度,那么整个数组或字符串都会被返回。)
6.lowercase:将字符串转为小写
7.number:将数字格式化成文本。它的第二个参数是可选的,用来控制小数点后截取的位数
8.orderBy:器可以用表达式对指定的数组进行排序(接受两个参数,第一个是必需的,
第二个是可选的)
9.uppercase:可以将字符串转换为大写形式

2.自定义过滤器
将一个句子的首字母转换成大写形式,可以用过滤器先将整个句子都转换成小写,再把首字母转换成大写:
html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
</head>
<body ng-app=”myApp”>
    <span>
        {{ “ginger loves dog treats” | lowercase | capitalize }}
    </span>
    <script>
        angular.module(‘myApp’, [])
            .filter(‘capitalize’, function () {
                return function (input) {
                    // input是我们传入的字符串
                    if (input) {
                        return input[0].toUpperCase() + input.slice(1);
                    }
                }
            });
    </script>
</body>
</html>

3.表单验证
1)在表单中控制变量
表单的属性可以在其所属的$scope对象中访问到,而我们又可以访问$scope对象,因此JavaScript可以间接地访问DOM中的表单属性。借助这些属性,我们可以对表单做出实时(和
AngularJS中其他东西一样)响应。这些属性包括下面这些。
html 代码

//可以使用下面的格式访问这些属性
formName.inputFieldName.property
1.未修改的表单
这是一个布尔属性,用来判断用户是否修改了表单。如果未修改,值为true,如果修改过值
为false:
formName.inputFieldName.$pristine
2.修改过的表单
只要用户修改过表单,无论输入是否通过验证,该值都返回true:
formName.inputFieldName.$dirty
3.合法的表单
这个布尔型的属性用来判断表单的内容是否合法。如果当前表单内容是合法的,下面属性的
值就是true:
formName.inputFieldName.$valid
4.不合法的表单
这个布尔属性用来判断表单的内容是否不合法。如果当前表单内容是不合法的,下面属性的
值为true:
formName.inputFieldName.$invalid
5.错误
这是AngularJS提供的另外一个非常有用的属性:$error对象。它包含当前表单的所有验证
内容,以及它们是否合法的信息。用下面的语法访问这个属性:
formName.inputfieldName.$error
如果验证失败,这个属性的值为true;如果值为false,说明输入字段的值通过了验证。

4.组合实例
html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
</head>
<body ng-app=”myApp”>
    <form name=”signup_form” novalidate ng-submit=”signupForm()” ng-controller=”signupController”>
        <fieldset>
            <legend>Signup</legend>
            <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 &&
signup_form.submitted”>
                        <small class=”error” ng-show=”signup_form.name.$error.required”>
                            Your name is required.
                        </small>
                        <small class=”error” ng-show=”signup_form.name.$error.minlength”>
                            Your name is required to be at least 3 characters
                        </small>
                        <small class=”error” ng-show=”signup_form.name.$error.maxlength”>
                            Your name cannot be longer than 20 characters
                        </small>
                    </div>
                </div>
            </div>
            <button type=”submit”>Submit</button>
        </fieldset>
    </form>
    <script>
        var app = angular.module(“myApp”, []);
        app.controller(“signupController”, function ($scope) {
            $scope.submitted = false;
            $scope.signupForm = function () {
                if ($scope.signup_form.$valid) {
                    // 正常提交
                } else {
                    $scope.signup_form.submitted = true;
                }
            }
        })
    </script>
</body>
</html>

七、指令简介

1.指令:自定义HTML 元素和属性

html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
</head>
<body ng-app=”myApp”>
    <my-directive></my-directive>
    <script>
        var app = angular.module(“myApp”, []);
        app.directive(“myDirective”, function () {
            return {
                restrict: ‘E’,
                template: ‘<a href=”http://www.g.cn”>Click me to go to google</a>’
            }
        })
    </script>
</body>
</html>

下面都是用来声明前面创建指令的合法格式:
<my-directive></my-directive>
<div my-directive></div>
<div class=”my-directive”></div>
html 代码

//为了让AngularJS能够调用我们的指令,需要修改指令定义中的restrict设置。这个设置告
诉AngularJS在编译HTML时用哪种声明格式来匹配指令定义。我们可以指定一个或多个格式。
例如,之前创建的指令中可以指定以元素(E)、属性(A)、类(C)或注释(M)的格式来
调用指令:
angular.module(‘myApp’, [])
.directive(‘myDirective’, function() {
return {
restrict: ‘EAC’,
replace: true,
template: ‘<a href=”http://google.com”>Click me to go to Google</a>’
};
});
无论有多少种方式可以声明指令,我们坚持使用属性方式,因为它有比较好的跨浏览器兼容性:
<div my-directive></div>

2.向指令中传递数据
html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
</head>
<body ng-app=”myApp”>
    <div my-directive my-url=”http://google.com” my-link-text=”Click me to go to Google”></div>
    <script>
        angular.module(‘myApp’, [])
            .directive(‘myDirective’, function () {
                return {
                    restrict: ‘A’,
                    replace: true,
                    scope: {
                        myUrl: ‘@’, //绑定策略
                        myLinkText: ‘@’ //绑定策略
                    },
                    template: ‘<a href=”{{myUrl}}”>’ +
                        ‘{{myLinkText}}</a>’
                };
            });
    </script>
</body>
</html>

html 代码

//默认情况下约定DOM属性和JavaScript中对象属性的名字是一样的(除非对象的属性名采用
的是驼峰式写法)。
由于作用域中属性经常是私有的,因此可以(虽然不常见)指定我们希望将这个内部属性同
哪个DOM属性进行绑定:
scope: {
myUrl: ‘@someAttr’,
myLinkText: ‘@’
}
上面的隔离作用域中的内容是:将指令的私有属性$scope.myUrl同DOM中some-attr属性
的值绑定起来。这个值既可以是硬编码的也可以是当前作用域(例如Some-attr=”{{expression}})
中某个表达式的运算结果。
在DOM中要用some-attr代替my-url:
<div my-directive
some-attr=”http://google.com”
my-link-text=”Click me to go to Google” >
</div>
更进一步,还可以在DOM对应的作用域上运算表达式,并将结果传递给指令,在指令内部
最终被绑定在属性上:
<div my-directive
some-attr=”{{ ‘http://’ + ‘google.com’ }}”>
</div>

e.g
html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
</head>
<body ng-app=”myApp”>
    <label for=””>Their URL field</label>
    <input type=”text” ng-model=”theirUrl” />
    <div my-directive some-attr=”theirUrl” my-link-text=”click me”>
    </div>
    <script>
        var app = angular.module(“myApp”, []);
        app.directive(“myDirective”, function () {
            return {
                restrict: “A”,
                replace: true,
                scope: {
                    myUrl: “=someAttr”,//使用=绑定策略代替@
                    myLinkText: “@”
                },
                template: ‘\
<div>\
<label>My Url Field</label> \
<input type=”text” ng-model=”myUrl”/><a href=”{{myUrl}}”>{{myLinkText}}</a>\
</div>’
            }
        })
    </script>
</body>
</html>

8、内置指令

1.基础ng属性指令
html 代码

//与原生HTML标签名相似的一组内置指令
ng-href;
ng-src;
ng-disabled;
ng-checked;
ng-readonly;
ng-selected;
ng-class;
ng-style

1)布尔属性
根据HTML标准的定义①,布尔属性代表一个true或false值。当这个属性出现时,这个属性的值就是true(无论实际定义的值是什么)。如果未出现,这个属性的值就是false。
当在AngularJS中使用动态数据绑定时,不能简单地将这个属性值设置为ture或false,因为根据标准定义只有当这个属性不出现时,它的值才为false。因此AngularJS提供了一组带有ng-
前缀版本的布尔属性,通过运算表达式的值来决定在目标元素上是插入还是移除对应的属性。

      **html 代码**
<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
    </style>
</head>
<body ng-app=”myApp”>
    <p class=”tip”>
        1. ng-disabled 使用ng-disabled可以把disabled属性绑定到以下表单输入字段上:
    </p>
    <p class=”tip”>
        input(text、checkbox、radio、number、url, email、submit); textarea; select; button
    </p>
    <textarea ng-disabled=”isDisabled”>Wait5seconds</textarea>
    <p class=”tip”>
        2.ng-readonly 同其他布尔属性一样,HTML定义只会检查readonly属性是否出现,而不是它的实际值。 通过ng-readonly可以将某个返回真或假的表达式同是否出现readonly属性进行绑定:
    </p>
    <input type=”text” ng-readonly=”{{ronly}}” value=”Some text here”>
    <p class=”tip”>
        3.ng-checked 标准的checked属性是一个布尔属性,不需要进行赋值。通过ng-checked将某个表达式同是 否出现checked属性进行绑定。
    </p>
    <label>myProperty={{myProperty}}</label>
    <input type=”checkbox” ng-click=”check()” ng-checked=”{{myProperty}}” />
    <br/>
    <label>someProperty = {{anotherProperty}}</label>
    <input type=”checkbox” ng-checked=”anotherProperty” ng-init=”anotherProperty = false” ng-model=”anotherProperty”>
    <p class=”tip”>
        4.ng-selected ng-selected可以对是否出现option标签的selected属性进行绑定:
    </p>
    <label>Select Two Fish</label>
    <input type=”checkbox” ng-model=”isTwoFish”>
    <select>
        <option value=”OneFish”>One Fish</option>
        <option ng-selected=”isTwoFish”>Two Fish</option>
    </select>
    <script>
        var app = angular.module(“myApp”, []);
        app.run(function ($rootScope, $timeout) {
            //ng-disabled example
            $rootScope.isDisabled = true;
            $timeout(function () {
                $rootScope.isDisabled = false;
            }, 5000);
            //readonly
            $rootScope.ronly = true;
            $rootScope.myProperty = true;
            $rootScope.check = function () {
                $rootScope.myProperty = !$rootScope.myProperty;
            }
        })
    </script>
</body>
</html>

2)类布尔属性
ng-href、ng-src等属性虽然不是标准的HTML布尔属性,但是由于行为相似,所以在AngularJS源码内部是和布尔属性同等对待的
html 代码

2.在指令中使用子作用域

 ng-app和ng-controller是特殊的指令,因为它们会修改嵌套在它们内部的指令的作用域。ng-app为AngularJS应用创建$rootScope,ng-controller则会以$rootScope或另外一个

ng-controller的作用域为原型创建新的子作用域。

1)ng-app
     任何具有ng-app属性的DOM元素将被标记为$rootScope的起始点。$rootScope是作用域链的起始点,任何嵌套在ng-app内的指令都会继承它。

2)ng-controller  
     内置指令ng-controller的作用是为嵌套在其中的指令创建一个子作用域,避免将所有操作和模型都定义在$rootScope上。用这个指令可以在一个DOM元素上放置控制器。子$scope

只是一个JavaScript对象,其中含有从父级$scope中通过原型继承得到的方法和属性,包括应用的$rootScope.嵌套在ng-controller中的指令有访问新子$scope的权限,但是要牢记每个
指令都应该遵守的和作用域相关的规则。
html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
    </style>
</head>
<body ng-app=”myApp”>
    <div ng-controller=”SomeController”>
        {{someModel.someValue}}
        <button ng-click=”someAction()”>Communicate to child</button>
        <div ng-controller=”ChildController”>
            {{someModel.someValue}}
            <button ng-click=”childAction()”>Communicate to parent</button>
        </div>
    </div>
    <script>
        var app = angular.module(“myApp”, []);
        app.controller(“SomeController”, function ($scope) {
            $scope.someModel = {
                someValue: “hello computer”
            }
            $scope.someAction = function () {
                $scope.someModel.someValue = “hello human,from parent”;
            }
        });
        app.controller(“ChildController”, function ($scope) {
            $scope.childAction = function () {
                $scope.someModel.someValue = “hello human,from child”;
            }
        })
    </script>
</body>
</html>

3)ng-include
使用ng-include可以加载、编译并包含外部HTML片段到当前的应用中。模板的URL被限制在与应用文档相同的域和协议下,可以通过白名单或包装成被信任的值来突破限制。更进一步,
需要考虑跨域资源共享(Cross-Origin Resource Sharing,CORS)和同源规则(Same Origin Policy)来确保模板可以在任何浏览器中正常加载。
使用ng-include时AngularJS会自动创建一个子作用域。如果你想使用某个特定的作用域,例如ControllerA的作用域,必须在同一个DOM元素上添加ng-controller =”ControllerA”
指令,这样当模板加载完成后,不会像往常一样从外部作用域继承并创建一个新的子作用域。
html 代码

<div ng-include=”/myTemplateName.html” ng-controller=”MyController” ng-init=”name = ‘World'”>
    Hello {{ name }}
</div>
4)ng-switch
     这个指令和ng-switch-when及on="propertyName"一起使用,可以在propertyName发生变化时渲染不同指令到视图中。
     **html 代码**
<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
    </style>
</head>
<body ng-app>
    <input type=”text” ng-model=”person.name” />
    <div ng-switch on=”person.name”>
        <p ng-switch-default>And the winner is</p>
        <div ng-switch-when=”Ari”>{{person.name}}</div>
    </div>
</body>
</html>

5)ng-view
ng-view指令用来设置将被路由管理和放置在HTML中的视图的位置。

6)ng-if
使用ng-if指令可以完全根据表达式的值在DOM中生成或移除一个元素。如果赋值给ng-if的表达式的值是false,那对应的元素将会从DOM中移除,否则对应元素的一个克隆将被重新插
入DOM中。ng-if同no-show和ng-hide指令最本质的区别是,它不是通过css显示或隐藏DOM节点,而是真正生成或移除节点。当一个元素被ng-if从DOM中移除,同它关联的作用域也会被销毁。而且当它重新加入DOM中时,会通过原型继承从它的父作用域生成一个新的作用域。如果ng-if内部的代码加载之后被jquery修改过(例如用.addClass),那么当ng-if的表达式值为false时,这个DOM元素会被移除,表达式再次成为true时这个元素及其内部的子元素会被重新插入DOM,此时这些元素的状态会是它们的原始状态,而不是它们上次被移除时的状态
html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
    </style>
</head>
<body ng-app>
    <div ng-if=”2+2===5″>
        Won’t see this DOM,not even in the source code
    </div>
    <div ng-if=”2+2===4″>
        Hi,I do exists
    </div>
</body>
</html>
7)ng-repeat
     用来遍历一个集合或为集合中的每个元素生成一个模板实例。集合中的每个元素都会被赋予自己的模板和作用域。同时每个模板实例的作用域中都会暴露一些特殊的属性。
     **html 代码**
$index:遍历的进度(0…length-1)。
$first:当元素是遍历的第一个时值为true。
$middle:当元素处于第一个和最后元素之间时值为true。
$last:当元素是遍历的最后一个时值为true。
$even:当$index值是偶数时值为true。
$odd:当$index值是奇数时值为true。
   **html 代码**
<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        .odd {
            background-color: blue;
        }
        .even {
            background-color: red;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <ul ng-controller=”PeopleController”>
        <li ng-repeat=”person in people” ng-class=”{even: !$even, odd: !$odd}”>
            {{person.name}} lives in {{person.city}}
        </li>
    </ul>
    <script>
        angular.module(‘myApp’, [])
            .controller(‘PeopleController’, function ($scope) {
                $scope.people = [
                    { name: “Ari”, city: “San Francisco” },
                    { name: “Erik”, city: “Seattle” }
                ];
            });
    </script>
</body>
</html>
8)ng-init
      ng-init指令用来在指令被调用时设置内部作用域的初始状态。对于任何需要健壮结构的场景,请在控制器中用数据模型对象来设置状态。
      **html 代码**
<div ng-init=”greeting=’Hello’;person=’World'”>
    {{greeting}} {{person}}
</div>
9){{ }}
     {{ }}语法是AngularJS内置的模板语法,它会在内部$scope和视图之间创建绑定。基于这个绑定,只要$scope发生变化,视图就会随之自动更新。事实上它也是指令,虽然看起来并不像,实际上它是ng-bind的简略形式,用这种形式不需要创建新的元素,因此它常被用在行内文本中。注意,在屏幕可视的区域内使用{{ }}会导致页面加载时未渲染的元素发生闪烁,用ng-bind

可以避免这个问题。
html 代码

<body ng-init=”greeting=’HelloWorld'”>
    {{ greeting }}
</body>
10)ng-bind
      尽管可以在视图中使用{{ }}模板语法(AngularJS内置的方式),我们也可以通过ng-bind指令实现同样的行为。
      **html 代码**
<body ng-init=”greeting=’HelloWorld'”>
    <p ng-bind=”greeting”></p>
</body>
     HTML加载含有{{ }}语法的元素后并不会立刻渲染它们,导致未渲染内容闪烁(Flash ofUnrendered Content,FOUC)。我可以用ng-bind将内容同元素绑定在一起避免FOUC。内容会被

当作子文本节点渲染到含有ng-bind指令的元素内。

11)ng-cloak
       除使用ng-bind来避免未渲染元素闪烁,还可以在含有{{ }}的元素上使用ng-cloak指令。ng-cloak指令会将内部元素隐藏,直到路由调用对应的页面时才显示出来。
         **html 代码**
<body ng-init=”greeting=’HelloWorld'”>
    <p ng-cloak>{{ greeting }}</p>
</body>
12)ng-bind-template
       同ng-bind指令类似,ng-bind-template用来在视图中绑定多个表达式。
       **html 代码**
<div ng-bind-template=”{{message}}{{name}}”>
</div>
13)ng-model
       ng-model指令用来将input、select、text area或自定义表单控件同包含它们的作用域中的属性进行绑定。它可以提供并处理表单验证功能,在元素上设置相关的css类(ng-valid、

ng-invalid等),并负责在父表单中注册控件。它将当前作用域中运算表达式的值同给定的元素进行绑定。如果属性并不存在,它会隐式创建并将其添加到当前作用域中。我们应该始终用ngModel来绑定$scope上一个数据模型内的属性,而不是$scope上的属性,这可以避免在作用域或后代作用域中发生属性覆盖。

14)ng-show/ng-hide
       ng-show和ng-hide根据所给表达式的值来显示或隐藏HTML元素。当赋值给ng-show指令的值为false时元素会被隐藏。类似地,当赋值给ng-hide指令的值为true时元素也会被隐藏。

元素的显示或隐藏是通过移除或添加ng-hide这个css类来实现的。.ng-hide类被预先定义在了AngularJS的css文件中,并且它的display属性的值为none(用了!important标记)。
html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        .odd {
            background-color: blue;
        }
        .even {
            background-color: red;
        }
    </style>
</head>
<body ng-app>
    <div ng-show=”2 + 2 == 5″>
        2 + 2 isn’t 5, don’t show
    </div>
    <div ng-show=”2 + 2 == 4″>
        2 + 2 is 4, do show
    </div>
    <div ng-hide=”2 + 2 == 5″>
        2 + 2 isn’t 5, don’t hide
    </div>
    <div ng-hide=”2 + 2 == 4″>
        2 + 2 is 4, do hide
    </div>
</body>
</html>
15)ng-change
       这个指令会在表单输入发生变化时计算给定表达式的值。因为要处理表单输入,这个指令要和ngModel联合起来使用。
       **html 代码**
<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        .odd {
            background-color: blue;
        }
        .even {
            background-color: red;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <div ng-controller=”EquationController”>
        <input type=”text” ng-model=”equation.x” ng-change=”change()” />
        <div>{{equation.output}}</div>
    </div>
    <script>
        angular.module(“myApp”, [])
            .controller(“EquationController”, function ($scope) {
                $scope.equation = {};
                $scope.change = function () {
                    $scope.equation.output = parseInt($scope.equation.x) + 2;
                }
            })
    </script>
</body>
</html>
16)ng-form
       ng-form用来在一个表单内部嵌套另一个表单。普通的HTML <form>标签不允许嵌套,但ng-form可以。这意味着内部所有的子表单都合法时,外部的表单才会合法。这对于用ng-repeat动态创建表单是非常有用的。
      **html 代码**
<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <form name=”signup_form” ng-controller=”FormController” ng-submit=”submitForm()” novalidate>
        <div ng-repeat=”field in fields” ng-form=”signup_form_input”>
            <input type=”text” name=”dynamic_input” ng-required=”field.isRequired” ng-model=”field.name” placeholder=”{{filed.placeholder}}”>
            <div ng-show=”signup_form_input.dynamic_input.$dirty &&
signup_form_input.dynamic_input.$invalid”>
                <span class=”error” ng-show=”signup_form_input.dynamic_input.$error.required”>
                    The field is required
                </span>
            </div>
        </div>
        <button type=”submit” ng-disabled=”signup_form.$invalid”>
            Submit All
        </button>
    </form>
    <script>
        angular.module(“myApp”, [])
            .controller(“FormController”, function ($scope) {
                $scope.fields = [
                    { placeholder: “Username”, isRequired: true },
                    { placeholder: “Password”, isRequired: true },
                    { placeholder: “Email(optional)”, isRequired: true }
                ];
                $scope.submitForm = function () {
                    alert(“it works”);
                }
            })
    </script>
</body>
</html>
17)ng-click
       用来指定一个元素被点击时调用的方法或表达式。
       **html 代码**
<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <div ng-controller=”CounterController”>
        <button ng-click=”count=count+1″ ng-init=”count=0″>Increment</button>
        count:{{count}}
        <button ng-click=”decrement()”>Decrement</button>
    </div>
    <script>
        angular.module(“myApp”, [])
            .controller(“CounterController”, function ($scope) {
                $scope.decrement = function () {
                    $scope.count = $scope.count – 1;
                }
            })
    </script>
</body>
</html>
18)ng-select
    ng-select用来将数据同HTML的<select>元素进行绑定。这个指令可以和ng-model以及ng-options指令一同使用,构建精细且表现优良的动态表单
    ng-options的值可以是一个内涵表达式(comprehension expression),其实这只是一种有趣的说法,简单来说就是它可以接受一个数组或对象,并对它们进行循环,将内部的内容提供给

select标签内部的选项。它可以是下面两种形式。
html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <div ng-controller=”CityController”>
        <select ng-model=”city” ng-options=”city.name for city in cities”>
            <option value=””>Choose CIty</option>
        </select>
        Best City:{{city.name}}
    </div>
    <script>
        angular.module(“myApp”, [])
            .controller(“CityController”, function ($scope) {
                $scope.cities = [
                    { name: “Seattle” },
                    { name: “San Francisco” },
                    { name: “Chicago” },
                    { name: “New York” },
                    { name: “Boston” }
                ]
            })
    </script>
</body>
</html>
19)ng-submit
      ng-submit用来将表达式同onsubmit事件进行绑定。这个指令同时会阻止默认行为(发送请求并重新加载页面),除非表单不含有action属性。
      **html 代码**
<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <form ng-submit=”submit()” ng-controller=”FormController”>
        Enter text and hit enter:
        <input type=”text” ng-model=”person.name” name=”person.name” />
        <input type=”submit” name=”person.name” value=”Submit” />
        <div>people={{people}}</div>
        <ul ng-repeat=”(index,object) in people”>
            <li>{{object.name}}</li>
        </ul>
    </form>
    <script>
        angular.module(“myApp”, [])
            .controller(“FormController”, function ($scope) {
                $scope.person = { name: null };
                $scope.people = [];
                $scope.submit = function () {
                    if ($scope.person.name) {
                        $scope.people.push({ name: $scope.person.name });
                        $scope.person.name = “”;
                    }
                }
            })
    </script>
</body>
</html>
20)ng-class
      使用ng-class 动态设置元素的类,方法是绑定一个代表所有需要添加的类的表达式。重复的类不会添加。当表达式发生变化,先前添加的类会被移除,新类会被添加。
      **html 代码**
<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
        .red {
            background: red;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <div ng-controller=”LotteryController”>
        <div>if {{x}} > 5 the following tip will show</div>
        <div ng-class=”{red: x>5}” ng-if=”x > 5″>
            You won!
        </div>
        <button ng-click=”x = generateNumber()” ng-init=”x=0″>
            DrawNumber
        </button>
    </div>
    <script>
        angular.module(“myApp”, [])
            .controller(“LotteryController”, function ($scope) {
                $scope.generateNumber = function () {
                    return Math.floor((Math.random() * 10) + 1);
                }
            })
    </script>
</body>
</html>
21)ng-attr-(suffix)
     **html 代码**
当AngularJS编译DOM时会查找花括号{{ some expression }}内的表达式。这些表达式会
被自动注册到$watch服务中并更新到$digest循环中,成为它的一部分:
<h1>Hello{{someExpression}}</h1>
有时浏览器会对属性会进行很苛刻的限制。SVG就是一个例子:
<svg>
<circle cx=”{{ cx }}”></circle>
</svg>
运行上面的代码会抛出一个错误,指出我们有一个非法属性。可以用ng-attr-cx来解决这
个问题。注意,cx位于这个名称的尾部。在这个属性中,通过用{{ }}来写表达式,达到前面提
到的目的。
<svg>
<circle ng-attr-cx=”{{ cx }}”><circle>
</svg>

九、指令详解

1.指令定义
AngularJS应用的模块中有很多方法可以使用,其中directive()这个方法是用来定义指令的
html 代码

angular.module(‘myApp’, [])
.directive(‘myDirective’, function ($timeout, UserDefinedService) {
// 指令定义放在这里
});
接受2个参数:
1.name(字符串)
指令的名字,用来在视图中引用特定的指令。
2.factory_function (函数)
这个函数返回一个对象,其中定义了指令的全部行为。$compile服务利用这个方法返回的对
象,在DOM调用指令时来构造指令的行为。
angular.application(‘myApp’, [])
.directive(‘myDirective’, function() {
// 一个指令定义对象
return {
// 通过设置项来定义指令,在这里进行覆写
};
});

指令的工厂函数只会在编译器第一次匹配到这个指令时调用一次。和controller函数类似,我们通过$injetor.invoke来调用指令的工厂函数。
当AngularJS在DOM中遇到具名的指令时,会去匹配已经注册过的指令,并通过名字在注册过的对象中查找。此时,就开始了一个指令的生命周期,指令的生命周期开始于$compile方法并结束于link方法

可能的选项如下所示,每个键的值说明了可以将这个属性设置为何种类型或者什么样的函数:
html 代码

.directive(‘myDirective’, function() {
    return {
    restrict: String,
    priority: Number,
    terminal: Boolean,
    template: String or Template Function:
    function(tElement, tAttrs) (…},
    templateUrl: String,
    replace: Boolean or String,
    scope: Boolean or Object,
    transclude: Boolean,
    controller: String or
    function(scope, element, attrs, transclude, otherInjectables) { … },
    controllerAs: String,
    require: String,
    link: function(scope, iElement, iAttrs) { … },
    compile: // 返回一个对象或连接函数,如下所示:
    function(tElement, tAttrs, transclude) {
    return {
    pre: function(scope, iElement, iAttrs, controller) { … },
    post: function(scope, iElement, iAttrs, controller) { … }
    }
    // 或者
    return function postLink(…) { … }
    }
    };
    });

html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        .normal {
            font-size: 14px;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <div ng-controller=”myController”>
        <p class=”tip”>1) restrict(字符串) 可选值如下:</p>
        <p class=”normal”>E(元素) A(属性,默认值) C(类名) M(注释)</p>
        <my-directive> </my-directive>
        <div my-directive></div>
        <div class=”my-directive”></div>
        <p class=”tip”>2)优先级(数值型)</p>
        <p class=”normal”>优先级参数可以被设置为一个数值。大多数指令会忽略这个参数,使用默认值0,但也有些 场景设置高优先级是非常重要甚至是必须的。例如,ngRepeat将这个参数设置为1000,这样就可 以保证在同一元素上,它总是在其他指令之前被调用。
        </p>
        <p class=”tip”>3)terminal(布尔型)</p>
        <p class=”normal”>这个参数用来告诉AngularJS停止运行当前元素上比本指令优先级低的指令。但同当前指令 优先级相同的指令还是会被执行。
        </p>
        <p class=”normal”>
            使用了terminal参数的例子是ngView和ngIf。ngIf的优先级略高于ngView,如果ngIf的表 达式值为true,ngView就可以被正常执行,但如果ngIf表达式的值为false,由于ngView的优先 级较低就不会被执行。
        </p>
        <p class=”tip”>4)template(字符串或函数)</p>
        <p class=”normal”>
            函数: 一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个代表模板的字符 串。tElement和tAttrs中的t代表template,是相对于instance的。
        </p>
        <p class=”tip”>5)templateUrl(字符串或函数)</p>
        <p class=”normal”>一个代表外部HTML文件路径的字符串;</p>
        <p class=”normal”>一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个外部HTML文件 路径的字符串。
        </p>
        <p class=”normal”>*在本地开发时,需要在后台运行一个本地服务器,用以从文件系统加载HTML模板,否则 会导致Cross Origin Request Script(CORS)错误。模板加载是异步的,意味着编译和链接要暂停,等待模板加载完成。模板加载后,AngularJS会将它默认缓存到$templateCache服务中。在实际生产中,可以提
            前将模板缓存到一个定义模板的JavaScript文件中,这样就不需要通过XHR来加载模板了
        </p>
        <p class=”tip”>6)replace(布尔型)</p>
        <p class=”normal”>replace是一个可选参数,如果设置了这个参数,值必须为true,因为默认值为false。默 认值意味着模板会被当作子元素插入到调用此指令的元素内部
        </p>
    </div>
    <script>
        var module = angular.module(“myApp”, []);
        module.directive(‘myDirective’, function () {
            return {
                restrict: ‘EAC’,
                template: ‘<div>Test Directive</div>’
            }
        });
    </script>
</body>
</html>

2.指令作用域

html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        .normal {
            font-size: 14px;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <div>
        <p class=”tip”>1) scope参数(布尔型或对象)</p>
        <p class=”normal”>scope参数是可选的,可以被设置为true或一个对象。默认值是false。当scope设置为true时,会从父作用域继承并创建一个新的作用域对象。</p>
        <p class=”normal”>如果一个元素上有多个指令使用了隔离作用域,其中只有一个可以生效。只有指令模板中的 根元素可以获得一个新的作用域。因此,对于这些对象来说scope默认被设置为true。
        </p>
        <p class=”normal”>内置指令ng-controller的作用,就是从父级作用域继承并创建一个新的子作用域。它会创 建一个新的从父作用域继承而来的子作用域。
        </p>
        <p class=”tip”>2) 隔离作用域</p>
        <p class=”normal”>
            具有隔离作用域的指令最主要的使用场景是创建可复用的组件,组件可以在未知上下文中使 用,并且可以避免污染所处的外部作用域或不经意地污染内部作用域。 创建具有隔离作用域的指令需要将scope属性设置为一个空对象{}。如果这样做了,指令的 模板就无法访问外部作用域了
        </p>
        <div ng-init=”myProperty=’wow,this is cool'”>
            Surrounding scope:{{myProperty}}
            <div my-inherit-scope-directive></div>
            <div my-directive></div>
        </div>
    </div>
    <script>
        angular.module(“myApp”, [])
            .directive(“myDirective”, function () {
                return {
                    restrict: ‘A’,
                    template: ‘Inside1 myDirective,isolate scope:{{myProperty}}’,
                    scope: {}
                }
            })
            .directive(“myInheritScopeDirective”, function () {
                return {
                    restrict: ‘A’,
                    template: ‘Inside2 myDirective,isolate scope:{{myProperty}}’,
                    scope: true
                }
            })
    </script>
</body>
</html>

3.绑定策略
html 代码

为了让新的指令作用域可以访问当前本地作用域中的变量,需要使用下面三种别名中的一种
本地作用域属性:使用@符号将本地作用域同DOM属性的值进行绑定。指令内部作用域可以
使用外部作用域的变量
双向绑定:通过=可以将本地作用域上的属性同父级作用域上的属性进行双向的数据绑定。
就像普通的数据绑定一样,本地属性会反映出父数据模型中所发生的改变。
父级作用域绑定 通过&符号可以对父级作用域进行绑定,以便在其中运行函数。意味着对这
个值进行设置时会生成一个指向父级作用域的包装函数。
<input type=”text” ng-model=”to”/>
<!– 调用指令 –>
<div scope-example ng-model=”to”
on-send=”sendMail(email)”
from-name=”ari@fullstack.io” />
这里有一个数据模型(ng-model),一个函数(sendMail())和一个字符串(from-name)。
在指令中做如下设置以访问这些内容:
scope: {
ngModel: ‘=’, // 将ngModel同指定对象绑定
onSend: ‘&’, // 将引用传递给这个方法
fromName: ‘@’ // 储存与fromName相关联的字符串
}

html 代码

<!DOCTYPE html>
<html>
<head>
<meta charset=”UTF-8″>
<title>Simple app</title>
<!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
<script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
<style>
.tip{
color:purple;
animation:anim 2s0.2seaseinfinite;
}
.normal{
font-size:14px;
}
@keyframesanim{
0%,100%{opacity: 1}
50%{opacity: 0.4}
}
input.ng-invalid{
border:1pxsolidred;
}
input.ng-valid{
border:1pxsolidgreen;
}
</style>
</head>
<body ng-app=”myApp”>
<divng-controller=”myController”>
<my-directivefor-test=”{{ test }}”></my-directive>
<div>
<divng-controller=”secondController”>
<second-directiveuser=”userInfo”></second-directive>
<div>
<divng-controller=”thirdController”>
<third-directiveget-des=”OuterDes”action=”click(name)”></third-directive>
</div>
<script>
varapp=angular.module(“myApp”,[]);
app.directive(“myDirective”,function(){
return {
restrict:”EA”,
template:”{{test}}”,
scope:{
test:’@forTest’
},
replace:true
}
})
.controller(“myController”,function($scope){
$scope.test=”a test (@ for string)”;
});
app.directive(“secondDirective”,function(){
return {
restrict:”EA”,
template:”{{user.gender}}”,
scope:{
user:”=”
}
}
})
.controller(“secondController”,function($scope){
$scope.userInfo= {name:”tom”,gender:”male”};
});
app.directive(“thirdDirective”,function(){
return {
restrict:”ECMA”,
template:'<div>{{des}}</div><button ng-click=”action({name:\’Name from inner\’})”>Get my name</button>’,
scope:{
getDes:’&’,
action:’&’
},
controller:function($scope){
$scope.des=$scope.getDes();
}
}
})
.controller(“thirdController”,function($scope){
$scope.OuterDes=”This is a test description”;
$scope.click=function(name){
alert(name);
}
})
</script>
</body>
</html>
1)transclude
      我们可以将整个模板,包括其中的指令通过嵌入全部传入一个指令中。这样做可以将任意内容和作用域传递给指令。transclude参数就是用来实现这个目的的,指令的内部可以访问外部指令的作用域,并且模板也可以访问外部的作用域对象。为了将作用域传递进去,scope参数的值必须通过{}或true设置成隔离作用域。如果没有设置scope参数,那么指令内部的作用域将被设置为传入模板的作用域。
     e.g
      **html 代码**
<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <!– <script type=”text/javascript” src=”js/angular.min.js”></script> –>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        .normal {
            font-size: 14px;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <p class=”normal”>* reference: http://www.angularjs.cn/A0pU
        <div ng-controller=”Ctrl”>
            <input type=”text” ng-model=”title”>
            <textarea ng-model=”text” id=”” cols=”30″ rows=”10″></textarea>
            <br/>
            <pane title=”title”>
                <div style=”color:purple”>
                    {{text}}
                </div>
            </pane>
        </div>
        <script>
            var app = angular.module(“myApp”, []);
            app.directive(“pane”, function () {
                return {
                    restrict: “E”,
                    transclude: true,
                    template: ‘<div style=”border: 1px solid red;”>’ +
                        ‘<div style=”background-color: gray”> {{title}}</div>’ +
                        ‘<div ng-transclude></div>’ +
                        ‘</div>’
                }
            });
            app.controller(“Ctrl”, function () {
            })
        </script>
</body>
</html>

e.g from the book
html 代码

angular.module(‘myApp’, []) .directive(‘sidebox’, function() { return { restrict: ‘EA’, scope: { title: ‘@’ }, transclude:
true, template: ‘
<div class=”sidebox”>\
    <div class=”content”>\
        <h2 class=”header”>{{ title }}</h2>\
        <span class=”content” ng-transclude>\
        </span>\
    </div>\
</div>’ }; }); //这段代码告诉AngularJS编译器,将它从DOM元素中获取的内容放到它发现ng-transclude 指令的地方。

指令的控制器和link函数可以进行互换。控制器主要是用来提供可在指令间复用的行为,但链接函数只能在当前内部指令中定义行为,且无法在指令间复用.由于指令可以require其他指令所使用的控制器,因此控制器常被用来放置在多个指令间共享的动作。如果我们希望将当前指令的API暴露给其他指令使用,可以使用controller参数,否则可以使用link来构造当前指令元素的功能性。如果我们使用了scope.$watch()或者想要与DOM元素做实时的交互,使用链接会是更好的选择。
*reference http://www.angularjs.cn/A0nR
https://segmentfault.com/q/1010000002400734

*如果指令使用了transclude参数,那么在控制器中就无法正常监听数据模型的变化了。这就是最佳实践总是建议在链接函数里使用$watch服务的原因。

1)controller(字符串或函数)

html 代码

//controller参数可以是一个字符串或一个函数。当设置为字符串时,会以字符串的值为名字,
来查找注册在应用中的控制器的构造函数:
angular.module(‘myApp’, [])
.directive(‘myDirective’, function() {
restrict: ‘A’, // 始终需要
controller: ‘SomeController’
})
// 应用中其他的地方,可以是同一个文件或被index.html包含的另一个文件
angular.module(‘myApp’)
.controller(‘SomeController’, function($scope, $element, $attrs, $transclude) {
// 控制器逻辑放在这里
});
//可以在指令内部通过匿名构造函数的方式来定义一个内联的控制器:
angular.module(‘myApp’,[])
.directive(‘myDirective’, function() {
restrict: ‘A’,
controller:
function($scope, $element, $attrs, $transclude) {
// 控制器逻辑放在这里
}
});
2)controllerAs(字符串)
  controllerAs参数用来设置控制器的别名,可以以此为名来发布控制器,并且作用域可以访问controllerAs。这样就可以在视图中引用控制器,甚至无需注入$scope。

3)require(字符串或数组)
 require参数可以被设置为字符串或数组,字符串代表另外一个指令的名字。require会将控制器注入到其值所指定的指令中,并作为当前指令的链接函数的第四个参数。

4.AngularJS 的生命周期
1)compile(对象或函数)
compile选项本身并不会被频繁使用,但是link函数则会被经常使用。本质上,当我们设置了link选项,实际上是创建了一个postLink()链接函数,以便compile()函数可以定义链接函数。通常情况下,如果设置了compile函数,说明我们希望在指令和实时数据被放到DOM中之前进行DOM操作,在这个函数中进行诸如添加和删除节点等DOM操作是安全的。
*compile和link选项是互斥的。如果同时设置了这两个选项,那么会把compile所返回的函数当作链接函数,而link选项本身则会被忽略。

2)链接
链接函数是可选的。如果定义了编译函数,它会返回链接函数,因此当两个函数都定义了时,编译函数会重载链接函数。如果我们的指令很简单,并且不需要额外的设置,可以从工厂函数(回调函数)返回一个函数来代替对象。如果这样做了,这个函数就是链接函数。
html 代码

angular.module(‘myApp’, [])
.directive(‘myDirective’, function() {
return {
pre: function(tElement, tAttrs, transclude) {
// 在子元素被链接之前执行
// 在这里进行Don转换不安全
// 之后调用’lihk’h函数将无法定位要链接的元素
},
post: function(scope, iElement, iAttrs, controller) {
// 在子元素被链接之后执行
// 如果在这里省略掉编译选项
//在这里执行DOM转换和链接函数一样安全吗
}
};
});
angular.module(‘myApp’, [])
.directive(‘myDirective’, function() {
return {
link: function(scope, ele, attrs) {
return {
pre: function(tElement, tAttrs, transclude) {
// 在子元素被链接之前执行
// 在这里进行Don转换不安全
// 之后调用’lihk’h函数将无法定位要链接的元素
},
post: function(scope, iElement, iAttrs, controller) {
// 在子元素被链接之后执行
// 如果在这里省略掉编译选项
//在这里执行DOM转换和链接函数一样安全吗
}
}
}
});

十、Angularjs模块加载

1.配置
在模块的加载阶段,AngularJS会在提供者注册和配置的过程中对模块进行配置。在整个AngularJS的工作流中,这个阶段是唯一能够在应用启动前进行修改的部分。
*唯一例外的是constant()方法,这个方法总会在所有配置块之前被执行。
html 代码

angular.module(‘myApp’, [])
.factory(‘myFactory’, function(){
var service = {};
return service;
})
.directive(‘myDirective’, function(){
return {
template: ‘<button>Click me</button>’
}
})
AngularJS会在编译时执行这些辅助函数。它们在功能上等同于下面的写法:
angular.module(‘myApp’, [])
.config(function($provide ,$compileProvider) {
$provide.factory(‘myFactory’, function() {
var service = {};
return service;
});
$compileProvider.directive(‘myDirective’, function() {
return {
template: ‘<button>Click me</button>’
};
});
});

2.运行块
和配置块不同,运行块在注入器创建之后被执行,它是所有AngularJS应用中第一个被执行的方法。
html 代码

angular.module(“myApp”, []).run(function($rootScope, AuthService) {
    $rootScope.$on(“$routeChangeStart”, function(evt, next, current) {
        // 如果用户未登录
        if (!AuthService.userLoggedIn()) {
            if (next.templateUrl === “login.html”) {
                // 已经转向登录路由因此无需重定向
            } else {
                $location.path(“/login”);
            }
        }
    });
});

十一、多重视图和路由

1.路由
我们可以使用AngularJS提供的when和otherwise两个方法来定义应用的路由。
html 代码

//我们可以用when方法来添加一个特定的路由。这个方法可以接受两个参数(when(path,
route))。
angular.module(‘myApp’,[])
.config([‘$routeProvider’,function($routeProvider){
$routeProvider.when(‘/’,{
templateUrl:’views/home.html’,
controller:’HomeController’
})
}]);
第一个参数是路由路径,这个路径会与$location.path进行匹配,$location.path也就是
当前URL的路径。如果路径后面还有其他内容,或使用了双斜线也可以正常匹配。我们可以在
URL中存储参数,参数需要以冒号开头(例如:name),后面会讨论如何用$routeParams读取这
些参数。
第二个参数是配置对象,决定了当第一个参数中的路由能够匹配时具体做些什么。配置对象
中可以进行设置的属性包括controller、template、templateURL、resolve、redirectTo和
reloadOnSearch。

html 代码

angular.module(“myApp”, []).config([
    “$routeProvider”,
    function($routeProvider) {
        $routeProvider
            .when(“/”, {
                templateUrl: “views/home.html”,
                controller: “HomeController”,
            })
            .when(“/login”, {
                templateUrl: “views/login.html”,
                controller: “LoginController”,
            })
            .when(“/dashbord”, {
                templateUrl: “views/dashbord.html”,
                controller: “DashbordController”,
                resove: {
                    user: function(SessionService) {
                        return SessionService.getCurrentUser();
                    },
                },
            })
            .otherwise({
                redirectTo: “/”,
            });
    },
]);

html 代码

1. controller
controller: ‘MyController’
// 或者
controller: function($scope) {}
如果配置对象中设置了controller属性,那么这个指定的控制器会与路由所创建的新作用
域关联在一起。如果参数值是字符型,会在模块中所有注册过的控制器中查找对应的内容,然后
与路由关联在一起。如果参数值是函数型,这个函数会作为模板中DOM元素的控制器并与模板
进行关联。
2. template
template: ‘<div><h2>Route</h2></div>’
AngularJS会将配置对象中的HTML模板渲染到对应的具有ng-view指令的DOM元素中。
3. templateUrl
templateUrl: ‘views/template_name.html’
应用会根据templateUrl属性所指定的路径通过XHR读取视图(或者从$templateCache中读
取)。如果能够找到并读取这个模板,AngularJS会将模板的内容渲染到具有ng-view指令的DOM
元素中。
4. resolve
resolve: {
‘data’: [‘$http’, function($http) {
return $http.get(‘/api’).then(
function success(resp) { return response.data; },
function error(reason) { return false; }
);
}];
}
如果设置了resolve属性,AngularJS会将列表中的元素都注入到控制器中。如果这些依赖是
promise对象,它们在控制器加载以及$routeChangeSuccess被触发之前,会被resolve并设置成一
个值。
5. redirectTo
redirectTo: ‘/home’
// 或者
redirectTo: function(route,path,search)
如果redirectTo属性的值是一个字符串,那么路径会被替换成这个值,并根据这个目标路
径触发路由变化。
如果redirectTo属性的值是一个函数,那么路径会被替换成函数的返回值,并根据这个目
标路径触发路由变化。
如果redirectTo属性的值是一个函数,AngularJS会在调用它时传入下面三个参数中:
(1) 从当前路径中提取出的路由参数;
(2) 当前路径;
(3) 当前URL中的查询串。
6. reloadOnSearch
如果reloadOnSearch选项被设置为true(默认),当$location.search()发生变化时会重新
加载路由。如果设置为false,那么当URL中的查询串部分发生变化时就不会重新加载路由。这
个小窍门对路由嵌套和原地分页等需求非常有用。
7.$routeParams
如果我们在路由参数的前面加上:,AngularJS就会把它解析出来并传递给$routeParams
e.g:
$routeProvider
.when(‘/inbox/:name’, {
controller: ‘InboxController’,
templateUrl: ‘views/inbox.html’
});
AngularJS会在$routeParams中添加一个名为name的键,它的值会被设置为加载进来的URL中的值

2.$location服务
$location服务没有刷新整个页面的能力。如果需要刷新整个页面,需要使用$window.location对象(window.location的一个接口)。
html 代码

1. path()
path()用来获取页面当前的路径:
$location.path(); // 返回当前路径
修改当前路径并跳转到应用中的另一个URL:
$location.path(‘/’); // 把路径修改为’/’路由
path()方法直接和HTML5的历史API进行交互,所以用户可通过点击后退按钮退回到上一个
页面。
2. replace()
如果你希望跳转后用户不能点击后退按钮(对于登录之后的跳转这种发生在某个跳转之后的
再次跳转很有用),AngularJS提供了replace()方法来实现这个功能:
$location.path(‘/home’);
$location.replace();
// 或者
$location.path(‘/home’).replace();
3. absUrl()
absUrl()方法用来获取编码后的完整URL:
$location.absUrl()
4. hash()
hash()方法用来获取URL中的hash片段:
$location.hash(); // 返回当前的hash片段
5. host()
host()方法用来获取URL中的主机:
$location.host();// 当前URL的主机
6. port()
port()方法用来获取URL中的端口号:
$location.port();// 当前URL的端口
7. protocol()
protocol()方法用来获取URL中的协议:
$location.protocol();// 当前URL的协议
8. search()
search()方法用来获取URL中的查询串
我们可以向这个方法中传入新的查询参数,来修改URL中的查询串部分:
// 用对象设置查询
$location.search({name: ‘Ari’, username: ‘auser’});
// 用字符串设置查询
$location.search(‘name=Ari&username=auser’);
search方法可以接受两个参数。
9. url()
url()方法用来获取当前页面的URL:
$location.url(); // 该URL的字符串
如果调用url()方法时传了参数,会设置并修改当前的URL,这会同时修改URL中的路径、
查询串和hash,并返回$location。
// 设置新的URL
$location.url(‘/home?name=Ari#hashthing’);

3.路由模式
$route服务在路由过程中的每个阶段都会触发不同的事件,可以为这些不同的路由事件设置监听器并做出响应。我们需要给路由设置事件监听器,用$rootScope来监听这些事件
html 代码

1. $routeChangeStart
AngularJS在路由变化之前会广播$routeChangeStart事件。在这一步中,路由服务会开始加
载路由变化所需要的所有依赖,并且模板和resolve键中的promise也会被resolve。
angular.module(‘myApp’, [])
.run([‘$rootScope’, ‘$location’, function($rootScope, $location) {
$rootScope.$on(‘$routeChangeStart’, function(evt, next, current) {
});
}]);
2. $routeChangeSuccess
AngularJS会在路由的依赖被加载后广播$routeChangeSuccess事件。
angular.module(‘myApp’, [])
.run([‘$rootScope’, ‘$location’, function($rootScope, $location) {
$rootScope.$on(‘$routeChangeSuccess’, function(evt, next, previous) {
});
}]);
$routeChangeStart事件带有三个参数:
 原始的AngularJS evt对象;
 用户当前所处的路由;
 上一个路由(如果当前是第一个路由,则为undefined)。
3. $routeChangeError
AngularJS会在任何一个promise被拒绝或者失败时广播$routeChangeError事件。
angular.module(‘myApp’, [])
.run(function($rootScope, $location) {
$rootScope.$on(‘$routeChangeError’, function(current, previous, rejection) {
});
});
$routeChangeError事件有三个参数:
 当前路由的信息;
 上一个路由的信息;
 被拒绝的promise的错误信息。
4. $routeUpdate
AngularJS在reloadOnSearch属性被设置为false的情况下,重新使用某个控制器的实例时,
会广播$routeUpdate事件。

十二、依赖注入

一个对象通常有三种方式可以获得对其依赖的控制权:
(1) 在内部创建依赖;
(2) 通过全局变量进行引用;
(3) 在需要的地方通过参数进行传递。

html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <script type=”text/javascript” src=”http://apps.bdimg.com/libs/angular-route/1.3.13/angular-route.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        .normal {
            font-size: 14px;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <div ng-controller=”MyController”>
        <button ng-click=”sayHello()”>Hello</button>
    </div>
    <script>
        angular.module(‘myApp’, [])
            .factory(‘greeter’, function () {
                return {
                    greet: function (msg) { alert(msg); }
                }
            })
            .controller(‘MyController’, function ($scope, greeter) {
                $scope.sayHello = function () {
                    greeter.greet(“Hello”);
                }
            })
    </script>
</body>
</html>

html 代码

在内部,AngularJS的处理过程是下面这样的:
// 使用注入器加载应用
var injector = angular.injector([‘ng’, ‘myApp’]);
// 通过注入器加载$controller服务:var $controller = injector.get(‘$controller’);
var scope = injector.get(‘$rootScope’).$new();
// 加载控制器并传入一个作用域,同AngularJS在运行时做的一样
var MyController = $controller(‘MyController’, {$scope: scope})

1.推断式注入声明
如果没有明确的声明,AngularJS会假定参数名称就是依赖的名称。因此,它会在内部调用函数对象的toString()方法,分析并提取出函数参数列表,然后通过$injector将这些参数注入进对象实例

2.显式注入声明
AngularJS提供了显式的方法来明确定义一个函数在被调用时需要用到的依赖关系。通过这种方法声明依赖,即使在源代码被压缩、参数名称发生改变的情况下依然能够正常工作。可以通过$inject属性来实现显式注入声明的功能。函数对象的$inject属性是一个数组,数组元素的类型是字符串,它们的值就是需要被注入的服务的名称。

3.行内注入声明
AngularJS提供的注入声明的最后一种方式,是可以随时使用的行内注入声明。这种方式其实是一个语法糖,它同前面提到的通过$inject属性进行注入声明的原理是完全一样的,但允许我们在函数定义时从行内将参数传入。此外,它可以避免在定义过程中使用临时变量。在定义一个AngularJS的对象时,行内声明的方式允许我们直接传入一个参数数组而不是一个函数。数组的元素是字符串,它们代表的是可以被注入到对象中的依赖的名字,最后一个参数就是依赖注入的目标函数对象本身。

十三、服务

1.注册一个服务
使用angular.module的factory API创建服务,是最常见也是最灵活的方式:
html 代码

angular.module(“myApp.services”, []).factory(“githubService”, function() {
    var serviceInstance = {};
    // 我们的第一个服务
    return serviceInstance;
});

服务的工厂函数用来生成一个单例的对象或函数,这个对象或函数就是服务,它会存在于应用的整个生命周期内。当我们的AngularJS应用加载服务时,这个函数会被执行并返回一个单例的服务对象。

2.使用服务

html 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <title>Simple app</title>
    <script type=”text/javascript” src=”http://www.ziqiangxuetang.com/try/angularjs/1.2.5/angular.min.js”></script>
    <script type=”text/javascript” src=”http://apps.bdimg.com/libs/angular-route/1.3.13/angular-route.js”></script>
    <style>
        .tip {
            color: purple;
            animation: anim 2s 0.2s ease infinite;
        }
        .normal {
            font-size: 14px;
        }
        @keyframes anim {
            0%,
            100% {
                opacity: 1
            }
            50% {
                opacity: 0.4
            }
        }
        input.ng-invalid {
            border: 1px solid red;
        }
        input.ng-valid {
            border: 1px solid green;
        }
    </style>
</head>
<body ng-app=”myApp”>
    <div ng-controller=”ServiceController”>
        <label for=”name”></label>
        <input type=”text” ng-model=”name” placeholder=”please enter a name” />
        <ul>
            <li ng-repeat=”event in events”>
                {{event.getHandledName(name)}}
            </li>
        </ul>
    </div>
    <script>
        angular.module(‘myApp’, [])
            .factory(“githubService”, function () {
                var getHandledName = function (name) {
                    return name + ” has been handled”;
                }
                return {
                    events: function (name) {
                        return getHandledName(name);
                    }
                }
            })
            .controller(“ServiceController”, function ($scope, githubService) {
                $scope.$watch(‘name’, function (newName) {
                    console.log(githubService.events(newName))
                })
            })
    </script>
</body>
</html>

3.创建服务时的设置项
在AngularJS应用中,factory()方法是用来注册服务的最常规方式,同时还有其他一些API可以在特定情况下帮助我们减少代码量
共有5种方法用来创建服务:factory() service() constant() value() provider()
html 代码

十四、同外界通信:XHR和服务器通信

1.使用$http
$http服务是只能接受一个参数的函数,这个参数是一个对象,包含了用来生成HTTP请求的配置内容。这个函数返回一个promise对象,具有success和error两个方法。
javascript 代码

var promise = $http({
    method: “GET”,
    url: “/api/users.json”,
});
promise.success(function(data, status, headers, config) {
    // 处理成功的响应
});
// 错误处理
promise.error(function(data, status, headers, config) {
    // 处理非成功的响应
});
//或者使用promise对象的then方法处理
promise.then(
    function(resp) {
        // resp是一个响应对象
    },
    function(resp) {
        // 带有错误信息的resp
    },
);

如果响应状态码在200和299之间,会认为响应是成功的,success回调会被调用,否则error回调会被调用。

2.设置对象
当我们将$http当作函数来调用时,需要传入一个设置对象,用来说明如何构造XHR对象。
html 代码

$http({
    method: ‘GET’,
    url: ‘/api/users.json’,
    params: {
    ‘username’: ‘auser’
    }
    });
    //设置对象可以包含以下键
    1. method(字符串)
    这个键是我们希望发送的请求的HTTP方法。它的值是下列各项其中之一:‘GET’、‘DELETE’、
    ‘HEAD’、‘JSONP’、‘POST’、‘PUT’
    2. url(字符串)
    绝对或相对的URL,是请求的目标。
    3. params(字符串map或对象)
    这个键的值是一个字符串map或对象,会被转换成查询字符串追加在URL后面。如果值不是
    字符串,会被JSON序列化。
    // 参数会转化为?name=ari的形式
    $http({
    params: {‘name’: ‘ari’}
    })
    4. data(字符串或对象)
    这个对象中包含了将会被当作消息体发送给服务器的数据。通常在发送POST请求时使用。
    从AngularJS 1.3开始,它还可以在POST请求里发送二进制数据。要发送一个blob对象,你
    可以简单地通过使用data参数来传递它。例如:
    var blob = new Blob([‘Hello World’], {type: ‘text/plain’});
    $http({
    method: ‘POST’,
    url: ‘/’,
    data: blob
    });
    5. headers(对象)
    一个列表,每一个元素都是一个函数,它会返回代表随请求发送的HTTP头。如果函数的返
    回值是null,对应的头不会被发送。
    6. xsrfHeaderName(字符串)
    保存XSFR令牌的HTTP头的名称。
    7. xsrfCookieName(字符串)
    保存XSFR令牌的cookie的名称。
    8. transformRequest(函数或函数数组)
    这是一个函数或函数数组,用来对HTTP请求的请求体和头信息进行转换,并返回转换后的
    版本。通常用于在请求发送给服务器之前对其进行序列化。
    这个函数看起来是这样的:
    function(data,headers) {}
    9. transformResponse(函数或函数数组)
    这是一个函数或函数数组,用来对HTTP响应的响应体和头信息进行转换,并返回转换后的
    版本。通常用来进行反序列化。
    这个函数看起来是这样的:
    function(data,headers) {}
    10. cache(布尔型或缓存对象)
    如果cache属性被设置为true,那么AngularJS会用默认的$http缓存来对GET请求进行缓存。
    如果cache属性被设置为一个$cacheFactory对象的实例,那么这个对象会被用来对GET请求进
    行缓存。
    11. timeout(数值型或promise对象)
    如果timeout被设置为一个数值,那么请求将会在推迟timeout指定的毫秒数后再发送。如
    果被设置为一个promise对象,那么当该promise对象被resolve时请求会被中止。
    12. withCredentials(布尔型)
    如果该属性被设置为true,那么XHR请求对象中会设置withCredentials标记。
    默认情况下,CORS请求不会发送cookie, 而withCredentials标记会在请求中加入
    Access-Control-Allow-Credentials头,这样请求就会将目标域的cookie包含在请求中。
    13. responseType(字符串)
    responseType选项会在请求中设置XMLHttpRequestResponseType属性。我们可以使用以下
    HTTP请求类型其中之一:
     “”(字符串,默认);
     “arraybuffer”(ArrayBuffer);
     “blob”(blob对象);
     “document”(HTTP文档);
     “json”(从JSON对象解析而来的JSON字符串);
     “text”(字符串);
     “moz-blob”(Firefox的接收进度事件);
     “moz-chunked-text”(文本流);
     “moz-chunked-arraybuffer”(ArrayBuffer流)。

3.响应对象
AngularJS传递给then()方法的响应对象包含四个属性。
html 代码

1.data(字符串或对象)
这个数据代表转换过后的响应体(如果定义了转换的话)。
2.status(数值型)
响应的HTTP状态码。
3.headers(函数)
这个函数是头信息的getter函数,可以接受一个参数,用来获取对应名字的值。例如,用如
下代码获取X-Auth-ID的值:
$http({
method: ‘GET’,
url: ‘/api/users.json’
}).then (resp) {
// 读取X-Auth-ID
resp.headers(‘X-Auth-ID’);
});
4.config(对象)
这个对象是用来生成原始请求的完整设置对象。
5.statusText(字符串)
这个字符串是响应的HTTP状态文本。
phpstorm 前端开发|php与前端开发的区别|web前端开发和php开发
» 本文来自:前端开发者 » 《angularjs 前端开发总结》
» 本文链接地址:https://www.rokub.com/4798.html
» 您也可以订阅本站:https://www.rokub.com
赞(0)
64K

评论 抢沙发

评论前必须登录!