国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Angularjs中UI Router全攻略

2019-11-20 10:39:33
字體:
來源:轉載
供稿:網友

首先給大家介紹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 ui-view></div>$stateProvider.state("home",{template: "<h1>hi</h1>"}) 

或者這樣配置:

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

==有名稱的ui-view

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

==多個ui-view

<div ui-view></div><div ui-view="data"></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

<!DOCTYPE html><html lang="en" ng-app="photoGallery"><head><meta charset="UTF-8"><title></title><link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css"/></head><body><h1>Welcome</h1><div ui-view></div><script src="node_modules/jquery/dist/jquery.js"></script><script src="node_modules/angular/angular.js"></script><script src="node_modules/angular-ui-router/release/angular-ui-router.js"></script><script src="node_modules/angular-animate/angular-animate.js"></script><script src="node_modules/bootstrap/dist/js/bootstrap.js"></script><script src="node_modules/angular-bootstrap/ui-bootstrap-tpls.js"></script><script src="app.js"></script></body></html> 

state之間的跳轉

index.html

<nav class="navbar navbar-inverse"><div class="container-fluid"><div class="navbar-header"><button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a ui-sref="home" class="navbar-brand">Home</a></div><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><ul class="nav navbar-nav"><li><a ui-sref="photos">Photos</a></li><li><a ui-sref="about">About</a></li></ul></div></div></nav><div ui-view></div>

以上通過ui-sref屬性完成state之間的跳轉。

多個view以及state嵌套

有時候,一個頁面上可能有多個ui-view,比如:

<div ui-view="header"></div><div ui-view="body"></div>

假設,以上頁面屬于一個名稱為parent的state中。

我們知道在ui-router中,一個state大致是這樣設置的:

<div ui-view="header"></div><div ui-view="body"></div>

所有state下views下的所有鍵值對(類似 "body@content":{templateUrl: 'partials/photos.html'})都被放到一個鍵值集合中。而ui-view的工作原理就是根據自己的屬性值,到這個鍵值集合中去找匹配的鍵,找到就把對應的頁面顯示出來。

點擊header對應的頁面鏈接,可能會跳轉到另外的子頁面出現在<div ui-view="body"></div>這個位置。這時候頁面出現了子父關系,而每個頁面都屬于某個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 ui-view="header"></div><div ui-view="body"></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" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a ui-sref="content.home" class="navbar-brand">Home</a></div><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><ul class="nav navbar-nav"><li><a ui-sref="content.photos">Photos</a></li><li><a ui-sref="content.about">About</a></li></ul></div></div></nav> 

index.html 這時變成了這樣

<div ui-view></div>

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上的<div ui-view></div>

.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頁面上的各個部分

看到<div ui-view="header"></div>,就加載如下:

"header@content":{templateUrl: 'partials/header.html'},

看到<div ui-view="body"></div>,先加載 "body@content":{templateUrl: 'partials/home.html'}

→ 點擊header上的鏈接

點擊<a ui-sref="content.photos">Photos</a>,來到:

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

把partials/photos.html顯示到<div ui-view="body"></div>中去。

點擊<div ui-view="body"></div>,來到:

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

把partials/about.html顯示到<div ui-view="body"></div>中去。

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

<div ui-view></div>

如何到達這個子頁面呢?修改header中的相關部分如下:

<nav class="navbar navbar-inverse"><div class="container-fluid"><div class="navbar-header"><button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a ui-sref="content.home" class="navbar-brand">Home</a></div><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><ul class="nav navbar-nav"><li><a ui-sref="content.photos.list">Photos</a></li><li><a ui-sref="content.about">About</a></li></ul></div></div> 

以上,通過<a ui-sref="content.photos.list">Photos</a>來到photos.html的子頁面photos-list.html.

photos-list.html 通過2種途徑到相鄰頁photo-detail.html

<h1>photos-list</h1><ul><li><a ui-sref="^.detail">我通過相對路徑到相鄰的state</a></li><li><a ui-sref="content.photos.detail">我通過絕對路徑到相鄰的state</a></li></ul> 

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

<h1>photo-details</h1><a class="btn btn-default" ui-sref=".comment">通過相對路徑去子state</a><div ui-view></div> 

photos-detail-comment.html 則很簡單:

<h1>photos-detail-comment</h1>

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
..........image2.jpg
..........image3.jpg
..........image4.jpg
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';}]);//別名:ctrPhotophotoGallery.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'},{ name:'User2', comment:'Very good'}]},{ id: 1, title: 'Photo 2', description: 'description for photo 2', imageName: 'image2.jpg', comments:[{ name: 'user2', comment: 'Nice'},{ name:'User1', comment:'Very good'}]},{ id: 2, title: 'Photo 3', description: 'description for photo 3', imageName: 'image3.jpg', comments:[{name: 'user1', comment: 'Nice'}]},{ id: 3, title: 'Photo 4', description: 'description for photo 4', imageName: 'image4.jpg', 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;}}]);//別名:ctrPhotoListphotoGallery.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;}}]);//別名:ctrPhotoDetailphotoGallery.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 ng-init="ctrPhotoList.init()"><div style="margin:auto; width: 40px;" ng-if="ctrPhotoList.reading"><i class="fa fa-spinner fa-5x fa-pulse"></i></div><div class="well well-sm" ng-repeat="photo in ctrPhotoList.photos"><div class="media"><div class="media-left" style="width:15%;"><a ui-sref="content.photos.detail"><img class="img-responsive img-rounded" src="../asserts/images/{{photo.imageName}}" alt=""></a></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 ng-init="ctrPhotoList.init()"><div style="margin:auto; width: 40px;" ng-if="ctrPhotoList.reading"><i class="fa fa-spinner fa-5x fa-pulse"></i></div><div class="well well-sm" ng-repeat="photo in ctrPhotoList.photos"><div class="media"><div class="media-left" style="width:15%;"><a ui-sref="content.photos.detail({id:photo.id})"><img class="img-responsive img-rounded" src="../asserts/images/{{photo.imageName}}" alt=""></a></div><div class="media-body"><h4 class="media-heading">{{photo.title}}</h4>{{photo.description}}</div></div></div></div> 

以上,通過<a ui-sref="content.photos.detail({id:photo.id})">把路由參數送出。

controller.js PhotoDetailController控制器通過$stateParams獲取路由參數

...//別名:ctrPhotoDetailphotosGallery.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><a class="btn btn-default" ui-sref=".comment">通過相對路徑去子state</a><a ui-sref="content.photos.list" style="margin-left: 15px;"><i class="fa fa-arrow-circle-left fa-2x"></i></a><div ng-init="ctrPhotoDetail.init()"><img class="img-responsive img-rounded" ng-src="../assets/images/{{ctrPhotoDetail.photo.imageName}}"style="margin:auto; width: 60%;"><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" ui-sref=".comment">Comments</button></div></div><div ui-view></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';}]);//別名:ctrPhotophotoGallery.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'},{ name:'User2', comment:'Very good', imageName: 'man.png'},{ name:'User3', comment:'Nice', imageName: 'woman.png'},{ name:'User4', comment:'Very good', imageName: 'woman.png'},{ name:'User5', comment:'Very good', imageName: 'man.png'},{ name:'User6', comment:'Nice', imageName: 'woman.png'},{ name:'User7', comment:'So so', imageName: 'man.png'}]},{ id: 1, title: 'Photo 2', description: 'description for photo 2', imageName: 'image2.JPG', comments:[{ name:'User1', comment: 'Nice', imageName: 'man.png'},{ name:'User2', comment:'Very good', imageName: 'man.png'},{ name:'User3', comment:'Nice', imageName: 'woman.png'},{ name:'User4', comment:'Very good', imageName: 'woman.png'}]},{ id: 2, title: 'Photo 3', description: 'description for photo 3', imageName: 'image3.JPG', comments:[{ name:'User1', comment: 'Nice', imageName: 'man.png'},{ name:'User2', comment:'Very good', imageName: 'man.png'},{ name:'User3', comment:'Nice', imageName: 'woman.png'},{ name:'User4', comment:'Very good', imageName: 'woman.png'},{ name:'User5', comment:'Very good', imageName: 'man.png'},{ name:'User6', comment:'Nice', imageName: 'woman.png'},{ name:'User7', comment:'So so', imageName: 'man.png'}]},{ id: 3, title: 'Photo 4', description: 'description for photo 4', imageName: 'image4.JPG', comments:[{ name:'User6', comment:'Nice', imageName: 'woman.png'},{ name:'User7', comment:'So so', imageName: 'man.png'}]}];//給子state下controller中的photos賦值this.pullData = function(){$scope.$$childTail.ctrPhotoList.photos = this.photos;}}]);//別名:ctrPhotoListphotoGallery.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;}}]);//別名:ctrPhotoDetailphotoGallery.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><a class="btn btn-default" ui-sref=".comment">通過相對路徑去子state</a><a ui-sref="content.photos.list" style="margin-left: 15px;"><i class="fa fa-arrow-circle-left fa-2x"></i></a><div ng-init="ctrPhotoDetail.init()"><img class="img-responsive img-rounded" ng-src="../assets/images/{{ctrPhotoDetail.photo.imageName}}"style="margin:auto; width: 60%;"><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" ui-sref=".comment({skip:0, limit:2})">Comments</button></div></div><div ui-view></div> 

以上,通過ui-sref=".comment({skip:0, limit:2})把查詢字符串傳遞出去。

photos-detail-comment.html

<h1>photos-detail-comment</h1><div ng-init="ctrPhotoComment.init()" style="margin-top:15px;"><div ng-repeat="comment in ctrPhotoComment.comments" class="well well-sm" style="margin: auto; width: 60%;"><div class="media"><div class="media-left media-middle"><a href=""><img class="img-circle" style="width:60px;" src="../assets/images/{{comment.imageName}}" alt=""></a></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.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
..........image2.jpg
..........image3.jpg
..........image4.jpg
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

<form name="form" ng-submit="login(user, password, form.$valid)"><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"><input name="user" type="text" class="form-control" ng-model="user" placeholder="User ..." required><span ng-show="form.user.$error.required && form.user.$dirty" class="label label-danger">Enter the user</span><hr><input name="password" type="password" class="form-control" ng-model="password" placeholder="Password ..." required><span ng-show="form.password.$error.required && form.password.$dirty" 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></form> 

header.html 修改如下

<nav class="navbar navbar-inverse"><div class="container-fluid"><div class="navbar-header"><button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand" ui-sref="content.home">Home</a></div><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><ul class="nav navbar-nav"><li><a ui-sref="content.photos.list">Photos</a> </li><li><a ui-sref="content.about">About</a> </li> </ul><ul class="nav navbar-nav navbar-right"> <li ng-if="user.name" class="dropdown"><a class="dropdown-toggle" role="button" aria-expanded="false" href="#" data-toggle="dropdown">{{user.name}} <span class="caret"></span></a><ul class="dropdown-menu" role="menu"><li><a ui-sref="content.home" ng-click="logoff()">Sing out</a></li> </ul> </li> <li ng-if="!user.name"><a ui-sref="content.login">Sing In</a></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><a class="btn btn-default" ui-sref=".comment">通過相對路徑去子state</a><a ui-sref="content.photos.list" style="margin-left: 15px;"><i class="fa fa-arrow-circle-left fa-2x"></i></a><div ng-init="ctrPhotoDetail.init()"><img class="img-responsive img-rounded" ng-src="../assets/images/{{ctrPhotoDetail.photo.imageName}}"style="margin:auto; width: 60%;"><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" ui-sref=".comment({skip:0, limit:2})">Comments</button></div></div><div ui-view></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" ng-repeat="log in accessLog track by $index"><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>
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 昔阳县| 长治市| 府谷县| 丽水市| 新和县| 福建省| 潞西市| 霍州市| 五原县| 盐亭县| 沙坪坝区| 大港区| 弋阳县| 镇坪县| 云南省| 嘉黎县| 安仁县| 监利县| 邯郸县| 大同县| 拜城县| 永清县| 淮安市| 博客| 阳谷县| 紫云| 交城县| 朝阳区| 福安市| 阳信县| 二连浩特市| 同江市| 齐齐哈尔市| 读书| 成武县| 静乐县| 县级市| 盐亭县| 原平市| 海安县| 高邮市|