AngularJS 指令(Directivce )一
指令(Directive),是AngularJS中一块比较重要的内容,在实践中,我们提倡将控制器(Controller)写得短小精悍,逻辑代码尽量少,要实现这种目的,我们主要通过将逻辑代码抽取到服务(Service)和指令中实现。
今天主要介绍一下指令的相关内容。
一、作用、目的
指令,本质上就是AngularJS扩展具有自定义功能的HTML元素的途径,AngularJS已经实现了很多内置指令,我们也可以通过自定义指令定制自己所需要的HTML元素,从而简化应用,并使自己的架构、代码更优雅,另一方面,由于AngularJS拥有自己的生命周期,很多插件在AngularJS应用中往往会显示“不好用”,这时候,就需要我们自己实现指令,对插件进行集成,例如,在工作中我们团队就对echarts和highcharts进行了集成。
二、定义语法
在AngularJS中,允许我们使用.directive() 方法定义指令, 我们可以通过传入一个字符串和一个函数来注册一个新指令。其中字符串是这个指令的名字,指令名应该是驼峰命名风格的,函数应该返回一个对象,该对象定义了我们指令的细节。
注:1、驼峰命名风格用来将一个短语写在一个单词中,除了第一个单词外其他单词首字母大写,中间不加空格。例如, cute boy 用驼峰风格来写应该是cuteBoy。
注:2、在HTML里使用 my-directive声明指令,指令定义必须以myDirective为名字。如下
<my-directive></my-directive>
angular.module('myApp', [])
.directive('myDirective', function() {
// 指令定义对象
return {
// 省略...
});
directive() 方法可以接受两个参数:
1. name(字符串)
指令的名字,用来在视图中引用特定的指令。
2. factory_function (函数)
这个函数返回一个对象,其中定义了指令的全部行为。
对象的可选设置如下:
angular.module('myApp', [])
.directive('myDirective', function() {
return {
restrict: String,
priority: Number,
terminal: Boolean,
template: String or Template Function:
function(tElement, tAttrs) (...},
templateUrl: String,
replace: Boolean or String,
scope: Boolean or Object,
transclude: Boolean,
controller: String or
function(scope, element, attrs, transclude, otherInjectables) { ... },
controllerAs: String,
require: String,
link: function(scope, iElement, iAttrs) { ... },
compile: // 返回一个对象或连接函数,如下所示:
function(tElement, tAttrs, transclude) {
return {
pre: function(scope, iElement, iAttrs, controller) { ... },
post: function(scope, iElement, iAttrs, controller) { ... }
}
// 或者
return function postLink(...) { ... }
}
};
});
- restrict(字符串)
restrict是一个可选的参数。它告诉AngularJS这个指令在DOM中可以何种形式被声明。默认AngularJS认为restrict的值是A,即以属性的形式来进行声明。
可选值如下:
E(元素) <my-directive></my-directive>
A(属性,默认值) <div my-directive="expression"></div>
C(类名) <div class="my-directive:expression;"></div>
M(注释) <--directive:my-directive expression-->
这些选项可以单独使用,也可以混合在一起使用:restrict: 'EA' // 输入元素或属性
属性是用来声明指令最常用的方式,因为它能在包括老版本的IE浏览器在内的所有浏览器中正常工作,并且不需要在文档头部注册新的标签。
注:1、尽量避免用注释方式来声明属性。这种方式最初被用来声明由多个标签组成的指令。这种方法在某些情况下特别有用,比如在<table> 元素内使用 ng-repeat指 令 , 但 在 AngularJS 1.2 中 ng-repeat 可 以 通 过 ng-repeat-start 和ng-repeat-end来更优雅地满足这个需求,注释模式就没有什么用武之地了。
- priority(数值型)
优先级参数可以被设置为一个数值。大多数指令会忽略这个参数,使用默认值0,但也有些场景设置高优先级是非常重要甚至是必须的。优先级高的指令先于其他指令调用。如果一个元素上具有两个优先级相同的指令,声明在前面的那个会被优先调用。
- terminal (布尔型)
terminal 是一个布尔型参数,可以被设置为true或false。这个参数用来告诉AngularJS停止运行当前元素上比本指令优先级低的指令。但同当前指令优先级相同的指令还是会被执行。
- template(字符串或函数)
template参数是可选的,必须被设置为以下两种形式之一:
一段HTML文本;
一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个代表模板的字符串。 tElement和tAttrs中的t代表template,是相对于instance的。模板元素或属性与实例元素或属性之间是有区别的。AngularJS会同处理HTML一样处理模板字符串。模板中可以通过大括号标记来访问作用域,例如{{ expression }} 。如果模板字符串中含有多个DOM元素,或者只由一个单独的文本节点构成,那它必须被包含在一个父元素内。换句话说,必须存在一个根DOM。
template: '\
<div> <-- single root element -->\
<a href="http://google.com">Click me</a>\
<h1>When using two elements, wrap them in a parent element</h1>\
</div>\
注意每一行末尾的反斜线,这样AngularJS才能正确解析多行字符串。在实际生产中,更好的选择是使用templateUrl参数引用外部模板,因为多行文本阅读和维护起来都是一场噩梦。
- templateUrl (字符串或函数)
templateUrl 是可选的参数,可以是以下类型:
一个代表外部HTML文件路径的字符串;
一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个外部HTML文件路径的字符串。
无 论 哪 种 方 式 , 模 板 的 URL 都 将 通 过 AngularJS 内 置 的 安 全 层 , 特 别 是 $getTrustedResourceUrl ,这样可以保护模板不会被不信任的源加载。
默认情况下,调用指令时会在后台通过Ajax来请求HTML模板文件。有两件事情需要知道。
在本地开发时,需要在后台运行一个本地服务器,用以从文件系统加载HTML模板,否则会导致Cross Origin Request Script( CORS)错误。
模板加载是异步的,意味着编译和链接要暂停,等待模板加载完成。通过Ajax异步加载大量的模板将严重拖慢一个客户端应用的速度。为了避免延迟,可以在部署应用之前对HTML模板进行缓存。在大多数场景下缓存都是一个非常好的选择,因为AngularJS通过减少请求数量提升了性能。模板加载后, AngularJS会将它默认缓存到$templateCache服务中。在实际生产中,可以提前将模板缓存到一个定义模板的JavaScript文件中。
- replace(布尔型)
replace是一个可选参数,如果设置了这个参数,值必须为true,因为默认值为false。默认值意味着模板会被当作子元素插入到调用此指令的元素内部。
- scope参数(布尔型或对象)
scope参数是可选的,可以被设置为true或一个对象。默认值是false。
当scope设置为true时,会从父作用域继承并创建一个新的作用域对象。
当scope设置为一个对象,则创建了一个隔离作用域。如果一个元素上有多个指令使用了隔离作用域,其中只有一个可以生效。只有指令模板中的根元素可以获得一个新的作用域。因此,对于这些对象来说scope默认被设置为true。
AngularJS提供了几种方法能够将指令内部的隔离作用域,同指令外部的作用域进行数据绑定。
@ (or @attr)@ (or @attr)@本地作用域属性:使用@符号将本地作用域同DOM属性的值进行绑定。指令内部作用域可以使用外部作用域的变量:
=双向绑定:通过=可以将本地作用域上的属性同父级作用域上的属性进行双向的数据绑定。就像普通的数据绑定一样,本地属性会反映出父数据模型中所发生的改变。
&父级作用域绑定 通过&符号可以对父级作用域进行绑定,以便在其中运行函数。意味着对这个值进行设置时会生成一个指向父级作用域的包装函数。
- transclude(布尔型)
transclude(嵌入)是一个可选的参数。如果设置了,其值必须为true,它的默认值是false。用以包含任意内容。
我们可以将整个模板,包括其中的指令通过嵌入全部传入一个指令中。这样做可以将任意内容和作用域传递给指令。 transclude参数就是用来实现这个目的的,指令的内部可以访问外部指令的作用域,并且模板也可以访问外部的作用域对象。
注:1、只有当你希望创建一个可以包含任意内容的指令时, 才使用 transclude: true。
注:2、如果指令使用了transclude参数,那么在控制器中就无法正常监听数据模型的变化了。这就是最佳实践总是建议在链接函数里使用$watch服务的原因。
未完待续
AngularJS 指令(Directivce )一的更多相关文章
- AngularJS指令
1. AngularJS指令的特点: AngularJS通过被称为指令的新属性来扩展HTML,指令的前缀为ng-. AngularJS通过内置的指令来为应用添加功能. AngularJS允许你自定义指 ...
- angularjs指令参数transclude
angularjs指令参数transclude transclude翻译为嵌入,和之前看到的vue中的slots作用差不多,目的是将指令元素的子内容嵌入到指令的模板中 定义指令 <div sid ...
- angularjs 指令—— 绑定策略(@、=、&)
angularjs 指令—— 绑定策略(@.=.&) 引入主题背景:angular 的指令配置中的template可以直接使用硬编码写相应的代码,不过也可以根据变量,进行动态更新.那么需要用到 ...
- AngularJS 指令
AngularJS 指令 AngularJS 指令是扩展的 HTML 属性,带有前缀 ng-. ng-app 指令 ng-app 指令定义了 AngularJS 应用程序的 根元素. ng-app 指 ...
- angularjs指令(二)
最近学习了下angularjs指令的相关知识,也参考了前人的一些文章,在此总结下. 欢迎批评指出错误的地方. Angularjs指令定义的API AngularJs的指令定义大致如下 angula ...
- angularJs指令执行的机制==大概的三个阶段
第一阶段:加载阶段 angularJs要运行的话,需要去等待angular.js加载完成,加载完之后呢,angular就会去查找到ng-app这个指令,ng-app在每个应用里面只能出现一次, 它也就 ...
- AngularJS学习笔记二:AngularJS指令
AngularJS 指令: AngularJS 通过被称为 指令 的新属性来扩展 HTML. AngularJS 指令是扩展的 HTML 属性,带有前缀 ng-. 几个常用 指令: ng-app 指令 ...
- AngularJs指令(一)
AngularJs应用现在越来越流行了,谷歌都与微软合作支持AngularJS2.0,这是要逆天了,说明AngularJs将来大势所趋.最近想跳槽,又重新拾起了AngluarJs(之前由于缺少项目应用 ...
- 【转】angularjs指令中的compile与link函数详解
这篇文章主要介绍了angularjs指令中的compile与link函数详解,本文同时诉大家complie,pre-link,post-link的用法与区别等内容,需要的朋友可以参考下 通常大家在 ...
- AngularJS指令进阶 – ngModelController详解
AngularJS指令进阶 – ngModelController详解 在自定义Angular指令时,其中有一个叫做require的字段,这个字段的作用是用于指令之间的相互交流.举个简单的例子,假如我 ...
随机推荐
- P4390 [BOI2007]Mokia 摩基亚 (CDQ解决三维偏序问题)
题目描述 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户C的位置在哪?"的问题,精确到毫米.但其真正高科 ...
- github仓库管理项目
一,建立本地git仓库 首先,git要求使用者必须提供自己的身份标识,为此我们需要在git bash中执行以下命令: git config --global user.name 'aa.Tessst ...
- Java&Selenium借助AutoIt 实现非Input类型自动化上传文件
通常情况下实现自动化上传文件,都是通过sendKeys函数直接将文件全路径传给页面空间就能完成,然而这种情况只能对Input类型的控件有效,对于非Input类型的控件可以借助AutoIt来完成 下载地 ...
- git 获得当前分支名及其对应的远程分支
git 获得当前分支名及其对应的远程分支 git symbolic-ref -q --short HEADgit rev-parse --abbrev-ref --symbolic-full-name ...
- kettle 数据抽取时会出现 无法插入NULL
kettle 数据抽取时会出现 无法插入NULL,其实是空字符串,原因是kettle默认不区分空字符串和NULL. 解决办法: 修改kettle.properties 文件:
- CSS3 -- 边框圆角
文章后有彩蛋哦 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- 洛谷P1052 过河【线性dp】【离散化】
题目:https://www.luogu.org/problemnew/show/P1052 题意: 青蛙要从0跳到超过$l$的地方,每一次可以跳$s$到$t$之间的任意数. 在河中有m个石头,要求在 ...
- Codeforces Round #456 (Div. 2) B题
B. New Year's Evetime limit per test1 secondmemory limit per test256 megabytesinputstandard inputout ...
- code命令用vscode打开项目代码
1. 打开vscode, 使用Command + shift + p, 输入shelll 选择
- HDU 3081 Marriage Match II 最大流OR二分匹配
Marriage Match IIHDU - 3081 题目大意:每个女孩子可以和没有与她或者是她的朋友有过争吵的男孩子交男朋友,现在玩一个游戏,每一轮每个女孩子都要交一个新的男朋友,问最多可以玩多少 ...