【ionic+angularjs】angularjs ui-router路由简介($urlRouter、
之前有写过一篇关于Angular自带的路由:ngRoute。今天来说说Angular的第三方路由:ui-router。那么有人就会问:为什么Angular有了自带的路由,我们还需要用ui-router呢?这里简单明了的说明下ngRoute和ui-router的区别吧,其实也没很大的区别,主要的就是ngRoute针对于单视图,而ui-router可用于多视图(这里说的视图是指在页面内我们可控制的,可变化的区域)。比如: 我们点击了一个link,我们需要在视图中跳转到指定的一个页面,那么ngRoute已经满足了我们的需求,而当我们点击的时候,需要在分别在不同的地方跳转两个不同的页面的时候,ngRoute就不够用了,我们就需要用到ui-router。 ui-router $urlRouterProvider angular.module('Demo',['ui.router']) .config(["$urlRouterProvider",function(){ $urlRouterProvider.deferIntercept(defer); // defer = true/false }]) 这是源码部分: this.deferIntercept = function (defer) { if (defer === undefined) defer = true; interceptDeferred = defer; // 默认是true }; otherwise(rule); angular.module('Demo',function(){ $urlRouterProvider.otherwise(rule); // rule = 重定向的url规则 }]) rule(rule); angular.module('Demo',function($urlRouterProvider){ $urlRouterProvider.rule(function ($injector,$location) { var path = $location.path(),normalized = path.toLowerCase(); if (path !== normalized) { return normalized; } }); }]) when(what,handler); angular.module('Demo',['ui.router']); .config(["$urlRouterProvider",function ($urlRouterProvider) { $urlRouterProvider.when($state.url,function ($match,$stateParams) { if ($state.$current.navigable !== state || !equalForKeys($match,$stateParams) { $state.transitionTo(state,$match,false); } }); }]); $urlRouter $bob = $urlRouter.href(new UrlMatcher("/about/:person"),{ person: "bob" }); // $bob == "/about/bob"; sync(); sync(); $state 方法: Go(to,options); $state.go('contact.detail'); href(stateOeName,options); $state.href("about.person",{ person: "bob" }) include(stateOrName,options); <div ng-class="{highlighted:$state.includes('.item')}">Item</div> $state.$current.name = 'contacts.details.item'; $state.includes("contacts"); // true $state.includes("contacts.details"); // true $state.includes("contacts.details.item"); // true $state.includes("contacts.list"); // false $state.includes("about"); // false 全局模式: $state.$current.name = 'contacts.details.item.url'; $state.includes("*.details.*.*"); // true $state.includes("*.details.**"); // true $state.includes("**.item.**"); // true $state.includes("*.details.item.url"); // true $state.includes("*.details.*.url"); // true $state.includes("*.details.*"); // false $state.includes("item.**"); // false is(stateOrName,options); <div ng-class="{highlighted: $state.is('.item')}">Item</div> $state.$current.name = 'contacts.details.item'; $state.is('contact.details.item'); // true $state.is(contactDetailItemStateObject); // true reload(state); $state.reload('contact.detail'); transitionTo(to,toParams,options); $state.transitionTo($state.current,$stateParams,{ reload: true,inherit: false,notify: true }); 事件: $stateProvider 依赖:$urlRouterProvider $urlMatcherFactoryProvider $stateProvider.decorator('views',function (state,parent) { var result = {},views = parent(state); angular.forEach(views,function (config,name) { var autoName = (state.name + '.' + name).replace('.','/'); config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html'; result[name] = config; }); return result; }); $stateProvider.state('home',{ views: { 'contact.list': { controller: 'ListController' },'contact.item': { controller: 'ItemController' } } }); $state.go('home'); 以上代码修饰了“views”直接通过state的名称绑定完对应的页面模板。
<a ui-sref="app.index">首页</a> <!-- 这里是正常的跳转 --> <a ui-sref="app.index({id:yourId})">你的主页</a> <!-- 这里是带参数对象的跳转,名称是id,值是yourId --> 简单的使用代码(ui-router的单视图): <div ng-app="Demo" ng-controller="testCtrl as ctrl"> <ol> <li><a ui-sref="app">app</a></li> <li><a ui-sref="test">test</a></li> </ol> <div ui-view></div> <script type="text/ng-template" id="'page1.html'"> this is page 1 for app. </script> <script type="text/ng-template" id="'page3.html'"> this is page 1 for test. </script> </div> angular.module('Demo',['ui.router']) .config(["$stateProvider","$urlRouterProvider",routeConfig]) .controller("testCtrl",angular.noop) function routeConfig($stateProvider,$urlRouterProvider){ $urlRouterProvider.otherwise("/app"); $stateProvider .state("app",{ url:"/app",templateUrl:"'page1.html'" }) .state("test",{ url:"/test",templateUrl:"'page3.html'" }) } 使用代码(ui-router的多视图): <div ng-app="Demo" ng-controller="testCtrl as ctrl"> <ol> <li><a ui-sref="app.page1">app</a></li> <li><a ui-sref="test.page1({id:1})">test</a></li> </ol> <div ui-view></div> <script type="text/ng-template" id="'layout.html'"> <div ui-view="nav@"></div> <div ui-view></div> </script> <script type="text/ng-template" id="'nav1.html'"> <ol> <li><a ui-sref="app.page1">app.page1</a></li> <li><a ui-sref="app.page2">app.page2</a></li </ol> </script> <script type="text/ng-template" id="'nav2.html'"> <ol> <li><a ui-sref="test.page1({id:1})">test.page1</a></li> <li><a ui-sref="test.page2">test.page2</a></li </ol> </script> <script type="text/ng-template" id="'page1.html'"> this is page 1 for app. </script> <script type="text/ng-template" id="'page2.html'"> this is page 2 for app. </script> <script type="text/ng-template" id="'page3.html'"> this is page 1 for test. </script> <script type="text/ng-template" id="'page4.html'"> this is page 2 for test. </script> </div> angular.module('Demo',$urlRouterProvider){ $urlRouterProvider.otherwise("/app/page1"); $stateProvider .state("app",{ url:"/app",views:{ "":{ templateUrl:"'layout.html'" },"nav":{ templateUrl:"'nav1.html'" } } }) .state("app.page1",{ url:"/page1",templateUrl:"'page1.html'" }) .state("app.page2",{ url:"/page2",templateUrl:"'page2.html'" }) .state("test",{ url:"/test",views:{ "":{ templateUrl:"'layout.html'" },"nav":{ templateUrl:"'nav2.html'" } } }) .state("test.page1",{ url:"/page1?:id",templateUrl:"'page3.html'",controller:["$stateParams",function($stateParams){ console.log($stateParams.id);// 1 这里实现传参 }],params:{ id:null } }) .state("test.page2",templateUrl:"'page4.html'" }) } 1.配置使用ui-router1.1导入js文件 需要注意的是:必须导入angular.min.js这个文件,且angular.min.js必须导入在angular-ui-router.min.js前面。 <script type="text/javascript" src="JS/angular.min.js"></script> <script type="text/javascript" src="JS/angular-ui-router.min.js"></script> 1.2注入angular模块 var app = angular.module('myApp',['ui.router']);
1.3定义视图 ui-view替代的是ngroute路由的ng-view。 <div ui-view></div> ui-view替代的是ngroute路由的ng-view。 <div ui-view></div> 1.4配置路由状态 app.config(["$stateProvider",function ($stateProvider){ $stateProvider .state("home",{ //导航用的名字,如<a ui-sref="login">login</a>里的login url: '/',//访问路径 template:'<div>模板内容......</div>' }) }]); 2.简单示例<html> <head> <title>ui-router</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- 导入JS --> <script type="text/javascript" src="JS/angular.min.js"></script> <script type="text/javascript" src="JS/angular-ui-router.min.js"></script> </head> <body > <div ng-app="myApp"> <div ui-view></div> <!-- 视图 --> </div> </body> <script type="text/javascript"> //定义模板,并注入ui-router var app = angular.module('myApp',['ui.router']); //对服务进行参数初始化,这里配stateProvider服务的视图控制 app.config(["$stateProvider",function ($stateProvider) { $stateProvider .state("home",{ url: '/',template:'<div>模板内容......</div>' }) }]); </script> </html> 3.嵌套路由的实现通过url参数的设置实现路由的嵌套(父路由与子路由通过”.“连接就形成了子路由)。嵌套路由可实现多层次的ui-view。 <body > <div ng-app="myApp" > <a ui-sref="parent">点我显示父view内容</a> <a ui-sref="parent.child">点我显示父view与子view内容</a> <div ui-view></div> <!-- 父View --> </div> </body> <script type="text/javascript"> var app = angular.module('myApp',['ui.router']); app.config(["$stateProvider",function ($stateProvider) { $stateProvider .state("parent",{//父路由 url: '/parent',template:'<div>parent' +'<div ui-view><div>'// 子View +'</div>' }) .state("parent.child",{//子路由 url: '/child',template:'<div>child</div>' }) }]); </script> 上面的是相对路径方式: .state("parent.child",{ url: '^/child',template:'<div>child</div>' }) 此时,’parent’将匹配…./index.html#/parent;‘parent.child’将匹配…./index.html#/child。 4. 通过views实现多视图多个示图时,使用views属性。该属性里包含了哪些ui-view,则对应的template或templateUrl里的内容就会填充该ui-view。 同一个状态下有多个视图示例: <body > <div ng-app="myApp" > <a ui-sref="index">点我显示index内容</a> <div ui-view="header"></div> <div ui-view="nav"></div> <div ui-view="body"></div> </div> </body> <script type="text/javascript"> var app = angular.module('myApp',function ($stateProvider) { $stateProvider .state("index",{ url: '/index',views:{ 'header':{template:"<div>头部内容</div>"},'nav':{template:"<div>菜单内容</div>"},'body':{template:"<div>展示内容</div>"} } }) }]); </script> 5.ui-view的定位@的作用 是用来绝对定位view,即说明该ui-view属于哪个模板。如:’header@index’表示名为header的view属于index模板。绝对和相对路径的效果一样,请看如下代码: <body > <div ng-app="myApp" > <a ui-sref="index">show index</a> <a ui-sref="index.content1">content222221</a> <a ui-sref="index.content2">content222222</a> <div ui-view="index"><div> </div> </body> <script type="text/javascript"> var app = angular.module('myApp',views:{ 'index':{template:"<div><div ui-view='header'></div> <div ui-view='nav'></div> <div ui-view='body'></div> </div>"},//这里必须要绝对定位 'header@index':{template:"<div>头部内容header</div>"},'nav@index':{template:"<div>菜单内容nav</div>"},'body@index':{template:"<div>展示内容contents</div>"} } }) //绝对定位 .state("index.content1",{ url: '/content1',views:{ 'body@index':{template:"<div>content22222222222222211</div>"} //'body@index'表时名为body的view使用index模板 } }) //相对定位:该状态的里的名为body的ui-view为相对路径下的(即没有说明具体是哪个模板下的) .state("index.content2",{ url: '/content2',views:{ 'body':{template:"<div>content2222222222222222222</div>"}// } }) }]); </script> 由上面代码可知,相对定位不能找到的ui-view需要用@来绝对定位。 6.URL路由传参(通过$stateParams服务获取参数)有 <body > <div ng-app="myApp" > <a ui-sref="index({id:30})">show index</a> <a ui-sref="test({username:'peter'})">show test</a> <div ui-view></div> </div> </body> <script type="text/javascript"> var app = angular.module('myApp',template:"<div>homePage</div>" }) .state("index",{ url: '/index/:id',template:"<div>indexcontent</div>",controller:function($stateParams){ alert($stateParams.id) } }) .state("test",{ url: '/test/:username',template:"<div>testContent</div>",controller:function($stateParams){ alert($stateParams.username) } }) }]); </script> 7.Resolve(预载入)参考资料: 使用预载入功能,开发者可以预先载入一系列依赖或者数据,然后注入到控制器中。在ngRoute中resolve选项可以允许开发者在路由到达前载入数据保证(promises)。在使用这个选项时比使用angular-route有更大的自由度。 预载入选项需要一个对象,这个对象的key即要注入到控制器的依赖,这个对象的value为需要被载入的factory服务。 如果传入的时字符串,angular-route会试图匹配已经注册的服务。如果传入的是函数,该函数将会被注入,并且该函数返回的值便是控制器的依赖之一。如果该函数返回一个数据保证(promise),这个数据保证将在控制器被实例化前被预先载入并且数据会被注入到控制器中。 <body > <div ng-app="myApp" > <a ui-sref="index">show index</a> <div ui-view></div> </div> </body> <script type="text/javascript"> var app = angular.module('myApp',{ url: '/index/{id}',resolve: { //这个函数的值会被直接返回,因为它不是数据保证 user: function() { return { name: "peter",email: "audiogroup@qq.com" } },//这个函数为数据保证,因此它将在控制器被实例化之前载入。 detail: function($http) { return $http({ method: 'JSONP',url: '/current_details' }); },//前一个数据保证也可作为依赖注入到其他数据保证中!(这个非常实用) myId: function($http,detail) { $http({ method: 'GET',url: 'http://facebook.com/api/current_user',params: { email: currentDetails.data.emails[0] } }) } },controller:function(user,detail,myId$scope){ alert(user.name) alert(user.email) console.log(detail) } }) }]); </script> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |