【译】Angular Router and UI-Router
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

英版原文:http://www.phloxblog.in/angular-router-ui-router/

原创翻译:Bolt_白衣苍狗


在本文中,我们来了解一个 AngularJS 的有用特性:路由(Routing)。路由帮助我们理顺应用中的逻辑视图,并把不同的视图绑定相应的控制器。

$routeProvider 是什么?

路由是通过 Angular 提供的一个开箱即用的服务提供商(service provider) $routeProvider 来管理的。Angular 服务就是服务工厂(service factory)创建的一个单例对象。服务工厂是服务提供商们依次创建的一些方法。这些服务提供商是构造函数。当实例化的时候,他们必须包含一个叫 $get 的属性,用来 hold 住服务工厂函数。

当我们使用 AngularJS 的依赖注入,以及注入一个服务对象到我们的控制器的时候,Angular 使用 $injector 来找到相应的服务注射器(service injector)。一旦它得到持续的服务注射器,就用 $get 方法得到服务对象的实例。有时服务提供商需要实例化服务对象的某些信息。

Angular 应用路由通过 $route 服务的提供商 $routeProvider 来声明。这个服务让控制器、视图模板、浏览器当前 URL 地址联系在一起变的简单。用这个特性,我们可以实现深层链接(deep linking),让我们利用浏览器的历史记录和书签。

基础路由示例:

<!DOCTYPE html>
<html>

  <head>
    <meta charset="UTF-8" />
    <title>$routeProvide example - CodePen</title>
  </head>

  <body>
    <div ng-app="pathApp" ng-controller="MainCtrl">

  Choose your option:
        <br />
      <br />
      <a href="/Book/Edit">Edit</a>
 |
        <a href="/Book/Delete">Delete</a>
 |
        <a href="/Book/Add">Add</a>
 |
        <a href="/Book/Show">Show</a>
      <div ng-view=""></div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.7/angular.min.js"></script>
    <script>angular.module('pathApp',[] ,function($routeProvider, $locationProvider){
  $routeProvider
  .when('/Book/Edit', {
    template: '<div>Edit</div>',
  })
  .when('/Book/Delete', {
    template: '<div>Delete</div>',
  })
  .when('/Book/Show', {
    template: '<div>Show</div>',
  })
  .when('/Book/Add', {
    template: '<div>Add</div>',
  })

  $locationProvider.html5Mode(true);

});

function MainCtrl($scope){
  $scope.test = "123";
}</script>
  </body>

</html>

上面这个示例是路由的一个基础示例。它还展示了路由相当 well 的工作流程。我们可以看到在这个 html 代码中,我们引导了 4 个不同的链接。它们指向 javascript 中 $routeProvider 的地址。在那里我们有一个验证特定选择的选项。

What is AngularUI Router?

UI-Router 是由 AngularUI 团队为 Angular 构建的一个路由框架。它提供了一个不同于 ngRoute 的途径,基于应用状态改变应用视图而不仅仅是路由 URL。

状态(States) vs URL 路由

视图和路由不能被站点 URL 给束缚住。换一个思维,我们可以在不改变 URL 的情况下使用我们的路由改变我们站点的局部。而当使用 ngRoute 时,我们必须使用 ngInclude 或者其他方法,并且还可能造成混乱。

ui-router

ui-router 完全兼容路由系统的自然状态机(the state-machine nature)。它允许定义状态,转换我们的应用到那些状态。更胜一筹的是它允许解耦嵌套,以优雅的方式做一些非常复杂的布局。 我们应该考虑一点不同的路由,但是只要想到基于状态方法,就将使得创建应用变的如此简单。因此,让我们通过代码来判断什么是最好的。

在下面的项目中,我们使用一点点特性来在一个单页上展示一个冰激凌列表和它们的单价。

Index.html:

<!DOCTYPE html>
<html>
  <head>
    <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>
       <div class="container">
      <div ui-view=""></div>
    </div>
     </body>
</html>

table-data.html:

<h2>Ice-Creams</h2>

<table class="table table-hover table-striped table-bordered">
    <thead>
        <tr>
            <td>Name</td>
            <td>Cost</td>
        </tr>
    </thead>
    <tbody>

        <tr ng-repeat="topic in topics">
            <td>{{ topic.name }}</td>
            <td>${{ topic.price }}</td>
        </tr>

    </tbody>
</table>

app.js:

var routerApp = angular.module('routerApp', ['ui.router']);

routerApp.config(function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/home');

    $stateProvider

        .state('home', {
            url: '/home',
            templateUrl: 'home.html'
        })

        // nested list with custom controller
        .state('home.list', {
            url: '/list',
            templateUrl: 'home-list.html',
            controller: function($scope) {
                $scope.topics = ['Butterscotch', 'Black Current', 'Mango'];
            }
        })

        // nested list with just some random string data
        .state('home.paragraph', {
            url: '/paragraph',
            template: 'I could sure use a scoop of ice-cream. '
        })

        .state('about', {
            url: '/about',
            views: {
                '': { templateUrl: 'about.html' },
                'columnOne@about': { template: '' },
                'columnTwo@about': { 
                    templateUrl: 'table-data.html',
                    controller: 'Controller'
                }
            }

        });

});

routerApp.controller('Controller', function($scope) {

    $scope.message = 'test';

    $scope.topics = [
        {
            name: 'Butterscotch',
            price: 50
        },
        {
            name: 'Black Current',
            price: 100
        },
        {
            name: 'Mango',
            price: 20
        }
    ];

});

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">

    <div class="col-sm-6">
        <div ui-view="columnOne"></div>
    </div>
        <div class="col-sm-6">
        <div ui-view="columnTwo"></div>
    </div>
</div>

home.html:

<div class="jumbotron text-center">
    <h1>Home</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>

home-list.html:

<ul>
    <li ng-repeat="topic in topics">{{ topic }}</li>
</ul>

在上面我们已经看到了基于 ui-router 的应用。但是正如我们在文章开头说的那样,不用 $stateprovider 我们也可以在不同的进行的启用路由。那就是 $routeprovider。

下面我们要看一个例子,由 $routeprovider 启用的路由。在这些示例中,我们将使用几个指向其他页面的链接以及它们返回的结果。一切都将显示在一个单一页面。

index.html:

<!DOCTYPE html>

<!-- define angular app -->
<html ng-app="scotchApp">

<head>

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-route.js"></script>
  <script src="script.js"></script>
</head>

<!-- define angular controller -->
<body ng-controller="mainController">

  <nav class="navbar navbar-default">
    <div class="container">
    <h1>Angular Routing Example with $routeprovider</h1>
           <ul class="nav navbar-nav navbar-right">
        <li><a href="#"><i class="fa fa-home"></i> Home</a></li>
        <li><a href="#about"><i class="fa fa-shield"></i> About</a></li>
        <li><a href="#contact"><i class="fa fa-comment"></i> Contact</a></li>
      </ul>
    </div>
  </nav>

  <div id="main">

    <!-- angular templating -->
        <!-- this is where content will be injected -->
    <div ng-view></div>

  </div>
  </body>
</html>

home.html:

<div class="text-center">
    <h1>Home Page</h1>

    <p>{{ message }}</p>
</div>

about.html:

<div class="text-center">
    <h1>Contact Page</h1>

    <p>{{ message }}</p>
</div>

contact.html:

<div class="text-center">
    <h1>About Page</h1>

    <p>{{ message }}</p>
</div>

script.js:

    // create the module and name it scotchApp
    var scotchApp = angular.module('scotchApp', ['ngRoute']);

    // configure our routes
    scotchApp.config(function($routeProvider) {
        $routeProvider

            // route for the home page
            .when('/', {
                templateUrl : 'home.html',
                controller  : 'mainController'
            })

            // route for the about page
            .when('/about', {
                templateUrl : 'about.html',
                controller  : 'aboutController'
            })

            // route for the contact page
            .when('/contact', {
                templateUrl : 'contact.html',
                controller  : 'contactController'
            });
    });

    // create the controller and inject Angular's $scope
    scotchApp.controller('mainController', function($scope) {
        // create a message to display in our view
        $scope.message = 'This is the home.';
    });

    scotchApp.controller('aboutController', function($scope) {
        $scope.message = 'Here you can know everything ABOUT us.';
    });

    scotchApp.controller('contactController', function($scope) {
        $scope.message = 'Contact us! For more information see below.';
    });

在上面应用中,我们使用了 html5。虽然我们没有在这些 apps 中使用任何设计。任何人可以使用 bootstrap 到他们想要的内容。这些示例仅可以展示如何使用 Angular 的路由工作。这里有一些基础示例。我们也可以做一些修改来提高性能。

评论
发表评论
暂无评论
WRITTEN BY
BoltDoggy
A doggy named Bolt.
TA的新浪微博
PUBLISHED IN
Bolt 应该翻译成`白衣苍狗`【休息一下】

一个连英语四级都没过的前端码奴,借助 Bing 词典

据说是全文翻译最烂的那个

整理,就像现在这段一样晦涩难懂

友情链接 大搜车前端团队博客
我的收藏