• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Angularjs中UI Router全攻略

angularjs 搞代码 4年前 (2021-12-31) 28次浏览 已收录 0个评论

这篇文章主要介绍了Angularjs中UI Router全攻略,涉及到angularjs ui router的基本用法,需要的朋友参考下吧

首先给大家介绍angular-ui-router的基本用法。

如何引用依赖angular-ui-router

 angular.module('app',["ui.router"]) .config(function($stateProvider){ $stateProvider.state(stateName, stateCofig); }) 

$stateProvider.state(stateName, stateConfig)

stateName是string类型
stateConfig是object类型
//statConfig可以为空对象
$stateProvider.state(“home”,{});
//state可以有子父级
$stateProvider.state(“home”,{});
$stateProvider.state(“home.child”,{})
//state可以是链式的
$stateProvider.state(“home”,{}).state(“about”,{}).state(“photos”,{});

stateConfig包含的字段:template, templateUrl, templateProvider, controller, controllerProvider, resolve, url, params, views, abstract, onEnter, onExit, reloadOnSearch, data

$urlRouteProvider

$urlRouteProvider.when(whenPath, toPath)
$urlRouterProvider.otherwise(path)
$urlRouteProvider.rule(handler)

$state.go

$state.go(to, [,toParams],[,options])
形参to是string类型,必须,使用”^”或”.”表示相对路径;
形参toParams可空,类型是对象;
形参options可空,类型是对象,字段包括:location为bool类型默认true,inherit为bool类型默认true, relative为对象默认$state.$current,notify为bool类型默认为true, reload为bool类型默认为false

$state.go(‘photos.detail’)
$state.go(‘^’)到上一级,比如从photo.detail到photo
$state.go(‘^.list’)到相邻state,比如从photo.detail到photo.list
$state.go(‘^.detail.comment’)到孙子级state,比如从photo.detail到photo.detial.comment

ui-sref

ui-sref=’stateName’
ui-sref=’stateName({param:value, param:value})’

ui-view

==没有名称的ui-view

 <div></div> $stateProvider.state("home",{ template: "<h1>hi</h1>" }) 

或者这样配置:

 $stateProvider.state("home"{ views: { "": { template: "<h1>hi</h1>" } } }) 

==有名称的ui-view

 <div></div> $stateProvider.state("home",{ views: { "main" : { template: "<h1>hi</h1>" } } }) 

==多个ui-view

 <div></div><div></div> $stateProvider.state("home",{ views: { "":{template: "<h1>hi</h1>"}, "data": {template: "<div>data</div>"} } }) 

项目文件结构

node_modules/
partials/
…..about.html
…..home.html
…..photos.html
app.js
index.html

创建state和view

app.js

 var photoGallery = angular.module('photoGallery',["ui.router"]); photoGallery.config(function($stateProvider, $urlRouterProvider){ $urlRouterProvider.otherwise('/home'); $stateProvider .state('home',{ url: '/home', templateUrl: 'partials/home.html' }) .state('photos',{ url: '/photos', templateUrl: 'partials/photos.html' }) .state('about',{ url: '/about', templateUrl: 'partials/about.html' }) }) 

index.html

   <title></title> <h1>Welcome</h1><div></div>

state之间的跳转

index.html

 <nav class="navbar navbar-inverse"> <div class="container-fluid"> <div class="navbar-header"> <button class="navbar-toggle collapsed" type="button"> <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>Home</div><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li> Photos</li><li> About</li></ul></div></div></nav><div></div>

以上通过ui-sref属性完成state之间的跳转。

多个view以及state嵌套

有时候,一个页面上可能有多个ui-view,比如:

 <div></div><div></div>

假设,以上页面属于一个名称为parent的state中。

我们知道在ui-router中,一个state大致是这样设置的:

 <div></div><div></div>

所有state下views下的所有键值对(类似 “body@content”:{templateUrl: ‘partials/photos.html’})都被放到一个键值集合中。而ui-view的工作原理就是根据自己的属性值,到这个键值集合中去找匹配的键,找到就把对应的页面显示出来。

点击header对应的页面链接,可能会跳转到另外的子页面出现在

这个位置。这时候页面出现了子父关系,而每个页面都属于某个state,这样state间就出现了子父关系。这些跳转的子页面,在路由设置中,可能被称为parent.son1, parent.son2…这就是state的嵌套。

在现有的文件结构上增加content.html, header.html,文件结构变为:

node_modules/
partials/
…..about.html
…..home.html
…..photos.html
…..content.html
…..header.html
app.js
index.html

content.html 包含了多各ui-view, 一个ui-view和页头相关,保持不变;令一个ui-view和会根据页头上的点击呈现不同的内容

 <div></div><div></div>

header.html 把原先indext.html中nav部分放到这里来

 <nav class="navbar navbar-inverse"> <div class="container-fluid"> <div class="navbar-header"> <button class="navbar-toggle collapsed" type="button"> <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>Home</div><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li> Photos</li><li> About</li></ul></div></div></nav>

index.html 这时变成了这样

app.js 路由现在这样设置

 var photoGallery = angular.module('photoGallery',["ui.router"]); photoGallery.config(function($stateProvider, $urlRouterProvider){ $urlRouterProvider.otherwise('home'); $stateProvider .state('content',{ url: '/', views:{ "":{templateUrl: 'partials/content.html'}, "header@content":{templateUrl: 'partials/header.html'}, } }) .state('content.home',{ url: 'home', views:{ "body@content":{templateUrl: 'partials/home.html'} } }) .state('content.photos',{ url: 'photos', views:{ "body@content":{templateUrl: 'partials/photos.html'} } }) .state('content.about',{ url:'about', views:{ "body@content":{templateUrl: 'partials/about.html'} } }) }) 

这时候,页面是这样呈现出来的:

→ 来到home这个路由

 .state('content.home',{ url: 'home', views:{ "body@content":{templateUrl: 'partials/home.html'} } }) 

以上,告诉我们partials/home.html将会被加载到与”body@content”匹配的ui-view中。暂时对应的ui-view还没有出现,于是等待。

→ 路由看到index.html上的

 .state('content',{ url: '/', views:{ "":{templateUrl: 'partials/content.html'}, "header@content":{templateUrl: 'partials/header.html'}, } })

于是,就找到了content这个state下views下的 “”:{templateUrl: ‘partials/content.html’}这个键值对,把partials/content.html显示出来。

→ 分别加载partials/content.html页面上的各个部分

看到

,就加载如下:

“header@content”:{templateUrl: ‘partials/header.html’},

看到

,先加载 “body@content”:{templateUrl: ‘partials/home.html’}

→ 点击header上的链接

点击Photos,来到:

 .state('content.photos',{ url: 'photos', views:{ "body@content":{templateUrl: 'partials/photos.html'} } }) 

把partials/photos.html显示到

中去。

点击

,来到:

 .state('content.about',{ url:'about', views:{ "body@content":{templateUrl: 'partials/about.html'} } })

把partials/about.html显示到

中去。

state多级嵌套

以上,在路由设置中,state名称有content, content.photos有了这样的一层嵌套。接下来,要实现state的多级嵌套。

在photos.html页面准备加载一个子页面,叫做photos-list.html;
与photo-list.html页面相邻的还有一个页面,叫做photo-detail.html;
在photo-detail.html页面上加载一个子页面,叫做photos-detail-comment.html;

这样,页面有了嵌套关系,state也相应的会有嵌套关系。

现在,文件结构变成:

node_modules/
partials/
…..about.html
…..home.html
…..photos.html
…..content.html
…..header.html
…..photos-list.html
…..photo-detail.html
…..photos-detail-comment.html
app.js
index.html

photos.html 加一个容纳子页面的ui-view

photos

如何到达这个子页面呢?修改header中的相关部分如下:

 <nav class="navbar navbar-inverse"> <div class="container-fluid"> <div class="navbar-header"> <button class="navbar-toggle collapsed" type="button"> <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>Home</div><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li> Photos</li><li> About</li></ul></div></div>

以上,通过Photos来到photos.html的子页面photos-list.html.

photos-list.html 通过2种途径到相邻页photo-detail.html

 <h1>photos-list</h1><ul> <li>我通过相对路径到相邻的state</li><li>我通过绝对路径到相邻的state</li></ul>

photo-detail.html 又提供了来到其子页面photos-detail-comment.html的ui-view

 <h1>photo-details</h1>通过相对路径去子state<div></div>

photos-detail-comment.html 则很简单:

photos-detail-comment

app.js state多级嵌套的设置为

 var photoGallery = angular.module('photoGallery',["ui.router"]); photoGallery.config(function($stateProvider, $urlRouterProvider){ $urlRouterProvider.otherwise('home'); $stateProvider .state('content',{ url: '/', views:{ "":{templateUrl: 'partials/content.html'}, "header@content":{templateUrl: 'partials/header.html'}, } }) .state('content.home',{ url: 'home', views:{ "body@content":{templateUrl: 'partials/home.html'} } }) .state('content.photos',{ url: 'photos', views:{ "body@content":{templateUrl: 'partials/photos.html'} } }) .state('content.photos.list',{ url: '/list', templateUrl: 'partials/photos-list.html' }) .state('content.photos.detail',{ url: '/detail', templateUrl: 'partials/photos-detail.html' }) .state('content.photos.detail.comment',{ url: '/comment', templateUrl: 'partials/photos-detail-comment.html' }) .state('content.about',{ url:'about', views:{ "body@content":{templateUrl: 'partials/about.html'} } }) })

 抽象state

如果一个state,没有通过链接找到它,那就可以把这个state设置为abstract:true,我们把以上的content和content.photos这2个state设置为抽象。

 .state('content',{ url: '/', abstract: true, views:{ "":{templateUrl: 'partials/content.html'}, "header@content":{templateUrl: 'partials/header.html'}, } }) ... .state('content.photos',{ url: 'photos', abstract: true, views:{ "body@content":{templateUrl: 'partials/photos.html'} } })

那么,当一个state设置为抽象,如果通过ui-sref或路由导航到该state会出现什么结果呢?

–会导航到默认路由上

$urlRouterProvider.otherwise(‘home’);

 .state('content.home',{ url: 'home', views:{ "body@content":{templateUrl: 'partials/home.html'} } }) 

最终把partials/home.html显示出来。

使用控制器

在实际项目中,数据大多从controller中来。

首先在路由中设置state所用到的控制器以及控制器别名。

 var photoGallery = angular.module('photoGallery',["ui.router"]); photoGallery.config(function($stateProvider, $urlRouterProvider){ $urlRouterProvider.otherwise('home'); $stateProvider .state('content',{ url: '/', abstract: true, views:{ "":{templateUrl: 'partials/content.html'}, "header@content":{templateUrl: 'partials/header.html'}, } }) .state('content.home',{ url: 'home', views:{ "body@content":{ templateUrl: 'partials/home.html', controller: 'HomeController', controllerAs: 'ctrHome' } } }) .state('content.photos',{ url: 'photos', abstract: true, views:{ "body@content":{ templateUrl: 'partials/photos.html', controller: 'PhotoController', controllerAs: 'ctrPhoto' } } }) .state('content.photos.list',{ url: '/list', templateUrl: 'partials/photos-list.html', controller: "PhotoListController", controllerAs: 'ctrPhotoList' }) .state('content.photos.detail',{ url: '/detail', templateUrl: 'partials/photos-detail.html', controller: 'PhotoDetailController', controllerAs: 'ctrPhotoDetail' }) .state('content.photos.detail.comment',{ url: '/comment', templateUrl: 'partials/photos-detail-comment.html' }) .state('content.about',{ url:'about', views:{ "body@content":{templateUrl: 'partials/about.html'} } }) })

添加controller.js,该文件用来定义所用到的controller.现在的文件结构为:

asserts/
…..css/
…..images/
……….image1.jpg-600
……….image2.jpg-600
……….image3.jpg-600
……….image4.jpg-600
node_modules/
partials/
…..about.html
…..home.html
…..photos.html
…..content.html
…..header.html
…..photos-list.html
…..photo-detail.html
…..photos-detail-comment.html
app.js

index.html

controllers.js

 photoGallery.controller('HomeController',['$scope', '$state', function($scope, $state){ this.message = 'Welcome to the Photo Gallery'; }]); //别名:ctrPhoto photoGallery.controller('PhotoController',['$scope','$state', function($scope, $state){ this.photos = [ { id: 0, title: 'Photo 1', description: 'description for photo 1', imageName: 'image1.jpg-600', comments:[ {name: 'user1', comment: 'Nice'}, { name:'User2', comment:'Very good'} ]}, { id: 1, title: 'Photo 2', description: 'description for photo 2', imageName: 'image2.jpg-600', comments:[ { name: 'user2', comment: 'Nice'}, { name:'User1', comment:'Very good'} ]}, { id: 2, title: 'Photo 3', description: 'description for photo 3', imageName: 'image3.jpg-600', comments:[ {name: 'user1', comment: 'Nice'} ]}, { id: 3, title: 'Photo 4', description: 'description for photo 4', imageName: 'image4.jpg-600', comments:[ {name: 'user1', comment: 'Nice'}, { name:'User2', comment:'Very good'}, { name:'User3', comment:'So so'} ]} ]; //给子state下controller中的photos赋值 this.pullData = function(){ $scope.$$childTail.ctrPhotoList.photos = this.photos; } }]); //别名:ctrPhotoList photoGallery.controller('PhotoListController',['$scope','$state', function($scope, $state){ this.reading = false; this.photos = new Array(); this.init = function(){ this.reading = true; setTimeout(function(){ $scope.$apply(function(){ $scope.ctrPhotoList.getData(); }); }, 1500); } this.getData = function(){ //调用父state中controller中的方法 $scope.$parent.ctrPhoto.pullData(); /*this.photos = $scope.$parent.ctrPhoto.photos;*/ this.reading = false; } }]); //别名:ctrPhotoDetail photoGallery.controller('PhotoDetailController',['$scope', '$state', function($scope,$state){ }]); 

以上,通过$scope.$$childTail.ctrPhotoList在父state中的controller中拿到子state中的controller;通过$scope.$parent.ctrPhoto在子state中的controller中拿到父state中的controller。

photos-list.html

 <h1>photos-list</h1><div> <div style="margin:auto;width: 40px"> <i class="fa fa-spinner fa-5x fa-pulse"></i></div><div class="well well-sm"> <div class="media"> <div class="media-left" style="width:15%">  </div><div class="media-body"> <h4 class="media-heading">{{photo.title}}</h4> {{photo.description}} </div></div></div></div>

state间如何传路由参数

在content.photos.detail这个state设置接收一个路由参数。

 .state('content.photos.detail',{ url: '/detail/:id', templateUrl: 'partials/photos-detail.html', controller: 'PhotoDetailController', controllerAs: 'ctrPhotoDetail' }) 

photos-list.html 送出一个路由参数

 <h1>photos-list</h1><div> <div style="margin:auto;width: 40px"> <i class="fa fa-spinner fa-5x fa-pulse"></i></div><div class="well well-sm"> <div class="media"> <div class="media-left" style="width:15%">  </div><div class="media-body"> <h4 class="media-heading">{{photo.title}}</h4> {{photo.description}} </div></div></div></div>

以上,通过把路由参数送出。

controller.js PhotoDetailController控制器通过$stateParams获取路由参数

 ... //别名:ctrPhotoDetail photosGallery.controller('PhotoDetailController', ['$scope', '$state', '$stateParams', function($scope, $state, $stateParams){ var id = null; this.photo = null; this.init = function(){ id = parseInt($stateParams.id); this.photo = $scope.ctrPhoto.photos[id]; } } ]); 

photos-detail.html 从以上的PhotoDetailController中获取数据。

 <h1>photo-details</h1>通过相对路径去子state <i class="fa fa-arrow-circle-left fa-2x"></i><div> <div class="well well-sm" style="margin:auto;width: 60%;margin-top: 15px"> <h4>{{ctrPhotoDetail.photo.title}}</h4><p>{{ctrPhotoDetail.photo.description}}</p></div><div style="margin:auto;width: 80%;margin-bottom: 15px"> <button style="margin-top: 10px;width:100%" class="btn btn-default">Comments</button></div></div><div></div>

state间如何传字符串参数

在路由中这样设置:

 .state('content.photos.detail.comment',{ url:'/comment?skip&limit', templateUrl: 'partials/photos-detail-comment.html', controller: 'PhotoCommentController', controllerAs: 'ctrPhotoComment' }) 

controllers.js 中修改如下

 photoGallery.controller('HomeController',['$scope', '$state', function($scope, $state){ this.message = 'Welcome to the Photo Gallery'; }]); //别名:ctrPhoto photoGallery.controller('PhotoController',['$scope','$state', function($scope, $state){ this.photos = [ { id: 0, title: 'Photo 1', description: 'description for photo 1', imageName: 'image1.JPG', comments:[ { name:'User1', comment: 'Nice', imageName: 'man.png-600'}, { name:'User2', comment:'Very good', imageName: 'man.png-600'}, { name:'User3', comment:'Nice', imageName: 'woman.png-600'}, { name:'User4', comment:'Very good', imageName: 'woman.png-600'}, { name:'User5', comment:'Very good', imageName: 'man.png-600'}, { name:'User6', comment:'Nice', imageName: 'woman.png-600'}, { name:'User7', comment:'So so', imageName: 'man.png-600'} ]}, { id: 1, title: 'Photo 2', description: 'description for photo 2', imageName: 'image2.JPG', comments:[ { name:'User1', comment: 'Nice', imageName: 'man.png-600'}, { name:'User2', comment:'Very good', imageName: 'man.png-600'}, { name:'User3', comment:'Nice', imageName: 'woman.png-600'}, { name:'User4', comment:'Very good', imageName: 'woman.png-600'} ]}, { id: 2, title: 'Photo 3', description: 'description for photo 3', imageName: 'image3.JPG', comments:[ { name:'User1', comment: 'Nice', imageName: 'man.png-600'}, { name:'User2', comment:'Very good', imageName: 'man.png-600'}, { name:'User3', comment:'Nice', imageName: 'woman.png-600'}, { name:'User4', comment:'Very good', imageName: 'woman.png-600'}, { name:'User5', comment:'Very good', imageName: 'man.png-600'}, { name:'User6', comment:'Nice', imageName: 'woman.png-600'}, { name:'User7', comment:'So so', imageName: 'man.png-600'} ]}, { id: 3, title: 'Photo 4', description: 'description for photo 4', imageName: 'image4.JPG', comments:[ { name:'User6', comment:'Nice', imageName: 'woman.png-600'}, { name:'User7', comment:'So so', imageName: 'man.png-600'} ]} ]; //给子state下controller中的photos赋值 this.pullData = function(){ $scope.$$childTail.ctrPhotoList.photos = this.photos; } }]); //别名:ctrPhotoList photoGallery.controller('PhotoListController',['$scope','$state', function($scope, $state){ this.reading = false; this.photos = new Array(); this.init = function(){ this.reading = true; setTimeout(function(){ $scope.$apply(function(){ $scope.ctrPhotoList.getData(); }); }, 1500); } this.getData = function(){ //调用父state中controller中的方法 $scope.$parent.ctrPhoto.pullData(); /*this.photos = $scope.$parent.ctrPhoto.photos;*/ this.reading = false; } }]); //别名:ctrPhotoDetail photoGallery.controller('PhotoDetailController', ['$scope', '$state', '$stateParams', function($scope, $state, $stateParams){ var id = null; this.photo = null; this.init = function(){ id = parseInt($stateParams.id); this.photo = $scope.ctrPhoto.photos[id]; } } ]); photoGallery.controller('PhotoCommentController', ['$scope', '$state', '$stateParams', function($scope, $state, $stateParams){ var id, skip, limit = null; this.comments = new Array(); this.init = function(){ id = parseInt($stateParams.id); var photo = $scope.ctrPhoto.photos[id]; if($stateParams.skip){ skip = parseInt($stateParams.skip); }else{ skip = 0; } if($stateParams.limit){ limit = parseInt($stateParams.limit); }else{ limit = photo.comments.length; } this.comments = photo.comments.slice(skip, limit); } } ]); 

也就是,$stateParams不仅可以接收路由参数,还可以接收查询字符串参数。

photo-detail.html 需要把查询字符串参数传递出去

 <h1>photo-details</h1>通过相对路径去子state <i class="fa fa-arrow-circle-left fa-2x"></i><div> <div class="well well-sm" style="margin:auto;width: 60%;margin-top: 15px"> <h4>{{ctrPhotoDetail.photo.title}}</h4><p>{{ctrPhotoDetail.photo.description}}</p></div><div style="margin:auto;width: 80%;margin-bottom: 15px"> <button style="margin-top: 10px;width:100%" class="btn btn-default">Comments</button></div></div><div></div>

以上,通过ui-sref=”.comment({skip:0, limit:2})把查询字符串传递出去。

photos-detail-comment.html

 <h1>photos-detail-comment</h1><div style="margin-top:15px"> <div class="well well-sm" style="margin: auto;width: 60%"> <div class="media"> <div class="media-left media-middle">  </div><div class="media-body"> <h4 class="media-heading">{{comment.name}}</h4> {{comment.comment}} </div></div></div></div>

state间如何传递对象

通过data属性,把一个对象赋值给它。

 .state('content',{ url: '/', abstract: true, data:{ user: "user", password: "1234" }, views:{ "":{templateUrl: 'partials/content.html'}, "header@content":{templateUrl: 'partials/header.html'}, } }) 

给header.html加上一个对应的控制器,并提供注销方法。

 $stateProvider .state('content',{ url: '/', abstract: true, data:{ user: "user", password: "1234" }, views:{ "":{templateUrl: 'partials/content.html'}, "header@content":{ templateUrl: 'partials/header.html', controller: function($scope, $rootScope, $state){ $scope.logoff = function(){ $rootScope.user = null; } } } } })

添加一个有关登录页的state

 .state('content.login',{ url:'login', data:{ loginError: 'User or password incorrect.' }, views:{ "body@content" :{ templateUrl: 'partials/login.html', controller: function($scope, $rootScope, $state){ $scope.login = function(user, password, valid){ if(!valid){ return; } if($state.current<i style="color:transparent">来源gaodai$ma#com搞$$代**码网</i>.data.user === user && $state.current.data.password === password){ $rootScope.user = { name: $state.current.data.user } // Or Inherited /*$rootScope.user = { name: $state.$current.parent.data.user };*/ $state.go('content.home'); }else{ $scope.message = $state.current.data.loginError; } } } } } }) 

添加login.html文件,现在的文件结构为:

asserts/
…..css/
…..images/
……….image1.jpg-600
……….image2.jpg-600
……….image3.jpg-600
……….image4.jpg-600
node_modules/
partials/
…..about.html
…..home.html
…..photos.html
…..content.html
…..header.html
…..photos-list.html
…..photo-detail.html
…..photos-detail-comment.html
…..login.html

app.js

index.html

login.html

  <div class="panel panel-primary" style="width:360px;margin: auto"> <div class="panel-heading"> <h3 class="panel-title">Indentification</h3></div><div class="panel-body"> <span class="label label-danger">Enter the user</span><hr><span class="label label-danger">Enter the password</span></div><div class="panel-footer"> <button class="btn btn-default" type="submit">Login</button><button class="btn btn-default" type="reset">Reset</button><span class="label label-danger">{{message}}</span></div></div>

header.html 修改如下

 <nav class="navbar navbar-inverse"> <div class="container-fluid"> <div class="navbar-header"> <button class="navbar-toggle collapsed" type="button"> <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>Home</div><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li> Photos</li><li> About</li></ul><ul class="nav navbar-nav navbar-right"> <li class="dropdown"> {{user.name}} <span class="caret"></span><ul class="dropdown-menu" role="menu"> <li>Sing out</li></ul></li><li> Sing In</li></ul></div></div></nav>

onEnter和onExit事件

 .state('content.photos.detail',{ url: '/detail/:id', templateUrl: 'partials/photos-detail.html', controller: 'PhotoDetailController', controllerAs: 'ctrPhotoDetail', resolve:{ viewing: function($stateParams){ return{ photoId: $stateParams.id } } }, onEnter: function(viewing){ var photo = JSON.parse(sessionStorage.getItem(viewing.photoId)); if(!photo){ photo = { views: 1, viewing: 1 } }else{ photo.views = photo.views + 1; photo.viewing = photo.viewing + 1; } sessionStorage.setItem(viewing.photoId, JSON.stringify(photo)); }, onExit: function(viewing){ var photo = JSON.parse(sessionStorage.getItem(viewing.photoId)); photo.viewing = photo.viewing - 1; sessionStorage.setItem(viewing.photoId, JSON.stringify(photo)); } })

在PhotoDetailController中:

 photoGallery.controller('PhotoDetailController', ['$scope', '$state', '$stateParams', function($scope, $state, $stateParams){ var id = null; this.photo = null; this.viewObj = null; this.init = function(){ id = parseInt($stateParams.id); this.photo = $scope.ctrPhoto.photos[id]; this.viewObj = JSON.parse(sessionStorage.getItem($stateParams.id)); } } ]);

photos-detail.html

 <h1>photo-details</h1>通过相对路径去子state <i class="fa fa-arrow-circle-left fa-2x"></i><div> <div class="well well-sm" style="margin:auto;width: 60%;margin-top: 15px"> <div class="well well-sm pull-right" style="width: 100px"> <i>Views <span class="badge">{{ctrPhotoDetail.viewObj.views}}</span></i></div><div class="well well-sm pull-right" style="width: 110px"> <i>Viewing <span class="badge">{{ctrPhotoDetail.viewObj.viewing}}</span></i></div><h4>{{ctrPhotoDetail.photo.title}}</h4><p>{{ctrPhotoDetail.photo.description}}</p></div><div style="margin:auto;width: 80%;margin-bottom: 15px"> <button style="margin-top: 10px;width:100%" class="btn btn-default">Comments</button></div></div><div></div>

StateChangeStart事件

controller.js 增加如下

 photoGallery.controller('RootController', ['$scope', '$state', '$rootScope', function($scope, $state, $rootScope){ $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ if(toState.data.required && !$rootScope.user){ event.preventDefault(); $state.go('content.login'); } }); } ]); 

修改content这个state:

 .state('content',{ url:'/', abstract: true, data:{ user: "user", password: "1234" }, views:{ "":{ templateUrl: 'partials/content.html', controller: 'RootController' }, "header@content":{ templateUrl: 'partials/header.html', controller: function($scope, $rootScope, $state){ $scope.logoff = function(){ $rootScope.user = null; } } } } })

content.photos.detail这个state

 .state('content.photos.detail',{ url:'/detail/:id', templateUrl: 'partials/photos-detail.html', controller: 'PhotoDetailController', controllerAs: 'ctrPhotoDetail', data:{ required: true }, resolve:{ viewing: function($stateParams){ return{ photoId: $stateParams.id } } }, onEnter: function(viewing){ var photo = JSON.parse(sessionStorage.getItem(viewing.photoId)); if(!photo){ photo = { views: 1, viewing: 1 } }else{ photo.views = photo.views + 1; photo.viewing = photo.viewing + 1; } sessionStorage.setItem(viewing.photoId, JSON.stringify(photo)); }, onExit: function(viewing){ var photo = JSON.parse(sessionStorage.getItem(viewing.photoId)); photo.viewing = photo.viewing - 1; sessionStorage.setItem(viewing.photoId, JSON.stringify(photo)); } })

以上,添加了

 data:{ required: true } 

同理,content.photos.detail.comment这个state

 .state('content.photos.detail.comment',{ url:'/comment?skip&limit', templateUrl: 'partials/photos-detail-comment.html', controller: 'PhotoCommentController', controllerAs: 'ctrPhotoComment', data:{ required: true } }) 

StateNotFound事件

 photosGallery.controller('RootController', ['$scope', '$state', '$rootScope', function($scope, $state, $rootScope){ $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ if(toState.data.required && !$rootScope.user){ event.preventDefault(); $state.go('content.login'); return; } }); $rootScope.$on('$stateNotFound', function(event, unfoundState, fromState, fromParams){ event.preventDefault(); $state.go('content.notfound'); }); } ]); 

添加一个state:

 .state('content.notfound',{ url:'notfound', views: { "body@content": {templateUrl: 'partials/page-not-found.html'} } }) 

page-not-found.html

 <div class="well well-sm" style="margin: 20px"> <i class="fa fa-frown-o fa-4x pull-left"></i><h3>404 - Sorry! Not found your page.</h3></div>

StateChangeSuccess事件

 photosGallery.controller('RootController', ['$scope', '$state', '$rootScope', function($scope, $state, $rootScope){ $rootScope.accessLog = new Array(); $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ if(toState.data.required && !$rootScope.user){ event.preventDefault(); $state.go('content.login'); return; } }); $rootScope.$on('$stateNotFound', function(event, unfoundState, fromState, fromParams){ event.preventDefault(); $state.go('content.notfound'); }); $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ $rootScope.accessLog.push({ user: $rootScope.user, from: fromState.name, to: toState.name, date: new Date() }); }); } ]); 

添加一个state

 .state('content.log',{ url:'log', data:{ required: true }, views: { "body@content": {templateUrl: 'partials/log.html'} } }) 

log.html

 <h1><i class="fa fa-file-text-o"></i> Access Log</h1><div style="margin:auto;width: 380px"> <div class="well well-sm"> <i class="fa fa-pencil fa-2x pull-left"></i> {{log.user ? log.user.name: 'anonymous'}} in {{log.date | date: 'longDate'}} at {{log.date | date: 'shortTime'}} <p>From: {{log.from}} => to: {{log.to}}</p></div></div>

StateChangeError事件

 photosGallery.controller('RootController', ['$scope', '$state', '$rootScope', function($scope, $state, $rootScope){ $rootScope.accessLog = new Array(); $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ if(toState.data.required && !$rootScope.user){ event.preventDefault(); $state.go('content.login'); return; } }); $rootScope.$on('$stateNotFound', function(event, unfoundState, fromState, fromParams){ event.preventDefault(); $state.go('content.notfound'); }); $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ $rootScope.accessLog.push({ user: $rootScope.user, from: fromState.name, to: toState.name, date: new Date() }); }); $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error){ event.preventDefault(); $state.go('content.error', {error: error}); }); } ]); 

添加2个state:

 .state('content.profile', { url:'profile', data:{ required: true }, resolve:{ showError: function(){ throw 'Error in code.'; } }, views:{ "body@content": {template: '<div>Error</div>'} } }) .state('content.error',{ url:'error/:error', views:{ "body@content":{ templateUrl: 'partials/error.html', controller: function($scope, $stateParams){ $scope.error = { message: $stateParams.error } } } } })

error.html

 <div class="well well-sm" style="margin: 20px"> <i class="fa fa-exclamation-circle fa-2x"> Sorry! But this message was displayed: {{error.message}}</i></div>

以上就是Angularjs中UI Router全攻略的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Angularjs中UI Router全攻略

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址