0

0

AngularJS指令用法详解

高洛峰

高洛峰

发布时间:2016-12-08 10:06:39

|

1269人浏览过

|

来源于php中文网

原创

本文实例讲述了angularjs指令用法。分享给大家供大家参考,具体如下:

指令(directives)是任何AngularJS应用中最重要的成分。尽管AngularJS已经自带了很多指令,你经常会发现需要自己亲手创建一些特别的指令。本文将会带你了解自定义指令并解释如何在现实世界中的Angular项目中使用它们。文章的最后,我们将一起用Angular指令来创建一个简单的笔记小应用。

综述

一个指令就是一个引入新语法的东西。指令是在DOM元素上做的标记,并同时附加了一些特定的行为。例如,静态的HTML并不知道如何来创建并显示一个日期选择插件。为了将这个新语法教给HTML我们需要一条指令。这个指令将会创建一个充当日期选择器的元素。我们将在随后看到如何实现这个指令。

如果你之前已经编写过Angular应用,那么你已经使用过指令了,不管你有没有意识到这点。你可能已经使用过像是ng-model,ng-repeat,ng-show等等这样的指令。所有这些指令都将特定的功能绑定到了DOM元素之上。例如,ng-repeat会重复特定的元素,而ng-show会有条件的展示元素。如果你想要创建一个可拖动元素的话你可能需要创建一个指令。指令背后的基本思想很简单。它通过在元素上绑定事件监听器并且将DOM变形来使HTML变得具有交互性。

从jQuery的角度来看指令

想想你如何使用jQuery来创建一个日期选择器。我们首先在HTML中添加一个普通的input字段然后在jQuery中我们调用$(element).dataPicker()来将其转换为一个日期选择器。但是,考虑一下。当一个设计师想要来检查这个标记时,他/她能够立刻猜出这个字段究竟是干什么用的吗?它仅仅是一个普通的input字段还是一个日期选择器?你必须要查看jQuery来确认这点。Angular的方法是使用指令来扩展HTML。因此,一个日期选择器的指令看上去可能如下所示:

   

或者如下所示:

   

这种创建UI成分的方法既直观又清楚。你可以看到元素就知道它的用途。

创建自定义指令

一个Angular指令可能以四种形式出现:

1.一个新的HTML元素(

2.一个元素上的属性(

3.作为一个类(

4.作为注释(

当然,我们完全可以决定我们的指令以什么形式出现在HTML中。现在,我们来看看一个典型的Angular指令是如何写成的。它和controller的注册方式类似,但是它会返回一个简单的对象(指令定义),其中那个包含有一些配置指令的属性。下面的代码展示了一个简单和Hello World指令:

var app = angular.module('myapp',[]);
app.directive('helloWorld',function(){
  return {
    restrict: 'AE',
    replace: true,
    template: '

Hello World!

' } });

   

在上面的代码中,app.diretive()函数在我们的模块中注册了一个新的指令。这个函数的第一个参数是指令的名称。第二个参数是一个返回指令定义对象的函数。如果你的指令对额外的对象/服务(services)例如 $rootScope, $http 或者 $compile 有依赖,它们也可以在其中被注入。这个指令可以作为一个HTML元素来使用,如下所示:

   

或者:

   

或者作为一个属性来使用:

   

或者:

   

如果你想要兼容HTML5,你可以在属性前面加上x-或者data-前缀。因此,下面的标记将会匹配helloWorld指令:

   

或者

   

注意

当匹配指令时,Angular会从元素/属性名之前去除前缀x-或者data-。然后将分隔符 - 或者 : 转换为驼峰表示法已匹配注册的指令。这就是为什么我们的helloWorld指令用在HTML中的时候实际上写成了hello-world。

尽管上面的这个简单的指令仅仅只是展示了一些静态的文本,其中还是有一些值得我们去探究的有趣的点。我们已经在这个指令定义对象中使用了三个属性。我们来看看这三个属性分别都有什么用:

F2移动可视化解决方案
F2移动可视化解决方案

F2移动可视化解决方案,一个专注于移动,开箱即用的可视化解决方案,完美支持 H5 环境同时兼容多种环境(node, 小程序,weex)。完备的图形语法理论,满足你的各种可视化需求。专业的移动设计指引为你带来最佳的移动端图表体验。

下载

restrict - 这个属性指明了一个指令应该如何在HTML中使用(记住指令可以以四种方式出现)。在这个例子中我们将它设置为'AE'。因此,这条指令可以作为一个HTML元素或者一个属性来使用。为了允许指令作为一个类来使用我们可以将restrict设置为'AEC'。

template - 这个实行指明了当指令被Angular编译和链接时生成的HTML标记。它不一定是一个简单的字符串。template可以很复杂,其中经常会涉及其它的指令,表达式({{}}),等等。在大多数情况下你可能会想要使用templateUrl而不是template。因此,理想情况下你应该首先将模板放置在一个单独的HTML文件中然后让templateUrl指向它。

replace - 这个属性指明了是否生成的模板会代替绑定指令的元素。在前面的例子中我们在HTML中使用指令为,并将replace属性设置为true。因此,在指令编译后,生成的模板代替了。最后的输出结果是

Hello World!

。如果你将replace设置为false,默认情况下,输出模板将会被插入到指令被调用的元素中。

link函数和作用域

有一个指令生成的模板是没有用的除非它在正确的作用域中北编译。默认情况下一个指令并不会得到一个新的子作用域。然而,它可以得到父作用域。这意味着如果一个指令位于在一个控制器中那么它将使用控制器的作用域。

为了利用作用域,我们可以使用一个叫做link的函数。它可以通过指令定义对象中的link属性来配置。我们现在对helloworld指令做一些修改一遍当用户在一个input字段中输入一个颜色名称时,Hello Wolld文字的背景颜色会自动发生改变。同样,当一个用户点击Hello World文字时,背景颜色会重置为白色。相应的HTML标记如下所示:


  
  

   

修改后的helloWorld指令代码如下所示:

app.directive('helloWorld',function(){
  return {
    restrict: 'AE',
    replace: true,
    template: '

', link: function(scope,elem,attr){ elem.bind('click',function(){ elem.css('background-color','white'); scope.$apply(function(){ scope.color = "white"; }); }); elem.bind('mouseover',function(){ elem.css('cursor','pointer'); }); } } });

   

注意到link函数被用在了指令中。它接收三个参数:

scope - 它代表指令被使用的作用域。在上面的例子中它等同于符控制器的作用域。

elem - 它代表绑定指令的元素的jQlite(jQuery的一个自己)包裹元素。如果你在AngularJS被包含之前就包括了jQuery,那么它将变成jQuery包裹元素。由于该元素已经被jQuery/jQlite包裹,我们没有必要将它包含在$()中来进行DOM操作。

attars - 它代表绑定指令的元素上的属性。例如,如果你在HTML元素上有一些指令形式为:,你可以在link函数内用attrs.someAttribute来引用这些属性。

link函数主要是用来对DOM元素绑定事件监听器,监视模型属性变化,并更新DOM。在前面的指令代码中,我们绑定了两个监听器,click和mouseover。click处理函数重置了

的背景颜色,而mouseover处理函数则将游标改变为pointer。模板中拥有表达式{{color}},它将随着父作用域中的模型color的变化而变化,从而改变了Hello World的背景色。

Compile函数

Compile函数主要用来在link函数运行之前进行一些DOM转化。它接收下面几个参数:

tElement - 指令绑定的元素

attrs - 元素上声明的属性

这里要注意compile不能够访问scope,而且必须返回一个link函数。但是,如果没有compile函数以依然可以配置link函数。compile函数可以被写成下面的样子:

app.directive('test',function(){
  return {
    compile: function(tElem,attrs){
      //在这里原则性的做一些DOM转换
      return function(scope,elem,attrs){
       //这里编写link函数
      }
    }
  }
});

   

大多数时候,你仅仅只需要编写link函数。这是因为大部分指令都只关心与注册事件监听器,监视器,更新DOM等等,它们在link函数中即可完成。像是ng-repeat这样的指令,需要多次克隆并重复DOM元素,就需要在link函数运行之前使用compile函数。你可能会问威慑呢么要将两个函数分别使用。为什么我们不能只编写一个函数?为了回答这个问题我们需要理解Angular是如何编译指令的!

指令是如何被编译的

当应用在启动时,Angular开始使用$compile服务解析DOM。这项服务会在标记中寻找指令然后将它们各自匹配到注册的适龄。一旦所有的指令都已经被识别完成,Angular就开始执行它们的compile函数。正如前面所提到的,compile函数返回一个link函数,该函数会被添加到稍后执行的link函数队列中。这叫做编译阶段(compile phase)。注意到即使同一个指令有几个实例存在,compile函数也只会运行一次。

在编译阶段之后就到了链接阶段(link phase),这时link函数就一个接一个的执行。在这个阶段中模板被生成,指令被运用到正确的作用域,DOM元素上开始有了事件监听器。不像是compile函数,lin函数会对每个指令的实例都执行一次。

改变指令的作用域

默认情况下指令应该访问父作用域。但是我们并不像对所有情况一概而论。如果我们对指令暴露了父控制器的scope,那么指令就可以自由的修改scope属性。在一些情况下你的指令可能想要添加一些只有内部可以使用的属性和函数。如果我们都在父作用域中完成,可能会污染了父作用域。因此,我们有两种选择:

一个子作用域 - 这个作用域会原型继承父作用域。

一个隔离的作用域 - 一个全新的、不继承、独立存在的作用域。

作用域可以由指令定义对象中的scope属性定义。下面的例子展示了这一点:

app.directive('helloWorld',function(){
  return {
    scope: true, //使用一个继承父作用域的自作用域
    restrict: 'AE',
    replace: true,
    template: '

Hello World!

' } });

   

上面的代码要求Angular为指令提供一个能够原型继承父作用域的子组用于。另一种情形,一个隔离作用域,代码如下所示:

app.directive('helloWorld',function(){
  return {
    scope: {}, //使用一个全新的隔离作用域
    restrict: 'AE',
    replace: true,
    template: '

Hello World!

' } });

   

上面的指令使用一个不继承父作用域的全新隔离作用域。当你想要创建一个可重用的组件时隔离作用域是一个很好的选择。通过隔离作用域我们确保指令是自包含的兵可以轻松地插入到任何HTML app中。这种做法防止了父作用域被污染,由于它不可访问父作用域。在我们修改后的helloWorld指令中如果你将scope设置为{},那么代码就不会再正常运行。它将创建一个隔离的作用域然后表达式{{color}}将无法引用隔离作用域中的属性因此值变为undefined。

隔离作用域并不意味着你一点都不能获取到父作用域中的属性。有一些技巧可以使你访问父作用域中的属性同时监听这些属性的变化。我们将在后续文章中提到这种高级技巧。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

1

2026.02.03

短剧入口地址汇总
短剧入口地址汇总

本专题整合了短剧app推荐平台,阅读专题下面的文章了解更多详细入口。

3

2026.02.03

植物大战僵尸版本入口地址汇总
植物大战僵尸版本入口地址汇总

本专题整合了植物大战僵尸版本入口地址汇总,前往文章中寻找想要的答案。

5

2026.02.03

c语言中/相关合集
c语言中/相关合集

本专题整合了c语言中/的用法、含义解释。阅读专题下面的文章了解更多详细内容。

2

2026.02.03

漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题
漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题

本专题围绕漫蛙漫画(Manwa / Manwa2)官网网页版入口进行整理,涵盖漫蛙漫画官方主页访问方式、网页版在线阅读入口、台版正版漫画浏览说明及基础使用指引,帮助用户快速进入漫蛙漫画官网,稳定在线阅读正版漫画内容,避免误入非官方页面。

3

2026.02.03

Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口
Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口

本专题汇总了俄罗斯知名搜索引擎 Yandex 的官网入口、免登录访问地址、中文登录方法与网页版使用指南,帮助用户稳定访问 Yandex 官网,并提供一站式入口汇总。无论是登录入口还是在线搜索,用户都能快速获取最新稳定的访问链接与使用指南。

30

2026.02.03

Java 设计模式与重构实践
Java 设计模式与重构实践

本专题专注讲解 Java 中常用的设计模式,包括单例模式、工厂模式、观察者模式、策略模式等,并结合代码重构实践,帮助学习者掌握 如何运用设计模式优化代码结构,提高代码的可读性、可维护性和扩展性。通过具体示例,展示设计模式如何解决实际开发中的复杂问题。

2

2026.02.03

C# 并发与异步编程
C# 并发与异步编程

本专题系统讲解 C# 异步编程与并发控制,重点介绍 async 和 await 关键字、Task 类、线程池管理、并发数据结构、死锁与线程安全问题。通过多个实战项目,帮助学习者掌握 如何在 C# 中编写高效的异步代码,提升应用的并发性能与响应速度。

2

2026.02.03

Python 强化学习与深度Q网络(DQN)
Python 强化学习与深度Q网络(DQN)

本专题深入讲解 Python 在强化学习(Reinforcement Learning)中的应用,重点介绍 深度Q网络(DQN) 及其实现方法,涵盖 Q-learning 算法、深度学习与神经网络的结合、环境模拟与奖励机制设计、探索与利用的平衡等。通过构建一个简单的游戏AI,帮助学习者掌握 如何使用 Python 训练智能体在动态环境中作出决策。

2

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
AngularJS教程
AngularJS教程

共24课时 | 3.3万人学习

走进 ES6 新标准语法
走进 ES6 新标准语法

共15课时 | 1.6万人学习

AngularJS 中文手册
AngularJS 中文手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号