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了)是3个用来设计动态web应用的构造框架。首先,它是二个框架,不是类库,是像EXT一样提供一整套方案用于设计web应用。它不仅仅是三个javascript框架,因为它的主题其实是对HTML标签的拉长。

何为HTML标签增强?其实就是使您可知用竹签完毕部分页面逻辑,具体措施就是由此自定义标签、自定义属性等,那一个HTML原生没有的竹签/属性在ng中有1个名字:指令(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、推文(Tweet)和Facebook那样的使用,都很能表明AngularJS的亮点。不过像娱乐支付之类对DOM举行多量说了算、又或许只有必要极高周转速度的施用,就不是AngularJS的用武之地了。

3 AugularJS特性

AngularJS是三个新面世的强中华V户端技术,提须求大家的一种开发强大应用的办法。那种办法拔取并且扩充HTML,CSS和javascript,并且弥补了它们的部分分外强烈的紧缺。本应当利用HTML来促成而现行由它支付的动态一些内容。

AngularJS有七个最要紧的效果和天性:

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

数码绑定大概是AngularJS最酷最实用的表征。它亦可扶助您防止书写多量的先河代码从而省去开销时间。三个非凡的web应用大概带有了十分之八的代码用来处理,查询和监听DOM。数据绑定是的代码更少,你可以小心于您的利用。

咱俩想像一下Model是你的使用中的不难事实。你的Model是您用来读取可能更新的有的。数据绑定指令提供了您的Model投射到view的措施。那些投射可以无缝的,毫不影响的运用到web应用中。

历史观来说,当model变化了。
开发人士要求手动处理DOM成分并且将品质反映到这个变迁中。那几个一个双向的长河。一方面,model变化使得了DOM中元素变化,另一方面,DOM成分的变迁也会潜移默化到Model。这么些在用户互动中越发扑朔迷离,因为开发人员须要处理和剖析

这个互动,然后融合到3个model中,并且更新View。那是一个手动的错综复杂进度,当3个应用极度巨大的时候,将会是一件十一分费劲的事体。

那边肯定有更好的化解方案!那就是AngularJS的双向数据绑定,可以联手DOM和Model等等。

此间有一个非凡简单的例证,用来演示3个input输入框和<h1>成分的双向绑定(例01):

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

3.2 特性二:模板

在AngularJS中,1个模板就是三个HTML文件。然则HTML的故事情节扩张了,包涵了累累救助你映射model到view的内容。

HTML模板将会被浏览器解析到DOM中。DOM然后改成AngularJS编译器的输入。AngularJS将会遍历DOM模板来生成一些指点,即,directive(指令)。全部的一声令下都担负针对view来设置数据绑定。

咱俩要掌握AuguarJS并不把模版当做String来操作。输入AngularJS的是DOM而非string。数据绑定是DOM变化,不是字符串的连日可能innerHTML变化。使用DOM作为输入,而不是字符串,是AngularJS分化于任何的框架的最大原因。使用DOM允许你增加指令词汇并且可以创建你自个儿的通令,甚至开发可采纳的零部件。

最大的利益是为设计师和开发者成立了3个严密的工作流。设计师可以像以后一样付出标签,然后开发者拿过来添加上作用,通过数量绑定将会使得这一个历程极度简单。

此地有一个例子,大家运用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允许你请求你的依赖,而不是祥和找寻它们。比如,大家必要2个东西,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是3个把view(三个DOM成分)连结到controller上的对象。在大家的MVC结构里,那几个$scope
将变成model,它提供多个绑定到DOM成分(以及其子成分)上的excecution
context。

即便听起来某个复杂,但 $scope
实际上就是一个JavaScript对象,controller和view都得以访问它,所以大家得以接纳它在两者间传递音信。在这些$scope 对象里,大家既存储数据,又囤积将要运维在view上的函数。

每三个Angular应用都会有1个 $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>标签上多了2个性情ng-app=”MyApp”,它的功效就是用来钦定ng的功能域是在<html>标签以内部分。在js中,大家调用angular对象的module方法来声称二个模块,模块的名字和ng-app的值对应。那样声喜宝(Hipp)下就足以让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 }}。

请查看例0③ 、例0④ 、例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 表达式可接受3个或八个串联起来的过滤器。

4.5过滤器

过滤器(filter)正如其名,成效就是吸收3个输入,通过某些规则举行处理,然后回处处理后的结果。主要用在数量的格式化上,例如获取一个数组中的子集,对数组中的成分举行排序等。过滤器日常是陪伴标记来拔取的,将你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连用,上3个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,你只需注入1个$filter就够了,使用格局如下:

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

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

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

}  

能够完结相同的效果。好处是你可以方便使用不相同的filter了。

4.5.2 ng的停放过滤器

ng内置了九种过滤器,使用办法都相当简单,看文档即懂。然则为了以往不去翻它的文档,作者在那边依然做2个详尽的笔录。

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。用来处理2个数组,然后能够过滤出含有有些子串的要素,作为多个子数组来回到。能够是字符串数组,也足以是目的数组。若是是目的数组,可以匹配属性的值。它接受多个参数,用来定义子串的极度规则。上边举个例子说贝拉米(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过滤器可以把2个js对象格式化为json字符串,没有参数。那东西有怎样用呢,作者一般也不会在页面上输出3个json串啊,官网说它可以用来拓展调试,嗯,是个正确的挑选。只怕,也得以用在js中行使,功能就和我们明白的JSON.stringify()一样。用法一级不难:

{{ jsonTest | json}}

  1. limitTo(限制数老板度或字符串长度)

  limitTo过滤器用来截取数组或字符串,接收1个参数用来钦定截取的尺寸,若是参数是负值,则从数组底部开头截取。个人觉得那么些filter有点鸡肋,首先只好从数组或字符串的早先/底部举办截取,其次,js原生的函数就可以替代它了,看看怎么用啊:

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

  1. lowercase(小写)

  把数量转载为全方位大写。太简单了,不多解释。同样是很鸡肋的一个filter,没有参数,只可以把全数字符串变为小写,不能够内定字母。怎么用自家都无心写了。

  1. uppercase(大写)

  同上。

  1. number(格式化数字)

  number过滤器可以为3个数字拉长千位分割,像那样,123,456,789。同时接受三个参数,能够内定float类型保留4人小数:

{{ num | number : 2 }}  

  1. orderBy(排序)

  orderBy过滤器可以将一个数组中的成分举行排序,接收贰个参数来钦命排序规则,参数可以是一个字符串,表示以该属性名称实行排序。可以是2个函数,定义排序属性。还是能够是一个数组,表示依次按数组中的属性值进行排序(若按第叁项比较的值卓殊,再按第②项相比),依旧拿地点的孩子数组举例:

<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方法,重临三个函数,该函数接收

输入值,并赶回处理后的结果。话不多说,大家来写1个探视。比如我必要3个过滤器,它可以回去七个数组中下标为奇数的成分,代码如下:

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的相当函数中,作为第1个参数,或然更七个参数也可以。

自定义过滤器实例(例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
1个名值对应的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样式,其表明式的重临值为3个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,那样页面上就不会先出现1个地址错误的链接。

本着那么些思路再多想一些,大家在模板中运用{{}}彰显数据时,在ng编译完毕以前页面上岂不是会来得出大括号及里面的表达式?确实是那般。为了避免这些,ng中有三个与{{}}等同的下令:ng-bind,同样用于单向绑定,在页面刚加载的时候就不会来得出对用户无用的数码了。即便那样你恐怕非但没舒心反而更纠结了,{{}}那么好用易领悟,还不可以用了不成?好音讯是大家还是能使用。因为小编编写的是单页面应用,页面只会在加载index.html的时

候出那几个题材,只需在index.html中的模板中换来ng-bind就行。其余的沙盘是大家动态加载的,就足以放心使用{{}}了。

4.6.5 自定义指令示例

上面大家来分析下命令的例证(例07)。

1.率先,大家定义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’}:定义2个名为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便有诸如此类的定义,其成效就是对外提供有个别特定的效果,如消息服务,文件裁减服务等,是1个单独的模块。ng的劳动是那般定义的:

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

它是2个单例对象或函数,对外提供特定的效能。

第三是贰个单例,即无论是这几个服务被注入到其余地点,对象始终唯有贰个实例。

协理那与我们温馨定义2个function然后在其他地点调用不一致,因为服务被定义在3个模块中,所以其利用范围是足以被大家管理的。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方法。

  上面通过3个小例子来分别考查弹指间。大家定义3个名为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方法本人再次回到1个构造器,系统会自动使用new关键字来创设出2个对象。所以大家看看在布局器函数内可以采纳this,那样调用该服务的地点便得以平昔通过remoteData.name来访问数据了。
4.7.3管击败务的借助关系

  服务与劳动中间可以有依靠关系,例如大家那边定义2个名为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为那几个服务从后台获取用户新闻的函数,并且对外揭破。当然,由于那是2个静态的例证,不大概访问后台,那么大家便制定其归来的数码。

然后我们把这几个服务充分到大家的controller中。我们创制1个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);

}

});

大家的user瑟维斯注入到大家的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想要推崇一种申明式的开发格局,即当我们须要动用某一模块或劳务时,不必要关爱此模块内部如何完毕,只需声惠氏(WYETH)下就足以应用了。在多处接纳只需举办反复声明,大大提升可复用性。

  比如大家的controller,在概念的时候用到2个$scope参数。

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

一旦大家在此地还需操作其余的东西,比如与浏览器地址栏实行互动。大家只需再多添

一个参数$location进去:

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

诸如此类便足以因而$location来与地方栏举行互相了,我们只是是声称了弹指间,所需的其他代码,框架已经帮大家注入了。大家很显然的觉拿到了这些函数已经不是常规意义上的javascript函数了,在例行的函数中,把形参换2个名字还是能运作,但在那边即使把$scope换来其余名字,程序便不可以运作了。因为那是早就定义好的服务名称。

那便是凭借注入机制。顺理成章的推论,大家可以协调定义模块和劳务,然后在急需的地点进行宣示,由框架来替大家注入。

来看下我们什么定义三个服务:

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

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

});  

看上去格外简单,是因为自个儿在此处仅仅是一向回到2个数组。在实际利用中,那里应该是索要向服务器发起一个请求,来获得到这一个模板们。服务的概念方式有几许种,包涵采用provider方法、使用factory方法,使用service方法。它们之间的差异暂时不敬爱。我们今后尽管能创设1个劳动出来就足以了。我利用了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
),约等于我们所要求的路由机制。通过路由机制,3个单页应用的相继视图就能够很好的团伙起来了。

4.9.1 ngRoute内容

  ng的路由机制是靠ngRoute提供的,通过hash和history二种艺术贯彻了路由,可以检测浏览器是或不是资助history来灵活调用相应的主意。ng的路由(ngRoute)是3个单独的模块,包涵以下内容:

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做出变化。(记住,那是个第1的概念),为了诠释怎么着是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上添加了八个东西,可是唯有3个绑定在了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有多少个(3个name,2个age),然后ng-repeat又有三个,因此十一个person一共是(2
* 10) +1,相当于说有21个$watch。

据此,每三个绑定到了DOM上的数额都会扭转3个$watch。

那那写$watch是曾几何时生成的吧?

当我们的模板加载落成时,约等于在linking阶段(Angular分为compile阶段和linking阶段),Angular解释器会招来每种directive,然后生成每一种要求的$watch。
6.1.3 $digest循环

还记得本身后边提到的恢弘的风云循环呢?当浏览器接收到可以被angular
context处理的轩然大波时,$digest循环就会触发。那一个轮回是由七个更小的大循环组合起来的。1个处理evalAsync队列,另贰个拍卖$watch队列。
那些是拍卖什么的呢?$digest将会遍历大家的$watch,然后询问:

•嘿,$watch,你的值是何等?

◦是9。

•好的,它改变过呢?

◦没有,先生。

•(那一个变量没变过,那下1个)

•你呢,你的值是有点?

◦报告,是Foo。

•刚才改变过没?

◦改变过,刚才是Bar。

•(很好,大家有DOM必要立异了)

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

那就是所谓的dirty-checking。既然全部的$watch都检查完了,那就要问了:有没有$watch更新过?假设有至少一个更新过,这几个轮回就会再次接触,直到全数的$watch都不曾变动。那样就可知确保逐个model都早已不会再变更。记住假设循环当先1陆回的话,它将会抛出一个非凡,幸免无限循环。当$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>

那边我们有2个$watch因为ng-click不生成$watch(函数是不会变的)。

咱们得以见到ng的拍卖流程:

•咱们按下按钮;

•浏览器接收到3个轩然大波,进入angular context;

•$digest循环先导推行,查询每一种$watch是不是变动;

•由于监视$scope.name的$watch报告了扭转,它会强制再实施五遍$digest循环;

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

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

此地很重点的是每3个进入angular
context的事件都会履行一个$digest循环,也等于说每回大家输入二个字母循环都会检查整个页面的兼具$watch。

6.1.4如何进入angular context

哪个人说了算怎样风浪进入angular context,而哪些又不进去呢?通过$apply!

假如当事件触发时,你调用$apply,它会进来angular
context,若是没有调用就不会进去。以后你可能会问:刚才的事例里自身也尚无调用$apply啊,为啥?Angular已经做了!由此你点击带有ng-click的因素时,时间就会被装进到1个$apply调用。尽管您有一个ng-model=”foo”的输入框,然后您敲1个f,事件就会那样调用$apply(“foo
= ‘f’;”)。

Angular何时不会自行为大家$apply呢?

那是Angular新手共同的苦楚。为何我的jQuery不会更新自个儿绑定的事物吗?因为jQuery没有调用$apply,事件没有进来angular
context,$digest循环永远没有执行。

大家来看3个诙谐的例证:

若果大家有下边那个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循环(除非当前正值推行循环,那种情况下会抛出3个那么些,那是我们不需求在那边执行$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>

那就是大家成立3个新的$watch的法子。第1个参数是壹个字符串或然函数,在此处是只是1个字符串,就是大家要监视的变量的名字,在那边,$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的第二个参数接受七个参数,新值和旧值。大家得以用他们来略过第壹回的施行。寻常你不必要略过第4遍举办,但在那几个事例里面你是索要的。

例子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的引用是不会转移的,大家只是每趟创制了2个新的$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出席了第⑨个参数,它是3个bool类型的参数,表示的是大家相比较的是目的的值而不是援引。由于当我们立异$scope.user.name时$scope.user也会改变,所以可以科学触发。

6.1.6 总结

本身梦想你们已经学会了在Angular中数据绑定是什么行事的。我思疑你的第叁印象是dirty-checking很慢,好啊,其实是畸形的。它像雷暴般快。可是,若是你在3个模板里有三千-贰仟个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不就是1个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-前缀了,防止与系统自带的下令重名。其余1个需清楚的地方,指令命名时用驼峰规则,使用时用-分割各单词。如:定义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’         

系统会自行发1个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就如3个大管事人一样,清点成效域内的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函数会被大总管会师一下组合成2个合体后的link函数,为了好了解,我们可以把它想象成葫芦小金刚,如同举办了那般的处理。

//合体后的link函数

function AB(){

  A(); //子link函数

  B(); //子link函数

}  

接下去进入link阶段,合体后的link函数被实践。所谓的链接,就是把view和scope链接起来。链接成啥样呢?就是大家耳熟能详的数量绑定,通过在DOM上登记监听器来动态修改scope中的数据,或然是利用$watchs监听
scope中的变量来修改DOM,从而确立双向绑定。由此也可以断定,葫芦小金刚可以访问到scope和DOM节点。

并非忘了小编们在概念指令中还配置着一个link参数呢,这么多link千万别搞混了。那那

个link函数是干嘛的吗,大家不是有葫芦小金刚了呗?这作者报告您,其实它是3个小三。此话怎讲?compile函数执行后回去link函数,但若没有布置compile函数呢?葫芦小金刚自然就不设有了。

堂屋不在了,当然就轮到小三出马了,大负责人$compile就把那边的link函数拿来执行。那就代表,配置的link函数也可以访问到scope以及DOM节点。值得注意的是,compile函数平常是不会被布置的,因为大家定义3个下令的时候,大多数意况不会透过编程的办法开展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中可以进行数量绑定的因由。

  作者暂且只好精通到那个水平了。实在不想驾驭那几个文化的话,只要简单记住2个标准化就行了:借使指令只举行DOM的改动,不开展多少绑定,那么配置在compile函数中,假设指令要拓展数据绑定,那么配置在link函数中。
6.2.5下令的细分作用域参数:scope

咱俩在上面写了3个简便的<say-hello></say-hello>,可以跟美人打招呼。不过看看人家ng内置的下令,都以那般用的:ng-model=”m”,ng-repeat=”a
in
array”,不单单是作为质量,还足以赋值给它,与成效域中的贰个变量绑定好,内容就足以动态变化了。假使大家的sayHello可以如此用:<say-hello
speak=”content”>美丽的女子</say-hello>,把要对嫦娥说的话写在2个变量content中,然后一旦在controller中修改content的值,页面就可以显得对常娥说的不比的话。这样就灵活多了,不至于见了月宫仙子只会说一句hello,然后就从未有过然后。

为了完成如此的功效,大家要求动用scope参数,上面来介绍一下。

行使scope为命令划分作用域

  顾名思义,scope肯定是跟成效域有关的2个参数,它的作用是描述指令与父作用域的涉嫌,这几个父作用域是指什么吗?想象一下大家采取指令的现象,页面结构应该是以此样子:

<div ng-controller=”testC”>

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

</div>  

外层肯定会有2个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吧。

最得力的要么取值为第3种,二个对象,可以用键值来显式的指明要从父功能域中运用性质的措施。当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>

  答案小编就隐瞒了,简单的很。下边有更要紧的事务要做,大家说好了要写一个当真能用的事物来着。接下来就整合所学到的东西来写3个折叠菜单,即点击可开展,再点击一次就裁减回去的菜系。

控制器及指令的代码如下(例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组件是个科学的想法,首先利用起来方便,只要求2个标签只怕性质就可以了,其次是可复用性高,通过controller可以动态控制ui组件的情节,而且具备双向绑定的力量。当我们想做的机件稍微复杂一点,就不是三个命令可以消除的了,就需求指令与指令的搭档才方可做到,那就须要开展指令间通讯。

想转手大家进行模块化开发的时候的原理,3个模块暴光(exports)对外的接口,别的一个模块引用(require)它,便足以动用它所提供的劳务了。ng的命令间合作也是其一规律,那也多亏自定义指令时controller参数和require参数的成效。

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

 

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

它是贰个结构器函数,今后得以社团出三个实例传给引用它的指令。为何叫controller(控制器)呢?其实就是报告引用它的授命,你能够操纵自己。至于可以决定这些东西吧,就须求在函数体中展开定义了。先看controller可以拔取的参数,成效域、节点、节点的习性、节点内容的迁徙,这几个都得以透过正视注入被传进来,所以您可以根据必要只写要用的参数。关于什么对外暴光接口,大家在底下的例证来证实。

require参数便是用来指明须求依赖的其它指令,它的值是一个字符串,就是所依赖的授命的名字,那样框架就能依照你钦命的名字来从对应的下令上边寻找定义好的controller了。但是还稍稍有点专门的地点,为了让框架寻找的时候更自在些,大家得以在名字前面加个小小的前缀:^,表示从父节点上搜寻,使用起来像这么:require
:
‘^directiveName’,尽管不加,$compile服务只会从节点自个儿寻找。其它还足以采纳前缀:?,在此以前缀将告诉$compile服务,若是所需的controller没找到,不要抛出尤其。

所要求精通的知识点就这一个,接下去是例证时间,如故是从书上抄来的3个例证,大家要做的是一个手风琴菜单,就是多个折叠菜单并列在联合,此例子用来显示指令间的通讯再合适可是。

率先大家要求定义外层的一个协会,起名为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中的代码,大家定义了3个折叠菜单数组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”函数来检测变化。每一回检测都会费用时间,所以富含复杂数据结构的大型列表将降低你使用的运维速度。

加强品质的先决条件

时间记下指令

为了测量3个列表渲染所消费的时日,咱们写了七个简便的次序,通过行使“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”工具可协理通晓渲染品质,还可兆示出1个JavaScript义务所开销的CPU时间。

通过限制列表的分寸举办着力的调优

消除该难点,最好的点子是限量所展现列表的轻重缓急。可透过分页、添加无限滚动条来促成。

分页,大家可以接纳AngularJS的“limitTo”过滤器(AngularJS1.1.4本子之后)和“startFrom”过滤器。可以经过限制突显列表的大小来减弱渲染时间。那是缩减渲染时间最便捷的办法。

6.3.2七大调优法则

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

那是最显眼的缓解方案,因为数量绑定是性质难题最或许的起点。假若您只想显示三次列表,并不需求更新、改变多少,放任数据绑定是绝佳的法门。但是可惜的是,你会失掉对数码的控制权,但除此之外该法,我们别无拔取。

2.毫不使用内联方法总计数据

为了在控制器中直接过滤列表,不要使用可获取过滤链接的章程。“ng-repeat”会评估每一种表明式。在大家的案例中,“filteredItems()”再次回到过滤链接。若是评估进度很慢,它将火速下跌整个应用的进程。

 

l <li ng-repeat=”item in filteredItems()”>
//那并不是3个好法子,因为要反复地评估。   

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隐藏多余的成分

对此长列表,使用过滤同样会下落工作功能,因为逐个过滤都会创制3个原始列表的子链接。在许多景况下,数据尚未生成,过滤结果也会保持不变。所以对数据列表举行预过滤,并依据事态将它应用到视图中,会大大节约处理时间。

在ng-repeat指令中应用过滤器,各种过滤器会回去三个本来链接的子集。AngularJS
从DOM中移除多余成分(通过调用
$destroy),同时也会从$scope中移除他们。当过滤器的输入发生变更时,子集也会趁着变化,成分必须开展双重链接,或着再调用$destroy。

绝大多数状态下,那样做很好,但假诺用户时时过滤,或许列表至极了不起,不断的链接与

销毁将影响属性。为了加紧过滤的进程,你可以运用ng-show和ng-hide指令。在控制器中,进行过滤,并为每项添加2个性子。依靠该属性来触发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.有关过滤的小提醒:防抖动输入

涸泽而渔第五点指出的不断过滤难题的另贰个办法是防抖动用户输入。例如,假若用户输入二个寻觅关键词,只当用户为止输入后,过滤器才会被激活。使用该防抖动服务的一个很好的解决方案请见:
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
起首向上层成分(例如,由最内层成分到最外层成分)开首冒泡,并且在传诵途径上具备绑定了同一事件的要素若满意匹配的拔取器,那么那么些元素上的轩然大波也会被触发。

信托事件有多少个优势:他们能在后人成分添加到文档后,能够处理那个事件;代管事人件的另3个便宜就是,当要求监视很多因素的时候,代总管件的支付更小。

比如说,在多少个表格的 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 上添加代总管件。