AngularJS 的嵌套路由 UI-Router
本篇文章翻譯自:https://scotch.io/tutorials/angular-routing-using-ui-router
下面是我自己做的demo。比上面的例子要簡單一點。
github DEMO地址如下:https://github.com/roverliang/UI-Router-DEMO
受本人英語水平限制,所以只能簡要翻譯,英語水平比較好的可以直接查看原文。
AngularJs的指令集是一個非常好的方式用來構建單頁的網頁應用。當創建一個單頁應用的時候,路由的重要性就凸顯出來。我們希望我們的導航欄就如同普通的網站一樣,點擊后沒有刷新,那么我們可以使用Angular的路由——ngRouter 方法。
但是,現在我們將注意力放在另外一個好用的方法上——UI-Router.
概覽
Angular 的Router 是什么?
UI-Router 是Angular 團隊創建的一個路由框架。他的指令和Angular的ngRoute方法很接近。它通過改變應用中視圖的狀態(State),而不是像ngRoute那樣通過改變當前應用的url來實現。
狀態(STATES)與 URL 路由 的異同。
使用這種方法,你的視圖和路由不是綁定在一起的。你可以改變你的站點的某些部分,而你的url而不用也跟着變化。當使用ngRoute,你必須使用nginclude或者其他的方法,這可能會導致混淆。現在你所有的狀態(state)、路由(route)以及視圖(view)
你將全部接管,使用config()方法,這將創建一個自上而下(等會解釋)的應用。
做一個示例
下面讓我們做一個UI-Route的教程。這將創建一個Home和About頁面。
開始
讓我們開始書寫我們的應用,我們需要一些文件。
- index.html // will hold the main template for our app
- app.js // our angular code
- partial-about.html // about page code
- partial-home.html // home page code
- partial-home-list.html // injected into the home page
- table-data.html // re-usable table that we can place anywhere
我們的應用框架已經搭建完畢,那就讓我們按照框架的結構填充代碼吧。
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<!-- CSS (load bootstrap) -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<style>
.navbar { border-radius:0; }
</style>
<!-- JS (load angular, ui-router, and our custom js file) -->
<script src="http://code.angularjs.org/1.2.13/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="app.js"></script>
</head>
<!-- apply our angular app to our site -->
<body ng-app="routerApp">
<!-- NAVIGATION -->
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" ui-sref="#">AngularUI Router</a>
</div>
<ul class="nav navbar-nav">
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="about">About</a></li>
</ul>
</nav>
<!-- MAIN CONTENT -->
<div class="container">
<!-- THIS IS WHERE WE WILL INJECT OUR CONTENT ============================== -->
<div ui-view></div>
</div>
</body>
</html>
上面事我們首頁的html文件,我們將引用BootStrap來傍午我們構建樣式。值得注意的是必須在引用AngularJS之后引用ui-router。UI Router是AngularJS的核心組成部分,就像ngRoute一樣。
當我們使用UI-Router創建一個鏈接的時候,你將會使用ui-sref。 這些在你的app.js將狀態會轉化成一個鏈接。
同理我們將使用
來 代替 ngRoute 的讓我們繼續構建我們的app.js吧。
// app.js
var routerApp = angular.module('routerApp', ['ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'partial-home.html'
})
// ABOUT PAGE AND MULTIPLE NAMED VIEWS =================================
.state('about', {
// we'll get to this in a bit
});
});
我們已經創建了我們的RouteAPP。我們將body放置在index.html中,在這個頁面中,我們有一個home選項和about選項。我們將使用partial-home.html作為模板文件。 讓我們在partial-home.html中填充些代碼吧。
<!-- partial-home.html -->
<div class="jumbotron text-center">
<h1>The Homey Page</h1>
<p>This page demonstrates <span class="text-danger">nested</span> views.</p>
</div>
截止現在我們已經擁有了我們的站點,雖然我們還沒有敲多少代碼,但是我們的確擁有了它。
上面一些無聊的構建文件的階段已經過去,下面讓我們看下為什么UI-Router會產生那么酷炫的效果。
嵌套視圖
接下來看看如何構建我們的應用。首先我們將在首頁添加兩個button。其次將根據用戶點擊不同的button切換不同的頁面。
我們將兩個button添加到partial-home.html ,然后思考如何才能進行頁面切換。
<!-- partial-home.html -->
<div class="jumbotron text-center">
<h1>The Homey Page</h1>
<p>This page demonstrates <span class="text-danger">nested</span> views.</p>
<a ui-sref=".list" class="btn btn-primary">List</a>
<a ui-sref=".paragraph" class="btn btn-danger">Paragraph</a>
</div>
<div ui-view></div>
當我們鏈接到一個嵌套視圖。我們將使用點(dot):ui-sref=".list"和ui-sref=".paragraph"。我們將在這個文件中定義他們,定義后會被注入(inject)到我們的新的視圖區
現在切換到我們app.js,讓我們創建剩下的嵌套狀態(states)
// app.js
...
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'partial-home.html'
})
// nested list with custom controller
.state('home.list', {
url: '/list',
templateUrl: 'partial-home-list.html',
controller: function($scope) {
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
// nested list with just some random string data
.state('home.paragraph', {
url: '/paragraph',
template: 'I could sure use a drink right now.'
})
...
現在 ui-sref 被定義在home.html中,標注一個狀態。隨着home.list和home.paragraph頁面創建。這些鏈接所對應的模板將會被注冊到ui-view中。
我們最后一件事要做的是partial-home-list.html文件定義。此外還創建了一個控制器,我們將在模板中使用這些數據(dogs對象)。
<!-- partial-home-list.html -->
<ul>
<li ng-repeat="dog in dogs">{{ dog }}</li>
</ul>
現在我們列表,它會將數據(dogs對象)注入到模板。如果我們點擊Paragraph,它會將字符串注入頁面中。
現在你應該發現了在我們的狀態上切換不同的部分是多么的簡單。我們並沒有使用ngInclude、ngShow,ngHide。或者ngIf。這保持我們的app.js是足夠的簡單。
在About下添加更多頁面
一個有多個視圖的應用程序會更加強大。也許你的網站上還有側邊欄,上面有熱門職位、最近的帖子、用戶什么之類的。這些都可以被分離出來,並且注入我們的模板。並且可以為每一個模板使用是一個控制器,這將充分保持我們應用程序的干凈。
對於我們的About頁,讓我們做一個雙欄,並有各自的數據。我們將先處理視圖,然后再看看我們如何使用用戶界面的路由器。
<!-- partial-about.html -->
<div class="jumbotron text-center">
<h1>The About Page</h1>
<p>This page demonstrates <span class="text-danger">multiple</span> and <span class="text-danger">named</span> views.</p>
</div>
<div class="row">
<!-- COLUMN ONE NAMED VIEW -->
<div class="col-sm-6">
<div ui-view="columnOne"></div>
</div>
<!-- COLUMN TWO NAMED VIEW -->
<div class="col-sm-6">
<div ui-view="columnTwo"></div>
</div>
</div>
這里會有更多的頁面,一個是columnOne,一個是columnTwo.
為什么有人會使用這種方法?這是一個很好的問題。是我們創建一個應用程序太模塊化,這可能會讓人困惑?從官方的UI路由器文檔,這里是一個堅實的例子,為什么你會有多個命名視圖。在他們的例子中,他們展示了一個應用程序的不同部分。每一部分都有自己的數據,所以每一部分都有自己的控制器和模板文件,使得構建類似這樣的東西很容易。
現在我們所有的視圖已經創建完畢,讓我們回到app.js
// app.js
...
.state('about', {
url: '/about',
views: {
// the main template will be placed here (relatively named)
'': { templateUrl: 'partial-about.html' },
// the child views will be defined here (absolutely named)
'columnOne@about': { template: 'Look I am a column!' },
// for column two, we'll define a separate controller
'columnTwo@about': {
templateUrl: 'table-data.html',
controller: 'scotchController'
}
}
});
}); // closes $routerApp.config()
// let's define the scotch controller that we call up in the about state
routerApp.controller('scotchController', function($scope) {
$scope.message = 'test';
$scope.scotches = [
{
name: 'Macallan 12',
price: 50
},
{
name: 'Chivas Regal Royal Salute',
price: 10000
},
{
name: 'Glenfiddich 1937',
price: 20000
}
];
});
...
整個流程就是這樣。完整的文章請查看https://scotch.io/tutorials/angular-routing-using-ui-router#sample-application
演示網站請查看:http://embed.plnkr.co/IzimSVsstarlFviAm7S7/preview
源碼:http://plnkr.co/edit/IzimSVsstarlFviAm7S7?p=preview
。
下面是我自己做的demo。比上面的例子要簡單一點。
github DEMO地址如下:https://github.com/roverliang/UI-Router-DEMO
應用目錄如下。