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>

4. 路由局部刷新位置:

<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。

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

<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;

});

Angular入门教程四的更多相关文章

  1. 无废话ExtJs 入门教程四[表单:FormPanel]

    无废话ExtJs 入门教程四[表单:FormPanel] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在窗体里加了个表单.如下所示代码区的第28行位置,items:form. ...

  2. PySide——Python图形化界面入门教程(四)

    PySide——Python图形化界面入门教程(四) ——创建自己的信号槽 ——Creating Your Own Signals and Slots 翻译自:http://pythoncentral ...

  3. Elasticsearch入门教程(四):Elasticsearch文档CURD

    原文:Elasticsearch入门教程(四):Elasticsearch文档CURD 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接: ...

  4. RabbitMQ入门教程(四):工作队列(Work Queues)

    原文:RabbitMQ入门教程(四):工作队列(Work Queues) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https:/ ...

  5. JasperReports入门教程(四):多数据源

    JasperReports入门教程(四):多数据源 背景 在报表使用中,一个页面需要打印多个表格,每个表格分别使用不同的数据源是很常见的一个需求.假如我们现在有一个需求如下:需要在一个报表同时打印所有 ...

  6. WebGL入门教程(四)-webgl颜色

    前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL入门教程(三)-webgl动画 颜色效果图: 操作步骤: 1.创建HTML5 canva ...

  7. 中文代码示例之Angular入门教程尝试

    原址: https://zhuanlan.zhihu.com/p/30853705 原文: 中文代码示例教程之Angular尝试 为了检验中文命名在Angular中的支持程度, 把Angular官方入 ...

  8. 2017-11-07 中文代码示例之Angular入门教程尝试

    "中文编程"知乎专栏原址 原文: 中文代码示例教程之Angular尝试 为了检验中文命名在Angular中的支持程度, 把Angular官方入门教程的示例代码中尽量使用了中文命名. ...

  9. Spring Cloud 入门教程(四): 分布式环境下自动发现配置服务

    前一章, 我们的Hello world应用服务,通过配置服务器Config Server获取到了我们配置的hello信息“hello world”. 但自己的配置文件中必须配置config serve ...

随机推荐

  1. 多事实表 SQL实现和SSAS中MDX实现的差异

    如图,资产负债视图是事实表,损益表也是事实表.都包含年.月.组织.账簿信息. SQL如何实现呢? 简单粗暴,事实事实表串事实表,Full Join select 损益视图.年 ,损益视图.年月 ,损益 ...

  2. ThinkPHP 5.0.x SQL注入分析

    前言 前段时间,晴天师傅在朋友圈发了一张ThinkPHP 注入的截图.最近几天忙于找工作的事情,没来得及看.趁着中午赶紧搭起环境分析一波.Think PHP就不介绍了,搞PHP的都应该知道. 环境搭建 ...

  3. 【性能测试】脚本开发,最普通的http协议脚本2

    Action() { lr_start_transaction("FM0075基金购买"); web_submit_data("ehouse_ehGetPwdRandom ...

  4. 毫秒查询9位数qq号码是否存在-BitMap算法应用

    实现详情请查看博客园 https://www.cnblogs.com/caoke/p/10793885.html 随机注册10万个放入BitMap,然后查询qq号码是否已存在,算法复杂度O(1). / ...

  5. mysql使用常见问题

    常见问题之一: 启动mysql时显示: The server quit without updating PID file 1.可能是/usr/local/mysql/data/mysql.pid文件 ...

  6. 没事用html5 canvas画一个仪表盘自用,自适应的哦

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. (转)CentOS 7 下 MySQL 5.7 配置 Percona Xtrabackup

    CentOS 7 下 MySQL 5.7 配置 Percona Xtrabackup 原文:http://qizhanming.com/blog/2017/05/10/install-percona- ...

  8. sql中COUNT(*)、COUNT(字段名)的区别

    数据表:其中IT002的Fname是null. 执行sql: ) FROM T_Employee 结果: 结论:COUNT(*)统计的是结果集的总条数,而COUNT(FName)统计的则是除了结果集中 ...

  9. hibernate多对多单向关联

    多对多单向,一个学生可以有多个老师,一个老师也可以教多个学生.老师可以找到他的学生,学生找不到教他的老师. 老师类Teacher: package com.oracle.hibernate; impo ...

  10. SpringBoot 整合 Logback

    Logback is intended as a successor to the popular log4j project, picking up where log4j leaves off.L ...