发表于: 2017-04-21 21:59:23

0 1258


今天完成的事情:

完成了找精英页面;

制作小课堂PPT并分享之;

明天计划的事情:

主攻找职位页面,搜索框,轮播图及左侧列表标签三部分;

遇到的问题:

暂无;

收获:

1.背景介绍

路由(route),几乎所有的MVC(VM)框架都应该具有的特性,因为它是前端构建单页面应用(SPA)必不可少的组成部分。

对于angular而言,自然也有内置的路由模块-ngRoute。但由于功能的局限性,往往不能满足开发需求。于是,AngularUI团队基于ngRoute开发了第三方模块-UI-Router。

2.知识剖析

UI-Router注入与配置

和ngRoute一样,UI-Router首先需要作为依赖注入应用

angular.module("myApp", ["ui.router"]).config(function($stateProvider){

     $stateProvider.state(stateName, stateConfig);

 })

            

html标签中设置视图插入位置: 如

<div ui-view></div>        

UI-router基本参数

$stateProvider:配置应用状态

用法:$stateProvider.state(stateName, stateConfig)

stateConfig:对象,该路由的具体配置项

url:默认相对路径(以^开头的是绝对路径)

views:每个子视图可以包含自己的模板、控制器和预载入数据。设置多视图。如果在单个状态不需要此属性。

template: HTML字符串或者返回HTML字符串的函数(一般用templateUrl)

templateUrl: HTML模板的路径或者返回HTML模板路径的函数

controller、controllerProvider:指定任何已经被注册的控制器或者一个作为控制器的函数

resolve:预载入依赖或数据,注入到控制器中。

onEnter, onExit:路由进入OR退出时执行的函数

1.views:当一个页面需要嵌入多个视图时,可以配置参数,这里介绍相对路径的配置,绝对路径用@的形式,可查看官方文档

  html

  <div ui-view="filters"></div>

  <div ui-view="tabledata"></div>

  <div ui-view="graph"></div>

$stateProvider

  .state('report',{

    views: {

      'filters': {

        templateUrl: 'report-filters.html',//指定模板

        controller: function($scope){ ... controller stuff just for filters view ... }//控制器

      },

      'tabledata': {

        templateUrl: 'report-table.html',

        controller: function($scope){ ... controller stuff just for tabledata view ... }

      },

      'graph': {

        templateUrl: 'report-graph.html',

        controller: function($scope){ ... controller stuff just for graph view ... }

      }

    }

  })      

resolve:向该路由控制器注入依赖或数据,格式{string|function}

 resolve: {promiseObj:  function($http){

            return $http({method: 'GET', url: '/someUrl'})

               .then (function (data) {

                   return doSomeStuffFirst(data);

               });

         }},   

 //在controller中注入promiseObj获取值

 controller: function($scope,promiseObj){

       $scope.items = promiseObj.data.items;

   }

onEnter 和 onExit 回调函数,在进入该路由和离开该路由时触发

//这个做登陆验证也不错,进入需要登陆的模块时,检测登陆状态,未登陆就跳转,做一些弹窗也可以

 $stateProvider.state("contacts", {

  template: '{{title}}',

  resolve: { title: 'My Contacts' },

  controller: function($scope, title){

    $scope.title = title;

  },

  onEnter: function(title){

    if (title) { ... do something ... }

  },

  onExit: function(title){

    if (title) { ... do something ... }

  }

})      

3.常见问题

1、路由间参数如何传递?

2、嵌套路由父子关系如何定义?

4.解决方案

1、路由间参数如何传递?

一、通过url传递:url中传递参数也有好几种形式,如(ui-sref="a({}),$state.go('a',({}))")

url:"/contacts/:contactId" //url中传入参数为 /contacts/42

url: "/contacts/{contactId}"

 //若为查询参数

url: "/contacts?myParam" //将匹配url的“/ contacts?myParam = value”

url: "/contacts?myParam1&myParam2" //will match to url of "/contacts?myParam1=value1&myParam2=wowcool"            

二、通过params属性设置             

.state('contacts', {

        url: "/contacts",

        params: {

            param1: null

        },

        templateUrl: 'contacts.html'

    })

<a ui-sref="contacts({param1: value1})">View Contacts</a> or $state.go('contacts', {param1: value1})

2、嵌套路由父子关系如何定义?            

$stateProvider

    .state('contacts.list', {});//点标记法(推荐)

$stateProvider //parent属性

    .state({

        name: 'list',       // 状态名也可以直接在配置里指定

        parent: 'contacts'  // 父路由的状态名

    });         

5.编码实战             

 .state('field.moduleDetail', {

                    url: '/moduleEdit?id',

                    templateUrl: 'Pages/moduleEdit.html',

                    controller: 'moduleEditController',

                    controllerAs: 'vm',

                })

ui-sref="field.moduleDetail({id:item.id})" //url 中http://admin.luoboduo.com/#/panel/moduleEdit?id=1

            

 .state('field.companyList', { //url:http://admin.luoboduo.com/#/panel/professionMsg (field URL为panel)

                url: '/companyMsg',

                templateUrl: 'Pages/companyMsg.html',

                controller: 'CompanyListController',

                controllerAs: 'vm'

            })

      

6.扩展思考

UI-router工作原理?

路由对于前端MVC(VM)而言,就是将hash值(#xxx)与一系列的路由规则进行查找匹配,匹配出一个符合条件的规则,然后根据这个规则,进行数据的获取,以及页面的渲染。

大致过程

1.创建路由规则

.state('home', {

        url: '/abc',

        template: 'hello world'

    });

首先,$urlRouterProvider创建并存储一个state对象,里面包含着该路由规则的所有配置信息。然后,调用$urlRouterProvider.when(...)方法,进行路由的注册(之前是路由的创建)

2.路由查找匹配

(1)angular 在刚开始的$digest时,$rootScope会触发$locationChangeSuccess事件(angular在每次浏览器hash change的时候也会触发$locationChangeSuccess事件)

(2)ui.router 监听了$locationChangeSuccess事件,于是开始通过遍历一系列rules,进行路由查找匹配

(3)当匹配到路由后,就通过$state.transitionTo(state,...),跳转激活对应的state

(4)最后,完成数据请求和模板的渲染

当我们访问http://xxxx#/abc的时候,这个路由规则被匹配到,对应的模板会被填到某个div[ui-view]中

一般路由要对rules进行遍历,但ui-router进行了优化:

ui.router在创建路由时,会实例化一个对应的state对象,并存储起来(states集合里面),每一个state对象都有一个state.name进行唯一标识(如:'home')

当通过ui-sref(会调用$state.go())指令或直接通过$state.go()跳转时,ui-sref="home"指令会给对应的dom添加click事件,然后根据state.name,直接跳转到对应的state,跳转到对应的state之后,ui.router会改变hash,所以触发’$locationChangeSuccess'事件,然后执行回调,在回调中通过一个判断代码规避循环rules

所以尽量避免直接使用href="#/xxx"来改变hash,然后跳转到对应state。这么做将进行rules遍历,浪费性能

7.参考文献

参考一:angular中的路由http://www.cnblogs.com/01-02/p/6071392.html

参考二:uiroueter官方文档 https://github.com/angular-ui/ui-router/wiki/Quick-Reference#stateprovider-1

8.更多讨论

uiRouter中还要很多对应事件,了解之后在项目中很有帮助

state事件

$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ ... }) 

$rootScope.$on('$stateNotFound', function(event, unfoundState, fromState, fromParams){ ... }) 

$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ ... })

$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error){ ... })

view事件

View被加载但是DOM树构建之前时:

$scope.$on('$viewContentLoading', function(event, viewConfig){ ... }); 

View被加载而且DOM树构建完成时:

$scope.$on('$viewContentLoaded', function(event){ ... });



返回列表 返回列表
评论

    分享到