AngularJS 进阶

AngularJS 进阶

依赖注入

依赖注入方式

  1. 内部创建依赖;
  2. 通过全局变量进行引用;
  3. 在需要的地方通过参数进行传递。
    前两种方式都不是很好,因为都需要依赖硬编码,使得修改、测试的时候会很麻烦。
    第三种方式是最好的实现方式,因为它不必在组件中主动查找和获取依赖,而是由外界传入。

AngularJS注入内容(服务)到函数中都是通过函数参数的方法,有三种方式:

  1. 推断式注入声明;
  2. 显示注入声明;
  3. 行内注入声明;
推断式注入声明

直接将要注入内容的名字写在函数参数中,名字必须准确。
建议:不要使用这种方式。因为大部分情况下,代码到生产环境时,都会打包压缩,变量名称会简化,如果名称变化可能就会找不到依赖。

app.controller("myController", function ($scope, $filter) {
    $scope.showId = 1;
});
显示注入声明

通过设置函数对象的$inject属性来实现显示注入声明的功能。
$inject属性是一个数据,数组的每个元素都是字符串,每个字符串代表了所要依赖的内容名字。
数组中字符串顺序必须和函数参数顺序相同。
函数参数名字可以随意修改,但数组中字符串必须是依赖内容的名字。
这种注入方式解决了推断式注入的压缩问题。因为压缩不能改变数组内容,而AngularJS通过数组内容查找依赖。

语法:

	var myController = function(rename$scope, renameGreeter) {...}
	myController.$inject = ["$scope", "greeter"];  // 这里数组内必须准确
行内注入声明

在调用方法定义一个控制器(服务、指令等)时,可以通过传入一个数组参数,而不是一个函数。数组的最后一个元素是函数,前面的元素都是这个函数要依赖内容的名字(字符串类型),函数参数与前面的元素一一对应。

语法结构:

        app.controller("myController", ["$scope", "$filter", function ($scope, $filter) {
            $scope.showId = 1;
        }]);

服务

服务是什么

服务就是一个函数或对象。

服务的作用

AngularJS的服务能在应用的整个生命周期内保存数据;
AngularJS的服务保证一份数据在整个应用中的一致性,比如:sessionid要求全局都是一份;
AngularJS的服务是各个控制器间通信的桥梁;
将多个控制器中的相似代码抽取出来定义一个服务,可以减少代码量,提高代码的可维护性。

如何使用服务

通过依赖注入方式将服务注入到函数中,就可以在函数中使用服务。
内置服务和自定义服务使用方式没有区别。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", []);
        // 通过依赖注入的方式,引入服务
        app.controller("myController", ["$scope", "$filter", function ($scope, $filter) {
            $scope.date = $filter("date")(new Date(), "yyyy-MM-dd");
        }]);
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="myController">
        {{date}}
    </div>
</div>
</body>
</html>

service创建方法

AngularJS提供了5种创建服务的方法:factory、service、constat、value、provider。
这个5种方法都是定义在模块实例上的,因此都是通过模块实例调用的。
通过依赖其他模块,可以使用其他模块上定义的服务。

factory

语法: app.factory(name, getFn);
参数说明:

  1. name:服务名。
  2. getFn:实例服务的函数,其返回值可以是函数、对象、简单类型等任意类型数据。

注意:AngularJS的服务都是单实例,即getFn函数在应用的整个生命周期内只会调用一次
当服务第一次注入到控制器或指令等时,AngularJS会自动调用getFn实例化服务,该实例会保存在AngularJS的缓存对象中,等有其他地方调用服务时,首先会判断缓存对象中是否存在,不存在再去实例化。

示例1:
(1)展示factory定义服务的方法;
(2)通过打印日志,说明多个控制器注入,服务也只会被实例化一次;
(3)各个控制器可以通过服务进行通信。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", []);
        app.factory("nameService", function () {
            console.log("init nameService");
            var name = "张三";
            return {
                getName: function () {
                    return name;
                },
                setName: function (newName) {
                    name = newName;
                }
            }
        });
        app.controller("controller1", ["$scope", "nameService", function ($scope, nameService) {
        	// controller1通过服务获取name,然后再修改name
            $scope.name1 = nameService.getName();
            nameService.setName("李四");
        }]);
        app.controller("controller2", ["$scope", "nameService", function ($scope, nameService) {
        	// controller2通过服务获取的是修改后的name
            $scope.name2 = nameService.getName();
        }]);
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="controller1">
        hello {{name1}}
    </div>
    <div ng-controller="controller2">
        hello {{name2}}
    </div>
</div>
</body>
</html>

示例2: 该示例主要说明通过模块依赖,可以使用其它模块定义的服务。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript">
        var app1 = angular.module("app1", []);
        app1.factory("nameService", function () {
            console.log("init nameService");
            var name = "张三";
            return {
                getName: function () {
                    return name;
                },
                setName: function (newName) {
                    name = newName;
                }
            }
        });
        // app依赖于app1,可以使用app1上定义的服务
        var app = angular.module("app", ["app1"]);
        app.controller("controller1", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name1 = nameService.getName();
            nameService.setName("李四");
        }]);
        app.controller("controller2", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name2 = nameService.getName();
        }]);
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="controller1">
        hello {{name1}}
    </div>
    <div ng-controller="controller2">
        hello {{name2}}
    </div>
</div>
</body>
</html>
service

语法:app.service(name, getFn)
参数说明:
name:服务名。
getFn:实例服务的构造函数。
service和factory创建服务的特性都是一样的,只是创建的方式不一样。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript">
        var app1 = angular.module("app1", []);
        app1.service("nameService", function () {
            console.log("init nameService");
            var name = "张三";
            return {
                getName: function () {
                    return name;
                },
                setName: function (newName) {
                    name = newName;
                }
            }
        });
        var app = angular.module("app", ["app1"]);
        app.controller("controller1", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name1 = nameService.getName();
            nameService.setName("李四");
        }]);
        app.controller("controller2", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name2 = nameService.getName();
        }]);

    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="controller1">
        hello {{name1}}
    </div>
    <div ng-controller="controller2">
        hello {{name2}}
    </div>
</div>
</body>
</html>
provider

语法:app.provider(name, getFn or Object);
参数说明:
name:服务名。
getFn or Object:可以是函数或对象。如果是函数,这个函数是一个构造函数,构造函数必须由 g e t 属 性 , 这 个 属 性 是 一 个 方 法 , 有 返 回 值 ; 如 果 是 对 象 , 也 必 须 有 get属性,这个属性是一个方法,有返回值;如果是对象,也必须有 getget属性,与函数中 g e t 一 样 。 当 服 务 注 入 到 控 制 器 时 , A n g u l a r J S 会 调 用 get一样。 当服务注入到控制器时,AngularJS会调用 getAngularJSget方法创建服务实例。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript">
        var app1 = angular.module("app1", []);
        app1.provider("nameService", function () {
            var self = this;
            self.name = "张三";
            self.setName = function (newName) {
                self.name = newName;
            };
            self.getName = function () {
                return self.name;
            };
            self.$get = function () {
                console.log("init nameService");
                return {
                    getName: self.getName,
                    setName: self.setName
                }
            }
        });
        var app = angular.module("app", ["app1"]);
        app.controller("controller1", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name1 = nameService.getName();
            nameService.setName("李四");
        }]);
        app.controller("controller2", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name2 = nameService.getName();
        }]);

    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="controller1">
        hello {{name1}}
    </div>
    <div ng-controller="controller2">
        hello {{name2}}
    </div>
</div>
</body>
</html>

通过对象形式定义:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript">
        var app1 = angular.module("app1", []);
        app1.provider("nameService", {
            name: "张三",
            $get: function () {
                var self = this;
                return {
                    getName: function () {
                        return self.name;
                    },
                    setName: function (newName) {
                        self.name = newName
                    }
                }
            }
        });
        var app = angular.module("app", ["app1"]);
        app.controller("controller1", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name1 = nameService.getName();
            nameService.setName("李四");
        }]);
        app.controller("controller2", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name2 = nameService.getName();
        }]);
        app.config(function (nameServiceProvider){
            console.log("config begin");
            nameServiceProvider.$get().setName("哈哈哈");
        });

    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="controller1">
        hello {{name1}}
    </div>
    <div ng-controller="controller2">
        hello {{name2}}
    </div>
</div>
</body>
</html>
factory、service、provider三种方法的区别和联系:

factory实际也是调用provider实现的服务;而service是调用factory。
在这里插入图片描述
在这里插入图片描述

provider创建的服务功能更加强大,可以通过app.config(function(服务名Provider){…}),提前设置provider服务的属性名。
app.config方法是在所有服务实例化前执行的,比如:如果通过服务控制国际化,那么就需要在所有服务实例化之前进行国际化的配置。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript">
        var app1 = angular.module("app1", []);
        app1.provider("nameService", function () {
            var self = this;
            self.name = "张三";
            self.setName = function (newName) {
                self.name = newName;
            };
            self.getName = function () {
                return self.name;
            };
            self.$get = function () {
                console.log("init nameService");
                return {
                    getName: self.getName,
                    setName: self.setName
                }
            }
        });
        var app = angular.module("app", ["app1"]);
        app.controller("controller1", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name1 = nameService.getName();
            nameService.setName("李四");
        }]);
        app.controller("controller2", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name2 = nameService.getName();
        }]);
        app.config(function (nameServiceProvider){
            console.log("config begin");
            // 服务实例化之前,设置provider服务的属性
            nameServiceProvider.setName("哈哈哈");
        });

    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="controller1">
        hello {{name1}}
    </div>
    <div ng-controller="controller2">
        hello {{name2}}
    </div>
</div>
</body>
</html>

使用场景建议:
(1)当希望在应用开始前对服务进行配置的时候需要使用provider()。比如,我们需要配置服务在不同的部署环境里面(开发,演示,生产)使用不同的后端进行处理的时候,或者国际化选择的时候。
(2)factory和service两个基本一致,可以随意使用。

value

语法:app.value(name, value); 实际上最终还是调用的factory实现的。
参数说明
name:服务名;
value:任意值;

**功能:**定义一个常量值服务,依赖注入后,就可以拿到这个常量值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript">
        var app1 = angular.module("app1", []);
        app1.value("nameService", {
            name: "张三"
        });
        var app = angular.module("app", ["app1"]);
        app.controller("controller1", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name1 = nameService.name;

        }]);
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="controller1">
        hello {{name1}}
    </div>
</div>
</body>
</html>
constant

语法:app.constant(name, value);
参数说明
name:服务名。
value:任意值。
功能:定义一个常量值服务,通过依赖注入拿到这个常量值。
实现上与value创建的常量服务有所区别,constant是将常量值直接放入了缓存对象中,所以可以通过app.config拿到,而value不行(使用factory创建的)。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript">
        var app1 = angular.module("app1", []);
        app1.constant("nameService", {
            name: "张三"
        });
        var app = angular.module("app", ["app1"]);
        app.controller("controller1", ["$scope", "nameService", function ($scope, nameService) {
            $scope.name1 = nameService.name;
        }]);
        // config获取constant服务就是名称,没有后缀
        app.config(function (nameService) {
            console.log(nameService.name);
        })
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="controller1">
        hello {{name1}}
    </div>
</div>
</body>
</html>

内置服务

$filter, $animate, $http等
详情参考:link

路由

SPA—单页面应用

SPA(single page application)是值浏览器只在初始时加载一次HTML页面,后面所有的操作知识改变视图的部分内容,不会重新加载整个HTML页面。
与后端交互一般是通过ajax实现的;
视图切换时通过路由实现的。

单页面应用中url地址的#是什么

单页面视图特点:url地址中锚部分(#开始)改变不会重新加载整个html页面,但是通过路由可以改变视图部分内容。

AngularJS实现单页面

实现SPA的核心:实现页面视图部分的切换,在AngularJS中,可以通过ngRouter和uiRouter两种方式实现SPA的视图切换。

ngRoute

ngRoute是什么

ngRoute是一个angularJS模块,主要用于路由控制,需要单独引入。
ngRoute是一种路由控制机制,核心原理是:当请求一个url时,根据路由配置匹配这个url,然后请求模板片段,并插入到ng-view指令所在的DOM中。

ngRoute核心内容

ngRoute模块包含以下内容:
ngView:提供不同路由模板插入的视图层。
$routerProvider:提供路由配置。
$router:用于构建各个路由的url、view、controller。
$routerParams:解析返回路由中带有的参数。

ui-router

ui-router是什么

ui-router是一个angularJS模块。
ui-router是Angular-UI提供的客户端路由框架。

ui-router核心内容

ui-view:提供不同路由模板插入的视图层;
ui-sref:将当前DOM连接到特定状态;
ui-sref-active:给所在DOM添加激活状态;
$stateProvider:状态配置;
$state:状态服务,提供状态判断、跳转等;
$stateParams:路由参数服务;
$urlRouterProvider: 提供特定URL被激活时处理机制。

ui-router基本用法

  1. 在主模板中使用ui-view定义一个状态模板视图层,不同状态对应的模板将会插入到这个ui-view指令所在的DOM元素中。
  2. 使用$stateProvider进行路由配置,包括每个状态对应的name、url、template以及controller。除了这些基本配置外,还会有一些额外配置,比如resolve配置等。
  3. 在每个路由的controller中完成对应的业务逻辑。
  4. 可以通过注入 s t a t e P a r a m s 服 务 获 取 状 态 上 配 置 的 参 数 , 还 可 以 通 过 stateParams服务获取状态上配置的参数,还可以通过 stateParamsscope监控 s t a t e C h a n g e S t a r t 和 stateChangeStart和 stateChangeStartstateChangeSuccess等事件。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
    	// 依赖注入ui.router
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home", {url: "/home", template: "这是Home"});
            $stateProvider.state("view1", {url: "/view1", template: "这是view1"});
            $stateProvider.state("view2", {url: "/view2", template: "这是view2"});
        });
    </script>
</head>
<body>
<div ng-app="app">
    <span ui-sref="home">Home</span>
    <span ui-sref="view1">view1</span>
    <span ui-sref="view2">view2</span>
    <div ui-view></div>
</div>
</body>
</html>

在这里插入图片描述

ui-router和ngRoute的区别

ui-router提供了ngRoute的全部功能。
ui-router解决了ngRoute一些不足:

  1. 视图不能嵌套,这意味着$scope会发生不必要的重新载入。
  2. 同一URL下不支持多个视图。这一需求也是常见的:我们希望导航栏用一个视图(和相应的控制器)、内容部分用另一个视图(和相应的控制器)。

ngRoute和ui-route核心内容对比:
$route —> $state
$routeParams —> $stateParams
$routeProvider —> $stateProvider

--->

uiView

uiView是angularJS的指令。
用法

  1. ,ui-view没有指定视图名时,各个状态对应的视图都是呈现在这个地方,即各个状态的template插入的地方。
  2. ,指定了视图名称,用于一个状态(一个URL)对应多个视图。

uiView可以嵌套;
一个状态可以对应多个视图。

示例:状态对应多个视图。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    views: {
                        leftView: {
                            template: "这是Home页面的left视图"
                        },
                        rightView: {
                            template: "这是Home页面的right视图"
                        }
                    }
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    views: {
                        leftView: {
                            template: "这是view1页面的left视图"
                        },
                        rightView: {
                            template: "这是view1页面的right视图"
                        }
                    }
                });
            $stateProvider.state("view2",
                {
                    url: "/view2",
                    views: {
                        leftView: {
                            template: "这是view2页面的left视图"
                        },
                        rightView: {
                            template: "这是view2页面的right视图"
                        }
                    }
                });
        });
    </script>
    <style>
        .view {
            border: 1px solid red;
            display: inline-block;
            width: 45%;
            height: 500px;
        }
    </style>
</head>
<body>
<div ng-app="app">
    <div>
        <span ui-sref="home">Home</span>
        <span ui-sref="view1">view1</span>
        <span ui-sref="view2">view2</span>
    </div>
    <div class="view" ui-view="leftView"></div>
    <div class="view" ui-view="rightView"></div>
</div>
</body>
</html>

在这里插入图片描述

ui-sref

作用:绑定ui-sref指令所在DOM到一个状态,当点击这个DOM时,会跳转到对应状态。
用法
(1)ui-sref=“stateName”
(2)ui-sref=“stateName({param:value, param:value})”,可以传递参数给对应的状态,可以通过 s t a t e P a r a m s 服 务 拿 到 对 应 的 状 态 。 ∗ ∗ 注 意 ∗ ∗ : 参 数 属 性 名 必 须 在 状 态 配 置 项 p a r a m s 中 定 义 , 否 则 无 法 生 效 。 u i − s r e f 功 能 和 stateParams服务拿到对应的状态。 **注意**:参数属性名必须在状态配置项params中定义,否则无法生效。 ui-sref功能和 stateParamsparamsuisrefstate.go(“stateName”)类似,只是一个用在HTML中,一个用在js中。

示例:ui-sref传递参数。
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    template: "这是Home页面的视图"
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    // 必须要在params中定义id属性,否则传入的参数不会加入到$stateParams服务中
                    params: {
                        id: 0
                    },
                    controller: function($scope, $stateParams){
                        console.log($stateParams);
                    },
                    template: "这是view1页面的视图"

                });
            $stateProvider.state("view2",
                {
                    url: "/view2",
                    template: "这是view2页面的视图"
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div>
        <span ui-sref="home">Home</span>
        <span ui-sref="view1({id: 10})">view1</span>
        <span ui-sref="view2">view2</span>
    </div>
    <div class="view" ui-view></div>
</div>
</body>
</html>

ui-sref-active

作用:给ui-sref-active指令所在DOM元素添加状态激活样式,当状态不激活时,样式类自动去掉。
用法:ui-sref-active=“class1 class2”

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    template: "这是Home页面的视图"
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    template: "这是view1页面的视图"

                });
            $stateProvider.state("view2",
                {
                    url: "/view2",
                    template: "这是view2页面的视图"
                });
        });
    </script>
    <style>
        .active {
            color: red;
        }
    </style>
</head>
<body>
<div ng-app="app">
    <div>
        <span ui-sref="home" ui-sref-active="active">Home</span>
        <span ui-sref="view1" ui-sref-active="active">view1</span>
        <span ui-sref="view2" ui-sref-active="active">view2</span>
    </div>
    <div class="view" ui-view></div>
</div>
</body>
</html>

$stataProvider

s t a t e P r o v i d e r 是 一 个 对 象 。 u i . r o u t e r 模 块 通 过 p r o v i d e r 方 法 定 义 了 stateProvider是一个对象。 ui.router模块通过provider方法定义了 stateProviderui.routerproviderstate服务,因此可以再config方法中配置 s t a t e 。 在 配 置 函 数 中 就 是 通 过 state。在配置函数中就是通过 statestateProvider调用state方法配置状态的。
$stateProvider提供了两个方法:一个是state方法用于配置状态,另一个是decorator方法用于获取或者重定义状态配置。

用法:$stateProvider.state(“stateName” , stateConfig);

stateConfig
stateName

类型:String
作用:定义状态的名字。
说明:可以通过小数点方式定义嵌套状态(有父子关系的状态)。例如:“contacts.list”。

示例:嵌套路由。
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            // 如果加上otherwise,就会导致默认打开/program;如果是多个页签,可以选择默认打开某个页签。
            // $urlRouterProvider.otherwise("/program");
            $stateProvider.state("program",
                {
                    url: "/program",
                    template: "<p ui-sref='program.list'>编程语言:</p><div ui-view></div>",
                    controller: function ($scope) {
                        $scope.tools = ["python", "java", "js"]
                    }
                });
            $stateProvider.state("program.list",
                {
                    url: "/list",
                    // 这里子路由中可以直接使用父作用域的数据
                    template: "<ul><li ng-repeat='tool in tools'>{{tool}}</li></ul>"
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div ui-sref="program">编程:</div>
    <div ui-view></div>
</div>
</body>
</html>
template,templateUrl,templateProvider

这三个都是定义状态对应的模板。
(1) template
类型:String 或 function。
说明:函数必须返回一个字符串,函数有一个$stateParams参数。

(2) templateUrl
类型:String 或 function。
说明:函数必须返回一个字符串,字符串内容是一个Url,函数有一个$stateParams参数。

(3) templateProvider
类型:function。
说明:函数必须返回一个字符串,字符串内容是一个url。与前两种函数方式区别:该方法可以给函数注入angularJS服务。

controller,controllerProvider

这两个都是定义状态对应的控制器。
(1)controller
类型:String 或 function。
说明:String内容是当前模板上已经定义好一个控制器名;如果是函数,类似于controller方法的第二个参数,定义一个控制器。

(2)controllerProvider
类型:function。
说明:函数必须返回一个字符串(控制器名称),或返回一个函数(定义控制器的函数)。controllerProvider提供了一种可以根据业务逻辑动态添加控制器的方法。

示例参考stateName中的示例,定义了控制器。

resolve

如果需要给状态controller注入一些该状态自己的函数或数据,可以通过resolve实现。
类型:Object
说明: 对象的每个属性都是要注入controller的依赖。属性值可以是一个字符串,也可以是一个函数。
(1)如果属性值是String,该字符串是一个该模块上已经注册的服务名;
(2)如果值是一个函数,则注入这个函数,函数的返回值就是依赖。如果函数返回一个promise,它会在控制器被实例化之前resolved,同时其返回值会注入到控制器中。

关于$q和promiselink
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            // 如果加上otherwise,就会导致默认打开/program
            // $urlRouterProvider.otherwise("/program");
            $stateProvider.state("program",
                {
                    url: "/program",
                    template: "<ul><li ng-repeat='tool in tools'>{{tool}}</li></ul>",
                    resolve: {
                        tools: function ($q, $timeout) {
                            var defer = $q.defer();
                            $timeout(function () {
                                // 1s后执行resolve,resolve的参数会作为promise执行成功的入参
                                defer.resolve(["python", "java", "js"]);
                            }, 1000);
                            // 返回一个promise对象
                            return defer.promise
                        },
                        id: function () {
                            return 100
                        }
                    },
                    controller: function ($scope, tools, id) {
                        $scope.tools = tools;
                        $scope.id = id;
                    }
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div ui-sref="program">编程:</div>
    <div ui-view></div>
</div>
</body>
</html>
url

类型:String
功能:给状态分配一个url。用户可以再浏览器中输入url,跳转到对应的视图。
说明:改参数设置的是一个完整url的锚部分,即#号后面的内容。还可以在url中设置参数,参数会存在$stateParams服务中。

例如1: url: “/contacts/:contactId”
例如2: url: “/view1/{viewId:.*}”
作用:可以将一个状态和多个url匹配。

示例:传参
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            // 如果加上otherwise,就会导致默认打开/program
            // $urlRouterProvider.otherwise("/program");
            $stateProvider.state("program",
                {
                    url: "/program:id",
                    template: "<div>这是第{{id}}条数据</div>",
                    controller: function ($scope, $stateParams) {
                        $scope.id = $stateParams.id;
                    }
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div ui-sref="program">编程:</div>
    <div ui-view></div>
</div>
</body>
</html>
params

类型:Object
功能:设置该状态参数,状态激活时,这些参数被放到 s t a t e P a r a m s 服 务 中 , 因 此 , 我 们 在 状 态 控 制 器 中 通 过 注 入 stateParams服务中,因此,我们在状态控制器中通过注入 stateParamsstateParams服务使用这些参数。
说明:不要和url一起使用,因为url也可以定义参数。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    template: "这是Home页面的视图"
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    // 必须要在params中定义id属性,否则传入的参数不会加入到$stateParams服务中
                    params: {
                        id: 0
                    },
                    controller: function($scope, $stateParams){
                        console.log($stateParams);
                    },
                    template: "这是view1页面的视图"

                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div>
        <span ui-sref="home">Home</span>
        <span ui-sref="view1({id: 10})">view1</span>
    </div>
    <div class="view" ui-view></div>
</div>
</body>
</html>
views

类型:对象。
功能:设置一个状态对应多个视图。
用法:{viewName: viewConfig…}
viewConfig:视图配置对象,与$stateProvider.state(name,stateConfig),第二个参数类似。

说明
(1)每个视图模板会放入页面中的ui-view=viewName所在的DOM中。
(2)设置了view后,template、templateUrl、templateProvider将被忽略。

示例:状态对应多个视图。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    views: {
                        leftView: {
                            template: "这是Home页面的left视图"
                        },
                        rightView: {
                            template: "这是Home页面的right视图"
                        }
                    }
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    views: {
                        leftView: {
                            template: "这是view1页面的left视图"
                        },
                        rightView: {
                            template: "这是view1页面的right视图"
                        }
                    }
                });
            $stateProvider.state("view2",
                {
                    url: "/view2",
                    views: {
                        leftView: {
                            template: "这是view2页面的left视图"
                        },
                        rightView: {
                            template: "这是view2页面的right视图"
                        }
                    }
                });
        });
    </script>
    <style>
        .view {
            border: 1px solid red;
            display: inline-block;
            width: 45%;
            height: 500px;
        }
    </style>
</head>
<body>
<div ng-app="app">
    <div>
        <span ui-sref="home">Home</span>
        <span ui-sref="view1">view1</span>
        <span ui-sref="view2">view2</span>
    </div>
    <div class="view" ui-view="leftView"></div>
    <div class="view" ui-view="rightView"></div>
</div>
</body>
</html>

在这里插入图片描述

abstract

类型:Boolean
默认值:false
功能:设置当前状态为抽象状态,抽象状态不能被点击直接激活。但是其子状态不受影响,可以被激活,如果子状态被激活,父状态也会一起激活。

说明:抽象状态一般主要用于为所有子状态提供一个公共性的东西。例如:使子状态的url都在一个父url下,所有子状态公用一段DOM时;所有子状态公用一个$scope时。

onEnter,onExit

类型:function
功能:进入状态或离开状态是调用的函数。
说明:这两个函数可以获得resolve定义的所有依赖。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    template: "这是Home页面的视图"
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    template: "这是view1页面的视图",
                    onEnter: function () {
                        console.log("onEnter");
                    },
                    onExit: function () {
                        console.log("onExit");
                    }
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div>
        <span ui-sref="home">Home</span>
        <span ui-sref="view1">view1</span>
    </div>
    <div class="view" ui-view></div>
</div>
</body>
</html>
date

类型:对象。
功能:给状态配置对象添加数据,主要用于向子状态传递数据。
说明:与resolve的功能类似,但是data不会被注入到控制器中,定义的promise也不会被resolve。

state

$state是定义在ui.router模块上的AngularJS服务。
ui.router通过provider定义了该服务,因此可以通过config方法配置该服务。
$state服务提供了很多非常有用的方法可以对状态进行控制。
$state服务通过依赖注入使用。

go()方法

语法:$state.go(toState, [,toParams][,options])
执行这个代码后,状态就会跳转到toState。
toState参数可以设置绝对路径或相对路径。以^和.开始就是相对路径,其他都是绝对路径。

例如:
$state.go(“contact.detail”) 会跳转到contact.detail状态
$state.go("^") 会跳转到父状态
$state.go("^.siblingName") 会跳转到siblingName状态
$state.go(".childName") 会跳转到childName状态

示例:绑定ng-click事件,在点击事件中通过$state.go跳转

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.controller("myController", ["$scope", "$state", function ($scope, $state) {
            $scope.homeFun = function () {
                $state.go("home");
            };
            $scope.view1Fun = function () {
                $state.go("view1", {greeting: "hello view1"});
            }
        }]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    template: "这是Home页面的视图"
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    params: {
                        greeting: ""
                    },
                    template: "这是view1页面的视图:{{greeting}}",
                    controller: function ($scope, $stateParams) {
                        $scope.greeting = $stateParams.greeting;
                    }
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="myController">
        <span ng-click="homeFun()">Home</span>
        <span ng-click="view1Fun()">view1</span>
    </div>
    <div ui-view></div>
</div>
</body>
</html>
reload()方法

语法:$state.reload()。
执行后当前状态会被重新加载。Resolve被重新resolved,controller重新实例化,但是状态事件不会被重新触发。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.controller("myController", ["$scope", "$state", function ($scope, $state) {
            $scope.homeFun = function () {
                $state.go("home");
            };
            $scope.view1Fun = function () {
                $state.go("view1", {greeting: "hello view1"});
            };
            $scope.reloadFun = function () {
                $state.reload();
            }
        }]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    template: "这是Home页面的视图"
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    params: {
                        greeting: ""
                    },
                    template: "这是view1页面的视图:{{greeting}}",
                    controller: function ($scope, $stateParams) {
                        $scope.greeting = $stateParams.greeting;
                    }
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="myController">
        <span ng-click="homeFun()">Home</span>
        <span ng-click="view1Fun()">view1</span>
        <span ng-click="reloadFun()">重新加载当前状态</span>
    </div>
    <div ui-view></div>
</div>
</body>
</html>
includes()方法

语法:$state.includes(stateName[, params])。
返回值:boolean。
判断当前激活状态是否是statName状态或子状态。如果传入了第二个参数params,那么将一块对比params,如果全部相同,返回true,否则返回false。

is()方法

语法:$state.is(stateName[, params])。
返回值:boolean。
判断当前激活状态是否是statName状态。如果传入了第二个参数params,那么将一块对比params,如果全部相同,返回true,否则返回false。

href()方法

语法:$state.href(stateName[, params][, options])。
返回值:String。
获取stateOrName对应状态激活时的url值。

get()方法

语法:$state.get(stateName)。
返回值:Object or Array。
有参数时:获取参数对应状态时配置参数;没有参数时,获取注册的所有状态对应的配置对象数组。

current

语法:$state.current。
返回值:Object。
获取当前激活状态对应的配置对象。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.controller("myController", ["$scope", "$state", function ($scope, $state) {
            $scope.homeFun = function () {
                $state.go("home");
            };
            $scope.view1Fun = function () {
                $state.go("view1", {greeting: "hello view1"});
            };
            $scope.getFun = function () {
                console.log($state.includes("view1"));
                console.log($state.is("view1"));
                console.log($state.href("view1"));
                console.log($state.get());
                console.log($state.current);
            }
        }]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    template: "这是Home页面的视图"
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    params: {
                        greeting: ""
                    },
                    template: "这是view1页面的视图:{{greeting}}",
                    controller: function ($scope, $stateParams) {
                        $scope.greeting = $stateParams.greeting;
                    }
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="myController">
        <span ng-click="homeFun()">Home</span>
        <button ng-click="getFun()">获取状态信息</button>
    </div>
    <div ui-view></div>
</div>
</body>
</html>

$stateParams

$stateParams是定义在ui-router模块上的AngularJS服务。
$stateParams主要用于保存当前激活状态对应的参数。可以设置参数的地方有:url属性、params属性。
$stateParams服务通过依赖注入方式使用。

$urlRouterProvider

$urlRouterProvider是一个对象。
u r l R o u t e r P r o v i d e r 是 通 过 p r o v i d e r 定 义 在 u i − r o u t e r 模 块 上 的 A n g u l a r J S 服 务 。 因 此 , 可 以 再 c o n f i g 配 置 函 数 中 设 置 urlRouterProvider是通过provider定义在ui-router模块上的AngularJS服务。因此,可以再config配置函数中设置 urlRouterProviderprovideruirouterAngularJSconfigurlRouterProvider。
$urlRouterProvider定义了三个方法:when()、otherwise()、rule()。

when()

$urlRouterProvider.when(whenUrlPath, toUrlPath)
功能:重定向url地址。
参数:whenPath是想要匹配的入口路径,toPath是要重定向的路径。

otherwise()

$urlRouterProvider.otherwise(urlPath)
功能:没有找到匹配的路径时,重定向到Path路径。主要用于设置默认路径。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.controller("myController", ["$scope", "$state", function ($scope, $state) {
            $scope.homeFun = function () {
                $state.go("home");
            };
            $scope.view1Fun = function () {
                $state.go("view1", {greeting: "hello view1"});
            };
        }]);
        app.config(function ($stateProvider, $urlRouterProvider) {
        	// 非法路由跳转到/view1
            $urlRouterProvider.otherwise("/view1");
            // /home重定向到/view1
            $urlRouterProvider.when("/home", "/view1");
            $stateProvider.state("home",
                {
                    url: "/home",
                    template: "这是Home页面的视图"
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    params: {
                        greeting: ""
                    },
                    template: "这是view1页面的视图:{{greeting}}",
                    controller: function ($scope, $stateParams) {
                        $scope.greeting = $stateParams.greeting;
                    }
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="myController">
        <span ng-click="homeFun()">Home</span>
        <button ng-click="view1Fun()">View1</button>
    </div>
    <div ui-view></div>
</div>
</body>
</html>

ui-router事件

ui-router中事件主要分状态改变事件和视图加载事件。
所有事件都是从 r o o t S c o p e 上 开 始 广 播 的 , 因 此 , 在 所 有 的 rootScope上开始广播的,因此,在所有的 rootScope广scope上都能监听这些事件。

状态改变事件
(1) $stateChangeStart:状态跳转开始时触发事件
(2) $stateChangeSuccess:状态跳转成功时触发事件
(3) $stateChangeErrot:状态跳转失败时触发事件
(4) $stateNotFound:没找到对应状态时触发事件

视图加载事件
(1) $viewContentLoading:视图开始加载时,DOM被渲染前触发事件
(2) $viewContentLoaded:视图加载完成时,DOM被渲染完成后触发事件

事件监听方法
s c o p e . scope. scope.on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams, options){…});
s c o p e . scope. scope.on("$stateNotFound", function(event, toState, toParams, fromState, fromParams, options){…});
s c o p e . scope. scope.on("$viewContentLoading", function(event, toState, toParams, fromState, fromParams, options){…});

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="application/javascript" src="lib/angular.min.js"></script>
    <script type="application/javascript" src="lib/angular-ui-router.js"></script>
    <script type="application/javascript">
        var app = angular.module("app", ["ui.router"]);
        app.controller("myController", ["$scope", "$state", "$rootScope", function ($scope, $state, $rootScope) {
            $scope.homeFun = function () {
                $state.go("home");
            };
            $scope.view1Fun = function () {
                $state.go("view1", {greeting: "hello view1"});
            };
            $scope.$on("$stateChangeStart", function(event, toState) {
                console.log("$stateChangeStart:" + toState.name);
            });
            $scope.$on("$stateChangeSuccess", function(event, toState) {
                console.log("$stateChangeSuccess:" + toState.name);
            });
            $scope.$on("$stateNotFound", function(event, unfoundState, fromState) {
                console.log("$stateNotFound:" + unfoundState.to);
            });
            $scope.$on("$viewContentLoading", function(event, viewConfig) {
                console.log("$viewContentLoading.");
            });
            $scope.$on("$viewContentLoaded", function(event, viewConfig) {
                console.log("$viewContentLoaded.");
            })
        }]);
        app.config(function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/home");
            $stateProvider.state("home",
                {
                    url: "/home",
                    template: "这是Home页面的视图"
                });
            $stateProvider.state("view1",
                {
                    url: "/view1",
                    params: {
                        greeting: ""
                    },
                    template: "这是view1页面的视图:{{greeting}}",
                    controller: function ($scope, $stateParams) {
                        $scope.greeting = $stateParams.greeting;
                    }
                });
        });
    </script>
</head>
<body>
<div ng-app="app">
    <div ng-controller="myController">
        <span ng-click="homeFun()">Home</span>
        <button ng-click="view1Fun()">View1</button>
        <div ui-view></div>
    </div>
</div>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值