Heim > Web-Frontend > js-Tutorial > Eine vollständige Anleitung zum UI-Router in Angularjs_AngularJS

Eine vollständige Anleitung zum UI-Router in Angularjs_AngularJS

WBOY
Freigeben: 2016-05-16 15:16:49
Original
1115 Leute haben es durchsucht

Zunächst werde ich Ihnen die grundlegende Verwendung von Angular-UI-Router vorstellen.

So verweisen Sie auf die Abhängigkeit Angular-UI-Router

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

$stateProvider.state(stateName, stateConfig)

stateName ist vom Typ string
stateConfig ist der Objekttyp
//statConfig kann ein leeres Objekt sein
$stateProvider.state("home",{});
//Staat kann Kinder und Eltern haben
$stateProvider.state("home",{});
$stateProvider.state("home.child",{})
//Zustand kann verkettet werden
$stateProvider.state("home",{}).state("about",{}).state("photos",{});

StateConfig enthält Felder: Vorlage, templateUrl, templateProvider, Controller, ControllerProvider, Auflösung, URL, Parameter, Ansichten, Zusammenfassung, onEnter, onExit, reloadOnSearch, Daten

$urlRouteProvider

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

$state.go

$state.go(to, [,toParams],[,options])
Der formale Parameter to ist vom Typ string, der zur Angabe eines relativen Pfads erforderlich ist Der formale Parameter toParams ist nullbar und der Typ ist Objekt
Die formalen Parameteroptionen können null sein und der Typ ist ein Objekt. Zu den Feldern gehören: location ist ein Bool-Typ und der Standardwert ist true, inherit ist ein Bool-Typ und der Standardwert ist true, relative ist ein Objekt und der Standardwert ist $ state.$current, notify ist ein Bool-Typ und der Standardwert ist true, und reload ist ein Bool-Typ und der Standardwert ist false

$state.go('photos.detail')

$state.go('^') zur vorherigen Ebene, z. B. von photo.detail zu photo
$state.go('^.list') zum angrenzenden Bundesstaat, z. B. von photo.detail zu photo.list
$state.go('^.detail.comment') zum Enkelstatus, z. B. von photo.detail zu photo.detial.comment

ui-sref

ui-sref='stateName'

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

UI-Ansicht

== UI-Ansicht ohne Namen


<div ui-view></div>
$stateProvider.state("home",{
template: "<h1>hi</h1>"
}) 
Nach dem Login kopieren
Oder konfigurieren Sie es so:


$stateProvider.state("home"{
views: {
"": {
template: "<h1>hi</h1>"
}
}
}) 
Nach dem Login kopieren
==Benannte UI-Ansicht


<div ui-view="main"></div>
$stateProvider.state("home",{
views: {
"main" : {
template: "<h1>hi</h1>"
}
}
}) 
Nach dem Login kopieren
==Mehrere UI-Ansicht


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

Projektdateistruktur

node_modules/

Teiltöne/
.....about.html
.....home.html
.....photos.html
app.js
index.html

Status und Ansicht erstellen

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'
})
}) 
Nach dem Login kopieren

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> 
Nach dem Login kopieren

Springen zwischen Zuständen

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>
Nach dem Login kopieren
Die oben genannten Sprünge zwischen Zuständen erfolgen über das ui-sref-Attribut.

Mehrere Ansichten und Statusverschachtelung

Manchmal kann es mehrere UI-Ansichten auf einer Seite geben, wie zum Beispiel:

<div ui-view="header"></div>
<div ui-view="body"></div>
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Gehen Sie davon aus, dass die obige Seite zu einem Bundesstaat mit dem Namen „Parent“ gehört.

Wir wissen, dass im UI-Router ein Status ungefähr so ​​eingestellt wird:

<div ui-view="header"></div>
<div ui-view="body"></div>
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Alle Schlüssel-Wert-Paare unter Ansichten in allen Zuständen (ähnlich wie „body@content“:{templateUrl: 'partials/photos.html'}) werden in einen Schlüssel-Wert-Satz eingefügt. Das Arbeitsprinzip von ui-view besteht darin, passende Schlüssel in diesem Schlüsselwertsatz basierend auf seinen eigenen Attributwerten zu finden und die entsprechende Seite anzuzeigen, wenn sie gefunden werden.

Klicken Sie auf den Seitenlink, der der Kopfzeile entspricht. Dadurch gelangen Sie möglicherweise zu einer anderen Unterseite, die an der Position von
erscheint. Zu diesem Zeitpunkt wird auf der Seite eine Kind-Eltern-Beziehung angezeigt, und jede Seite gehört zu einem bestimmten Staat, sodass zwischen den Staaten eine Kind-Eltern-Beziehung auftritt. Diese umgeleiteten Unterseiten können in den Routing-Einstellungen parent.son1, parent.son2... heißen. Dies ist die Verschachtelung des Status.

Fügen Sie content.html und header.html zur vorhandenen Dateistruktur hinzu, und die Dateistruktur wird zu:

node_modules/

Teiltöne/
.....about.html
.....home.html
.....photos.html
.....content.html
.....header.html
app.js
index.html

content.html enthält mehrere UI-Ansichten, die sich auf den Seitenkopf beziehen und je nach Klick auf den Seitenkopf unterschiedliche Inhalte anzeigen.

<div ui-view="header"></div>
<div ui-view="body"></div>
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
header.html Fügen Sie hier den Navigationsteil der ursprünglichen indext.html ein


<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> 
Nach dem Login kopieren
index.html sieht jetzt so aus

app.js-Routing ist jetzt wie folgt eingerichtet

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'}
}
})
}) 
Nach dem Login kopieren
Zu diesem Zeitpunkt wird die Seite wie folgt dargestellt:

→ Gehe zur Home-Route

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

以上,告诉我们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'},
}
})
Nach dem Login kopieren

于是,就找到了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'}
}
}) 
Nach dem Login kopieren

把partials/photos.html显示到

中去。

点击

,来到:

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

把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" 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> 
Nach dem Login kopieren

以上,通过Photos来到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> 
Nach dem Login kopieren

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> 
Nach dem Login kopieren

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'}
}
})
})
Nach dem Login kopieren

抽象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'}
}
})
Nach dem Login kopieren

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

--会导航到默认路由上

$urlRouterProvider.otherwise('home');


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

最终把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'}
}
})
})
Nach dem Login kopieren

添加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';
}]);
//别名: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'},
{ 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;
}
}]);
//别名: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){
}]); 
Nach dem Login kopieren

以上,通过$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> 
Nach dem Login kopieren

state间如何传路由参数

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

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

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> 
Nach dem Login kopieren

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

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];
}
}
]); 
Nach dem Login kopieren

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> 
Nach dem Login kopieren

state间如何传字符串参数

在路由中这样设置:

.state('content.photos.detail.comment',{
url:'/comment&#63;skip&limit',
templateUrl: 'partials/photos-detail-comment.html',
controller: 'PhotoCommentController',
controllerAs: 'ctrPhotoComment'
}) 
Nach dem Login kopieren

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'},
{ 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;
}
}]);
//别名: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);
}
}
]); 
Nach dem Login kopieren

也就是,$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> 
Nach dem Login kopieren

以上,通过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> 
Nach dem Login kopieren

state间如何传递对象

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

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

给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;
}
}
}
}
})
Nach dem Login kopieren

添加一个有关登录页的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;
}
}
}
}
}
}) 
Nach dem Login kopieren

添加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> 
Nach dem Login kopieren

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> 
Nach dem Login kopieren

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));
}
})
Nach dem Login kopieren

在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));
}
}
]);
Nach dem Login kopieren

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> 
Nach dem Login kopieren

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');
}
});
}
]); 
Nach dem Login kopieren

修改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;
}
}
}
}
})
Nach dem Login kopieren

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));
}
})
Nach dem Login kopieren

以上,添加了

data:{
required: true
} 
Nach dem Login kopieren

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

.state('content.photos.detail.comment',{
url:'/comment&#63;skip&limit',
templateUrl: 'partials/photos-detail-comment.html',
controller: 'PhotoCommentController',
controllerAs: 'ctrPhotoComment',
data:{
required: true
}
}) 
Nach dem Login kopieren

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');
});
}
]); 
Nach dem Login kopieren

添加一个state:

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

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> 
Nach dem Login kopieren

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()
});
});
}
]); 
Nach dem Login kopieren

添加一个state

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

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 &#63; log.user.name: 'anonymous'}} in {{log.date | date: 'longDate'}} at {{log.date | date: 'shortTime'}}
<p>From: {{log.from}} => to: {{log.to}}</p>
</div>
</div> 
Nach dem Login kopieren

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});
});
}
]); 
Nach dem Login kopieren

添加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
}
}
}
}
})
Nach dem Login kopieren

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>
Nach dem Login kopieren
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage