1. 前言
在Angular中,指令是一种为DOM元素添加功能的方式。Angular内置了一些指令,比如ng-model、ng-repeat等,但是我们也可以自定义指令来实现特定的功能。
在本篇文章中,我们将深入学习Angular中的Directive指令,讨论它们的作用以及如何定义和使用它们。
2. 什么是指令
在Angular中,指令是定义在标签中的一些属性,它们可以让我们扩展HTML标记的能力并且提供与标记相关联的行为。指令可以被认为是一个领域特定语言(DSL),它们代表了一个部件,用来体现该部件在网页中的功能。
2.1 内置指令
Angular自带了一些内置的指令,它们是ng-app、ng-model、ng-repeat、ng-if、ng-switch、ng-class、ng-click等。这些指令提供了很多方便开发者的功能。
下面我们通过一个例子来学习其中的一些指令:
// app.js文件
angular.module('app', [])
.controller('ctrl', function ($scope) {
$scope.todos = [
{ text: '学习 AngularJS', done: false },
{ text: '练习乐器', done: false },
{ text: '阅读', done: true },
{ text: '锻炼身体', done: false }
];
$scope.getTotalTodos = function () {
return $scope.todos.length;
};
$scope.addTodo = function () {
$scope.todos.push({ text: $scope.formTodoText, done: false });
$scope.formTodoText = '';
};
$scope.clearCompleted = function () {
$scope.todos = $scope.todos.filter(function (todo) {
return !todo.done;
});
};
});
// index.html文件
<body ng-app="app">
<div ng-controller="ctrl">
<h2>Todo List</h2>
<form ng-submit="addTodo()">
<input type="text" ng-model="formTodoText" placeholder="新增待办事项">
<button type="submit">添加</button>
</form>
<span>{{getTotalTodos()}} 项待办事项</span>
<ul>
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span ng-class="{done: todo.done}">{{todo.text}}</span>
</li>
</ul>
<button ng-click="clearCompleted()">清除已完成事项</button>
</div>
</body>
在上面的代码中,我们定义了一个todo list,网页上有一个添加待办事项的表单,以及一个展示待办事项列表的区域,还有一个清除已完成事项的按钮。
这个例子中用到的指令有:
- ng-app:定义应用程序的根元素,通常放在html或body标签上;
- ng-controller:定义控制器并指定该控制器对应的DOM元素;
- ng-repeat:遍历一个集合,对集合中的每个元素都执行一次相同的操作;
- ng-submit:处理表单的提交事件;
- ng-model:把表单元素的值和$scope中的属性绑定在一起,形成双向数据绑定;
- ng-click:处理元素的点击事件;
- ng-class:根据条件添加或删除类名。
2.2 指令的种类
根据指令的作用域,Angular中的指令可以分为三种类型:
- 作用于元素的指令
这种指令会直接应用于HTML元素,例如ng-repeat、ng-if等。
- 作用于属性的指令
这种指令会对元素的属性进行扩展,例如ng-model、ng-class等。
- 作用于注释的指令
这种指令使用注释指令语法表示,例如ng-view、ng-include等。这种指令通常用于在一个单页面应用程序中更改视图。
3. 自定义指令
在上面的例子中,我们用到了内置指令,但是我们也可以通过Angular的指令API来定义自己的指令,以下代码是自定义指令的一个例子:
// app.js文件
angular.module('app', [])
.controller('ctrl', function ($scope) {
$scope.words = [
{ text: 'AngularJS', count: 3 },
{ text: 'directive', count: 1 },
{ text: 'directive2', count: 10 },
{ text: 'words', count: 3 }
];
})
.directive('wordCounter', function () {
return {
restrict: 'AE',
scope: {
words: '=',
title: '@'
},
template: '重要的词汇:<ul><li ng-repeat="word in words">{{word.text}}-{{word.count}}</li></ul>',
};
});
// index.html文件
<body ng-app="app">
<div ng-controller="ctrl">
<h2>My Directive</h2>
<p word-counter words="words" title="词汇统计结果"></p>
</div>
</body>
在上面的代码中,我们定义了一个名为wordCounter的指令。这个指令承担的任务是,从作用域中获取词汇列表(words)并计算每个词汇出现的次数,最后把这些统计结果展示在词汇列表中。
其中,directive函数会返回一个对象,该对象会包含指令相关的属性和行为。在这个例子中,我们设置了restrict、scope和template属性:
- restrict指令描述了指令指向的HTML元素的类型,它可以是三种值之一,A表示该指令可以被以属性的形式使用,E表示可以以元素的形式使用,甚至可以使用组合形式 AE 或 EA,表示同时支持两种使用方式。
- scope定义了该指令所需要的数据的作用域。其中'='操作符表示通过双向数据绑定的方式绑定,'@'操作符表示先读取$scope中变量的值来进行绑定。
- template用于展示统计结果的HTML模板。
在HTML文件中,我们使用word-counter指令,并传入需要统计的词汇列表。
自定义指令可以让我们在Angular应用程序中封装一个独立的功能模块,并且使得代码模块化,易于维护。
4. 总结
在本文中,我们学习了Angular中的指令。我们讨论了内置指令和自定义指令,了解了指令的种类和如何定义及使用指令。
指令是Angular的重要概念之一,它使我们能够封装并重复使用组件,并将数据和行为绑定到特定元素上。熟练使用指令将使我们的Angular开发变得更易于维护和扩展。