• Angular入门教程四


    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;

    });

  • 相关阅读:
    SpringBoot2.0 整合 Dubbo框架 ,实现RPC服务远程调用
    Spark家族:Win10系统下搭建Scala开发环境
    Linux系统:centos7下搭建Rocketmq4.3中间件,配置监控台
    Linux系统:Centos7环境搭建Redis单台和哨兵集群环境
    Linux系统:常用Linux系统管理命令总结
    Linux系统:centos7下安装Jdk8、Tomcat8、MySQL5.7环境
    Linux系统:centos7下搭建ZooKeeper3.4中间件,常用命令总结
    SpringBoot2.0 整合 Redis集群 ,实现消息队列场景
    SpringBoot2.0 基础案例(17):自定义启动页,项目打包和指定运行环境
    SpringBoot2.0 基础案例(16):配置Actuator组件,实现系统监控
  • 原文地址:https://www.cnblogs.com/ndos/p/8331795.html
Copyright © 2020-2023  润新知