angularJS详解

当时篇稿子转载  kooky798
的博客,http://blog.csdn.net/yy374864125/article/details/41349417,

描绘及如此详细为是不曾谁了,必须粉一个

 

 

1 前言

前端技术的前进是这般之快,各种精彩技术、优秀框架的起简直叫人口比比皆是,紧跟时代潮流,学习掌握新知识自然是休敢怠慢。

AngularJS是google在保护,其当国外已经颇炎热,可是国内的下状况可产生未聊之差异,参考文献/网络文章也罢酷匮乏。这里虽以自我念AngularJS写成文档,一方面作为团结学路程达之笔录,另一方面也被起趣味的同室有参照。

首先我要好也是同样誉为学习者,会盖学习者的角度来整理自己的创作思路,这里可能仅是些探索,有知或是技术达到的谬误还求大家指出;其次我特意喜欢编写小例子来拿同起事情说知道,故在文中会尽可能多的用示例加代码讲解,我深信这会是同样种植于好之计;最后,我深知AngularJS的施用方法跟jquery的运用方法有好挺不同,在豪门都发出jquery、ext经验的基准下于angular的学会困难重重,不过自己再次信任于豪门之坚持不懈下,能够高效的学好AngularJS,至少我们也能够深入摸底及AngularJS的主导思想,对咱们以后好之插件开发、项目开还见面来十分酷之迪。

2 AngularJS概述

2.1 AngularJS是什么?

AngularJs(后面就简称ng了)是一个用来设计动态web应用之布局框架。首先,它是一个框架,不是类库,是像EXT一样提供一整套方案用于设计web应用。它不光是一个javascript框架,因为她的中心其实是针对HTML标签的增长。

哪为HTML标签增强?其实就算是如果您能够用竹签完成有页面逻辑,具体办法就是是经过由定义标签、自定义属性等,这些HTML原生没有底标签/属性在ng中来一个名字:指令(directive)。后面会详细介绍。那么,什么又是动态web应用为?与传统web系统相互区别,web应用能够吧用户提供丰富的操作,能够遵循用户操作不断更新视图而休开展url跳反。ng官方也声称其更适用于付出CRUD应用,即数据操作比较多之行使,而休是打要图像处理类似以。

以促成这些,ng引入了一部分老过硬的性状,包括模板机制、数据绑定、模块、指令、依赖注入、路由于。通过数量及模板的绑定,能够被我们摆脱繁琐的DOM操作,而用注意力集中在业务逻辑上。

 
另外一个疑点,ng是MVC框架为?还是MVVM框架?官网发出关联ng的筹划下了MVC的中心思维,而同时休全是MVC,因为当写代码时我们真正是以用ng-controller这个命令(起码打名字上看,是MVC吧),但以此controller处理的事务基本上还是同view进行交互,这么看来又杀接近MVVM。让咱们拿眼光移到官网那个非醒目的title上:“AngularJS
— Superheroic JavaScript MVW Framework”。

2.2 AngularJS简单介绍

AngularJS
重新定义了前者采用之开发方式。面对HTML和JavaScript之间的界限,它

不单不畏缩不前,反而正面攻击,提出了行的化解方案。

多多前端采用的开发框架,比如Backbone、EmberJS等,都求开发者继承这框架特有的组成部分JavaScript对象。这种措施有该亮点,但它不必要地传了开发者自己代码的靶子空间,还求开发者去了解内存里那些抽象对象。尽管如此我们要受了这种方法,因为网络最初的统筹无法提供
我们今天所欲的交互性,于是我们用框架,来救助咱填补JavaScript和HTML之间的分野。而且发生了她,你绝不还“直接”操控DOM,只要吃您的DOM注上metadata(即AngularJS里的directive们),然后让AngularJS来提携您操纵DOM。同时,AngularJS不因(也未伤)任何其他的框架。你甚至足以根据其他的框架来开发AngularJS应用。

API地址:http://docs.angularjs.org/api/;

AngularJS在github上的华语粗译版地址:https://github.com/basestyle/angularjs-cn。

2.3 什么时候该用AngularJS

AngularJS是一个 MV*
框架,最适于开发客户端的单页面应用。它不是个功能库,而是用来开发动态网页的框架。它小心于扩充HTML的意义,提供动态数据绑定(data
binding),而且她能同其它框架(如jQuery)合作协调。

倘若你若开支之是单页应用,AngularJS就是你的极品之选。Gmail、Google
Docs、Twitter和Facebook这样的应用,都好能够表达AngularJS的优点。但是像玩开发之类对DOM进行大量决定、又或者仅仅用
极高周转速度之运,就非是AngularJS的用武之地了。

3 AugularJS特性

AngularJS是一个新出现的雄强客户端技术,提供被大家之同种出强大使的措施。这种措施以而扩张HTML,CSS和javascript,并且弥补了她的部分大明显的不足。本应有用HTML来贯彻而如今由于她开发之动态一些情节。

AngularJS有五个最要的效用跟特点:

3.1 特性一:双向的数码绑定

数码绑定可能是AngularJS最深最实用的性状。它能帮助你免开大量之启代码用省去开支时间。一个天下无双的web应用或含了80%之代码用来拍卖,查询以及监听DOM。数据绑定是的代码更少,你可小心让你的利用。

咱们想象一下Model是若的运中之简单事实。你的Model是您用来读取或者更新的有些。数据绑定指令提供了卿的Model投射到view的法门。这些投射可以无缝的,毫不影响之应用至web应用被。

民俗来说,当model变化了。
开发人员需要手动处理DOM元素而将性能反映至这些变化中。这个一个双向的经过。一方面,model变化让了DOM中元素变化,另一方面,DOM元素的转也会见影响及Model。这个于用户互动中尤其错综复杂,因为开发人员需要处理及剖析

这些互动,然后融合到一个model中,并且更新View。这是一个手动的复杂性过程,当一个使用非常大之时节,将会晤是如出一辙起十分艰难的政工。

此一定有再次好的解决方案!那就是是AngularJS的双向数据绑定,能够一起DOM和Model等等。

此出一个非常简单的事例,用来演示一个input输入框和<h1>元素的双向绑定(例01):

证实:实际效果请大家看AngularJS/demo/index.html

3.2 特性二:模板

以AngularJS中,一个模板就是一个HTML文件。但是HTML的始末扩展了,包含了过多辅助而照model到view的情。

HTML模板将会见叫浏览器解析到DOM中。DOM然后改成AngularJS编译器的输入。AngularJS将见面全体历DOM模板来十分成有指导,即,directive(指令)。所有的一声令下都担负对view来设置数据绑定。

咱俩设理解AuguarJS并无把模版当做String来操作。输入AngularJS的凡DOM而无string。数据绑定是DOM变化,不是字符串的连续要innerHTML变化。使用DOM作为输入,而非是字符串,是AngularJS区别为外的框架的极端可怜原因。使用DOM允许你扩展指令词汇并且可创造而协调的指令,甚至开而选用的机件。

极可怜之裨益是啊设计师和开发者创建了一个紧紧的工作流。设计师可以像过去相同付出标签,然后开发者拿过来添加上功能,通过数据绑定以会见叫这个进程非常简单。

此发生一个事例,我们运用ng-repeat指令来循环图片数组并且加入img模板,如下:

function AlbumCtrl($scope) {

    scope.images = [

        {“image”:”img/image_01.png”, “description”:”Image 01
description”},

        {“image”:”img/image_02.png”, “description”:”Image 02
description”},

        {“image”:”img/image_03.png”, “description”:”Image 03
description”},

        {“image”:”img/image_04.png”, “description”:”Image 04
description”},

        {“image”:”img/image_05.png”, “description”:”Image 05
description”}

    ];

}

<div ng-controller=”AlbumCtrl”>

  <ul>

    <li ng-repeat=”image in images”>

      <img ng-src=”http://m.cnblogs.com/142260/{{image.thumbnail}}”
rel=”nofollow”/>

    </li>

  </ul>

</div>

此处还有雷同项事值得提一词,AngularJS并无强制你学习一个新的语法或者从你的利用被提出你的模版。

3.3 特性三:MVC

对客户端应用开发AngularJS吸收了传统的MVC基本原则。MVC或者Model-View-Controll设计模式针对不同之人头或许意味着不同的事物。AngularJS并无履行传统意义上之MVC,更近乎受MVVM(Moodel-View-ViewModel)。

Model

model是使被之简约多少。一般是大概的javascript对象。这里没有必要继承框架的classes,使用proxy对象封装或者以特别的setter/getter方法来访问。事实上我们处理vanilla
javascript的法就是是一个百般好之风味,这种方法让我们更少动下的原型。

ViewModel

viewmodel是一个为此来提供特别数据以及措施从而保障指定view的目标。

viewmodel是$scope的目标,只在于AnguarJS的用被。$scope只是一个简的js对象,这个目标下简便的API来侦测和广播状态变化。

Controller

controller负责设置初始状态和参数化$scope方法用以控制行为。需要指出的controller并无保留状态为无与长途服务互动。

View

view是AngularJS解析后渲染和绑定后转变的HTML
。这个片段帮助你创造web应用之架构。$scope拥有一个对数据的参考,controller定义行为,view处理布局和互相。

3.4 特性四:服务与倚重注入

AngularJS服务那意图就是是对外提供有特定的作用。

AngularJS拥有内建的负注入(DI)子系统,可以协助开发人员更易之支出,理解以及测试用。

DI允许而请而的依靠,而休是温馨招来寻她。比如,我们需要一个事物,DI负责找创建而提供于咱。

为要取得基本之AngularJS服务,只需要添加一个简短劳动作为参数,AngularJS会侦测并且提供于你:

function EditCtrl($scope, $location, $routeParams) {

     // Something clever here…

}

汝吗可以定义自己之服务又让它注入:

angular.module(‘MyServiceModule’, []).

    factory(‘notify’, [‘$window’, function (win) {

    return function (msg) {

        win.alert(msg);

    };

}]);

function myController(scope, notifyService) {

    scope.callNotify = function (msg) {

        notifyService(msg);

    };

}

myController.$inject = [‘$scope’, ‘notify’];

3.5 特性五:指令(Directives)

命令是我个人最好爱的风味。你是勿是为愿意浏览器可做简单有意思的工作?那么AngularJS可以完成。

命可以为此来创造于定义之竹签。它们可用来点缀元素或操作DOM属性。可以当作标签、属性、注释和类名使用。

这边是一个例,它监听一个事变又对的换代她的$scope ,如下:

myModule.directive(‘myComponent’, function(mySharedService) {

    return {

        restrict: ‘E’,

        controller: function($scope, $attrs, mySharedService) {

            $scope.$on(‘handleBroadcast’, function() {

                $scope.message = ‘Directive: ‘ +
mySharedService.message;

            });

        },

        replace: true,

        template: ‘<input>’

    };

});

然后,你可以动用此自定义的directive来运:

<my-component ng-model=”message”></my-component>

使相同系列之零件来创造而协调之采取将会晤受你再便民的丰富,删除和翻新功能。

 

4 功能介绍

4.1数码绑定

AngularJS的双向数据绑定,意味着你得在Mode(JS)中改多少,而这些改变就就会见活动出现于View上,反之亦然。即:一方面可以形成model变化让了DOM中元素变化,另一方面为足以成功DOM元素的成形吧会见影响至Model。

每当我们以jQuery的时光,代码中会大量充斥类似这样的话语:var val =
$(‘#id’).val();
$(‘#id’).html(str);等等,即频繁之DOM操作(读取和写入),其实我们的终极目的并无是要是操作DOM,而是一旦落实工作逻辑。ng的绑定以给您摆脱DOM操作,只要模板与数据经过声明进行了绑定,两者将随时保持同,最新的多寡会实时显示在页面中,页面被用户改的数也会实时被记录在数据模型中。

于View到Controller再到View的多少交互(例01):

<html ng-app=”demoApp”>

……

<input type=”text” ng-model=”user.name”
placeholder=”请输入名称”/>

Hello, {{ user.name }}!

……

关键: ng-app 、 ng-model 和 { {user.name } }

第一:
<html>元素的ng-app属性。标识是DOM里面的情节将启用AngularJS应用。

说不上:告诉AngularJS,对页面上之“user.name” 这个Model进行双向数据绑定。

老三:告诉AngularJS,在“{{
user.name}}”这个令模版上亮“user.name”这个Model的数据。

自打Server到Controller再届View的数交互(例02):

<html ng-app=”demoApp”>

……

<div  ng-controller=”demoController”>

<input type=”text” ng-model=”user.name” disabled=”disabled”/>

<a href=”javascript:void(0);” target=”_blank”
rel=”nofollow”>获取名字</a>

……

demoApp.controller(“demoController”, function($http, $scope){

$scope. getAjaxUser = function(){

// $http.get({url:”../xxx.action”}).success(function(data){

// $scope.user= data;

// });

$scope.user = {“name”:”从JOSN中拿走之称”,”age”:22};

};

});

变更$scope中的user,View也会自动更新。

4.2 scopes、module、controller

4.2.1 scopes

$scope是一个管view(一个DOM元素)连结至controller上之靶子。在我们的MVC结构里,这个
$scope
将改成model,它提供一个绑定到DOM元素(以及其子元素)上的excecution
context。

尽管放起来有点复杂,但 $scope
实际上就是一个JavaScript对象,controller和view都得以看它,所以我们好以其于两边间传递信息。在这个
$scope 对象里,我们既存储数据,又囤积将要运行于view上之函数。

各一个Angular应用还见面有一个 $rootScope。这个 $rootScope
是绝顶级的scope,它对诺在含有 ng-app 指令属性的非常DOM元素。

app.run(function($rootScope) { $rootScope.name = “张三”; });

设页面上从未有过明确设定 $scope ,Angular 就见面拿多少和函数都绑定到这里,
第一有的中之例子就是是乘就一点遂运行的。

这么,我们即便足以于view的另地方看是name属性,使用模版表达式{{}},像这样:

{{ name }}  

4.2.2 module

先是得鲜明一下模板的概念。在自我还非理解有模板这个东西的下,曾经用js拼接有怪丰富的HTML字符串,然后append到页面中,这种办法考虑真是又土以笨。后来以看好管HTML代码包裹于一个<script>标签中作模板,然后照需取来使用。

于ng中,模板十分简短,它便是我们页面及的HTML代码,不需要增大其他附加的事物。在模板被得用各种吩咐来增进其的功用,这些指令可以给你管模版与数量巧妙的绑定起来。

在<html>标签上大多矣一个属性ng-app=”MyApp”,它的作用就之所以来指定ng的作用域是在<html>标签中部分。在js中,我们调用angular对象的module方法来声称一个模块,模块的名与ng-app的值对应。这样声明一下就是得吃ng运行起来了。

示例:

<html ng-app=”demoApp”>

var demoApp = angular.module(‘demoApp’, []);

4.2.3 ng-controller

假设明了创建一个$scope
对象,我们将让DOM元素设置一个controller对象,使用的凡ng-controller
指令属性:

<div ng-controller=”MyController”> {{ person.name }} </div>
 

ng-controller指令给各地的DOM元素创建了一个初的$scope
对象,并拿之$scope 对象涵盖进外层DOM元素的$scope
对象里。在上头的例子里,这个外层DOM元素的$scope 对象,就是$rootScope
对象。这个scope链是如此的:

 

 

具有scope都以原型继承(prototypal
inheritance),这代表她都能够访问父scope们。对其它性质与艺术,如果AngularJS在时scope上摸不至,就会见暨父
scope上去寻找,如果以父scope上也没找到,就见面连续提高回溯,一直到$rootScope
上。即要controller是基本上重合嵌套的,就会见起太里面一直往他找,这个scope链是这般的:

 

唯的异:有些指令属性可以选择性地创造一个独自的scope,让这scope不连续其的父scope们,这个会以指令详解中证实。

4.3 ajax

$http
服务是AngularJS的核心服务之一,它帮忙我们通过XMLHttpRequest对象或JSONP与长途HTTP服务开展交流。

$http
服务是这样一个函数:它承受一个装置对象,其中指定了安创造HTTP请求;它用赶回一个答应(*参照JavaScript异步编程的promise模式),其中提供简单单办法:
success方法与error方法。

demoApp.controller(“demoController”, function($http, $scope){

$scope. getAjaxUser = function(){

$http.get({url:”../xxx.action”}).success(function(data){

alert(data);

}).error(function(){

Alert(“出错了!”);

});

 

};

});

AngularJS的AJAX与jquery等框架的AJAX基本一致,这里就是非多说了。

4.4表达式

ng中的表达式与javascript表达式类似但是非可以划等号,它是ng自己定义之相同效模式。表达式可以用作指令的值,如ng-modle=”people.name”、ng-click=”showMe()”,看起是这样像字符串,故而也让字符串表达式。也可以当标记中行使表达式,如{{1+2}},或者跟过滤器一起用{{1+2
|
currency}}。在框架之中,字符串不会见简单的下eval()来推行,而是来一个特别的$parse服务来处理。在ng表达式中不可以行使循环语句子、判断语句,事实上在模板被以复杂的表达式也是一个非引进的做法,这样视图与逻辑就是混在同了

俺们于动用任何模板库时,一般都见面发模板的循环输出、分支输出、逻辑判断等类的控制。

比方惦记了解指令属性之运行,我们亟须事先清楚表达式。在事先的例证里我们就呈现了表达式,例如
{{ user.name }}。

告查看例03、例04、例05。

{{ 8 + 1 }} 9

{{ person }} {“name”:”Ari Lerner”}

{{ 10 * 3.3 | currency }} $33.00

表达式粗略来拘禁有点像 eval(javascript)
的结果。它们会经Angular.js的处理,从而有以下重点而奇之性:

l 所有表达式都于scope这个context里叫实践,因此可采用有地方 $scope
中的变量。

l 如果一个表达式的履行导致品种错误或引用错误,这些不当将非会见于扔来。

l 表达式里无允许其他决定函数流程的力量(如if/else等规范语句)

l 表达式可承受一个还是多只串联起的过滤器。

4.5过滤器

过滤器(filter)正使该誉为,作用就是收到一个输入,通过某个规则进行拍卖,然后返回处理后底结果。主要用在数量的格式化上,例如获取一个数组中的子集,对数组中之元素进行排序等。过滤器通常是伴随标记来使用的,将您model中之数格式化为需要的格式。表单的支配功能重要干到数证实和表单控件的滋长。ng内置了部分过滤器,它们是:

currency(货币)、date(日期)、filter(子串匹配)、json(格式化json对象)、limitTo(限制个数)、lowercase(小写)、uppercase(大写)、number(数字)、orderBy(排序)。

4.5.1过滤器使用办法

共计九种。除此之外还得由定义过滤器,这个就算强大了,可以满足任何要求的数据处理。Filter还是很简单的,需要理解的凡搭的filter如何使用,以及自己如何定义一个filter。

filter的个别栽采取方法:

  1. 以模板被采用filter

  我们可以一直当{{}}中动用filter,跟当表达式后面用 |
分割,语法如下:

{{ expression | filter }}

啊得基本上个filter连用,上一个filter的出口将当下一个filter的输入:

{{ expression | filter1 | filter2 | … }}  

filter可以收参数,参数用 : 进行私分,如下:

{{ expression | filter:argument1:argument2:… }}  

除了针对{{}}中之数进行格式化,我们还好以指令中运用filter,例如先对数组array进行过滤处理,然后再循环输出:

<span ng-repeat=”a in array | filter “>  

  1. 在controller和service中使用filter

  我们的js代码中为堪下过滤器,方式就是咱们耳熟能详的乘注入,例如我一旦于controller中运用currency过滤器,只需要以它们注入及该controller中即可,代码如下:

app.controller(‘testC’,function($scope,currencyFilter){

    $scope.num = currencyFilter(123534);  

}  

以模板被采取{{num}}就可以直接输出$123,534.00了!在劳动遭遇利用filter也是相同的理。

  如果你若当controller中以多个filter,并不需要一个一个流入吗,ng提供了一个$filter服务好来调用所要的filter,你仅仅需要注入一个$filter就够了,使用办法如下:

app.controller(‘testC’,function($scope,$filter){

$scope.num = $filter(‘currency’)(123534);  

$scope.date = $filter(‘date’)(new Date());  

}  

可以直达相同的意义。好处是您得方便使用不同的filter了。

4.5.2 ng的嵌入过滤器

ng内置了九种过滤器,使用方法还非常简单,看文档即懂。不过为以后不失翻她的文档,我以此间还是开一个详尽的记录。

currency(货币)、date(日期)、filter(子串匹配)、json(格式化json对象)、limitTo(限制个数)、lowercase(小写)、uppercase(大写)、number(数字)、orderBy(排序)

  1. currency (货币处理)

  使用currency可以拿数字格式化为货币,默认是美元符号,你得自己传所欲的符号,例如我传入人民币:

{{num | currency : ‘¥’}}  

  1. date (日期格式化)

  原生的js对日期的格式化能力有限,ng提供的date过滤器基本得以满足一般的格式化要求。用法如下:

{{date | date : ‘yyyy-MM-dd hh:mm:ss EEEE’}}  

参数用来指定所设之格式,y M d h m s E 分别代表 年 月 日 时 分 秒
星期,你可以自由组合它们。也堪行使不同之个数来界定格式化的位数。另外参数为得下一定的描述性字符串,例如“shortTime”将会管时光格式为12:05
pm这样的。ng提供了八种描述性的字符串,个人觉得这些小多余,我了可以依据自己之愿望组合产生想如果的格式,不甘于失去记这么多单词~

  1. filter(匹配子串)

  这个名为filter的filter。用来拍卖一个屡屡组,然后可以过滤出含有某个子串的因素,作为一个子数组来回到。可以是字符串数组,也可以是目标往往组。如果是目标往往组,可以兼容配属性的价值。它接受一个参数,用来定义子串的匹配规则。下面举个例证说明一下参数的用法,我于是现时特别生气的几个子女定义了一个数组:

$scope.childrenArray = [

        {name:’kimi’,age:3},

        {name:’cindy’,age:4},

        {name:’anglar’,age:4},

        {name:’shitou’,age:6},

        {name:’tiantian’,age:5}

];

$scope.func = function(e){return e.age>4;}{{ childrenArray | filter :
‘a’ }} //匹配属性值中含有a的

{{ childrenArray | filter : 4 }}  //匹配属性值中寓4底

{{ childrenArray | filter : {name : ‘i’} }}
//参数是目标,匹配name属性中含有i的

{{childrenArray | filter : func }} 
//参数是函数,指定返回age>4底  

  1. json(格式化json对象)

  json过滤器可以将一个js对象格式化为json字符串,没有参数。这东西有什么用啊,我一般为非会见于页面上输出一个json串啊,官网说她可以为此来开展调试,嗯,是只对的抉择。或者,也得用当js中采用,作用就是跟咱们耳熟能详的JSON.stringify()一样。用法超级简单:

{{ jsonTest | json}}

  1. limitTo(限制数组长度要字符串长度)

  limitTo过滤器用来截取数组或字符串,接收一个参数用来指定截取的尺寸,如果参数是负值,则由数组尾部开始截取。个人觉得这filter有点鸡肋,首先只能由数组或字符串的开头/尾部进行截取,其次,js原生的函数就足以代表它了,看看怎么用吧:

{{ childrenArray | limitTo : 2 }}  //将会显示数组中的前片项  

  1. lowercase(小写)

  把多少转发为全体大写。太简单了,不多讲。同样是可怜鸡肋的一个filter,没有参数,只能管任何字符串变为小写,不克指定字母。怎么用自都懒得写了。

  1. uppercase(大写)

  同上。

  1. number(格式化数字)

  number过滤器可以呢一个数字增长千位分割,像这样,123,456,789。同时接收一个参数,可以指定float类型保留几各小数:

{{ num | number : 2 }}  

  1. orderBy(排序)

  orderBy过滤器可以拿一个数组中之素进行排序,接收一个参数来指定排序规则,参数可以是一个字符串,表示因该属性名称进行排序。可以是一个函数,定义排序属性。还足以是一个频组,表示依次以数组中之属于性值进行排序(若仍第一起于的价值当,再比如次件于),还是将点的子女数组举例:

<div>{{ childrenArray | orderBy : ‘age’ }}</div>     
//按age属性值进行排序,若是-age,则倒序

<div>{{ childrenArray | orderBy : orderFunc }}</div>  
//按照函数的回来值进行排序

<div>{{ childrenArray | orderBy : [‘age’,’name’] }}</div> 
//如果age相同,按照name进行排序  内置的过滤器介绍了了,写的自都急忙睡着了。。。正而您所看到的,ng内置的过滤器也并无是全能的,事实上好多都较鸡肋。更个性化的需便待我们来定义自己之过滤器了,下面来探哪由定义过滤器。
4.5.3自定义过滤器及示范

  filter的自定义方式吗甚简短,使用module的filter方法,返回一个函数,该函数接收

输入值,并返处理后底结果。话不多说,我们来形容一个望。比如我欲一个过滤器,它可回到一个数组中下标为奇数的元素,代码如下:

app.filter(‘odditems’,function(){

    return function(inputArray){

        var array = [];

        for(var i=0;i<inputArray.length;i++){

            if(i%2!==0){

                array.push(inputArray[i]);

            }

        }

        return array;

    }

});  

格式就是这么,你的拍卖逻辑就是形容在里头的非常闭包函数中。你啊得叫投机的过滤器接收参数,参数就定义在return的充分函数中,作为第二个参数,或者另行多只参数为足以。

自定义过滤器实例(例04):

/* View html */

First name:<input ng-model=”user.firstName”/><br/>

Last  name:<input ng-model=”user.lastName”/> <br/>

First name:{{user.firstName}}      Last  name:{{user.lastName}}
<br/>

Fullname:{{user | flFullname}}<br/>

Fullname:{{user | flFullname:”-”}}<br/>

Fullname:{{user | flFullname:”•” | uppercase }}

/* Controller js */

demoApp.filter(“flFullname”, function() {

    return function(user, sep) {

        sep = sep || ” “;

        user = user || {};

        fullName = “”;

        if(user.firstName){fullName += user.firstName;}

        if(user.lastName){fullName = fullName + sep + user.lastName;}

        if(fullName && fullName.length>0){return fullName;

        }else{return “”;}

    };

});

4.6指令(directive)

  通过以模板,我们可以把model和controller中之数目组装起呈现为浏览器,还足以经过数量绑定,实时更新视图,让咱们的页面变成动态的。

  模板被可应用的东西包括以下四种:

1.发令(directive):ng提供的要么从定义的竹签以及性质,用来加强HTML表现力;

2.号(markup):即双大括声泪俱下{{}},可拿数据单向绑定到HTML中;

3.过滤器(filter):用来格式化输出数据;

4.表单控制:用来增进表单的求证功能。

里头,指令的是使用量最充分的,ng内置了过多命用来支配模板,如ng-repeat,ng-class,也时有发生许多命令来救助你做到业务逻辑,如ng-controller,ng-model。

令的几种下方式如下:

l 作为标签:<my-dir></my-dir>

l 作为性能:<span my-dir=”exp”></span>

l 作为注释:<!– directive: my-dir exp –>

l 作为类名:<span class=”my-dir: exp;”></span>

实际常用之即使是作为标签以及属性。
4.6.1体裁相关的命令

  既然模板就是屡见不鲜的HTML,那自己根本关注的哪怕是体制的支配,元素的恒、字体、背景色等等如何得以活决定。下面来瞧常用的体控制指令。

  1. ng-class

   ng-class用来受元素绑定类名,其表达式的返回值可以是以下三种植:

l 类名字符串,可以为此空格分割多个类名,如’redtext boldtext’;

l 类名数组,数组中之各级一样件都见面层叠起来生效;

l
一个名值对应的map,其键值为类名,值也boolean类型,当值为true时,该类会叫加在要素上。

  下面来拘禁一个采取map的例证:

ng-class测试

红色 加粗 删除线

map:{redtext:{{red}}, boldtext:{{bold}}, striketext:{{strike}}}

  如果你想拼接一个类名出来,可以行使插值表达式,如:

  <div class=”{{style}}text”>字体样式测试</div>

  然后在controller中指定style的值:

  $scope.style = ‘red’;

  注意自己为此了class而未是ng-class,这是未得以对换的,官方的文档也未举行证明,姑且认为就是ng的语法规则吧。

  与ng-class相近的,ng还提供了ng-class-odd、ng-class-even两单指令,用来配合ng-repeat分别在奇数列和偶数列下相应之好像。这个用来当报表中实现隔行换色再便宜可了。

  1. ng-style

  ng-style用来绑定元素的css样式,其表达式的返回值为一个js对象,键也css样式名,值也该体对应的官取值。用法比较简单:

<div ng-style=”{color:’red’}”>ng-style测试</div>

<div ng-style=”style”>ng-style测试</div>

$scope.style = {color:’red’};  

  1. ng-show,ng-hide

   对于比较常用之元素显隐控制,ng也举行了打包,ng-show和ng-hide的价也boolean类型的表达式,当值为true时,对应的show或hide生效。框架会因此display:block和display:none来支配元素的显隐。

4.6.2表单控件功能有关指令

  对于常用之表单控件功能,ng也开了包,方便灵活决定。

  ng-checked控制radio和checkbox的当选状态

  ng-selected控制下拉绳的当选状态

  ng-disabled控制失效状态

  ng-multiple控制多选择

  ng-readonly控制就念状态

  以上命令的取值均为boolean类型,当值为true时相关状态生效,道理比较简单就无多开说明。注意:
上面的这些不过是只为绑定,即只是于数到模板,不能够反作用被数据。要双向绑定,还是要以
ng-model 。

4.6.3轩然大波绑定相关指令

事件绑定是javascrpt中于重要的相同部分情节,ng对是吧做了详实的包裹,正如我们前以了之ng-click一样,事件之命令如下:

ng-click

  ng-change

  ng-dblclick

  ng-mousedown

  ng-mouseenter

  ng-mouseleave

  ng-mousemove

  ng-mouseover

  ng-mouseup

  ng-submit

  事件绑定指令的取值为函数,并且要加上括号,例如:

<select ng-change=”change($event)”></select>  

接下来于controller中定义如下:

$scope.change = function($event){

         alert($event.target);

         //……………………

}  

当模板被可就此变量$event将事件目标传递到controller中。

对ng的这种规划,一些人有所质疑,视图与事件绑定混在联名到底好不好?我们无是若尊重视图与逻辑分离也?如此一来,把事件之绑定以换扭了内联的,岂不是历史的落后。我呢一样对这个表示不脱,因为未写onclick已经重重年。。。但既然已经在了,我们不妨向合理的主旋律上惦记同一纪念,或许ng的设计者压根就是非思给模板成为单纯的视图层,本来就是想提高HTML,让其发出少数政工能力。这么想的言辞似乎也克想通,好吧,先骗一下祥和吧~

4.6.4特殊的ng-src和ng-href

在认证及时有限个指令的非常规之前,需要先了解一下ng的开行和实施进程,如下图:

 

1) 浏览器加载静态HTML文件并分析为DOM;

  2) 浏览器加载angular.js文件;

  3) angular监听DOMContentLoaded 事件,监听到开始启动;

  4) angular寻找ng-app指令,确定作用范围;

  5) 找到app中定义之Module使用$injector服务开展依赖注入;

  6) 根据$injector服务创建$compile服务用于编译;

  7) $compile服务编译DOM中之指令、过滤器等;

  8) 使用ng-init指令,将作用域中之变量进行调换;

  9) 最后生成了我们在最后视图。

  可以看,ng框架是当DOMcontent加载完毕后才开发挥作用。假如我们模板被来平等摆图纸如下:

  <img src=”http://m.cnblogs.com/142260/”{{imgUrl}}” />

  那么当页面开始加载到ng编译完成前,页面上会见一直亮同一张错误的图纸,因为路{{imgUrl}}还无为轮换。

  为了避免这种场面,我们运用ng-src指令,这样以路为科学得到之前就无会见显示搜不顶图片。同理,<a>标签的href属性也得换成ng-href,这样页面上便未会见优先出现一个地址错误的链接。

顺着这个思路再多思量一些,我们当模板被采用{{}}显示数据经常,在ng编译完成前页面上怎么不是会显示有大括号及里面的表达式?确实是这么。为了避免这,ng中生一个跟{{}}等同的吩咐:ng-bind,同样用于单为绑定,在页面刚加载的早晚便不见面显示出对用户无用的数量了。尽管这样你也许不仅仅没有舒心反而还纠结了,{{}}那么好用善亮,还无可知为此了无化?好信息是我们还是得以下。因为自修的凡单页面应用,页面才见面当加载index.html的时

候出这个题目,只需要以index.html中之模板被换成ng-bind就尽。其他的模板是咱动态加载的,就好放心使用{{}}了。

4.6.5 自定义指令示例

脚我们来分析下命令的例证(例07)。

1.第一,我们定义一个曰吧userInfo的命:

demoApp.directive(‘userInfo’,function(){

return {

        restrict : ‘E’,

        templateUrl : ‘userInfoTemplate.html’,

        replace : true,

        transclude : true,

        scope : {

            mytitle : ‘=etitle’

        },

        link : function(scope,element,attrs){

            scope.showText = false;

            scope.toggleText = function(){

                scope.showText = ! scope.showText;

            }

        }

    };

})  

Restrict也’E’:用作标签;replace为true:用模板替换当前签;transclude为true:将眼前因素的情节转移至模板被;scope
为 {mytitle :
‘=etitle’}:定义一个叫吧mytitle的MODEL,其值指向当前因素的etitle属性;templateUrl为’userInfoTemplate.html’:模板内容也ng-template定义ID为userInfoTemplate.html的情节;link:指定所涵盖的行为。其现实的征跟其余参数,请参见:6.2发令详解。

  1. userInfoTemplate.html模板为:

<script type=”text/ng-template” id=”userInfoTemplate.html”>

<div class=”mybox”>

<div class=”mytitle” style=”cursor: pointer;”
ng-click=”toggleText()”>

{ {mytitle} }

</div>

<div ng-transclude ng-show=”showText”>

</div>

</div>

</script>

将手上因素的情节补充加到有ng-transclude属性的这个DIV下,默认是隐藏的。

3.Controller信息:

demoApp.controller(“test7Controller”, function($scope){

$scope.title = ‘个人简介’;

$scope.text = ‘大家好,我在研究AngularJs,欢迎大家和自身交流。’;

$scope.updateInfo = function (){

$scope.title = ‘个人信息’;

$scope.text = ‘大家好,今天天气真好!’;

}

});

4.命下办法(View信息)为:

<user-info etitle=”title”>{ {text} }</user-info>

Etitle指向Controller中之$scope.title。注意命名方式:指令称吧userInfo,对应之签吗user-info。

4.7服务(service)
4.7.1劳动介绍

  服务这定义其实并无生,在任何语言中如java便产生如此的定义,其作用就是是对外提供有特定的效果,如信息服务,文件减少服务等,是一个独的模块。ng的劳务是如此定义之:

Angular services are singletons objects or functions that carry out
specific tasks common to web apps.

她是一个单例对象要函数,对外提供特定的功力。

首先是一个单例,即无论这个服务让注入到其他地方,对象始终就来一个实例。

副这同我们温馨定义一个function然后每当其他地方调用不同,因为劳动让定义在一个模块中,所以该利用限制是好叫我们管理之。ng的避免全局变量污染意识很大。

  ng提供了成百上千搭的服务,可以到API中翻http://docs.angularjs.org/api/。知道了概念,我们来拉一个service出来溜溜,看看到底是个什么用法。  

  我们以controller中一直声明$location服务,这仗ng的指注入机制。$location提供地方栏相关的劳务,我们以此只是简短的得当前底地点。

  服务之施用是这般概括,我们得以把服务注入到controller、指令或是另外服务遭遇。
4.7.2从定义服务

  如同指令一样,系统放的劳动为$开头,我们呢得友善定义一个劳务。定义服务的道发生如下几栽:

l 使用系统内置的$provide服务;

l 使用Module的factory方法;

l 使用Module的service方法。

  下面通过一个略例子来分别考瞬间。我们定义一个称呼吧remoteData服务,它可以从远程获取数据,这为是咱们当程序中不时以的效能。不过自己这里没有远程服务器,就形容好一点数码模拟一下。

//使用$provide来定义

var app = angular.module(‘MyApp’, [], function($provide) {

    $provide.factory(‘remoteData’, function() {

 var data = {name:’n’,value:’v’};

        return data;

    });

});

//使用factory方法

app.factory(‘remoteData’,function(){

    var data = {name:’n’,value:’v’};

    return data;

});

//使用service方法

app.service(‘remoteData’,function(){

    this.name = ‘n’;

    this.value = ‘v’;

});

Module的factory和$provide的factory方法是一样型一样的,从官网文档看她其实就是是平掉事。至于Module内部是怎么样调用的,我这边并无打算追究,我若知道怎么用就哼了。

更看Module的service方法,它从不return任何事物,是因service方法本身返回一个构造器,系统会自行使用new关键字来创造有一个靶。所以我们看看在结构器函数内可以动用this,这样调用该服务的地方即可直接通过remoteData.name来访问数了。
4.7.3管制服务的指关系

  服务以及劳务当中可以生出赖关系,例如我们这边定义一个曰也validate的劳务,它的打算是说明数据是否合法,它用靠我们从远程获取数据的劳动remoteData。代码如下:

  
以factory的参数中,我们好一直传入服务remoteData,ng的赖注入机制就拉咱做好了另干活。不过早晚要保证这参数的名号与劳务号相同,ng是根据名称来识别的。若参数的名次与服务号不均等,你不怕必出示的扬言一下,方式如下:

app.factory(‘validate’,[‘remoteData’,function(remoteDataService){

    return function(){

        if(remoteDataService.name==’n’){

            alert(‘验证通过’);

        }

    };

}]);  

我们以controller中流入服务为是一模一样的理,使用的名需要与劳务号相同才得是注入。否则,你要采用$inject来手动指定注入的劳动。比如:

function testC(scope,rd){

    scope.getData = function(){

        alert(‘name:’+rd.name+’   value:’+rd.value);

    }

}

testC.$inject = [‘$scope’,’remoteData’];

 

  于controller中注入服务,也可以以定义controller时使用数组作为第二只参数,在此处

将劳务注入进来,这样于部数体中应用非一样的服务号为是可以的,不过假如保证注入的依次是同一的,如:

app.controller(‘testC’,[‘$scope’,’remoteData’,function($scope,rd){

    $scope.getData = function(){

        alert(‘name:’+rd.name+’   value:’+rd.value);

    }

}]);
4.7.4 自定义服务示范

属下让咱们看下例子(例08 自定义服务)代码,自定义userService服务:

demoApp.factory(‘userService’, [‘$http’, function($http) {

var doGetUser = function(userId, path) {

//return $http({

//method: ‘JSONP’,

//url: path

//});

/*手动指定数量*/

var data =
{userId:”woshishui”,userName:”我是谁”,userInfo:”我是谁!我是谁!”};;

if(userId==’zhangsan’){

data =
{userId:”zhangsan”,userName:”张三”,userInfo:”我是张三,我为温馨”};

}else if(userId==’lisi’){

data =
{userId:”lisi”,userName:”李四”,userInfo:”我是李四,我哉你狂!”};

}

return data;

}

return {

/*userService对外暴露的函数,可生多只*/

getUser: function(userId) {

return doGetUser(userId, ‘../xxx/xxx.action’);

}

};

}]);

咱俩创建了一个就生一个计的userService,getUser为者服务由后台获取用户信息之函数,并且对外暴露。当然,由于当时是一个静态的例子,无法访问后台,那么我们即便制定该归来的数。

然后我们把这个服务丰富到我们的controller中。我们树立一个controller并加载(或者注入)userService作为运行时因,我们将service的讳作参数传递给controller
函数:

demoApp.controller(“test8Controller”, function($scope,userService){

/*章信息*/

$scope.articles = [{

title : “爱飞像风”,

userId : “zhangsan”,

userName : “张三”

},{

title : “无法停止的冰暴”,

userId : “lisi”,

userName : “李四”

}];

$scope.showUserInfo = false;//显示作者详细信息开关

$scope.currentUser = {}; //当前选中之撰稿人

$scope.getUserInfo = function(userId){

$scope.currentUser = userService.getUser(userId);

//调用 userService的getUser函数

$scope.showUserInfo = true;

setTimeout(function(){//定时器:隐藏作者详细信息

$scope.showUserInfo = false;

},3000);

}

});

咱们的userService注入到我们的test8Controller后,我们就算可像以其他服务(我们面前提到的$http服务)一样的利用userService了。

连锁的HTML代码如下:

/* View HTML*/

<tr ng-repeat=”article_ in articles”>

<td>

{{article_.title}}

</td>

<td>

<a href=”javascript:void(0);” target=”_blank” rel=”nofollow”>

</td>

</tr>

……

<div ng-show=”showUserInfo”>

用户ID:{{currentUser.userId}}<br/>

用户名:{{currentUser.userName}}<br/>

用户简介:{{currentUser.userInfo}}<br/>

</div>

4.8依注入DI

通过依赖注入,ng想使强调一种声明式的开发方式,即当我们需要使用某个一样模块或服务经常,不欲关爱是模块内部如何贯彻,只需要声明一下哪怕可行使了。在多处采用就待进行频繁声明,大大提高可复用性。

  比如我们的controller,在概念之时光用到一个$scope参数。

app.controller(‘testC’,function($scope){});  

设若我们当此地还亟需操作其他的物,比如同浏览器地址栏进行交互。我们唯有需要再多添

一个参数$location进去:

app.controller(‘testC’,function($scope,$location){});  

如此这般即便可由此$location来跟地方栏进行互动了,我们特是声称了瞬间,所急需的别样代码,框架已经帮咱注入了。我们大明朗的发到了是函数已经休是例行意义上的javascript函数了,在健康的函数中,把形参换一个名依然可以运作,但每当此处设把$scope换成别的讳,程序即使不能够运作了。因为当时是曾定义好之劳动号。

当时虽是指注入机制。顺理成章的推断,我们好自己定义模块和劳动,然后在用的地方进行宣示,由框架来替我们注入。

来拘禁下我们怎样定义一个劳动:

app.factory(‘tpls’,function(){

    return [‘tpl1′,’tpl2′,’tpl3′,’tpl4’];

});  

看上去相当简单,是坐自己在此处只有是直归一个数组。在其实采用中,这里当是索要为服务器发起一个要,来赢得到这些模板们。服务之概念方式发生一些种植,包括运用provider方法、使用factory方法,使用service方法。它们之间的分暂且不关心。我们现在如能创造一个劳务出来就是得了。我利用了factory方法。一个用注意的地方是,框架提供的服务名字还是出于$开头的,所以我们团结定义的最好不要用$开头,防止有命名冲突。

概念好一个劳务后,我们就算可当控制器中声明使用了,如下:

app.controller(‘testC’,function($scope,tpls){

    $scope.question = questionModel;

    $scope.nowTime = new Date().valueOf();

    $scope.templates = tpls; //赋值到$scope中

    $scope.addOption = function(){

        var o = {content:”};

        $scope.question.options.push(o);

    };

    $scope.delOption = function(index){

        $scope.question.options.splice(index,1);

    };

});  

这,若于模板被修如下代码,我们虽可博到劳动tpls所提供的数了:

模板:

<a href=”javascript:void(0);” target=”_blank” rel=”nofollow”>

4.9路由(route)

以谈路出于体制面前发必不可少先提取一下现比盛行的单页面应用,就是所谓的single
page
APP。为了落实无刷新的视图切换,我们司空见惯会就此ajax请求于后台取多少,然后套及HTML模板渲染在页面上,然而ajax的一个沉重缺陷就是是致浏览器后降落按钮失效,尽管我们得当页面及拓宽一个大大的归来按钮,让用户点击返回来导航,但连接无法避免用户习惯性的点后退。解决是题材的一个法是下hash,监听hashchange事件来拓展视图切换,另一个道是为此HTML5的history
API,通过pushState()记录操作历史,监听popstate事件来拓展视图切换,也有人拿立即给pjax技术。基本流程如下:

如此一来,便形成了经过地方栏进行导航的深链接(deeplinking
),也就是咱所要之路由机制。通过路由机制,一个单页应用之一一视图就足以生好之团组织起了。

4.9.1 ngRoute内容

  ng的路由机制是负ngRoute提供的,通过hash和history两种办法贯彻了路由,可以检测浏览器是否支持history来灵活调用相应的措施。ng的路由(ngRoute)是一个独的模块,包含以下内容:

l 服务$routeProvider用来定义一个路由表,即地址栏与视图模板的炫耀

l 服务$routeParams保存了地址栏中的参数,例如{id : 1, name : ‘tom’}

l
服务$route完成行程由于相当,并且提供路由相关的性能访问同波,如访问时路由对应之controller

l 指令ngView用来当主视图备受指定加载子视图的区域

 以上内容还长$location服务,我们便好实现一个单页面应用了。下面来拘禁一下切实如何使这些情节。

4.9.2 ng的路由机制

  第一步:引入文件和靠

  ngRoute模块包含在一个独的文件被,所以首先步用以页面上引入这文件,如下:

<script src=”http://code.angularjs.org/1.2.8/angular.min.js”
rel=”nofollow”/>

<script src=”http://code.angularjs.org/1.2.8/angular-route.min.js”
rel=”nofollow”/>  

无非引入还不够,我们尚待于模块声明遭流入对ngRoute的赖,如下:

var app = angular.module(‘MyApp’, [‘ngRoute’]);  

完成了这些,我们就是可以模板或是controller中使用方面的劳务同指令了。下面我们用定义一个路由表。

  第二步:定义路由表

  $routeProvider提供了概念路由表的劳务,它产生少单主导措施,when(path,route)和otherwise(params),先押一下中心中的主导when(path,route)方法。

  when(path,route)方法接收两独参数,path是一个string类型,表示该修路由于规则所匹配的门径,它将跟地址栏的始末($location.path)值进行匹配。如果需要相当参数,可以当path中动用冒号加名的方,如:path为/show/:name,如果地址栏是/show/tom,那么参数name和所对应之值tom便会为保存在$routeParams中,像这么:{name
:
tom}。我们也足以为此*进行模糊匹配,如:/show*/:name将匹配/showInfo/tom。

  route参数是一个object,用来指定当path匹配后所欲的如出一辙雨后春笋安排起,包括以下内容:

l controller
//function或string类型。在脚下模板上推行之controller函数,生成新的scope;

l controllerAs //string类型,为controller指定别名;

l template
//string或function类型,视图z所用底模板,这部分情节将为ngView引用;

l templateUrl
//string或function类型,当视图模板也独立的html文件或者使用了<script
type=”text/ng-template”>定义模板时利用;

l resolve //指定当前controller所依赖的任何模块;

l redirectTo //重定向的地址。

极端简便易行情况,我们定义一个html文件为模板,并初始化一个点名的controller:

function emailRouteConfig($routeProvider){

    $routeProvider.when(‘/show’, {

        controller: ShowController,

        templateUrl: ‘show.html’

    }).

    when(‘/put/:name’,{

       controller: PutController,

       templateUrl: ‘put.html’

    });  

};  

otherwise(params)方法对许路径匹配不至常之事态,这时候我们可以配备一个redirectTo参数,让它们重定向到404页面或者是首页。

  第三步:在主视图模板被指定加载子视图的位置

  我们的单页面程序还是局部刷新的,那这“局部”是何吧,这就轮至ngView出马了,只需要于模板被简易的应用此命令,在何用,哪里就是“局部”。例如:

<div
ng-view></div>  或:<ng-view></ng-view>  

我们的子视图将会晤以此为引入进来。完成就三步后,你的顺序的路由就配置好了。

4.9.3 路由于示例

下我们拿因此一个例证(例09)来说明路由于的利用方式跟步骤:

1.啊demoApp添加一个路由,代码如下:

demoApp.config([‘$routeProvider’,function($routeProvider) {  

$routeProvider.when(‘/list’, {  

templateUrl: ‘route/list.html’,  

  controller: ‘routeListController’

}).when(‘/list/:id’, {  

  templateUrl: ‘route/detail.html’,

   controller: ‘routeDetailController’

  }).otherwise({  

        redirectTo: ‘/list’  

     });  

}]);

/list
对诺为:route/list.html页面,显示用户列表;/list/:id对许为route/detail.html页面,显示用户详细信息。

2.为list.html和detail.html分别声明Controller:routeListController和routeDetailController。

demoApp.controller(‘routeListController’,function($scope) {  

$scope.users =
[{userId:”zhangsan”,userName:”张三”,userInfo:”我是张三,我也团结带盐!”},

{userId:”lisi”,userName:”李四”,userInfo:”我是李四,我耶卿狂!”},

{userId:”woshishui”,userName:”我是谁”,userInfo:”我是谁!我是谁!我是谁!”}];

 

});  

demoApp.controller(‘routeDetailController’,function($scope,
$routeParams, userService) {  

    $scope.userDetail = userService.getUser($routeParams.id);

});

routeDetailController中要上面提到的一模一样,注入了userService服务,在此地一直用来用。

3.创list.html和detail.html页面,代码如下:

<hr/>  

<h3>Route : List.html(用户列表页面)</h3>  

<ul>  

<li ng-repeat=”user in users”>  

      <a
href=”http://m.cnblogs.com/142260/3817063.html?full=1\#/list/{{
user.userId }}” target=”_blank” rel=”nofollow”>

</li>  

</ul>

<hr/>

 

<h3>Route : detail.html(用户详细信息页面)</h3>  

<h3>用户名:<span style=”color:
red;”>{{userDetail.userName}}</span></h3>

<div>

<span>用户ID:{{userDetail.userId}}</span><span>用户名:{{userDetail.userName}}</span>

</div>

<div>

用户简介:<span>{{userDetail.userInfo}}</span>

</div>

<div>

<a href=”http://m.cnblogs.com/142260/3817063.html?full=1\#/list”
target=”_blank” rel=”nofollow”>返回</a>  

</div>

  1. 程由于片刷新位置:

<h1>AngularJS路由(Route) 示例</h1>  

<div ng-view></div>

4.10 NG动画效果

4.10.1 NG动画效果简介

NG动画效果,现在可由此CSS3或者是JS来兑现,如果是经过JS来贯彻的话,需要另JS库(比如JQuery)来支撑,实际上底层实现还是赖其他JS库,只是NG将该包装了,

如若其再爱用。

NG动画效果包含以下几栽:

    enter:元素添加到DOM中时实施动画;
    leave:元素于DOM删除时实施动画;
    move:移动元素时实施动画;
    beforeAddClass:在吃元素添加CLASS之前实施动画;
    addClass:在受元素添加CLASS时实行动画;
    beforeRemoveClass:在叫元素删除CLASS之前实施动画;
    removeClass:在吃元素删除CLASS时实施动画。

其二休戚相关参数为:

var ngModule = angular.module(‘YourApp’, [‘ngAnimate’]);

  demoApp.animation(‘.my-crazy-animation’, function() {

return {

   enter: function(element, done) {

  //run the animation here and call done when the animation is
complete

        return function(cancelled) {

          //this (optional) function will be called when the animation

          //completes or when the animation is cancelled (the
cancelled

          //flag will be set to true if cancelled).

        };

      },

      leave: function(element, done) { },

      move: function(element, done) { },

      //animation that can be triggered before the class is added

      beforeAddClass: function(element, className, done) { },

      //animation that can be triggered after the class is added

      addClass: function(element, className, done) { },

      //animation that can be triggered before the class is removed

      beforeRemoveClass: function(element, className, done) { },

      //animation that can be triggered after the class is removed

      removeClass: function(element, className, done) { }

    };

  });
4.10.2 动画作用示例

下面我们来拘禁下DEMO中之事例(例10)。

1.率先,我们于demoApp下定义一个动画片效果,匹配CLASS:”
.border-animation”

/*概念动画*/

demoApp.animation(‘.border-animation’, function(){

return{

beforeAddClass : function (element, className, done) {

$(element).stop().animate({

‘border-width’:1

},2000, function() {

done();

});

},

removeClass : function (element ,className ,done ) {

$(element).stop().animate({

‘border-width’:50

},3000, function() {

done();

});

}

};

});

卡通效果的含义就是是:在匹配CLASS为border-animation的因素添加一个CLASS之前若其边框的增幅在2秒内成为1PX;并在那个移除一个CLASS时要该边框的小幅在3秒内化为50PX。

  1. 视图中之代码如下(主要,其他有关样式请查看例子代码):

<div class=”border-animation” ng-show=”testShow”></div>

<a href=”javascript:void(0);” target=”_blank” rel=”nofollow”>

ng-show为false时会见呢其长“ng-hide“的CLASS;
ng-show为true时会为该移除“ng-hide“的CLASS,从而触发动画作用。

3.其它代码:

demoApp.controller(“test10Controller”, function($scope, $animate){

$scope.testShow = true;

});

5 功能演示

些微(详情请看AngularJS/demo WEB演示)

6 AngularJS进阶

6.1数据绑定原理研究

Angular用户还惦记了解数码绑定是怎么落实的。你或许会见看各式各样的词汇:$watch、$apply、$digest、dirty-checking…它们是啊?它们是哪行事之为?这里我想对这些题目,其实它们以官方的文档里还已经回了,但是本人或想念管其了合在一起来讲,但是自只是用同一种简易的方式来讲课,如果假定惦记询问技术细节,查看源代码。

6.1.1 AngularJS扩展事件循环

咱们的浏览器一直当等候事件,比如用户交互。假如你点击一个按钮或者当输入框里输入东西,事件的回调函数就见面以javascript解释器里行,然后你虽可做其他DOM操作,等回调函数执行完毕时,浏览器就会相应地针对DOM做出变化。(记住,这是独重要的定义),为了诠释啊是context以及她什么做事,我们尚需讲又多的定义。

6.1.2 $watch 队列

每次你绑定一些物至您的DOM上经常若就算见面向$watch队列里插入一长长的$watch。想象一下$watch就是老大可以检测她监视的model里时刻来转移之东西。例如你生如下的代码:

/*View  index.html */

User: <input type=”text” ng-model=”user” />

Password: <input type=”password” ng-model=”pass” />

每当此间我们发出只$scope.user,他受绑定以了第一单输入框上,还生个$scope.pass,它给绑定在了亚个输入框上,然后我们在$watch
list里面在两只$watch。

再度拘留下的例子:

/*Controller  controllers.js */

app.controller(‘MainCtrl’, function($scope) {

   $scope.foo = “Foo”;

   $scope.world = “World”;

});

/*View  index.html */

Hello, {{ World }}

此间,即便我们当$scope上添加了少于个东西,但是偏偏发一个绑定以了DOM上,因此当此地仅生成了一个$watch。

还拘留下面的例证:

/*Controller  controllers.js */

app.controller(‘MainCtrl’, function($scope) {

  $scope.people = […];

});

/*View  index.html */

<ul>

  <li ng-repeat=”person in people”>

      {{person.name}} – {{person.age}}

  </li>

</ul>

这边还要变更了稍稍只$watch呢?每个person有点儿独(一个name,一个age),然后ng-repeat又产生一个,因此10单person一共是(2
* 10) +1,也就是说有21个$watch。

从而,每一个绑定到了DOM上的数目还见面变卦一个$watch。

这就是说这写$watch是什么时别的也?

当我们的沙盘加载了时,也尽管是当linking阶段(Angular分为compile阶段及linking阶段),Angular解释器会找每个directive,然后生成每个需要的$watch。
6.1.3 $digest循环

还记得自己眼前提到的扩张的事件循环呢?当浏览器接收至得被angular
context处理的波频仍,$digest循环就见面触发。这个轮回是由简单只更小之大循环组合起来的。一个甩卖evalAsync队列,另一个处理$watch队列。
这个是处理啊的吗?$digest将会遍历我们的$watch,然后询问:

•嘿,$watch,你的价是呀?

◦是9。

•好之,它改变过为?

◦没有,先生。

•(这个变量没换了,那下一个)

•你吧,你的价值是稍稍?

◦报告,是Foo。

•刚才改变了并未?

◦改变过,刚才是Bar。

•(很好,我们发出DOM需要创新了)

•继续探听直到$watch队列都检查过。

马上就是所谓的dirty-checking。既然有的$watch都检查结束了,那就算假设咨询了:有没有产生$watch更新过?如果生至少一个更新了,这个轮回就会见再接触,直到所有的$watch都尚未生成。这样虽可知确保每个model都早已不见面再度变更。记住要循环超过10不善的说话,它将会晤丢弃来一个不行,防止无限循环。当$digest循环结束时,DOM相应地变化。

例如:

/*Controller  controllers.js */

app.controller(‘MainCtrl’, function() {

  $scope.name = “Foo”;

  $scope.changeFoo = function() {

      $scope.name = “Bar”;

  }

});

/*View  index.html */

{{ name }}

<button ng-click=”changeFoo()”>Change the name</button>

此处我们出一个$watch因为ng-click不老成$watch(函数是勿会见变换的)。

咱得看来ng的处理流程:

•我们仍下按钮;

•浏览器接收至一个事变,进入angular context;

•$digest循环开始实施,查询每个$watch是否变动;

•由于监视$scope.name的$watch报告了转移,它会强制再实行同样涂鸦$digest循环;

•新的$digest循环没有检测到转;

•浏览器拿回控制权,更新与$scope.name新值相应部分的DOM。

此处特别要紧之是每一个进来angular
context的波还见面履行一个$digest循环,也就是说每次我们输入一个字母循环都见面检查全页面的有所$watch。

6.1.4什么入angular context

哪位说了算什么风波上angular context,而哪些又非进入呢?通过$apply!

如果当事件触发时,你调用$apply,它见面进angular
context,如果无调用就不见面进入。现在而或会见咨询:刚才底例证里自己也并未调用$apply啊,为什么?Angular已经召开了!因此若点击带有ng-click的元素时,时间纵会见吃装进到一个$apply调用。如果您产生一个ng-model=”foo”的输入框,然后您敲一个f,事件就是见面这样调用$apply(“foo
= ‘f’;”)。

Angular什么时候不会见活动吗我们$apply呢?

立马是Angular新手共同之苦难。为什么自己的jQuery不会见更新自己绑定的物啊?因为jQuery没有调用$apply,事件没进angular
context,$digest循环永远不曾履行。

咱们来拘禁一个幽默之事例:

假设我们发出脚是directive和controller。

/*Controller  app.js */

app.directive(‘clickable’, function() {

return {

  restrict: “E”,

  scope: {

    foo: ‘=’,

    bar: ‘=’

  },

  template: ‘<ul
style=”<li>{{foo}}</li><li>{{bar}}</li></ul>’,

  link: function(scope, element, attrs) {

    element.bind(‘click’, function() {

      scope.foo++;

      scope.bar++;

    });

  }

}

});

app.controller(‘MainCtrl’, function($scope) {

  $scope.foo = 0;

  $scope.bar = 0;

});

她以foo和bar从controller里绑定到一个list里面,每次点击是因素的时刻,foo和bar都见面自增1。那我们点击元素的当儿会来啊啊?我们能收看更新也?答案是否定的。因为点击事件是一个没包装到$apply里面的大规模的风波,这表示我们见面去我们的计数吗?不会见。

的确的结果是:$scope确实改变了,但是尚未强制$digest循环,监视foo
和bar的$watch没有实行。也就是说要我们好执行同样浅$apply那么这些$watch就见面映入眼帘这些变迁,然后根据需要创新DOM。

执行$apply:

element.bind(‘click’, function() {

scope.foo++;

  scope.bar++;

  scope.$apply();

});

$apply是咱们的$scope(或者是direcvie里的link函数中的scope)的一个函数,调用它见面强制一蹩脚$digest循环(除非当前正行循环,这种情况下会扔来一个可怜,这是咱不待以那边执行$apply的标志)。

又好之采取$apply的法门:

element.bind(‘click’, function() {

  scope.$apply(function() {

      scope.foo++;

      scope.bar++;

  });

})

出什么不等同的?差别就是于率先独本子被,我们是以angular
context的外更新的数量,如果产生产生误,Angular永远不懂得。很引人注目在斯像只稍玩具的例证中未会见发出什么特别摩,但是想象一下咱若发生个alert框显示错误被用户,然后我们发只第三着的库房开展一个大网调用然后失败了,如果我们无将她封装上$apply里面,Angular永远不会见清楚失败了,alert框就永远不会见弹出来了。

故此,如果你想用一个jQuery插件,并且使履$digest循环来更新您的DOM的话,要管您调用了$apply。

偶自己想多说一样句子之是稍微人当只能调用$apply时会“感觉不精”,因为他们见面看她们举行错了哟。其实不是这般的,Angular不是什么魔术师,他呢非明了老三正库想使创新绑定的数据。

6.1.5使用$watch来监视

公都清楚了咱们设置的别绑定都产生一个它自己的$watch,当需要经常更新DOM,但是我们而只要于定义自己之watches呢?简单,来拘禁个例子:

/*Controller  app.js */

app.controller(‘MainCtrl’, function($scope) {

  $scope.name = “Angular”;

  $scope.updated = -1;

  $scope.$watch(‘name’, function() {

    $scope.updated++;

  });

});

/*View  index.html*/

<body ng-controller=”MainCtrl”>

  <input ng-model=”name” />

  Name updated: {{updated}} times.

</body>

即便是咱创建一个初的$watch的道。第一独参数是一个字符串或者函数,在此地是独是一个字符串,就是咱而监视的变量的讳,在这里,$scope.name(注意我们就待

于是name)。第二单参数是当$watch说我监视的表达式发生变化后一旦执行的。我们要懂之首先宗事即使是当controller执行及者$watch时,它见面即时执行同样不良,因此我们安updated为-1。

例子2:

/*Controller  app.js */

app.controller(‘MainCtrl’, function($scope) {

  $scope.name = “Angular”;

  $scope.updated = 0;

  $scope.$watch(‘name’, function(newValue, oldValue) {

    if (newValue === oldValue) { return; } // AKA first run

    $scope.updated++;

  });

});

/*View  index.html*/

<body ng-controller=”MainCtrl”>

  <input ng-model=”name” />

  Name updated: {{updated}} times.

</body>

watch的次只参数接受两独参数,新值和旧值。我们可就此他们来小过第一次于的推行。通常你莫欲有些过第一差实施,但每当是事例里你是急需之。

例子3:

/*Controller  app.js */

app.controller(‘MainCtrl’, function($scope) {

  $scope.user = { name: “Fox” };

  $scope.updated = 0;

  $scope.$watch(‘user’, function(newValue, oldValue) {

    if (newValue === oldValue) { return; }

    $scope.updated++;

  });

});

/*View  index.html*/

<body ng-controller=”MainCtrl”>

  <input ng-model=”user.name” />

  Name updated: {{updated}} times.

</body>

咱们想只要监视$scope.user对象里的任何变更,和原先一样这里只是用一个目标来代表前面的字符串。

呃?没因此,为甚?因为$watch默认是较简单个目标所引用的是不是相同,在例子1以及2里面,每次变更$scope.name都见面创一个初的着力变量,因此$watch会执行,因为对这个变量的援已经变更了。在点的例证里,我们在监视$scope.user,当我们转移$scope.user.name时,对$scope.user的援是无会见变动之,我们只是每次创建了一个初的$scope.user.name,但是$scope.user永远是如出一辙的。

例子4:

/*Controller  app.js */

app.controller(‘MainCtrl’, function($scope) {

  $scope.user = { name: “Fox” };

 

  $scope.updated = 0;

 

  $scope.$watch(‘user’, function(newValue, oldValue) {

    if (newValue === oldValue) { return; }

    $scope.updated++;

  }, true  );

});

/*View  index.html*/

<body ng-controller=”MainCtrl”>

  <input ng-model=”user.name” />

  Name updated: {{updated}} times.

</body>

现行中了咔嚓!因为咱们本着$watch加入了第三单参数,它是一个bool类型的参数,表示的凡我们于的是目标的价如果不是援。由于当我们创新$scope.user.name时$scope.user也会转移,所以会科学触发。

6.1.6 总结

自我期望你们就学会了当Angular中多少绑定是怎工作之。我猜测你的第一印象是dirty-checking很缓慢,好吧,其实是畸形的。它像闪电一般快。但是,如果您于一个模板里出2000-3000独watch,它会开变慢。但是自己认为如果你达到这数量级,就足以搜索个用户体验专家发问一下了。

不管怎样,随着ECMAScript6的来,在Angular未来的版里我们以见面有Object.observe那样会大改善$digest循环的进度。

6.2起定义指令详解

angular的一声令下机制。angular通过指令的措施贯彻了HTML的扩张,增强后的HTML不仅助长相焕然一新,同时为取了众多无敌的技术。更决定的凡,你还得于定义指令,这就算表示HTML标签的限可扩大至无限大。angular赋予了若造物主的力量。既然是作angular的精髓之一,相应的吩咐相关的知识也不行多的。
6.2.1发令的编译过程

  以始发于定义指令之前,我们发出必不可少了解一下指令在框架中的执行流程:

1.浏览器得到 HTML 字符串内容,解析得到 DOM 结构。

2.ng 引入,把 DOM 结构扔给 $compile 函数处理:

① 找有 DOM 结构中起变量占位符;

② 匹配找来 DOM 中含有的备指令引用;

③ 把命关联到 DOM;

④ 关联到 DOM 的差不多独命以权重排列;

⑤ 执行令中之 compile 函数(改变 DOM 结构,返回 link 函数);

⑥ 得到的具有 link 函数组成一个列表作为 $compile 函数的返。

  1. 履 link 函数(连接模板的 scope)。

这边注意别一下$compile和compile,前者是ng内部的编译服务,后者是靠令中之编译函数,两者发挥作用的限定不一。compile和link函数息息相关又有所区别,这个当后头会讲。了解履行流程对后的知晓会时有发生帮扶。

于此处小人或会见咨询,angular不就是是一个js框架为,怎么还会和编译扯上吧,又非是比如说C++那样的高档语言。其实是编译非彼编译,ng编译的工作是分析指令、绑定监听器、替换模板被的变量等。因为做事法要命像高级语言编辑中之递归、堆栈过程,所以起名为编译,不要疑惑。
6.2.2下令的使用方法跟命名方式

  指令的几栽采取方法如下:

    作为标签:<my-dir></my-dir>
    作为性能:<span my-dir=”exp”></span>
    作为注释:<!– directive: my-dir exp –>
    作为类名:<span class=”my-dir: exp;”></span>

  其实常用的便是用作标签及特性,下面两栽用法即尚没有见了,感觉就是是为此来卖萌之,姑且留个印象。我们由定义之命令就要支持这样的用法。

有关从定义指令的命名,你可以不管怎么由名字都推行,官方是引进用[取名空间-指令名称]这样的方,像ng-controller。不过你只是绝对不要就此ng-前缀了,防止和网自带的命令重名。另外一个得了解的地方,指令命名时用驼峰规则,使用时用-分割各单词。如:定义myDirective,使用时像这么:<my-directive>。

6.2.3从定义指令的布参数

脚是概念一个正规指令的示范,可配置的参数包括以下部分:

myModule.directive(‘namespaceDirectiveName’, function
factory(injectables) {

        var directiveDefinitionObject = {

            restrict:
string,//指令的采取方法,包括标签,属性,类,注释

            priority: number,//指令执行之先期级

            template: string,//指令以的沙盘,用HTML字符串的样式表示

            templateUrl: string,//从指定的url地址加载模板

            replace:
bool,//是否就此模板替换当前因素,若为false,则append在脚下因素上

            transclude: bool,//是否用手上元素的情转移到模板被

            scope: bool or object,//指定指令的作用域

        controller: function controllerConstructor($scope, $element,
$attrs, $transclude){…},//定义跟任何指令进行互的接口函数

            require: string,//指定要借助之任何指令

link: function postLink(scope, iElement, iAttrs)
{…},//以编程的点子操作DOM,包

满载添加监听器等

            compile: function compile(tElement, tAttrs, transclude){

                return: {

                    pre: function preLink(scope, iElement, iAttrs,
controller){…},

                    post: function postLink(scope, iElement, iAttrs,
controller){…}

                }

            }//编程的法修改DOM模板的副本,可以回到链接函数

        };

        return directiveDefinitionObject;

});         

看起来好复杂的旗帜,定义一个令需要这样多步骤嘛?当然不是,你得因自己之内需来摘取下什么参数。事实上priority和compile用的比少,template和templateUrl又是轧的,两者选其一即可。所以不用紧张,接下去分别上一下这些参数:

l
指令的展现配置参数:restrict、template、templateUrl、replace、transclude;

l 指令的所作所为配置参数:compile和link;

l 指令划分作用域配置参数:scope;

l 指令中通信配置参数:controller和require。
6.2.3令的呈现参数restrict等

命的表现配置参数:restrict、template、templateUrl、replace、transclude。

自身拿优先打一个简单易行的事例开始。

    例子的代码如下:

var app = angular.module(‘MyApp’, [],
function(){console.log(‘here’)});

app.directive(‘sayHello’,function(){

return {

     restrict : ‘E’,

template : ‘<div>hello</div>’

};

})         

下一场于页面被,我们就算得行使这名为吧sayHello的指令了,它的意向就是是出口一个hello单词。像这么用:

<say-hello></say-hello>         

这样页面就会展示出hello了,看一下转移的代码:

<say-hello>

<div>hello</div>

</say-hello>

   稍有些解释一下我们为此到的星星单参数,restirct用来指定指令的用项目,其取值及意义如下:

取值
    

含义
    

使示例

E
    

标签
    

<my-menu title=Products></my-menu>

A
    

属性
    

<div my-menu=Products></div>

C
    


    

<div class=”my-menu”:Products></div>

M
    

注释
    

<!–directive:my-menu Products–>

默认值是A。也可采取这些价值的结合,如EA,EC等等。我们这边指定为E,那么其就是可像标签一样使用了。如果指定为A,我们使用起来应当像这么:

<div say-hello></div>

起转变的代码中,你也看出了template的意,它就是描述您的指令长什么体统,这片情节以起于页面中,即该令所在的沙盘被,既然是模板被,template的内容遭呢得使ng-modle等另指令,就像以模板被采取相同。

以方生成的代码中,我们视了<div>hello</div>外面还包方同样重合<say-hello>标签,如果我们无思使立马无异重叠多余的东西了,replace就派上用场了,在部署中将replace赋值为true,将获取如下结构:

<div>hello</div>

   replace的意正如其名,将命标签替换为temple中定义的情。不写的话默认为false。

面的template未休也最好简单了,如果你的模板HTML较复杂,如从定义一个ui组件指令,难道只要拼接老长的字符串?当然不待,此时就待用templateUrl便只是解决问题。你可以用指令的沙盘单独命名也一个html文件,然后在命令定义着以templateUrl指定好文件的门径即可,如:

templateUrl : ‘helloTemplate.html’         

系会自行发一个http请求来博取到对应之沙盘内容。是不是可怜有益于也,你不用纠结于拼接字符串的烦扰了。如果你是一个追完善的出考虑性能的工程师,可能会见咨询:那这样的话岂不是要是牺牲一个http请求?这也不用担心,因为ng的模板还好为此另外一栽方式定义,那即便是使<script>标签。使用起来如下:

<script type=”text/ng-template” id=”helloTemplate.html”>

     <div>hello</div>

</script>        

 你可将立即段代码写在页面头部,这样虽不必去请求其了。在实际上项目蒙,你啊堪拿装有的沙盘内容集中在一个文件被,只加载同不善,然后因id来取用。

连接下我们来拘禁其他一个较实用之布:transclude,定义是否以手上因素的情节转移至模板被。看说明多少抽象,不过亲手尝试就老大明白了,看下面的代码(例06):

app.directive(‘sayHello’,function(){

return {

     restrict : ‘E’,

template : ‘<div>hello,<b
ng-transclude></b>!</div>’,

     replace : true,

      transclude : true

};

})         

指定了transclude为true,并且template修改了一晃,加了一个<b>标签,并于方运用了ng-transclude指令,用来喻指令把内容转移至之位置。那我们如果换的情节是呀吧?请看下指令时之变更:

<say-hello>美女</say-hello>

情节是呀而也观看了哈~在运作的时光,美女将会给移到<b>标签中,原来这个布局的图就是——乾坤大挪移!看效果:

hello, 美女!

夫还是杀有因此的,因为您定义之一声令下不容许一直是那粗略,只来一个空标签。当你待对指令中的内容进行拍卖常,此参数就特别出可用。

6.2.4下令的行为参数:compile和link

6.2.3被简单介绍了打定义一个限令的几乎独简易参数,restrict、template、templateUrl、replace、transclude,这几乎单明白起来相对好多,因为其才提到到了呈现,而尚未涉嫌行为。我们延续上学ng自定义指令的几乎独重级参数:compile和link

l 理解compile和link

  不知大家产生没有产生这么的觉得,自己定义指令的上和写jQuery插件有几乎分相似之远在,都是预先事先定义好页面结构以及监听函数,然后以某个元素上调用一下,该因素即具有了特殊之效果。区别在于,jQuery的主脑是DOM操作,而ng的指令中除可以拓展DOM操作外,更尊重的凡多少与模板的绑定。jQuery插件在调用的时刻才开初始化,而ng指令在页面加载进来的当儿即便为编译服务($compile)初始化好了。

每当命令定义对象中,有compile和link两单参数,它们是召开呀的呢?从字面意义上看,编译、链接,貌似太肤浅了接触。其实只是大来内涵,为了当打定义指令的时段会正确使用它,现在产生必不可少了解一下ng是怎么样编译指令的。

l 指令的分析流程详解

  我们理解ng框架会在页面载入了的早晚,根据ng-app划定的用意域来调用$compile服务进行编译,这个$compile就如一个百般总管一样,清点作用域内的DOM元素,看看哪要素上用了命令(如<div
ng-modle=”m”></div>),或者如何因素本身便是个指令(如<mydierc></mydirec>),或者采取了插值指令(
{{}}也是同等种指令,叫interpolation
directive),$compile大总管会将清点好的资产做一个清单,然后根据这些指令的优先级(priority)排列一下,真是只细心之百般总管哈~大总管还会见基于指令中的配备参数(template,place,transclude等)转换DOM,让指令“初具人形”。

接下来就起来以梯次执行诸指令的compile函数,注意此处的compile可不是可怜总管$compile,人家带在$是土豪,此处执行的compile函数是咱指令中配备的,compile函数中可拜到DOM节点并拓展操作,其主要职责就是进展DOM转换,每个compile函数执行完后犹见面回一个link函数,这些link函数会为杀总管汇合一下结合成一个合体后的link函数,为了好掌握,我们好拿它们想象成葫芦小金刚,就像是进展了如此的处理。

//合体后的link函数

function AB(){

  A(); //子link函数

  B(); //子link函数

}  

连通下去进入link阶段,合体后的link函数被实践。所谓的链接,就是把view和scope链接起。链接成啥样呢?就是我们熟悉的数据绑定,通过当DOM上登记监听器来动态修改scope中之数,或者是采用$watchs监听
scope中之变量来修改DOM,从而建立双向绑定。由此也足以判定,葫芦小金刚得看到scope和DOM节点。

不要忘记了咱们当概念指令中尚布置在一个link参数为,这么多link千万别为混了。那就

只link函数是干嘛的呢,我们无是发生葫芦小金刚了呗?那自己报您,其实它们是一个聊三。此话怎讲?compile函数执行后归link函数,但要没配置compile函数呢?葫芦小金刚当就是未有了。

正房不以了,当然就是轮到多少三来马了,大总管$compile就把此的link函数拿来施行。这便代表,配置的link函数也可拜到scope以及DOM节点。值得注意的是,compile函数通常是勿会见为部署的,因为我们定义一个下令的时光,大部分状态不见面经过编程的方开展DOM操作,而重新多的是拓展监听器的报、数据的绑定。所以,小三叫做正言顺的吃杀总管宠爱。

任凭罢了很总管、葫芦小金刚与小三的故事,你是不是对准指令的分析过程较清晰了吧?不过细细琢磨,你或还是碰头看情节生硬,有些细节像要没透彻的懂得,所以还欲重明白下面的知识点:

l compile和link的区别

  其实以自看了官方文档后即便一直有疑点,为什么监听器、数据绑定不可知在compile函数中,而偏偏要放在link函数中?为什么有了compile还亟需link?就和你质疑自己编的故事一样,为什么最后小三叫宠坏了?所以我们发必要探究一下,compile和link之间到底有什么分别。好,正房与小三的PK现在开班。

率先是性。举个例子:

<ul>

  <li ng-repeat=”a in array”>

    <input ng-modle=”a.m” />

  </li>

</ul>         

咱们的观测对象是ng-repeat指令。假设一个前提是休设有link。大总管$compile在编译这段代码时,会查找到ng-repeat,然后实施其的compile函数,compile函数根据array的长度复制出n个<li>标签。而复制出的<li>节点受到还有<input>节点并且动了ng-modle指令,所以compile还要扫描其并配合指令,然后绑定监听器。每次循环都举行这样多之做事。而愈发糟糕的一些凡是,我们会以次中朝array中上加元素,此时页面及会见实时更新DOM,每次发新因素进来,compile函数都把上面的步调再挪相同整个,岂不是设累很了,这样性能必然不行。

今昔投标那个而,在编译的时段compile就独自管生成DOM的事,碰到需要绑定监听器的地方先抱着,有几独满怀几独,最后将它们汇总成一个link函数,然后同连推行。这样即便自在多了,compile只待实践同一涂鸦,性能自然提升。

除此以外一个有别于是能力。

尽管compile和link所召开的事务多,但其的力范围还是休等同的。比如正房能随便你的储蓄,小三就是未能够。小三能让你初恋的感觉到,正房却未能够。

我们得看一下compile函数和link函数的概念:

function compile(tElement, tAttrs, transclude) { … }

function link(scope, iElement, iAttrs, controller) { … }            

这些参数都是透过依赖注入而赢得的,可以随需声明使用。从名字啊易见到,两单函数各自的任务是什么,compile可以拿到transclude,允许而自己编程管理乾坤大挪移的作为。而link中好用到scope和controller,可以与scope进行数量绑定,与另指令进行通信。两者虽然都可拿到element,但是还是出分之,看到个别的前缀了吧?compile拿到的凡编译前之,是于template里以过来的,而link拿到之是编译后的,已经跟作用域建立了

事关,这也正是link中可以展开数量绑定的案由。

  我少只能解到者程度了。实在不思量明白这些文化的话,只要简单记住一个口径就是实施了:如果指令就进行DOM的改,不开展数据绑定,那么配置在compile函数中,如果指令要拓展数据绑定,那么配置在link函数中。
6.2.5下令的分开作用域参数:scope

咱俩当上面写了一个大概的<say-hello></say-hello>,能够与美女打招呼。但是看人家ng内置的通令,都是这样用的:ng-model=”m”,ng-repeat=”a
in
array”,不单单是作为性能,还得赋值给它们,与作用域中的一个变量绑定好,内容就可以动态变化了。假如我们的sayHello可以这么用:<say-hello
speak=”content”>美女</say-hello>,把要针对性嫦娥说的口舌写以一个变量content中,然后要在controller中改content的价,页面就可来得对美女说之不比的讲话。这样就活多矣,不至于见了美女只会说一样句hello,然后便没然后。

为贯彻如此的功用,我们需要动用scope参数,下面来介绍一下。

下scope为令划分作用域

  顾名思义,scope肯定是跟作用域有关的一个参数,它的来意是讲述指令与父作用域的干,这个父作用域是负什么也?想象一下我们采用指令的场景,页面结构应该是是样子:

<div ng-controller=”testC”>

    <say-hello speak=”content”>美女</say-hello>

</div>  

外层肯定会生出一个controller,而于controller的定义着大约是这法:

var app = angular.module(‘MyApp’, [],
function(){console.log(‘here’)});

app.controller(‘testC’,function($scope){

$scope.content = ‘今天天气真好!’;

}); 

所谓sayHello的父作用域就是以此叫做testC的控制器所辖的限制,指令和父作用域的关系得以发如下取值:

取值
    

说明

false
    

默认值。使用父作用域作为友好之作用域

true
    

新建一个作用域,该作用域继承父作用域

javascript对象
    

和父作用域隔离,并指定可以打父作用域访问的变量

初一看押取值为false和true好像没什么区别,因为取值为true时会持续父作用域,即父作用域中的任何变量都得看到,效果和直接采用父作用域差不多。但细一想还是生分之,有矣友好的作用域后便可以以内部定义自己的物,与同父作用域混在一道是发生本质上之区别。好比是爸爸的钱而想花多少花多少,可您自己赚取的钱父亲会花多少就不好说了。你若想看就有限个作用域的别,可以在link函数中打印出来看,还记得link函数中可以看到scope吧。

极致灵的或者取值为老三种,一个目标,可以为此键值来显式的指明要打父作用域中使用性质的计。当scope值为一个靶时,我们就是成立了一个及父层隔离的作用域,不过也非是意隔绝,我们得以手工搭同幢大桥,并放行某些参数。我们如果落实对嫦娥说各种话虽得依靠此。使用起来像这么:

scope: {

        attributeName1: ‘BINDING_STRATEGY’,

        attributeName2: ‘BINDING_STRATEGY’,…

}  

键为属性名称,值吗绑定策略。等等!啥给绑定策略?最讨厌冒新名词也未说明的一言一行!别急,听我慢慢道来。

 

  先说属性名称吧,你是免是觉得此attributeName1就是父作用域中之某变量名称?错!其实这个特性名称是乘令自己的模版被设采取的一个名称,并无对准诺父作用域中之变量,稍后的例证中我们来说明。再来拘禁绑定策略,它的取值按照如下的规则:

符号
    

说明
    

举例

@
    

传送一个字符串作为性能的值
    

str : ‘@string’

=
    

应用父作用域中的一个属性,绑定数据及令的性质被
    

name : ‘=username’

&
    

行使父作用域中之一个函数,可以当指令中调用
    

getName : ‘&getUserName’

  总之就是是用符号前缀来说明如何为令传值。你一定迫不及待要拘留例子了,我们构成例子看一下,小二,上栗子~

举例说明

自家眷恋使落实地方想像的跟美女多说点话的功能,即我们让sayHello指令加一个属性,通过叫属性赋值来动态改变说话的内容
主要代码如下:

app.controller(‘testC’,function($scope){

   $scope.content = ‘今天天气真好!’;

});

app.directive(‘sayHello’,function(){

    return {

        restrict : ‘E’,

template: ‘<div>hello,<b ng-transclude></b>,{{ cont
}}</div>’,

        replace : true,

        transclude : true,

        scope : {

 

             cont : ‘=speak’

         }

    };

});

下一场在模板被,我们如下使用指令:

<div ng-controller=”testC”>

    <say-hello speak=” content “>美女</say-hello>

</div>

探访运行效果:

美人今天天气真好!

  执行之流程是如此的:

  ① 指令给编译的上会扫描到template中的{ {cont}
},发现凡是一个表达式;

  ②
查找scope中的条条框框:通过speak与父作用域绑定,方式是传递父作用域中之性;

  ③ speak与父作用域中之content属性绑定,找到它们的价值“今天天气真好!”;

  ④ 将content的值显示在模板被。

这般咱们提的内容content就和父作用域绑定到了一致该,如果动态修改父作用域的content的价,页面上的内容就是见面就变动,正而你点击“换句话”所看到的同等。

  这个例子也绝小气了咔嚓!简单就略,但足被我们了解掌握,为了印证而是匪是的确的晓了,可以考虑一下如何修改命令定义,能于sayHello以如下两种植方法采取:

<span say-hello speak=”content”>美女</span>

<span say-hello=”content” >美女</span>

  答案我不怕背着了,简单的慌。下面有再关键之政工若做,我们说好了若描写一个实在能为此之物来在。接下来就结成所模拟到之物来写一个折叠菜单,即点击可进行,再点击一破就是抽回去的菜谱。

控制器和指令的代码如下(例07):

app.controller(‘testC’,function($scope){

        $scope.title = ‘个人简介’;

    $scope.text =
‘大家好,我是同样称为前端工程师,我正研究AngularJs,欢迎大家和自交流’;

});

    app.directive(‘expander’,function(){

        return {

            restrict : ‘E’,

            templateUrl : ‘expanderTemp.html’,

            replace : true,

            transclude : true,

            scope : {

                mytitle : ‘=etitle’

            },

            link : function(scope,element,attris){

                scope.showText = false;

                scope.toggleText = function(){

                    scope.showText = ! scope.showText;

                }

            }

        };

    });

HTML中之代码如下:

 

<script type=”text/ng-template” id=”expanderTemp.html”>

    <div  class=”mybox”>

<div class=”mytitle” ng-click=”toggleText()”>

{{mytitle}}

</div>

<div ng-transclude ng-show=”showText”>

</div>

</div>

</script>

<div ng-controller=”testC”>

    <expander etitle=”title”>{{text}}</expander>

</div>

  还是比好看懂的,我特做一些少不了的分解。首先我们定义模板的时利用了ng的一律栽概念方式<script
type=”text/ng-template”id=”expanderTemp.html”>,在指令中即使可以用templateUrl根据这id来找到模板。指令中的{{mytitle}}表达式由scope参数指定由etitle传递,etitle指向了父作用域中的title。为了促成点击标题能够进行缩内容,我们拿当下有的逻辑在了link函数中,link函数可以看到令的作用域,我们定义showText属性来代表内容有的显隐,定义toggleText函数来开展控制,然后于模板被绑定好。
如果拿showText和toggleText定义在controller中,作为$scope的性也?显然是蛮的,这就是是隔离作用域的意义所在,父作用域中之事物除了title之外都被挡。

面的例子中,scope参数使用了=号来指定获取属性之路为父作用域的性能,如果我们纪念以命令中运用父作用域中之函数,使用&符号即可,是同样的规律。
6.2.6借助令间通信参数:controller和require

  使用指令来定义一个ui组件是单科学的想法,首先以起来方便,只需要一个标签或者性质就好了,其次是只是复用性高,通过controller可以动态控制ui组件的情,而且具有双向绑定的能力。当我们怀念做的零件稍微复杂一点,就无是一个下令可以搞定的了,就需指令与指令的搭档才足以好,这就是待开展指令中通信。

想念转手我们进行模块化开发之时光的原理,一个模块暴露(exports)对外的接口,另外一个模块引用(require)它,便可行使其所提供的服务了。ng的下令中合作为是者原理,这吗亏从定义指令时controller参数和require参数的作用。

controller参数用于定义指令对外提供的接口,它的写法如下:

 

controller: function controllerConstructor($scope, $element, $attrs,
$transclude)  

她是一个构造器函数,将来可组织出一个实例传给援它的下令。为什么给controller(控制器)呢?其实就是喻引用它的授命,你得控制我。至于可以操纵那些东西也,就需要以函数体中展开定义了。先押controller可以使的参数,作用域、节点、节点的性、节点内容的迁移,这些还得以经过依赖注入被染进,所以若可以根据需要单独写如因此之参数。关于如何对外暴露接口,我们当底下的例子来证明。

require参数就是为此来指明要靠的外指令,它的值是一个字符串,就是所依赖之一声令下的讳,这样框架就能以卿指定的名来起对应之通令上面寻找定义好的controller了。不过还小小有硌特别之地方,为了给框架寻找的下再次自在来,我们可当名字前加个小小的前缀:^,表示于父节点上摸索,使用起来如这么:require
:
‘^directiveName’,如果无加以,$compile服务只有会于节点本身寻找。另外还足以应用前缀:?,此前缀将告诉$compile服务,如果所用的controller没找到,不要弃来非常。

所要了解的知识点就这些,接下是例证时间,依旧是自开及抄来的一个事例,我们若召开的是一个手风琴菜单,就是大半个折叠菜单并列在并,此例子用来展示指令中的通信再适合不了。

首先我们要定义外层的一个组织,起名为accordion,代码如下:

app.directive(‘accordion’,function(){

        return {

            restrict : ‘E’,

            template : ‘<div ng-transclude></div>’,

            replace : true,

            transclude : true,

controller :function(){

                var expanders = [];

                this.gotOpended = function(selectedExpander){

                    angular.forEach(expanders,function(e){

                        if(selectedExpander != e){

                            e.showText = false;

                        }

                    });

                }

                this.addExpander = function(e){

                    expanders.push(e);

                }

            }

        }

    });

消说明的只有controller中之代码,我们定义了一个折叠菜单数组expanders,并且经过this关键字来对外暴露接口,提供简单只方式。gotOpended接受一个selectExpander参数用来改数组中对应expander的showText属性值,从而实现对各个子菜单的显隐控制。addExpander方法对外提供向expanders数组增加元素的接口,这样于子菜单的下令中,便足以调用它把我投入到accordion中。

扣押一下咱们的expander需要举行什么的改动为:

app.directive(‘expander’,function(){

        return {

            restrict : ‘E’,

            templateUrl : ‘expanderTemp.html’,

            replace : true,

            transclude : true,

            require : ‘^?accordion’,

            scope : {

                title : ‘=etitle’

            },

 

            link : function(scope,element,attris,accordionController){

                scope.showText = false;

                accordionController.addExpander(scope);

                scope.toggleText = function(){

                    scope.showText = ! scope.showText;

                    accordionController.gotOpended(scope);

                }

            }

        };

    });

率先以require参数引入所欲的accordion指令,添加?^前缀表示于父节点查找并且失败后非弃来非常。然后就是得以以link函数中应用已流好的accordionController了,调用addExpander方法将好之作用域作为参数传入,以供accordionController访问其性质。然

后当toggleText方法中,除了使管温馨之showText修改外,还要调用accordionController的gotOpended方法通知父层指令把其余菜单给收缩起来。

令定义好后,我们不怕可使了,使用起来如下:

 

<accordion>

<expander ng-repeat=”expander in expanders”
etitle=”expander.title”>

{{expander.text}}

</expander>

</accordion>  

外层使用了accordion指令,内层使用expander指令,并且在expander上之所以ng-repeat循环输出子菜单。请小心这里遍历的数组expanders可不是accordion中定义的异常expanders,如果您这么觉得了,说明要针对作用域不够了解。此expanders是ng-repeat的价,它是以外层controller中的,所以,在testC中,我们要加上如下数据:

$scope.expanders = [

            {title: ‘个人简介’,

             text:
‘大家吓,我是千篇一律称为前端工程师,我在研究AngularJs,欢迎大家与我交流’},

            {title: ‘我的爱好’,

             text: ‘LOL ‘},

            {title: ‘性格’,

             text: ‘ 我的秉性就是无性格’}

        ];

6.3 性能与调优
6.3.1属性测试

AnglarJS作为一如既往慢性可以之Web框架,可大大简化前端开发的承担。

AnglarJS很棒,但当处理包含复杂数据结构的巨型列表时,其运作速度就见面好缓慢。

就是咱以核心管理页面迁移至AngularJS过程被碰到的题目。这些页面在亮500实践数据时本应该工作顺利,但首只措施的渲染时间竟花费了7秒,太吓人了。后来,我们发现了于贯彻过程被存在个别个重大性能问题。一个以及“ng-repeat
”指令有关,另一个和过滤器有关。

AngularJS 中之ng-repeat在拍卖大型列表时,速度为什么会变换缓?

AngularJS中之ng-repeat在拍卖2500独以上的双向数据绑定时进度会转换缓。这是由于AngularJS通过“dirty
checking”函数来检测变化。每次检测还见面花时间,所以富含复杂数据结构的巨型列表将骤降你用之周转速度。

增长性能的先决条件

岁月记下指令

为测量一个列表渲染所花的岁月,我们形容了一个简单易行的主次,通过动“ng-repeat”的习性“$last”来记录时间。时间存放于TimeTracker服务受到,这样时间记下就是和服务器端的数加载分开了。

// Post repeat directive for logging the rendering time   

angular.module(‘siApp.services’).directive(‘postRepeatDirective’,   

[‘$timeout’, ‘$log’,  ‘TimeTracker’,   

  function($timeout, $log, TimeTracker) {  

    return function(scope, element, attrs) {  

      if (scope.$last){  

         $timeout(function(){  

             var timeFinishedLoadingList =
TimeTracker.reviewListLoaded();  

             var ref = new Date(timeFinishedLoadingList);  

             var end = new Date();  

             $log.debug(“## DOM rendering list took: ” + (end – ref) +
” ms”);  

         });  

       }  

    };  

  }  

]);  

// Use in HTML:   

<tr ng-repeat=”item in items” post-repeat-directive>…</tr>
 

Chrome开发者工具的日子轴(Timeline)属性

以Chrome开发者工具的年月轴标签中,你得望见事件、每秒内浏览器帧数和内存分配。“memory”工具用来检测内存泄漏,及页面所急需的内存。当帧速率每秒低于30帧时就是会出现页面闪烁问题。“frames”工具而帮了解渲染性能,还而兆示出一个JavaScript任务所花费的CPU时间。

透过限制列表的大大小小进行着力的调优

釜底抽薪该问题,最好之不二法门是限量所显示列表的大小。可通过分页、添加无限滚动条来贯彻。

分页,我们可利用AngularJS的“limitTo”过滤器(AngularJS1.1.4版后)和“startFrom”过滤器。可以经限制显示列表的轻重缓急来减少渲染时间。这是减少渲染时间最好迅速之艺术。

6.3.2拐老调整优法则

1.渲染没有数量绑定的列表

立即是极其明白的化解方案,因为数量绑定是性质问题最好可能的来源于。如果您只是想展示同一次列表,并不需要更新、改变多少,放弃数据绑定是绝佳的措施。不过可惜的凡,你晤面失掉对数据的控制权,但除该法,我们别无选择。

2.决不使用内联方法算数据

为以控制器中一直过滤列表,不要采取可收获了滤链接的法。“ng-repeat”会评估每个表达式。在咱们的案例被,“filteredItems()”返回了滤链接。如果评估过程充分缓慢,它将很快下滑整个应用的速度。

 

l <li ng-repeat=”item in filteredItems()”>
//这并无是一个吓方式,因为只要勤地评估。   

l <li ng-repeat=”item in items”> //这是若运用的道  

3.使简单只列表(一个为此来开展视图显示,一个用作数据源)

且显示的列表与总的数额列表分开,是坏实用之模子。你可本着一些过滤进行预处理,并拿存于缓存中之链接以及视图上。下面案例显示了主导落实过程。filteredLists变量保存在缓存中之链接,applyFilter方法来处理映射。

/* Controller */  

// Basic list    

var items = [{name:”John”, active:true }, {name:”Adam”},
{name:”Chris”}, {name:”Heather”}];    

// Init displayedList   

$scope.displayedItems = items;  

// Filter Cache   

var filteredLists[‘active’] = $filter(‘filter)(items, {“active” :
true});  

// Apply the filter   

$scope.applyFilter = function(type) {  

    if (filteredLists.hasOwnProperty(type){ // Check if filter is
cached   

       $scope.displayedItems = filteredLists[type];  

    } else {   

        /* Non cached filtering */  

    }  

}  

// Reset filter   

$scope.resetFilter = function() {  

    $scope.displayedItems = items;  

}  

/* View */  

<button ng-click=”applyFilter(‘active’)”>Select
active</button>  

<ul><li ng-repeat=”item in
displayedItems”>{{item.name}}<li></ul>  

4.每当任何模板被使用ng-if来代替ng-show

万一您用命令、模板来渲染额外的音,例如通过点击来显示列表项的详细信息,一定要使 
ng-if(AngularJSv.
1.1.5从此)。ng-if可阻止渲染(与ng-show相比)。所以任何DOM和数量绑定可因需要展开评估。

<li ng-repeat=”item in items”>  

 

   <p> {{ item.title }} </p>  

   <button ng-click=”item.showDetails = !item.showDetails”>Show
details</buttons>  

   <div ng-if=”item.showDetails”>  

       {{item.details}}  

   </div>  

</li>  

5.决不采用ng-mouseenter、ng-mouseleave等一声令下

运用其中指令,像ng-mouseenter,AngularJS会使您的页面闪烁。浏览器的帧速率通常低于每秒30轴。使用jQuery创建动画、鼠标悬浮效果好化解该问题。确保将鼠标事件放入jQuery的.live()函数中。

6.关于过滤的略提示:通过ng-show隐藏多余的因素

对此长列申,使用过滤同样会回落工作效率,因为每个过滤都见面创造一个原始列表的子链接。在成千上万景象下,数据没有变动,过滤结果吧会保持不转换。所以针对数据列表进行先期过滤,并依据气象将她利用到视图中,会大大节约处理时。

当ng-repeat指令中以过滤器,每个过滤器会回一个土生土长链接的子集。AngularJS
从DOM中移除多余元素(通过调用
$destroy),同时为会见起$scope中移除他们。当过滤器的输入有反时,子集也会趁变化,元素必须进行再次链接,或正还调用$destroy。

大部景象下,这样做老好,但如若用户时时过滤,或者列表非常伟大,不断的链接和

销毁将震慑性。为了加紧过滤的快慢,你可以使ng-show和ng-hide指令。在控制器中,进行过滤,并也每起添加一个性能。依靠该属性来触发ng-show。结果是,只为这些因素增加ng-hide类,来取代将它移除子列表、$scope和DOM。

触发ng-show的主意之一是下表达式语法。ng-show的值由表达式语法来确定。可以关押下的例子:

<input ng-model=”query”></input>  

<li ng-repeat=”item in items” ng-show=”([item.name] |
filter:query).length”> {{item.name}} </li>

<span style=”font-size: 14px; line-height: 24px; font-family:;
white-space: normal;”></span>

7.有关过滤的略微提示:防抖动输入

缓解第6接触提出的缕缕过滤问题之任何一个智是防抖动用户输入。例如,如果用户输入一个搜关键词,只当用户已输入后,过滤器才见面给激活。使用该防抖动服务的一个格外好之化解方案请见:
http://jsfiddle.net/Warspawn/6K7Kd/。将它应用到你的视图及控制器中,如下所示:

/* Controller */  

// Watch the queryInput and debounce the filtering by 350 ms.   

$scope.$watch(‘queryInput’, function(newValue, oldValue) {  

    if (newValue === oldValue) { return; }  

    $debounce(applyQuery, 350);  

});  

var applyQuery = function() {   

    $scope.filter.query = $scope.query;  

};    

/* View */  

<input ng-model=”queryInput”/>  

<li ng-repeat= item in items | filter:filter.query>{{ item.title
}} </li>

 
7 总结

angular上手比较麻烦,初家(特别是习惯了用JQuery的总人口)可能无极端适应其语法以及思维。随着对ng探索的一步步尖锐,也真感觉到到了就一点,尤其是框架中的一点执行机制。

7.1页面效果

 ng-show ng-hide 无动画效果问题
7.2委事件(代理事件)
7.2.1 NG循环及波绑定

<ul>

  <li ng-repeat=”a in array”>

    <input ng-modle=”a.m” />

  </li>

</ul>

Ng会因array的长短复制出n个<li>标签。而复制出之<li>节点受到还有<input>节点并且采用了ng-modle指令,所以ng会指向负有的<input>绑定监听器(事件)。如果array很特别,就会绑定太多的风波,性能出现问题。

7.2.2 jQuery委派事件
 

由jQuery1.7开,提供了.on()附加事件处理程序。

.on( events [, selector ] [, data ], handler(eventObject) )

参数Selector为一个摘取器字符串,用于过滤出为选中的元素被会接触事件之后人元素。如果选择器是
null 或者忽视了该选择器,那么吃入选的元素总是会接触事件。

假若看略selector或者是null,那么事件处理程序让名直接事件 或者
直接绑定事件
。每次选中的因素触发事件不时,就见面履处理程序,不管她一直绑定以要素上,还是从后(内部)元素冒泡到拖欠因素的。

当提供selector参数时,事件处理程序是借助也委任事件(代理事件)。事件无见面以直绑定的素上触,但当selector参数选择器匹配到后代(内部因素)的时候,事件处理函数才会为硌。jQuery
会从 event target
开始于上层元素(例如,由最内层元素到最外层元素)开始冒泡,并且以传途径上享有绑定了千篇一律事件的元素而满足匹配的选择器,那么这些因素上之风波吧会于触发。

寄事件时有发生有限只优势:他们会当后人元素添加到文档后,可以拍卖这些事件;代理事件之任何一个便宜就,当用监视很多素的时刻,代理事件的支出更粗。

诸如,在一个表的 tbody 中蕴含 1,000 行,下面是例子会吗当下 1,000
元素绑定事

$(“#dataTable tbody tr”).on(“click”, function(event){
alert($(this).text());});

委任事件之章程就生一个元素的事件处理程序,tbody,并且事件只是会向上冒泡一交汇(从吃点击的tr
到 tbody ):

$(“#dataTable tbody”).on(“click”, “tr”, function(event){ 
alert($(this).text());});

有的是委的事件处理程序绑定到 document
树的顶层附近,可以降性能。每次出事变时,jQuery 需要比起 event
target(目标元素)
开始到文档顶部的路线中各一个要素上具备拖欠品种的轩然大波。为了取得重新好的性能,在绑定代理事件频仍,绑定的元素最好尽可能的近目标元素。避免在大型文档中,过多之当
document 或 document.body 上加加代理事件。

相关文章