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

相关推荐
IT布道7 天前
解决angular与jetty websocket 每30s自动断连的问题
websocket·angular.js·jetty
葡萄城技术团队13 天前
在 Angular 应用程序中使用 Genkit 的完整指南
前端·angular.js
界面开发小八哥15 天前
界面控件Kendo UI for Angular 2025 Q2新版亮点 - 增强跨设备的无缝体验
前端·ui·界面控件·kendo ui·angular.js
蓝乐15 天前
Angular项目IOS16.1.1设备页面空白问题
前端·javascript·angular.js
欧阳天羲18 天前
Angular 框架下 AI 驱动的企业级大前端应用开
前端·人工智能·angular.js
甜瓜看代码23 天前
1.
react.js·node.js·angular.js
天若有情67324 天前
React、Vue、Angular的性能优化与源码解析概述
vue.js·react.js·angular.js
啃火龙果的兔子1 个月前
Angular 从框架搭建到开发上线的完整流程
前端·javascript·angular.js
葡萄城技术团队1 个月前
Angular V20 新特性
angular.js
hashiqimiya1 个月前
AngularJS 待办事项 App
前端·javascript·angular.js