angular-ui-routerangular-ui-router入门


备注

Angular UI-RouterAngularJS的客户端单页面应用程序路由框架。

当用户浏览应用程序时,SPA的路由框架会更新浏览器的URL。相反,这允许更改浏览器的URL以驱动应用程序中的导航,从而允许用户创建到SPA内深处的书签。

UI-Router应用程序被建模为状态的分层树。 UI-Router提供状态机,以类似事务的方式管理这些应用程序状态之间的转换。

取自UI-Router Github页面

版本

发布日期
0.2.18 2016年2月7日
0.2.17 2016年1月25日
0.2.16 2016年1月24日
0.2.15 2016年5月19日
0.2.14 2016年4月23日
0.2.13 二〇一六年十一月二十日
0.2.12 2016年11月13日
0.2.11 2016年8月26日
0.2.10 2016年3月12日
0.2.9 2014年1月17日
0.2.8 2014年1月16日

基本观点

的index.html

<html>
    <head>
        <title>Angular-UI Router Example</title>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.9/angular.js"></script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.js"></script>
        <script type="text/javascript" src="../js/script.js"></script>
    </head>
    <body ui-view="mainView"> <!-- Defining a container for our view -->
    </body>
</html>
 

的script.js

var app = angular.module('app', ['ui.router']);
app.config(['$stateProvider', function($stateProvider){
    $stateProvider.state('home', {                        // Creating a state called 'home'
        url: '',                                          // An empty URL means that this state will be loaded on the main URL when no other state is called
        views: {
            'mainView': {                                 // Section for our view-container that we defined in the HTML
                template: '<h1>It works!</h1>'            // Setting a template for this view
                /*templateUrl: '../templates/home.html'*/ //templateUrl would load the file and uses it's content as the template
             }
        }
    });
}])
 

定义具有多个视图的状态

在ui-router中,状态可以包含多个视图,每个视图都有自己的控制器和模板

.state('dashboard', {
     name: 'dashboard',
     url: '/dashboard',
     views: {
         "view1": {
             templateUrl: "path/to/view1.html",
             controller: "view1Controller"
         },
         "view2": {
             templateUrl: "path/to/view2.html",
             controller: "view2Controller"
         }
     }
 })
 

然后在州的HTML中,您可以链接这些视图

<div ui-view="view1"></div>
<div ui-view="view2"></div>
 

你好世界的例子

第1步:安装

在使用Angular-UI路由器之前,必须在项目中包含AngularJS。有关详细指南,请参阅此文档

您可以分别从GitHub-Page或NuGet,NPM,Bower下载Angular-UI路由器。

在网页中包含JS文件后,可以在应用程序中注入ui.router 模块。在您的脚本文件中,您应该具有以下内容:

var app = angular.module('app', []);
 

现在我们将把Angular-UI路由器注入到我们自己的应用程序中,如下所示:

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

现在Angular-UI路由器将加载我们的应用程序。以下步骤将解释Angular-UI路由器背后的基础知识,并将展示一些基本功能。


第2步:定义简单状态

您可以在Angular config 功能中配置UI-Router。使用$stateProvider 来定义状态。在以下示例中,每个州都有一个URL,控制器和一个模板。

(function() {
  var app = angular.module('app', ['ui.router']);
  
  app.config(['$stateProvider', function($stateProvider) {
      $stateProvider
        .state('home', {
          url: "/home",
          templateUrl: "home.html",
          controller: "homeCtrl"
        })
        .state('kitchen', {
          url: "/kitchen",
          templateUrl: "kitchen.html",
          controller: "kitchenCtrl"
        })
        .state('den', {
          url: "/denCtrl",
          templateUrl: "den.html",
          controller: "denCtrl"
        })
        .state('itemDetail', {
          url: "/items/:itemName",
          templateUrl: "item.html",
          controller: "itemDetailCtrl"
        })

    }])
})();
 

在HTML中,您将需要ui-view 指令,以便可以在其中填充状态视图。

<div ui-view></div>
 

第3步:访问状态

共有3种方法可以访问$stateProvider 定义的状态。

1.通过ui-sref 指令

您可以使用ui-sref 指令访问HTML中的状态

<li ui-sref-active="active">
    <a ui-sref="kitchen">Go to the Kitchen</a>
</li>
<li ui-sref-active="active">
    <a ui-sref="den">Enter the den</a>
</li>
<li ui-sref-active="active">
    <a ui-sref="itemDetail({itemName:'keyboard'})">Key Board</a>
</li>
 

2.通过控制器中的$state 服务

您还可以使用.go 方法提供给控制器的$state 导航到控制器内的其他状态。

.controller(function($scope, $state) {
    // ...
    $scope.navigateTo = function(stateName) {
        $state.go(stateName); // i.e. $state.go('den'); 
    };
})
 

3.通过浏览器中的URL

假设你有一个名为kitchen 的状态定义如下:

$stateProvider
  .state("kitchen", {
    url: "/kitchenUrl",
    ...
  });
 

然后访问appdomain / kitchenUrl作为浏览器中的URL将进入您的kitchen 状态,假设没有嵌套状态, appdomain 是托管您的应用程序的服务器。

如果你仍然感到困惑,这里是一个完全工作的Plnkr

将数据解析为状态

您可以在转换到状态时将数据resolve 到您的状态,通常在状态需要使用该数据时有用,或者在需要对某些提供的输入进行身份验证时解析为状态。

定义状态时,需要提供要解析为.resolve 属性的值映射,每个已解析的值应具有返回promise 的函数

.state('main', {
     url: "/main",
     templateUrl: "path/to/main.html",
     controller: 'mainCtrl',
     resolve: {
         serverData: function ($http) {
             return $http.get('some/url');
         }
     }
});
 

现在,在mainCtrl 你可以访问数据(即如果$http 调用成功解析)。

.controller("mainCtrl", function($scope, serverData) {
    $scope.resolvedData = serverData.then(resp=> resp.data);
    ....
})
 

使用转换事件

UI-Router公开转换事件,这些事件有助于处理转换错误,基于某些参数值处理/阻止转换,自定义身份验证等。

这些事件可以绑定到$rootScope 以获得全局效果,也可以绑定到每个控制器效果的$scope


$stateChangeError - 当尝试更改状态失败并抛出错误时广播此事件,此事件使用以下签名触发回调函数:

回调(event,toState,toParams,fromState,fromParams,error)

event :事件对象

toState :目标状态

toParams :传递给目标状态的参数

fromState :当前状态

fromParams :传递给当前状态的参数

错误 :错误对象


$stateChangeStart - 当状态转换开始时广播此事件,此事件使用以下签名触发回调函数:

回调(event,toState,toParams,fromState,fromParams,options)

options :状态选项对象

$stateChangeSuccess - 当状态转换完成时,该事件被广播,此事件使用以下签名触发回调函数:

回调(event,toState,toParams,fromState,fromParams,options)


$stateNotFound - 当找不到您请求转换到的状态时,将广播此事件,此事件将使用以下签名触发回调函数:

回调(event,unfoundState,fromParams,fromState)

unfoundState - 表示未找到状态的对象


例:

$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams, options) {
    $log.debug("$stateChangeSuccess: event: %o toState: %o, toParams: %o, fromState: %o, fromParams: %o, options: %o", event, toState, toParams, fromState, fromParams, options);
    // runs when the state has successfully changed
});

$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {
    $log.debug("$stateChangeStart: event: %o toState: %o, toParams: %o, fromState: %o, fromParams: %o, options: %o", event, toState, toParams, fromState, fromParams, options);
    // runs when the state has just started to transition
});

$rootScope.$on('$stateNotFound', function (event, unfoundState, fromParams, fromState) {
    $log.debug("$stateNotFound: event: %o unfoundState: %o, fromParams: %o, fromState: %o", event, unfoundState, fromParams, fromState);
    // runs when the state wsa not found
});

$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
    $log.debug("$stateChangeError: event: %o toState: %o, toParams: %o, fromState: %o, fromParams: %o, error: %o", event, toState, toParams, fromState, fromParams, error);
    // runs when there was an error while attempting to transition
});