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 上加加代理事件。