zoukankan      html  css  js  c++  java
  • angularjs 路由机制

    前言

    AngularJS路由主要有内置的ngRoute和一个基于ngRoute开发的第三方路由模块ui-router,内置的ngRoute有时满足开发需求,使用ui-router可以解决很多原生ngRoute的不足。 
    AngularJS的路由实际上是一种纯前端的解决方案,它的本质是:当请求一个url时,根据路由配置这个url,然后再请求模板片段,并插入到ng-view中。AngularJS的路由更倾向于通过改变url进行页面的局部刷新。

     

    一 ngRoute

    使用ngRoute需要额外加载这个模块文件,如:

    <script src="../angular/angular.js"></script>
    <script src="../angular-route/angular-route.js"></script>

    同时还需要在模块声明中注入对ngRoute的依赖:

    var app = angular.module('MyApp', ['ngRoute']);

    使用ngRoute包含以下几个内容:

    名称所属使用
    ngView directive 提供不同路由模板插入的视图层
    $routeProvider provider 提供路由配置
    $route service 用于构建各个路由的url,view,controller的关系
    $routeParams service 解析返回路由中带有的参数

    $routeProvider提供了定义路由表的服务,有两个核心方法: 
    1. when(path,route) 
    path: string类型,表示该条路由规则所匹配的路径。 
    注意: 如果路径中需要匹配参数,如path路径是:/show/:name,如果地址栏为:/show/lydia,那么这里的name以及所对应的值lydia都会保存在$routeParams服务中,需要通过$routeParams.name来获取。 
    route: object类型,用来指定一系列配置项。

    配置说明
    controller 控制器名称
    controllerAs 给控制器起个别名
    template 对应路径的页面模板,会出现在ng-view处
    templateUrl 对应模板的路径
    resolve 该属性会以键值对对象的形式,给路由相关的控制器绑定服务或者值。然后把执行的结果值或者对应的服务引用,注入到控制器中。如果resolve中是一个promise对象,那么会等它执行成功后,才注入到控制器中,此时控制器会等待resolve中的执行结果。
    redirectTo 重定向地址
    reloadOnSearch 设置是否在只有地址改变时,才加载对应的模板。search和params改变都不会加载模板。默认为true,当$location.search()发生变化时会重新加载路由。
    caseInsensitiveMatch 路径区分大小写

    2.otherwise(params) 
    对应了路径匹配不到时的情况。

    使用方法

    第一步:添加页面 
    html页面,哪里需要局部刷新,哪里就用ng-view:

    <body ng-app="routeApp">
    <div ng-view></div>
    
    
    <script src="bower_components/angular/angular.js"></script>
    <script src="scripts/app.js"></script>
    <script src="scripts/controllers/main.js"></script>
    </body>

    第二步:controller添加路由配置

    var routeApp = angular.module('routeApp',[]);
    routeApp.config(['$routeProvider',function ($routeProvider) {
          $routeProvider
          .when('/list', {
            templateUrl: 'views/route/list.html',
            controller: 'RouteListCtl'
          })
          .when('/list/:id', {
              templateUrl: 'views/route/detail.html',
              controller: 'RouteDetailCtl'
          })
          .otherwise({
            redirectTo: '/list'
          });
    }]);

    再添加两个controller

    routeApp.controller('RouteListCtl',function($scope) {
    });
    routeApp.controller('RouteDetailCtl',function($scope, $routeParams) {
        $scope.id = $routeParams.id;
    });

    上面这个例子只是简单的例举一下带参数和不带参数的url的路由配置和获取方法,具体的html页面和结果就不展示了。

    resolve的用法

    $routeProvider的第二个参数是路由的一些具体配置项目,这里有一个比较重要的配置,即resolve。配置resolve意味着在进入这个路由之前必须等待resolve中的数据返回,也就是说,在跳转目标路由之前先做一些额外工作去预加载数据,只有当数据准备妥当之后,才会去载入目标路由的模板和执行相应的controller。

    $routeProvider
        .when("/news", {
            templateUrl: "newsView.html",
            controller: "newsController",
            resolve: {
                message: function(messageService){
                    return messageService.getMessage();
            }
        }
    })

    在上例中,只有message有值的情况下才会去加载html页面和js。 
    在路由跳转之前,会触发resolve下的所有promise,只有当所有的promise都被正确的resolve之后才会进行路由切换,此时$route会抛出$routeChangeSuccess的事件,如果没有被正确的resolve,那么$route会抛出$routeChangeError的事件,并且终止路由切换。

    二 ui-router

    ui-router相比ngRoute的优势在于,一个页面可以嵌套多个视图,,创建嵌套分层的视图,多个视图去控制某一个视图等。 
    安装:

    npm install angular-ui-router --save

    同时在项目中引入:

    <script type="text/javascript" src="app/bower_components/angular-ui-router/release/angular-ui-router.js"></script>

    对应的controller中引入ui-router的依赖:

    angular.module('myApp', ['ui.router']);

    ui-router包含的内容与ngRoute很像,可以进行一下类比:

    ngRouteui-router
    ng-view ui-view
    $routeProvider $stateProvider
    $routeParams $stateParams
    $route $state

    1.$state配置参数

    参数说明
    url 默认相对路径(以^开头的是绝对路径)
    views views里的每个子视图可以包含自己的模板、控制器和预载入数据
    abstract 抽象模板不能被激活
    template HTML字符串或者返回HTML字符串的函数

    举个例子: 
    html页面:

    <body>
      <div>
      <div ui-view="filters"></div>
      <div ui-view="mailbox"></div>
      <div ui-view="priority"></div>
    </div>
    </body>

    js:

    angular.module('myApp').config(['$stateProvider',function($stateProvider) {
    $stateProvider
      .state('report',{
        views: {
          'filters': {
            template: '<h4>Filter inbox</h4>',
            controller: function($scope) {}
          },
          'mailbox': {
            templateUrl: 'partials/mailbox.html'
          },
          'priority': {
            template: '<h4>Priority inbox</h4>',
            resolve: {
              facebook: function() {
                return FB.messages();
              }
            }
          }
        }
      }).state('blog',{
            url:'/blog',
            views:{
                'container':{templateUrl:'templates/blog/layout.html'}
            }
        })

    abstract抽象模板 
    抽象模板不能被激活,但是它的子模板可以被激活。抽象模板通常用于提供一个包括了很多视图的模板,它可以传递$scope作用域给子模板,也可以在同一个url下传递自定义数据或预加载的依赖。如:

    $stateProvider
      .state('admin', {
        abstract: true,
        url: '/admin',
        template: '<div ui-view></div>'
      })
      .state('admin.index', {
        url: '/index',
        template: '<h3>Admin index</h3>'
      })
      .state('admin.users', {
        url: '/users',
        template: '<ul>...</ul>'
      });

    2.$stateParams 
    使用$stateparams来提取在url中的不同参数。 
    如果一个url是这样的:

    '/inbox/:inboxId/messages/{sorted}?from&to'

    当用户访问时,请求的url是这样的:

    '/inbox/123/messages/ascending?from=10&to=20'

    那么$stateParams对象的值为:

    {inboxId: '123', sorted: 'ascending', from: 10, to: 20}

    3.$urlRouterProvider 
    $urlRouterProvider和ngRoute一样,有when()和otherwise()两种用法,除此之外,还有rule()方法,可以越过任何url的匹配或者在其他路由前做路由修改,函数返回一个有效的路径的字符串。

    app.config(function($urlRouterProvider){
        // 忽略url的大小写
        $urlRouterProvider.rule(function ($injector, $location) {
            var path = $location.path(), normalized = path.toLowerCase();
            if (path != normalized) 
                return normalized;
        });
    })

    路由的匹配方式

    url:"/user/:id" 
    url:"/user/{id}"

    上面的这两个写法是一样的。

    // 只会匹配 contactId 为1到8位的数字
    url: "/contacts/{contactId:[0-9]{1,8}}"

    可以通过?来指定参数作为查询参数,如:

    url: "/contacts?myParam"     //匹配 "/contacts?myParam=value"
    
    url: "/contacts?myParam1&myParam2"
    // 匹配 "/contacts?myParam1=value1&myParam2=wowcool"
  • 相关阅读:
    Oracle 数据库对象
    oracle基础知识
    中文乱码问题
    会话技术Cookie&Session
    HttpServletRequest请求
    JAVA基础之设置随机成语验证码
    HttpServletResponse响应
    Spring注解 AOP@Aspect
    Visual studio Code使用技巧
    缓存相关
  • 原文地址:https://www.cnblogs.com/lyy-2016/p/8762999.html
Copyright © 2011-2022 走看看