Angular学习之Directive指令

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开发变得更易于维护和扩展。