angularjs 指令详解
一、指令定义
对于指令,可以把它简单的理解成在特定DOM元素上运行的函数,指令可以扩展这个元素的功能。
首先来看个完整的参数示例再来详细的介绍各个参数的作用及用法:
<div my-directive></div>
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[string]
restrict是一个可选的参数。用于指定该指令在DOM中以何种形式被声明。默认值是A,即以属性的形式来进行声明。
可选值如下:
E(元素) <my-directive></my-directive>
A(属性,默认值) <div my-directive></div>
C(类名) <div class="my-directive:expression;"></div>
M(注释) <--directive:my-directive expression-->
一般考虑到浏览器的兼容性,强烈建议使用默认的属性就可以即即以属性的形式来进行声明。最后一种方式建议在不要求逼格指数的时候千万不要用。
replace[bool]
replace是一个可选参数,如果设置了这个参数,值必须为true,因为默认值为false。默认值意味着模板会被当作子元素插入到调用此指令的元素内部,
例如上面的示例默认值情况下,生成的html代码如下:
<my-directive value="http://www.baidu.com" text="百度"><a href="http://www.baidu.com">百度</a></my-directive>
如果设置replace=true
<a href="http://www.baidu.com" value="http://www.baidu.com" text="百度">百度</a>
templateUrl[string or function]
templateUrl是可选的参数,可以是以下类型:
- 一个代表外部HTML文件路径的字符串;
- 一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个外部HTML文件路径的字符串。
无论哪种方式,模板的URL都将通过ng内置的安全层,特别是$getTrustedResourceUrl,这样可以保护模板不会被不信任的源加载。 默认情况下,调用指令时会在后台通过Ajax来请求HTML模板文件。加载大量的模板将严重拖慢一个客户端应用的速度。为了避免延迟,可以在部署应用之前对HTML模板进行缓存。
angular.module('app',[])
.directive('myDirective', function () {
return {
restrict: 'A',
templateUrl: function (elem, attr) {
return attr.value + ".html"; //当然这里我们可以直接指定路径,同时在模板中可以包含表达式
}
};
})
controller[string or function]
controller参数可以是一个字符串或一个函数。当设置为字符串时,会以字符串的值为名字,来查找注册在应用中的控制器的构造函数.
angular.module('myApp', [])
.directive('myDirective', function() {
restrict: 'A',
replace: true,
templateUrl: 'test.html',
controller: 'SomeController'
})
可以在指令内部通过匿名构造函数的方式来定义一个内联的控制器
angular.module('myApp',[])
.directive('myDirective', function() {
restrict: 'A',
controller:
function($scope, $element, $attrs, $transclude) {
// 控制器逻辑放在这里
}
});
我们可以将任意可以被注入的ng服务注入到控制器中,便可以在指令中使用它了。控制器中也有一些特殊的服务可以被注入到指令当中。这些服务有:
1. $scope
与指令元素相关联的当前作用域。
2. $element
当前指令对应的元素。
3. $attrs
由当前元素的属性组成的对象。
<div id="aDiv"class="box"></div>
具有如下的属性对象:
{
id: "aDiv",
class: "box"
}
三、指令作用域
scope参数[bool or object]
scope参数是可选的,可以被设置为true或一个对象。默认值是false。
html代码
<div ng-controller='MainController' ng-init="myProperty='Hello World!'">
外部: {{ myProperty}}
<input ng-model="myProperty" />
<div my-directive></div>
</div>
js代码
angular.module('myApp', [])
.controller('MainController', function ($scope) {
})
.directive('myDirective', function () {
return {
restrict: 'A',
scope:false,//切换为{},true测试
priority: 100,
template: '<div>内部:{{ myProperty }}<input ng-model="myProperty"/></div>'
};
});
当我们改变scope的值我们会发现
false:继承但不隔离
1.当我们将scope
设置为false
的时候,我们创建的指令和父作用域(其实是同一个作用域)共享同一个model
模型,所以在指令中修改模型数据,它会反映到父作用域的模型中。
true:继承并隔离
2.当我们将scope
设置为true
的时候,我们就新创建了一个作用域,只不过这个作用域是继承了我们的父作用域;
我觉得可以这样理解,我们新创建的作用域是一个新的作用域,只不过在初始化的时候,用了父作用域的属性和方法去填充我们这个新的作用域。它和父作用域不是同一个作用域。
{}:隔离且不继承
3.当我们将scope
设置为{}
时,意味着我们创建的一个新的与父作用域隔离的新的作用域,这使我们在不知道外部环境的情况下,就可以正常工作,不依赖外部环境。
四、绑定策略
在使用独立作用域scope的时候,一般有三种绑定传递策略, @单向传递字符串 =双向传递 &单向传递父级的方法
<inputtype="text"ng-model="myUrl">
<div my-directive my-url="{{myUrl}}" my-age="age" change-my-age="changeAge()></div> ①
angular.module('myApp',[])
.directive('myDirective',function(){
return{
restrict:'A',//属性方式
replace:true,
scope:{
myUrl:'@',//@绑定策略(默认绑定到 my-url指令属性)
myAge:'='//=双向绑定(父子互相影响)
changeMyAge:'&' //传递父作用域的方法
},
template:'<a href="{{myUrl}}" ng-click=changeMyAge()>{{ myAge }}</a>'
}
});
在上面的代码中,我创建了一个指令
myDirective
该指令创建了两个变量 myUrl、myLinkText,并且这俩个变量都是采用@绑定策略
。说一下,不管是
@
、=
还是&
绑定策略,它们都有一个默认的方式,以@绑定策略为例,如上面代码那么样:myUrl:'@'
,直接用一个@
表示绑定的方式,它就会默认得将指令属性my-url的值赋值给myUrl变量。当然,你不想使用默认的方式,也就是说,你不想myUrl变量绑定my-url的值,而想要绑定其它属性名的值,那么你可以在
@
后加上你希望的属性名(格式要求:驼峰式)。如,我想讲myUrl绑定到
<myDirective></myDirective>
指令的some-attr属性的值,那么你可以这样写:myUrl:'@someAttr'
。那么我们知道了指令的myUrl变量的值是如何来的,那么我们要如何在template中使用它呢?
这个很简单,看上面的代码就能很明白了,我们在template中的代码中需要用表达式的方式对其引用
{{myUrl}}
,这样我们就能够使用到myUrl变量的值了~
1. 本地作用域属性:使用@符号将本地作用域同DOM属性的值进行绑定,使指令内部作用域可以使用外部作用域的变量:
@
可以在指令中使用绑定的字符串了。
2. 双向绑定:通过=可以将本地作用域上的属性同父级作用域上的属性进行双向的数据绑定。就像普通的数据绑定一样,本地属性会反映出父数据模型中所发生的改变。
3. 父级作用域绑定 通过&符号可以对父级作用域进行绑定,以便在其中运行函数。意味着对这个值进行设置时会生成一个指向父级作用域的包装函数。
要使调用带有一个参数的父方法,我们需要传递一个对象,这个对象的键是参数的名称,值是要传递给参数的内容。
angularjs 指令详解的更多相关文章
- angularjs 指令详解 - template, restrict, replace
通过指令机制,angularjs 提供了一个强大的扩展系统,我们可以通过自定义指令来扩展自己的指令系统. 怎样定义自己的指令呢? 我们通过 Bootstrap UI来学习吧.这个项目使用 angula ...
- AngularJS指令详解
一.什么是指令? 在<AngularJs权威教程>中,指令可以简单理解成特定的DOM元素上运行的函数:我认为还可以理解成将将自定义的HTML标签解析成原始的标签,然后为其加入一些扩展的功能 ...
- 迈向angularjs2系列(2):angular2指令详解
一:angular2 helloworld! 为了简单快速的运行一个ng2的app,那么通过script引入预先编译好的angular2版本和页面的基本框架. index.html: <!DOC ...
- [转]JVM指令详解(上)
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 本文主要记录一些JVM指令,便于记忆与查阅. 一.未归类系列A 此系列暂未归类. 指令码 助记符 ...
- C#中的预处理器指令详解
这篇文章主要介绍了C#中的预处理器指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregio ...
- rsync指令详解
rsync指令详解(更详细的看官方文档http://rsync.samba.org/ftp/rsync/rsync.html) [root@Centos epel]# rsync --help rsy ...
- #pragma 预处理指令详解
源地址:http://blog.csdn.net/jx_kingwei/article/details/367312 #pragma 预处理指令详解 在所有的预处理指令中, ...
- LDM与STM指令详解
title: LDM与STM指令详解 date: 2019/2/26 17:58:00 toc: true --- LDM与STM指令详解 指令形式如下,这里的存储方向是针对寄存器的 Load Mul ...
- C#中的预处理指令详解
这篇文章主要介绍了C#中的预处理指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregion ...
随机推荐
- 织梦在服务器上面安装的时候一直提示data文件没有权限,可我已经写了权限,还是提示
1.进入服务器,打开IIS,点击相应无权限的文件夹data,然后点击右上角的编辑权限. 2.勾选写入,然后确定即可. 3.织梦一直收到黑客的攻击,这里建议站长朋友设置下权限,来降低织梦系统的危险系数. ...
- Linux - ubuntu读取/root/.profile时发现错误:mesg:ttyname fa
启动ubuntu,以root用户登陆,打开命令行终端 输入命令:#vim /root/.profile 找到.profile文件中的mesg n 将其替换成tty -s && mesg ...
- C# winform页面可视化设计打开失败,提示未能加载程序集或他的一个依赖项,dll错误
这种情况发生在最初项目是x86属性,改成x64后,一些原来dll,页面没有及时更新,导致页面找不到dll, 最简单的解决方式,把项目属性改成AnyCpu,重新编译下,就可以打开可视化设计窗口了.
- php实现监控在线服务应用程序小栗子
下面我就给大家举个栗子(例子) 某单位需要实现监控服务器状态,和监控服务器应用网站,还有需要监控服务器的中间件,数据库状态监控.听到这个任务是不是恨透头疼,这想起来是不是头疼.还好有系统可用,但是我现 ...
- apktool给软件加注册机修改图标和文件名
功能实现,即让你的软件具有注册机功能,或者破解别人的软件,据为己有! 先反编译文件包 然后全局工具,修改图标和名称 加注册机,输入key,下载计算器,即可.给某个用户设置自定义的使用时间!
- ZooKeeper对比Eureka
刚开始看到Eureka这个单词的时候真心不会念,查了后发现他有一个好听的名字,来,大家一起念 [ jʊ'rikə ] 简介 Eureka本身是Netflix开源的一款提供服务注册和发现的产品,并且提供 ...
- Go_认识golang
官方地址:https://golang.org/ 什么是Go? 支持并发.垃圾回收的编译型 系统编程语言 Go语言有哪些特点? 1. 类型安全 和 内存安全 2. 以非常直观和极低代价的方案实现高并发 ...
- 三、Html常用标签
1,基本标签 <html>:html文档的根元素,可以指定一个xmlns属性,值只能是http://www/w3.org/1999/xhtml. <body>:页面主体部分 & ...
- 查阅API文档
Java的API文档:就一句话:应用程序接口 •API (Application Programming Interface,应用程序编程接口)是 Java 提供的基本编程接口. •Java语言提供了 ...
- 数据流(任务并行库 TPL)
TPL 数据流库向具有高吞吐量和低滞后时间的占用大量 CPU 和 I/O 操作的应用程序的并行化和消息传递提供了基础. 它还能显式控制缓存数据的方式以及在系统中移动的方式. 为了更好地了解数据流编程模 ...