AngularJSangularJS详解

那篇小说转发  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、GoogleDocs、推文(Tweet)和脸谱那样的应用,都很能发挥AngularJS的亮点。可是像娱乐支付之类对DOM举行大气说了算、又或者唯有须求极高周转速度的施用,就不是AngularJS的用武之地了。

3 AugularJS特性

AngularJS是一个新出现的强陆风X8户端技术,提需求大家的一种开发强大应用的点子。那种艺术使用并且扩展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的值对应。那样声雅培(Abbott)下就可以让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 分别代表 年 月 日 时 分 秒
星期,你能够自由组合它们。也得以利用不相同的个数来界定格式化的位数。别的参数也得以行使一定的讲述性字符串,例如“short提姆e”将会把时间格式为12:05
pm那样的。ng提供了多样描述性的字符串,个人认为那个有些多余,我一心可以依照自己的意思组合出想要的格式,不情愿去记这么多单词~

  1. filter(匹配子串)

  这么些叫做filter的filter。用来拍卖一个数组,然后可以过滤出含有某个子串的因素,作为一个子数组来回到。可以是字符串数组,也足以是目的数组。如若是目标数组,可以匹配属性的值。它接受一个参数,用来定义子串的匹配规则。上面举个例子说爱他美(Aptamil)(Nutrilon)下参数的用法,我用现在尤其火的多少个儿女定义了一个数组:

$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是按照名称来识其余。若参数的名次与服务名称不平等,你就非得出示的声爱他美(Karicare)下,格局如下:

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 {

/*user瑟维斯对外暴露的函数,可有五个*/

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服务)一样的使用user瑟维斯了。

连带的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”来记录时间。时间存放在提姆eTracker服务中,那样时间记下就与劳务器端的数目加载分开了。

// 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开发者工具的日子轴(提姆eline)属性

在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 上添加代总管件。

相关文章