AngularJS
AngularJS 简介
AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购。是一款优秀的前端JS框架,已经被用于Google的多款产品当中。AngularJS有着诸多特性,最为核心的是:MVVM、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。
AngularJS 基本概念
在创建第一个应用程序之前,你需要理解Angular中的一些概念。 在本章,通过一个简单的例子,你可以快速接触Angular中所有重要的部分。 但是,我不会花时间去解释细节,而是着重于帮助你建立一个全局性的"概观"。
概念 | 说明 |
---|---|
模板(Template) | 带有Angular扩展标记的HTML |
指令(Directive) | 用于通过自定义属性和元素扩展HTML的行为 |
模型(Model) | 用于显示给用户并且与用户互动的数据 |
作用域(Scope) | 用来存储模型(Model)的语境(context)。模型放在这个语境中才能被控制器、指令和表达式等访问到 |
表达式(Expression) | 模板中可以通过它来访问作用域(Scope)中的变量和函数 |
编译器(Compiler) | 用来编译 模板(Template),并且对其中包含的指令(Directive)和表达式(Expression)进行实例化 |
过滤器(Filter) | 负责格式化表达式(Expression)的值,以便呈现给用户 |
视图(View) | 用户看到的内容(即DOM) |
数据绑定(Data Binding) | 自动同步模型(Model)中的数据和视图(View)表现 |
控制器(Controller) | 视图(View)背后的业务逻辑 |
依赖注入(Dependency Injection) | 负责创建和自动装载对象或函数 |
注入器(Injector) | 用来实现依赖注入(Injection)的容器 |
模块(Module) | 用来配置注入器 |
服务(Service) | 独立于视图(View)的、可复用的业务逻辑 |
AngularJS 数据绑定
在Angular网页应用中,数据绑定是数据模型(model)与视图(view)组件的自动同步。Angular的实现方式允许你把应用中的模型看成单一数据源。而视图始终是数据模型的一种展现形式。当模型改变时,视图就能反映这种改变,反之亦然。
代码示例:
xml
<!doctype html>
<html ng-app="myApp">
<head>
<title>AngularJS 数据绑定</title>
<script src="http://code.angularjs.org/1.2.25/angular.min.js"></script>
</head>
<body>
<div ng-controller="myController">
<!-- 单向数据绑定 -->
<p>单项数据绑定:{{message}}</p>
<!-- 双向数据绑定 -->
<label for="inputText">输入内容:</label>
<input type="text" id="inputText" ng-model="inputValue">
<p>双向数据绑定结果:{{inputValue}}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function ($scope) {
$scope.message = "单向数据绑定";
$scope.inputValue = '';
});
</script>
</body>
</html>
AngularJS 控制器
在 AngularJS 里,控制器(Controller)是至关重要的组件,它承担着管理应用程序数据与行为的职责。
定义与创建
在 AngularJS 里,控制器其实就是一个 JavaScript 函数,借助$scope
对象来对数据和行为进行管理。你可以通过angular.module().controller()
方法创建控制器。示例如下:
ini
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
// 这里可以定义数据和方法
$scope.message = 'Hello, AngularJS!';
$scope.sayHello = function() {
alert($scope.message);
};
});
在上述代码中,myApp
是应用模块,myController
是控制器名称,$scope
作为参数传入控制器函数。
使用方法
定义好控制器后,要使用ng - controller
指令把它关联到 HTML 元素上。
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS Controller Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-controller="myController">
<p>{{message}}</p>
<button ng-click="sayHello()">点击打招呼</button>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.message = 'Hello, AngularJS!';
$scope.sayHello = function() {
alert($scope.message);
};
});
</script>
</body>
</html>
在这个例子中,ng - controller="myController"
把myController
控制器和<div>
元素关联起来,这样<div>
内的子元素 就能访问$scope
里的数据和方法了。
作用
管理数据
控制器能够在$scope
对象里定义和管理数据,这些数据可以在 HTML 模板中借助数据绑定来显示。
bash
app.controller('myController', function($scope) {
$scope.person = {
name: 'John',
age: 30
};
});
css
<div ng-controller="myController">
<p>姓名: {{person.name}}</p>
<p>年龄: {{person.age}}</p>
</div>
处理业务逻辑
控制器能够定义方法,用来处理用户的交互和业务逻辑。
bash
app.controller('myController', function($scope) {
$scope.calculateSum = function(a, b) {
return a + b;
};
});
css
<div ng-controller="myController">
<p>两数之和: {{calculateSum(2, 3)}}</p>
</div>
监听事件
控制器可以监听并处理 DOM 事件,像点击、输入等。
javascript
app.controller('myController', function($scope) {
$scope.clickHandler = function() {
alert('按钮被点击了!');
};
});
ini
<div ng-controller="myController">
<button ng-click="clickHandler()">点击我</button>
</div>
注意事项
- 单一职责原则 :控制器应当专注于处理特定的业务逻辑,避免承担过多的职责。如果业务逻辑过于复杂,可考虑将部分功能拆分成服务。
- ** <math xmlns="http://www.w3.org/1998/Math/MathML"> s c o p e 的作用域 ∗ ∗ :每个控制器都有自己的 scope的作用域**:每个控制器都有自己的 </math>scope的作用域∗∗:每个控制器都有自己的scope对象, <math xmlns="http://www.w3.org/1998/Math/MathML"> s c o p e 的作用域是嵌套的,子元素可以访问父元素的 scope的作用域是嵌套的,子元素可以访问父元素的 </math>scope的作用域是嵌套的,子元素可以访问父元素的scope。不过要注意避免$scope的滥用,防止作用域污染。
AngularJS 服务
在 AngularJS 里,服务(service)是一种单例对象,主要用于在不同组件(像控制器、指令等)间共享数据和逻辑。
定义与特性
服务是 AngularJS 应用中的一个可注入对象,在整个应用生命周期里,服务实例只有一个,这就是单例特性。此特性让服务成为在不同组件间共享数据和方法的理想选择。
创建服务
AngularJS 提供了多种创建服务的方式,常见的有以下几种:
(1)service
方式
ini
var app = angular.module('myApp', []);
app.service('myService', function() {
this.getData = function() {
return [1, 2, 3];
};
});
在这个例子中,myService
就是一个服务,它有一个getData
方法,返回一个数组。
(2)factory
方式
ini
app.factory('myFactory', function() {
var factory = {};
factory.getData = function() {
return [4, 5, 6];
};
return factory;
});
factory
方式返回一个对象,这个对象包含了服务的方法和数据。
(3)provider
方式
ini
app.provider('myProvider', function() {
this.$get = function() {
var provider = {};
provider.getData = function() {
return [7, 8, 9];
};
return provider;
};
});
provider
方式相对复杂,它可以在配置阶段进行配置,然后在运行时通过$get
方法返回服务实例。
常用服务类型
1)内置服务
$http
用于发送 HTTP 请求,和服务器进行数据交互。
lua
app.controller('myController', function($scope, $http) {
$http.get('https://api.example.com/data')
.then(function(response) {
$scope.data = response.data;
}, function(error) {
console.error('请求出错:', error);
});
});
$timeout
类似于 JavaScript 的setTimeout
函数,用于延迟执行代码。
php
app.controller('myController', function($scope, $timeout) {
$timeout(function() {
$scope.message = '延迟显示的消息';
}, 2000);
});
$interval
类似于 JavaScript 的setInterval
函数,用于定时执行代码。
ini
app.controller('myController', function($scope, $interval) {
var counter = 0;
var interval = $interval(function() {
counter++;
$scope.counterValue = counter;
}, 1000);
// 可以在适当的时候取消定时器
$scope.cancelInterval = function() {
$interval.cancel(interval);
};
});
2)自定义服务
开发者可以根据业务需求创建自定义服务,用于封装特定的业务逻辑。比如,创建一个处理用户认证的服务:
ini
app.service('authService', function() {
this.isAuthenticated = false;
this.login = function(username, password) {
// 模拟登录逻辑
if (username === 'admin' && password === 'password') {
this.isAuthenticated = true;
return true;
}
return false;
};
this.logout = function() {
this.isAuthenticated = false;
};
});
使用场景
- 数据共享:不同的控制器或指令需要访问相同的数据时,可使用服务来共享这些数据。例如,多个页面需要显示用户的登录信息,就可以把用户信息存储在一个服务里。
- 业务逻辑封装:将一些通用的业务逻辑封装在服务中,提高代码的可复用性和可维护性。例如,将数据验证、加密解密等逻辑封装在服务里。
- 与服务器交互 :使用
$http
服务或自定义服务来处理与服务器的通信,将数据请求和处理逻辑封装在服务中,让控制器更加简洁。
AngularJS 作用域
在 AngularJS 里,作用域(Scope)是一个核心概念,它充当着数据模型和视图之间的桥梁,负责在两者间进行数据绑定和事件传递。
定义
作用域是一个对象,它包含了应用程序的数据和方法,并且有层级结构。AngularJS 应用中,每个控制器、指令都有与之关联的作用域,作用域提供了一个上下文环境,在这个环境里可以定义和管理数据与行为。
类型
1. 根作用域($rootScope)
- 定义 :
$rootScope
是所有作用域的顶级作用域,在整个 AngularJS 应用中只有一个$rootScope
实例。当应用启动时,AngularJS 会自动创建$rootScope
。 - 作用 :可以在
$rootScope
上定义全局的数据和方法,让应用中的所有子作用域都能访问。不过要谨慎使用,因为过多使用全局数据可能导致代码难以维护和调试。
ini
var app = angular.module('myApp', []);
app.run(function($rootScope) {
$rootScope.globalMessage = '这是全局消息';
});
2. 子作用域
- 定义 :每个控制器和指令都会创建自己的子作用域,子作用域继承自其父作用域(通常是
$rootScope
或上级控制器的作用域)。 - 作用:用于管理局部的数据和行为。不同的控制器和指令可以有自己独立的子作用域,保证数据和逻辑的隔离。
bash
app.controller('myController', function($scope) {
$scope.localMessage = '这是局部消息';
});
特性
1. 作用域继承
子作用域会继承父作用域的属性和方法。当在子作用域中访问一个属性时,AngularJS 会先在子作用域中查找,如果找不到,会继续在父作用域中查找,以此类推,直到找到该属性或到达$rootScope
。
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Scope Inheritance</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-controller="parentController">
<p>父作用域消息: {{message}}</p>
<div ng-controller="childController">
<p>子作用域访问父作用域消息: {{message}}</p>
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('parentController', function($scope) {
$scope.message = '来自父作用域的消息';
});
app.controller('childController', function($scope) {
// 子作用域可以访问父作用域的 message 属性
});
</script>
</body>
</html>
2. 作用域隔离
某些指令(如自定义指令)可以创建隔离作用域,隔离作用域不继承父作用域的属性和方法,通过特定的绑定策略与父作用域进行数据交互。这样可以避免作用域之间的相互影响,提高指令的复用性。
javascript
app.directive('myDirective', function() {
return {
scope: {
// 创建隔离作用域
data: '=' // 双向数据绑定
},
template: '<p>隔离作用域数据: {{data}}</p>'
};
});
生命周期
1. 创建
当 AngularJS 应用启动时,会创建$rootScope
。在创建控制器、指令等组件时,会相应地创建子作用域。
2. 链接
作用域会与对应的 DOM 元素进行链接,建立数据绑定和事件监听。
3. 变更检测
AngularJS 会定期(如用户交互、异步操作完成等)触发变更检测机制,检查作用域中的数据是否发生变化。如果数据发生变化,会更新对应的视图。
4. 销毁
当对应的 DOM 元素被移除或组件被销毁时,作用域也会被销毁,释放内存资源。可以通过$scope.$destroy()
方法手动销毁作用域。
注意事项
- 作用域污染 :要避免在
$rootScope
上定义过多的全局数据,防止作用域污染,使代码难以维护。 - 作用域链查找:由于作用域链查找机制,过多的嵌套作用域可能会影响性能。在设计应用时,要合理规划作用域的层级结构。
AngularJS 依赖注入
依赖注入(Dependency Injection,简称 DI)是 AngularJS 框架的一个核心特性,它能提升代码的可测试性、可维护性与可扩展性。
定义
依赖注入是一种设计模式,它允许对象在创建时不直接创建或管理其依赖项,而是通过外部传入的方式来获取这些依赖项。在 AngularJS 里,依赖注入用于将服务、值、常量等注入到控制器、指令、过滤器等组件中,使组件间的耦合度降低。
工作原理
AngularJS 的依赖注入系统借助$injector
服务来实现。当 AngularJS 应用启动时,会创建一个$injector
实例,它负责管理和解析所有的依赖项。在组件(如控制器)定义时,声明所需的依赖项名称,$injector
会根据这些名称查找并注入相应的依赖项实例。
注入方式
1. 隐式注入
bash
var app = angular.module('myApp', []);
app.controller('myController', function($scope, $http) {
// 使用 $scope 和 $http 服务
$http.get('https://api.example.com/data')
.then(function(response) {
$scope.data = response.data;
});
});
在这个例子中,AngularJS 根据函数参数名$scope
和$http
自动注入对应的服务。不过,这种方式在代码经过压缩工具处理后,参数名会被改变,从而导致注入失败。
2. 显式注入
bash
app.controller('myController', ['$scope', '$http', function($scope, $http) {
$http.get('https://api.example.com/data')
.then(function(response) {
$scope.data = response.data;
});
}]);
这种方式通过一个数组来指定依赖项名称,数组的最后一个元素是实际的控制器函数,前面的元素依次是要注入的依赖项名称。这样即使代码被压缩,AngularJS 也能根据数组中的名称正确注入依赖项。
3. $inject
属性注入
bash
function MyController($scope, $http) {
$http.get('https://api.example.com/data')
.then(function(response) {
$scope.data = response.data;
});
}
MyController.$inject = ['$scope', '$http'];
app.controller('myController', MyController);
这种方式是将依赖项名称通过$inject
属性添加到函数上,同样能避免代码压缩带来的问题。
实际应用场景
1. 服务注入
在控制器、指令等组件中注入服务,以实现数据共享和业务逻辑封装。例如,注入$http
服务来与服务器进行数据交互:
javascript
app.service('dataService', function($http) {
this.getData = function() {
return $http.get('https://api.example.com/data');
};
});
app.controller('myController', ['$scope', 'dataService', function($scope, dataService) {
dataService.getData()
.then(function(response) {
$scope.data = response.data;
});
}]);
2. 配置注入
在应用配置阶段注入常量和值,用于配置服务或模块。例如:
javascript
app.constant('API_URL', 'https://api.example.com');
app.service('dataService', ['$http', 'API_URL', function($http, API_URL) {
this.getData = function() {
return $http.get(API_URL + '/data');
};
}]);
优点
- 可测试性:通过依赖注入,能方便地替换依赖项为模拟对象,从而进行单元测试。
- 可维护性:降低组件间的耦合度,使代码更易于理解和修改。
- 可扩展性:可以轻松地添加或替换依赖项,而不影响其他组件。
AngularJS 模板
在 AngularJS 里,模板是用户界面的蓝图,它把静态 HTML 和动态数据及逻辑相结合,最终生成用户看到的页面。
定义
AngularJS 模板本质上是 HTML 文件,不过其中融入了 AngularJS 的特定语法和指令,这些内容能让模板动态地展示数据、处理事件和控制页面结构。
模板语法
在Angular中有以下元素属性可以直接在模板中使用:
- 表达式(Expressions) :用双括号 {{ }} 给元素绑定表达式。
- 指令(Directive) :一个可扩展已有DOM元素或者代表可重复使用的DOM组件,用扩展属性(或者元素)标记。
- 过滤器(Filter) :格式化数据显示在界面上。
- 表单控件(Form Control) :验证用户输入。
1. 插值表达式(双大括号)
插值表达式用双大括号{{ }}
表示,用于在 HTML 中显示 AngularJS 作用域(scope)中的数据。示例如下:
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>插值表达式示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-controller="myController">
<p>你好,{{name}}!</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.name = '张三';
});
</script>
</body>
</html>
在这个例子中,{{name}}
会被$scope
中的name
属性值(即 "张三")替代。
2. 指令
指令是 AngularJS 模板的核心特性,它可以扩展 HTML 的功能。常见的指令有:
(1)ng-repeat
用于循环渲染列表数据。示例如下:
xml
<div ng-controller="myController">
<ul>
<li ng-repeat="item in items">{{item}}</li>
</ul>
</div>
<script>
app.controller('myController', function($scope) {
$scope.items = ['苹果', '香蕉', '橙子'];
});
</script>
这里的ng-repeat
指令会遍历$scope.items
数组,为每个元素生成一个<li>
元素。
(2)ng-if
根据条件决定是否渲染某个元素。示例如下:
ini
<div ng-controller="myController">
<p ng-if="showMessage">这是一条消息。</p>
<button ng-click="toggleMessage()">切换消息显示</button>
</div>
<script>
app.controller('myController', function($scope) {
$scope.showMessage = false;
$scope.toggleMessage = function() {
$scope.showMessage = !$scope.showMessage;
};
});
</script>
当$scope.showMessage
为true
时,<p>
元素才会被渲染。
(3)ng-model
用于实现双向数据绑定,让表单元素的值和$scope
中的数据相互关联。示例如下:
xml
<div ng-controller="myController">
<input type="text" ng-model="inputValue">
<p>你输入的内容是:{{inputValue}}</p>
</div>
<script>
app.controller('myController', function($scope) {
$scope.inputValue = '';
});
</script>
3. 过滤器
过滤器用于格式化数据的显示方式。常见的过滤器有currency
(货币格式化)、date
(日期格式化)等。
bash
<div ng-controller="myController">
<p>价格:{{price | currency:'¥'}}</p>
<p>日期:{{date | date:'yyyy-MM-dd'}}</p>
</div>
<script>
app.controller('myController', function($scope) {
$scope.price = 123.45;
$scope.date = new Date();
});
</script>
这里的currency
过滤器将price
格式化为货币形式,date
过滤器将date
格式化为指定的日期格式。
4. 表单控件
模板的加载方式
1. 内联模板
内联模板就是直接将模板代码写在 HTML 文件中。
2. 外部模板
可以将模板代码放在单独的 HTML 文件中,然后通过ng-include
指令或路由配置来加载。
ini
<div ng-include="'templates/myTemplate.html'"></div>
优点
- 动态性:能够根据数据的变化动态更新页面内容,提供良好的用户体验。
- 可维护性:将视图和逻辑分离,使代码更易于理解和维护。
- 复用性:可以通过指令和模板的复用,减少代码重复,提高开发效率。
AngularJS 过滤器
在 AngularJS 里,过滤器(Filters)是一种用来格式化数据显示的工具,它能将数据转换为特定的格式,从而更符合用户的展示需求。
定义
过滤器本质上是一个函数,它接收输入数据,对其进行处理后返回处理后的数据。在模板中,可以使用管道符号(|
)来应用过滤器。
使用方式
在模板中使用过滤器时,将管道符号(|
)置于要过滤的数据之后,接着跟上过滤器名称。若过滤器需要参数,可使用冒号(:
)分隔参数。示例如下:
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>过滤器使用示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-controller="myController">
<p>{{ price | currency }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.price = 123.45;
});
</script>
</body>
</html>
在这个例子中,{{ price | currency }}
将$scope.price
的值通过currency
过滤器格式化为货币形式。
内置过滤器
AngularJS 提供了多个内置过滤器,以下是一些常见的内置过滤器:
1. currency
用于将数字格式化为货币形式。可以指定货币符号,默认是美元符号$
。示例如下:
css
<p>{{ 123.45 | currency:'¥' }}</p>
这会将123.45
格式化为¥123.45
。
2. date
用于格式化日期对象。可以指定日期格式,例如yyyy-MM-dd
、MM/dd/yyyy
等。示例如下:
xml
<script>
app.controller('myController', function($scope) {
$scope.now = new Date();
});
</script>
<p>{{ now | date:'yyyy-MM-dd' }}</p>
这会将当前日期格式化为YYYY-MM-DD
的形式。
3. uppercase
和lowercase
uppercase
用于将字符串转换为大写形式,lowercase
用于将字符串转换为小写形式。示例如下:
bash
<p>{{ 'hello' | uppercase }}</p>
<p>{{ 'WORLD' | lowercase }}</p>
分别会输出HELLO
和world
。
4. filter
用于过滤数组,返回满足指定条件的元素。示例如下:
xml
<script>
app.controller('myController', function($scope) {
$scope.items = ['apple', 'banana', 'cherry'];
$scope.searchText = 'a';
});
</script>
<ul>
<li ng-repeat="item in items | filter:searchText">{{ item }}</li>
</ul>
这会显示数组中包含字母a
的元素,即apple
和banana
。
5. orderBy
用于对数组进行排序。可以指定排序的字段和排序顺序(升序或降序)。示例如下:
xml
<script>
app.controller('myController', function($scope) {
$scope.people = [
{ name: 'John', age: 25 },
{ name: 'Jane', age: 20 },
{ name: 'Bob', age: 30 }
];
});
</script>
<ul>
<li ng-repeat="person in people | orderBy:'age'">{{ person.name }} - {{ person.age }}</li>
</ul>
这会按年龄对people
数组进行升序排序。
AngularJS中的所有内置过滤器
格式化相关
currency
:用于将数字转换为货币格式,可指定货币符号。例如{{ 123.45 | currency:'€' }}
会把数字转换为欧元货币格式。date
:对日期对象进行格式化,支持多种日期和时间格式。如{{ myDate | date:'yyyy-MM-dd HH:mm:ss' }}
。number
:把数字转换为带千分位分隔符的字符串,还能指定小数点后的位数。例如{{ 1234.5678 | number:2 }}
会保留两位小数并添加千分位分隔符。uppercase
:将字符串转换为大写形式,如{{ 'hello' | uppercase }}
会输出HELLO
。lowercase
:将字符串转换为小写形式,如{{ 'WORLD' | lowercase }}
会输出world
。
数组和对象处理相关
filter
:过滤数组或对象,返回满足特定条件的元素。可以使用字符串、对象或函数作为过滤条件。例如ng-repeat="item in items | filter:{name:'John'}"
会过滤出name
属性为John
的元素。orderBy
:对数组进行排序,可以指定排序的字段和排序方向(升序或降序)。例如ng-repeat="person in people | orderBy:'age':true"
会按age
字段降序排列。limitTo
:截取数组或字符串的一部分。正数表示从开头截取,负数表示从末尾截取。如{{ [1, 2, 3, 4, 5] | limitTo:3 }}
返回[1, 2, 3]
,{{ 'hello' | limitTo:-3 }}
返回llo
。json
:将对象或数组转换为格式化的 JSON 字符串,常用于调试。例如{{ {key: 'value'} | json }}
会输出格式化后的 JSON 字符串。
其他
slice
:从数组中提取指定范围的元素,类似于 JavaScript 的Array.prototype.slice
方法。例如{{ [1, 2, 3, 4, 5] | slice:1:3 }}
返回[2, 3]
。orderBy
:按照指定规则对数组进行排序。可指定排序的字段以及排序顺序(升序或降序)。例如ng - repeat="item in items | orderBy:'propertyName'"
会按照propertyName
字段对items
数组进行升序排序。filter
:根据指定条件过滤数组中的元素。可以使用字符串、对象或函数来定义过滤条件。例如ng - repeat="item in items | filter:'searchText'"
会过滤出包含searchText
的元素。
自定义过滤器
除了使用内置过滤器,还可以根据需求创建自定义过滤器。自定义过滤器通过angular.module().filter()
方法来定义。示例如下:
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>自定义过滤器示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-controller="myController">
<p>{{ text | reverse }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.filter('reverse', function() {
return function(input) {
if (!input) return '';
return input.split('').reverse().join('');
};
});
app.controller('myController', function($scope) {
$scope.text = 'hello';
});
</script>
</body>
</html>
链式使用过滤器
可以将多个过滤器链式使用,依次对数据进行处理。示例如下:
css
<p>{{ 123.456 | number:2 | currency:'¥' }}</p>
这里先使用number
过滤器将数字保留两位小数,再使用currency
过滤器将其格式化为货币形式。
AngularJS 指令
在 AngularJS 里,指令(Directive)是一种强大的特性,它能对 HTML 进行扩展,让 HTML 拥有动态行为和交互能力。
定义
指令本质上是 AngularJS 编译器在解析 HTML 模板时会识别的特殊属性或元素。当编译器遇到指令时,会根据指令的定义执行相应的操作,比如修改 DOM 结构、绑定事件、实现数据绑定等。
内置指令
1. 数据绑定指令
ng-bind
用于将作用域中的数据绑定到 HTML 元素的文本内容上。和双大括号插值表达式类似,但ng-bind
能避免在页面加载时出现闪烁问题。示例如下:
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>ng-bind示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-controller="myController">
<p ng-bind="message"></p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.message = '这是一条消息。';
});
</script>
</body>
</html>
ng-model
实现双向数据绑定,让表单元素(如输入框、下拉框等)的值和作用域中的数据相互关联。示例如下:
xml
<div ng-controller="myController">
<input type="text" ng-model="inputValue">
<p>你输入的内容是:{{inputValue}}</p>
</div>
<script>
app.controller('myController', function($scope) {
$scope.inputValue = '';
});
</script>
2. 流程控制指令
ng-repeat
用于循环渲染列表数据。可以遍历数组或对象,为每个元素生成一个 DOM 元素。示例如下:
xml
<div ng-controller="myController">
<ul>
<li ng-repeat="item in items">{{item}}</li>
</ul>
</div>
<script>
app.controller('myController', function($scope) {
$scope.items = ['苹果', '香蕉', '橙子'];
});
</script>
ng-if
根据条件决定是否渲染某个元素。当条件为true
时,元素会被渲染到 DOM 中;为false
时,元素会从 DOM 中移除。示例如下:
ini
<div ng-controller="myController">
<p ng-if="showMessage">这是一条消息。</p>
<button ng-click="toggleMessage()">切换消息显示</button>
</div>
<script>
app.controller('myController', function($scope) {
$scope.showMessage = false;
$scope.toggleMessage = function() {
$scope.showMessage = !$scope.showMessage;
};
});
</script>
ng-show
和 ng-hide
根据条件控制元素的显示和隐藏。ng - show
当条件为true
时显示元素,ng - hide
当条件为true
时隐藏元素。和ng - if
不同的是,元素不会从 DOM 中移除,只是通过 CSS 的display
属性来控制显示状态。示例如下:
ini
<div ng-controller="myController">
<p ng-show="isVisible">这是可见的消息。</p>
<p ng-hide="isVisible">这是隐藏的消息。</p>
<button ng-click="toggleVisibility()">切换可见性</button>
</div>
<script>
app.controller('myController', function($scope) {
$scope.isVisible = false;
$scope.toggleVisibility = function() {
$scope.isVisible = !$scope.isVisible;
};
});
</script>
ng-switch
根据表达式的值在多个模板中选择一个进行显示。结合 ng-switch-when
和 ng-switch-default
使用。示例如下:
erlang
<div ng-switch="selectedOption">
<div ng-switch-when="option1">选项 1 的内容</div>
<div ng-switch-when="option2">选项 2 的内容</div>
<div ng-switch-default>默认内容</div>
</div>
3. 事件绑定指令
ng-click
绑定点击事件,当元素被点击时,执行指定的表达式或函数。示例如下:
xml
<div ng-controller="myController">
<button ng-click="sayHello()">点击打招呼</button>
</div>
<script>
app.controller('myController', function($scope) {
$scope.sayHello = function() {
alert('你好!');
};
});
</script>
ng-change
绑定表单元素值改变事件,当表单元素的值发生改变时,执行指定的表达式或函数。示例如下:
xml
<div ng-controller="myController">
<input type="text" ng-model="inputValue" ng-change="valueChanged()">
</div>
<script>
app.controller('myController', function($scope) {
$scope.inputValue = '';
$scope.valueChanged = function() {
console.log('输入值已改变:', $scope.inputValue);
};
});
</script>
4. 样式控制指令
ng-class
根据条件动态地添加或移除 CSS 类。有对象语法、数组语法和表达式语法等多种使用方式。示例如下:
ini
<div ng-controller="myController">
<p ng-class="{red: isRed, bold: isBold}">这是一个动态样式的段落。</p>
<button ng-click="toggleRed()">切换红色</button>
<button ng-click="toggleBold()">切换加粗</button>
</div>
<script>
app.controller('myController', function($scope) {
$scope.isRed = false;
$scope.isBold = false;
$scope.toggleRed = function() {
$scope.isRed = !$scope.isRed;
};
$scope.toggleBold = function() {
$scope.isBold = !$scope.isBold;
};
});
</script>
AngularJS中的所有内置指令
数据绑定指令
ng-bind
:将作用域中的数据绑定到 HTML 元素的文本内容上,避免插值表达式闪烁问题。例如<span ng-bind="name"></span>
。ng-bind-html
:将作用域中的 HTML 代码绑定到元素上,会对 HTML 进行转义处理。比如<div ng-bind-html="htmlContent"></div>
。ng-bind-template
:用于在一个元素内绑定多个表达式,支持使用多个插值表达式。像<span ng-bind-template="{{firstName}} {{lastName}}"></span>
。ng-model
:实现表单元素和作用域数据的双向绑定,常用于输入框、下拉框等表单元素。例如<input type="text" ng-model="userInput">
。
流程控制指令
ng-if
:根据条件动态创建或移除 DOM 元素。当条件为true
时,元素被添加到 DOM 中;为false
时,元素从 DOM 中移除。如<div ng-if="isVisible">可见内容</div>
。ng-show
:根据条件显示或隐藏元素,通过设置display
样式实现,元素仍存在于 DOM 中。例如<p ng-show="showParagraph">显示的段落</p>
。ng-hide
:与ng-show
相反,根据条件隐藏或显示元素。如<p ng-hide="hideParagraph">隐藏的段落</p>
。ng-switch
:根据表达式的值在多个模板中选择一个进行显示。结合ng-switch-when
和ng-switch-default
使用。
事件处理指令
ng-click
:绑定点击事件,当元素被点击时执行指定的表达式或函数。如<button ng-click="doSomething()">点击我</button>
。ng-dblclick
:绑定双击事件,元素被双击时触发相应操作。例如<div ng-dblclick="doubleClickAction()">双击此处</div>
。ng-mousedown
:绑定鼠标按下事件。如<div ng-mousedown="mouseDownHandler()">鼠标按下</div>
。ng-mouseup
:绑定鼠标松开事件。例如<div ng-mouseup="mouseUpHandler()">鼠标松开</div>
。ng-mouseenter
:绑定鼠标进入元素事件。如<div ng-mouseenter="mouseEnter()">鼠标进入</div>
。ng-mouseleave
:绑定鼠标离开元素事件。例如<div ng-mouseleave="mouseLeave()">鼠标离开</div>
。ng-mousemove
:绑定鼠标在元素内移动事件。如<div ng-mousemove="mouseMove()">鼠标移动</div>
。ng-keydown
:绑定键盘按键按下事件。例如<input type="text" ng-keydown="keyDown($event)">
。ng-keyup
:绑定键盘按键松开事件。如<input type="text" ng-keyup="keyUp($event)">
。ng-keypress
:绑定键盘按键按下并释放事件。例如<input type="text" ng-keypress="keyPress($event)">
。ng-change
:绑定表单元素值改变事件,常用于输入框、下拉框等。如<input type="text" ng-model="inputValue" ng-change="valueChanged()">
。ng-submit
:绑定表单提交事件。例如<form ng-submit="submitForm()">...</form>
。
样式和类操作指令
ng-class
:根据条件动态添加或移除 CSS 类,有对象、数组、表达式等多种语法。如<div ng-class="{active: isActive}">动态类</div>
。ng-class-even
:与ng-repeat
配合使用,为偶数行元素添加指定的 CSS 类。例如<li ng-repeat="item in items" ng-class-even="'even-row'">{{item}}</li>
。ng-class-odd
:与ng-repeat
配合使用,为奇数行元素添加指定的 CSS 类。如<li ng-repeat="item in items" ng-class-odd="'odd-row'">{{item}}</li>
。ng-style
:根据表达式的值动态设置元素的内联样式。例如<div ng-style="{color: textColor}">动态样式</div>
。
表单相关指令
ng-disabled
:根据条件禁用表单元素,如按钮、输入框等。例如<button ng-disabled="isDisabled">禁用按钮</button>
。ng-readonly
:根据条件设置表单元素为只读状态。如<input type="text" ng-readonly="isReadOnly">
。ng-required
:设置表单元素为必填项。例如<input type="text" ng-model="requiredInput" ng-required="true">
。ng-pattern
:使用正则表达式验证表单元素的值。如<input type="text" ng-model="email" ng-pattern="/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/">
。ng-minlength
:设置表单元素输入值的最小长度。例如<input type="text" ng-model="minLengthInput" ng-minlength="3">
。ng-maxlength
:设置表单元素输入值的最大长度。如<input type="text" ng-model="maxLengthInput" ng-maxlength="10">
。
其他指令
-
ng-app
:用于定义 AngularJS 应用的根元素,标记应用的启动点。例如<html ng-app="myApp">
。 -
ng-controller
:将控制器关联到 HTML 元素上,为元素及其子元素提供作用域和行为。如<div ng-controller="MyController">...</div>
。 -
ng-include
:用于动态加载外部 HTML 模板文件并插入到当前位置。例如<div ng-include="'template.html'"></div>
。 -
ng-pluralize
:根据数量值显示不同的复数形式文本。css<ng-pluralize count="itemCount" when="{'0': '没有项目', 'one': '1 个项目', 'other': '{} 个项目'}"> </ng-pluralize>
-
ng-transclude
:用于在自定义指令中插入外部内容,实现内容的复用。 -
ng-init
:在元素作用域中初始化变量,一般不建议大量使用。例如<div ng-init="name='John'">...</div>
。
自定义指令
除了使用内置指令,还可以根据需求创建自定义指令。自定义指令通过angular.module().directive()
方法来定义。示例如下:
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>自定义指令示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-controller="myController">
<my-directive message="这是自定义指令的消息。"></my-directive>
</div>
<script>
var app = angular.module('myApp', []);
app.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
message: '@'
},
template: '<p>{{message}}</p>'
};
});
app.controller('myController', function($scope) {
// 控制器逻辑
});
</script>
</body>
</html>
在这个例子中,定义了一个名为myDirective
的自定义指令,它是一个元素指令(restrict: 'E'
),通过scope
属性接收外部传递的message
属性,并在模板中显示该消息。
AngularJS 表单
在 AngularJS 里,表单是实现用户交互的重要组件,它能够收集用户输入的数据,并将这些数据提交到服务器进行处理。
表单的创建
在 AngularJS 中,使用 HTML 的<form>
元素来创建表单。可以给表单添加name
属性,这样就能在作用域中引用该表单。示例如下:
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS表单示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-controller="myController">
<form name="myForm">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" ng-model="user.username">
<br>
<label for="password">密码:</label>
<input type="password" id="password" name="password" ng-model="user.password">
<br>
<input type="submit" value="提交">
</form>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.user = {};
});
</script>
</body>
</html>
在这个例子中,创建了一个包含用户名和密码输入框的表单,通过ng-model
指令将输入框的值绑定到$scope.user
对象的相应属性上。
数据绑定
1. 单向数据绑定
使用ng - bind
或双大括号插值表达式可以将作用域中的数据显示在表单元素上,但这种方式是单向的,即数据从作用域流向视图。例如:
ini
<p ng-bind="user.username"></p>
2. 双向数据绑定
使用ng - model
指令可以实现表单元素和作用域数据的双向绑定。当表单元素的值发生变化时,作用域中的数据也会随之更新;反之亦然。例如:
ini
<input type="text" ng-model="user.username">
表单验证
AngularJS 提供了丰富的表单验证机制,通过内置指令可以方便地对表单元素进行验证。
1. 内置验证指令
ng-required
设置表单元素为必填项。例如:
ini
<input type="text" ng-model="user.username" ng-required="true">
ng-pattern
使用正则表达式验证表单元素的值。例如,验证邮箱格式:
ini
<input type="text" ng-model="user.email" ng-pattern="/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/">
ng-minlength
和ng-maxlength
设置表单元素输入值的最小和最大长度。例如:
ini
<input type="text" ng-model="user.password" ng-minlength="6" ng-maxlength="20">
2. 验证状态
每个表单元素和整个表单都有一些验证状态属性,可以通过这些属性来判断表单或元素的验证状态。常见的验证状态属性有:
$valid
:表示表单或元素是否通过验证。$invalid
:表示表单或元素是否未通过验证。$dirty
:表示表单或元素的值是否被修改过。$pristine
:表示表单或元素的值是否未被修改过。$touched
:表示表单或元素是否被用户触碰过(如获得过焦点)。$untouched
:表示表单或元素是否未被用户触碰过。
可以根据这些验证状态属性来显示相应的错误信息。例如:
ini
<form name="myForm">
<input type="text" name="username" ng-model="user.username" ng-required="true">
<span ng-show="myForm.username.$dirty && myForm.username.$invalid">用户名是必填项。</span>
<input type="submit" value="提交" ng-disabled="myForm.$invalid">
</form>
表单提交
可以使用ng-submit
指令来绑定表单的提交事件。当表单提交时,会执行指定的表达式或函数。例如:
xml
<form name="myForm" ng-submit="submitForm()">
<input type="text" ng-model="user.username" ng-required="true">
<input type="submit" value="提交">
</form>
<script>
app.controller('myController', function($scope) {
$scope.user = {};
$scope.submitForm = function() {
if ($scope.myForm.$valid) {
// 表单验证通过,处理提交逻辑
console.log('提交的数据:', $scope.user);
}
};
});
</script>
在这个例子中,当表单提交时,会调用submitForm
函数,在函数中会先检查表单的验证状态,如果验证通过,则处理提交逻辑。
AngularJS 组件
在 AngularJS 1.x 版本里,组件是一种较为特殊的指令,它简化了指令的使用方式,提供了更清晰的结构,便于构建可复用的视图部件。
定义与特点
-
定义:组件本质上是一个带有预定义配置的指令,通过特定的语法来定义,专注于封装视图和行为。
-
特点
- 隔离作用域:组件默认使用隔离作用域,能避免与外部作用域产生冲突,提高组件的复用性和可维护性。
- 模板和控制器分离:组件将模板(HTML)和控制器(JavaScript)分离,使代码结构更清晰。
- 绑定策略明确 :使用特定的绑定语法(如
@
、=
、&
)来定义组件与外部作用域之间的数据交互方式。
使用方法
1. 定义组件
使用angular.module().component()
方法来定义组件。示例如下:
php
var app = angular.module('myApp', []);
app.component('myComponent', {
templateUrl: 'my - component.html',
bindings: {
message: '@', // 单向字符串绑定
data: '=', // 双向数据绑定
onSubmit: '&' // 绑定函数
},
controller: function() {
var $ctrl = this;
$ctrl.submit = function() {
$ctrl.onSubmit({ data: $ctrl.data });
};
}
});
2. 模板文件(my-component.html
)
bash
<div>
<p>{{$ctrl.message}}</p>
<input type="text" ng-model="$ctrl.data">
<button ng-click="$ctrl.submit()">提交</button>
</div>
3. 在 HTML 中使用组件
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS组件示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-controller="myController">
<my-component message="这是组件消息" data="myData" on-submit="handleSubmit(data)"></my-component>
</div>
<script>
var app = angular.module('myApp', []);
app.component('myComponent', {
templateUrl: 'my-component.html',
bindings: {
message: '@',
data: '=',
onSubmit: '&'
},
controller: function() {
var $ctrl = this;
$ctrl.submit = function() {
$ctrl.onSubmit({ data: $ctrl.data });
};
}
});
app.controller('myController', function($scope) {
$scope.myData = '';
$scope.handleSubmit = function(data) {
console.log('提交的数据:', data);
};
});
</script>
</body>
</html>
绑定策略
@
(单向字符串绑定) :用于将外部作用域的字符串值传递给组件。在组件内部,这个值是只读的。例如:<my-component message="这是组件消息"></my-component>
,组件内部可以通过$ctrl.message
访问这个值。=
(双向数据绑定) :用于在组件和外部作用域之间实现双向数据绑定。当组件内部的数据发生变化时,外部作用域的数据也会相应更新;反之亦然。例如:<my-component data="myData"></my-component>
,组件内部可以通过$ctrl.data
修改和访问这个值。&
(绑定函数) :用于将外部作用域的函数传递给组件,组件可以调用这个函数。例如:<my-component on-submit="handleSubmit(data)"></my-component>
,组件内部可以通过$ctrl.onSubmit()
调用这个函数,并传递参数。
生命周期钩子
组件提供了一些生命周期钩子函数,允许开发者在组件的不同生命周期阶段执行特定的操作。以下是 AngularJS 组件所有生命周期钩子的详细介绍:
1. $onInit()
-
调用时机 :在组件的所有绑定(
bindings
)初始化完成之后调用。此阶段,组件的所有输入绑定(@
、=
、&
)都已被正确赋值。 -
用途:通常用于组件的初始化操作,像初始化数据、调用服务获取初始数据等。
-
示例代码:
phpangular.module('myApp', []).component('myComponent', { bindings: { initialData: '<' }, controller: function() { var $ctrl = this; $ctrl.$onInit = function() { // 对初始数据进行处理 $ctrl.processedData = $ctrl.initialData.map(item => item * 2); }; } });
2. $onChanges(changesObj)
-
调用时机:当组件的绑定属性发生变化时会调用该钩子,这里的变化既包括父组件传入的数据改变,也包括在组件内部对绑定属性的修改。在组件初始化时,若绑定属性有初始值,该钩子也会被调用。
-
参数 :
changesObj
是一个包含所有变化属性的对象,每个属性对应一个包含currentValue
(当前值)、previousValue
(前一个值)和isFirstChange
(是否为首次变化)的对象。 -
用途:用于响应绑定属性的变化,根据新值更新组件的状态或执行其他操作。
-
示例代码:
phpangular.module('myApp', []).component('myComponent', { bindings: { data: '=' }, controller: function() { var $ctrl = this; $ctrl.$onChanges = function(changesObj) { if (changesObj.data) { if (!changesObj.data.isFirstChange()) { // 处理数据变化 console.log('数据已更新,新值为:', changesObj.data.currentValue); } } }; } });
3. $postLink()
-
调用时机:在组件的 DOM 链接完成之后调用。此时,组件的模板已经被渲染到页面上,并且子组件和指令也已经完成链接。
-
用途:适合进行一些与 DOM 操作相关的初始化工作,比如添加事件监听器、操作 DOM 元素样式等。
-
示例代码:
phpangular.module('myApp', []).component('myComponent', { template: '<button id="myButton">点击我</button>', controller: function($element) { var $ctrl = this; $ctrl.$postLink = function() { // 为按钮添加点击事件监听器 var button = $element.find('button'); button.on('click', function() { console.log('按钮被点击了!'); }); }; } });
4. $onDestroy()
-
调用时机:在组件被销毁之前调用,通常是在组件的 DOM 元素从页面上移除时触发。
-
用途:主要用于清理资源,防止内存泄漏,例如取消定时器、移除事件监听器、关闭网络请求等。
-
示例代码:
phpangular.module('myApp', []).component('myComponent', { controller: function($interval) { var $ctrl = this; var intervalId = $interval(function() { console.log('定时器正在运行...'); }, 1000); $ctrl.$onDestroy = function() { // 取消定时器 $interval.cancel(intervalId); }; } });
5. $doCheck()
-
调用时机 :在每次变更检测循环中调用,变更检测是 AngularJS 用于检查数据是否发生变化并更新视图的机制。该钩子在
$onChanges
之后调用。 -
用途:用于实现自定义的变更检测逻辑。当 AngularJS 内置的变更检测机制无法满足需求时,可以在这个钩子中手动检查数据的变化。
-
示例代码:
iniangular.module('myApp', []).component('myComponent', { controller: function() { var $ctrl = this; $ctrl.someData = [1, 2, 3]; var previousData = angular.copy($ctrl.someData); $ctrl.$doCheck = function() { if (!angular.equals($ctrl.someData, previousData)) { // 数据发生了变化 console.log('数据已改变!'); previousData = angular.copy($ctrl.someData); } }; } });
AngularJS 组件路由
AngularJS 的 Component Router 是一个用于单页面应用(SPA)的路由解决方案,它允许开发者根据 URL 的变化动态地加载不同的组件和视图,从而实现页面的切换和导航。
基本概念
- 路由配置:定义了 URL 路径与组件之间的映射关系。当用户访问某个 URL 时,路由器会根据配置找到对应的组件并将其渲染到指定的视图容器中。
- 路由参数 :可以在 URL 中包含参数,用于传递数据给组件。例如,
/users/:id
中的:id
就是一个路由参数。 - 视图容器 :是一个 HTML 元素,用于显示当前路由对应的组件。通常使用
<ng-outlet>
指令来定义视图容器。
配置路由
要使用 Component Router,首先需要引入 ngComponentRouter
模块,并在应用中配置路由。示例如下:
xml
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS Component Router示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-component-router/1.3.3/angular-component-router.js"></script>
</head>
<body>
<a ng-link="['Home']">主页</a>
<a ng-link="['About']">关于</a>
<ng-outlet></ng-outlet>
<script>
var app = angular.module('myApp', ['ngComponentRouter']);
app.value('$routerRootComponent', 'app');
app.component('app', {
template: '<ng-outlet></ng-outlet>',
$routeConfig: [
{ path: '/', name: 'Home', component: 'home', useAsDefault: true },
{ path: '/about', name: 'About', component: 'about' }
]
});
app.component('home', {
template: '<h2>欢迎来到主页</h2>'
});
app.component('about', {
template: '<h2>关于我们</h2>'
});
</script>
</body>
</html>
在这个例子中:
-
引入了
ngComponentRouter
模块。 -
使用
$routerRootComponent
指定根组件为app
。 -
在app组件中,通过
$routeConfig
配置路由,定义了两个路由:/
路径对应Home
路由,使用home
组件,并且设置为默认路由。/about
路径对应About
路由,使用about
组件。
路由导航
可以使用 ng-link
指令来创建导航链接,实现路由导航。例如:
css
<a ng-link="['Home']">主页</a>
<a ng-link="['About']">关于</a>
ng-link
指令的参数是一个数组,数组的第一个元素是路由的名称,后面可以跟路由参数。例如:
css
<a ng-link="['User', { id: 1 }]">用户 1</a>
路由参数
可以在路由配置中定义路由参数,然后在组件中获取这些参数。示例如下:
php
app.component('app', {
template: '<ng-outlet></ng-outlet>',
$routeConfig: [
{ path: '/users/:id', name: 'User', component: 'user' }
]
});
app.component('user', {
template: '<h2>用户 ID: {{$ctrl.userId}}</h2>',
controller: function($routerParams) {
var $ctrl = this;
$ctrl.userId = $routerParams.id;
}
});
在这个例子中,/users/:id
定义了一个路由参数 id
,在 user
组件的控制器中,通过 $routerParams
服务获取该参数的值。
路由生命周期钩子
Component Router 提供了一些生命周期钩子,允许开发者在路由导航的不同阶段执行特定的操作。以下为你详细介绍所有的路由生命周期钩子:
1. $routerCanActivate(next, prev)
-
调用时机:在路由即将激活之前调用,此钩子可用于决定是否允许路由激活。
-
参数:
next
:是一个对象,包含了即将激活的路由信息,像路由参数、路由配置等。prev
:是上一个路由的相关信息对象,若没有上一个路由,该参数为null
。
-
返回值 :可以返回一个布尔值或者一个 Promise 对象。若返回
true
或者 Promise 被解析为true
,则允许路由激活;若返回false
或者 Promise 被拒绝,则阻止路由激活。 -
用途:常用于实现权限验证、数据预加载等功能。比如,在用户未登录时阻止其访问需要登录权限的页面。
-
示例代码:
phpapp.component('protectedPage', { template: '<h2>这是受保护的页面</h2>', controller: function(AuthService) { var $ctrl = this; $ctrl.$routerCanActivate = function(next, prev) { return AuthService.isLoggedIn(); }; } });
2. $routerOnActivate(next, prev)
-
调用时机:当路由成功激活后调用,此时组件已创建且绑定属性已初始化。
-
参数:
next
:包含即将激活的路由信息。prev
:包含上一个路由的信息。
-
用途 :可用于初始化组件数据、根据路由参数加载数据等操作。例如,根据路由中的
id
参数从服务器获取对应的数据。 -
示例代码:
iniapp.component('userPage', { template: '<h2>用户信息:{{$ctrl.user.name}}</h2>', controller: function($routerParams, UserService) { var $ctrl = this; $ctrl.$routerOnActivate = function(next, prev) { var userId = $routerParams.id; UserService.getUserById(userId).then(function(user) { $ctrl.user = user; }); }; } });
3. $routerOnReuse(next, prev)
-
调用时机:当路由被复用的时候调用。在某些情况下,组件可能不会被销毁,而是被复用,此时会触发该钩子。
-
参数:
next
:包含即将激活的路由信息。prev
:包含上一个路由的信息。
-
用途:可用于重置组件状态、更新组件数据等。
-
示例代码:
phpapp.component('reusablePage', { template: '<h2>可复用页面</h2>', controller: function() { var $ctrl = this; $ctrl.$routerOnReuse = function(next, prev) { // 重置组件状态 $ctrl.resetState(); }; $ctrl.resetState = function() { // 重置逻辑 }; } });
4. $routerCanDeactivate(next, prev)
-
调用时机:在路由即将失活之前调用,用于决定是否允许路由失活。
-
参数:
next
:包含即将激活的下一个路由信息。prev
:包含当前即将失活的路由信息。
-
返回值 :可以返回一个布尔值或者一个 Promise 对象。若返回
true
或者 Promise 被解析为true
,则允许路由失活;若返回false
或者 Promise 被拒绝,则阻止路由失活。 -
用途:常用于在用户离开页面时进行数据保存提示、确认操作等。比如,当用户在表单中输入了未保存的数据时,提示用户保存。
-
示例代码:
phpapp.component('formPage', { template: '<form><input type="text" ng-model="$ctrl.inputValue"></form>', controller: function() { var $ctrl = this; $ctrl.inputValue = ''; $ctrl.$routerCanDeactivate = function(next, prev) { if ($ctrl.inputValue) { return confirm('你有未保存的数据,确定要离开吗?'); } return true; }; } });
5. $routerOnDeactivate(next, prev)
-
调用时机:当路由成功失活后调用,此时组件即将被销毁。
-
参数:
next
:包含即将激活的下一个路由信息。prev
:包含当前即将失活的路由信息。
-
用途:可用于清理资源,如取消定时器、释放内存等操作,以避免内存泄漏。
-
示例代码:
phpapp.component('timerPage', { template: '<h2>定时器页面</h2>', controller: function($interval) { var $ctrl = this; var intervalId = $interval(function() { // 定时操作 }, 1000); $ctrl.$routerOnDeactivate = function(next, prev) { $interval.cancel(intervalId); }; } });
AngularJS Api
AngularJS提供了很多功能丰富的组件,处理核心的ng组件外,还扩展了很多常用的功能组件,如ngRoute(路由),ngAnimate(动画),ngTouch(移动端操作)等,只需要引入相应的头文件,并依赖注入你的工作模块,则可使用。
ng ngRoute ngAnimate ngAria ngResource ngCookies ngTouch ngSanitize ngMock