AngularJS

AngularJS

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.showMessagetrue时,<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-ddMM/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. uppercaselowercase

uppercase用于将字符串转换为大写形式,lowercase用于将字符串转换为小写形式。示例如下:

bash 复制代码
<p>{{ 'hello' | uppercase }}</p>
<p>{{ 'WORLD' | lowercase }}</p>

分别会输出HELLOworld

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的元素,即applebanana

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-showng-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-whenng-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-whenng-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-minlengthng-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)初始化完成之后调用。此阶段,组件的所有输入绑定(@=&)都已被正确赋值。

  • 用途:通常用于组件的初始化操作,像初始化数据、调用服务获取初始数据等。

  • 示例代码

    php 复制代码
    angular.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(是否为首次变化)的对象。

  • 用途:用于响应绑定属性的变化,根据新值更新组件的状态或执行其他操作。

  • 示例代码

    php 复制代码
    angular.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 元素样式等。

  • 示例代码

    php 复制代码
    angular.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 元素从页面上移除时触发。

  • 用途:主要用于清理资源,防止内存泄漏,例如取消定时器、移除事件监听器、关闭网络请求等。

  • 示例代码

    php 复制代码
    angular.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 内置的变更检测机制无法满足需求时,可以在这个钩子中手动检查数据的变化。

  • 示例代码

    ini 复制代码
    angular.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>

在这个例子中:

  1. 引入了 ngComponentRouter 模块。

  2. 使用 $routerRootComponent 指定根组件为 app

  3. 在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 被拒绝,则阻止路由激活。

  • 用途:常用于实现权限验证、数据预加载等功能。比如,在用户未登录时阻止其访问需要登录权限的页面。

  • 示例代码

    php 复制代码
    app.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 参数从服务器获取对应的数据。

  • 示例代码

    ini 复制代码
    app.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:包含上一个路由的信息。
  • 用途:可用于重置组件状态、更新组件数据等。

  • 示例代码

    php 复制代码
    app.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 被拒绝,则阻止路由失活。

  • 用途:常用于在用户离开页面时进行数据保存提示、确认操作等。比如,当用户在表单中输入了未保存的数据时,提示用户保存。

  • 示例代码

    php 复制代码
    app.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:包含当前即将失活的路由信息。
  • 用途:可用于清理资源,如取消定时器、释放内存等操作,以避免内存泄漏。

  • 示例代码

    php 复制代码
    app.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

相关推荐
前端小干将2 天前
Angular学习入门指南
angular.js
李恩泽的博客9 天前
Angular 样式绑定以及父子传值还有路由
angular.js
爱看书的小沐9 天前
【小沐学Web3D】three.js 加载三维模型(Angular)
前端·javascript·vue·webgl·three.js·angular.js·opengl
勘察加熊人10 天前
angular+form实现2048小游戏
javascript·ecmascript·angular.js
ElasticPDF-新国产PDF编辑器11 天前
Angular use pdf.js and Elasticpdf tutorial
javascript·pdf·angular.js
ElasticPDF-新国产PDF编辑器11 天前
Angular 项目使用 pdf.js 及批注插件Elasticpdf 教程
javascript·pdf·angular.js
ElasticPDF-新国产PDF编辑器12 天前
Angular 项目 PDF 批注插件库在线版 API 示例教程
前端·pdf·angular.js
hz.ts12 天前
Angular 国际化
javascript·ecmascript·angular.js