指令简单理解 就是 在元素上运行的函数 (这个函数有个名称,或者叫属性,比如id 等这种形式)
或者说 扩展这个元素的功能
原来的HTML 元素 比如 input 就只是一个输入框 如果我们在这个元素上加入 指令,就可以扩展这个元素的功能了
比如说:ng-click 可以让一个元素能够监听click事件,并在接收到事件的时候执行angularJS表达式
例如:上面的input 输入框,有ng-change 指令,它可以动态监听input的值是否发生变化
定义指令:使用 directive()方法 接收两个参数:
1.name 字符串,指令的 名称 简单理解就是给某个元素添加了一个新的属性
2.factory_function 函数
在这个函数里面 一般返回一个对象,函数里面定义了这个指令的全部行为,
angular.module('myApp',[])
.directive('myDirective',function(){
//一个指令 定义对象 这个对象的名称 就是第一个参数 name 这里就是:myDirective
return {
//通过设置项进行定义指令 最佳的方式
//或者返回一个函数,来代替定义指令 这个函数称为 连接传递函数 postLink 简单指令用的比较多
};
});
注意事项:自己定义的指令一般 有 my作为前缀,或者用项目名也比较合适,不要使用ng开头,避免冲突
指令的工厂函数只会在编译器第一次匹配到这个指令的时候调用一次,
知识点回顾:javascript对象由 键和值组成 。当一个给定的键的值被设置为 一个字符串,布尔值,数字,数组或者对象时,我们把这个键称为属性,当把键设置为函数时,我们把它叫做方法
可能的选项如下:
angular.module('myApp',[])
.directive('myDirective',function(){
//一个指令 定义对象 这个对象的名称 就是第一个参数 name 这里就是:myDirective
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(){},
post:function(){}
// or
return function postLink(){}
}
};
});
各个选项的意义:
restrict:String 字符串,可选参数,它表示这个指令在DOM中是以何种形式被声明 默认是A
E 代表元素的意思 作用形如:<myDirective></myDirective> 将一些功能封装在元素的内部
A 代表属性的意思 作用形如:<div myDirective=""></div> 给一个已经存在的元素添加 数据或者行为
C 代表类名的意思 作用形如:<div class="myDirective:xx"></div>
M 代表注释的意思 作用形如:<--directive:myDirective --> 这是少用
上面的各个选项 可以单独使用,也可以混合使用 比如'EA'
优先级:priority:Number 数值型
大多数忽略这个函数,默认是 0 ,当需求需要的时候,这个指令非常的用,
作用:比如:使得某个元素在 同一级别的元素上,总是在其他指令之前被调用
terminal:Boolean,布尔型
作用:让angularJS停止在 当前元素 上比 本定义的指令 优先级 低 的所有 指令,相同优先级的指令还会执行
可以参考:ngView 和 ngif
template:String or Template Function:function(tElement,tAttrs){}, 字符串或者函数
字符串:一段 Html文本
函数:可以接受两个参数的函数,参数为:tElement,tAttrs 返回值是:代表模板的字符串
参数中:tElement,tAttrs 的t代表 template 是相对于 instance 的
作用:就是将多个DOM元素封装在一起
如果模板字符串中含有多个DOM元素,或者只有一个单独的文本节点构成,那他必须被包含在一个父元素内部
换句话说 必须存在一个跟DOM元素
举个例子:
<script type="text/javascript"> var myAppModule = angular.module("myApp",[]); myAppModule.directive("xingoo",function(){ return { restrict:'AE', template:'<div><input type="text" ng-model="username"/>{{username}}</div><br>', repalce:true } }) </script>
注意template 返回模板字符串的时候,如果有多行的话,需要在每行后面加上反斜线 或者使用 <br> 的形式
由于多行维护和阅读都非常的困难,所以这个方案不被大量使用,简单的时候就这样用,但是复制的情况下建议使用
templateUrl
这里面的难点在于 模板 中作用域的问题
templateUrl:String,字符串【也可以是函数】
字符串:代表外部HTML文件路径的字符串 一般通过ajax 请求HTML模板文件
【函数:一个可以接收两个参数的函数,返回的是一个外部HTML文件的路径的字符串】
麻烦的问题:一般选择从 服务器文件系统中加载HTML模板,这个加载的过程是异步的,编译和链接需要暂停,等待模板加载完成,严重拖慢客户端应用速度,
解决方法:在部署之前对HTML模板进行缓存 这是一个非常好的选择 放在一个定义模板的javascript文件中
replace:Boolean or String,布尔型
如果设置了这个参数,值必须是true,因为默认是false
默认的意思是 :模板会被当作 子元素 插入到 调用此指令的元素内容 意思就是添加了一个子元素
scope:Boolean or Object,布尔型或者对象
参数可选,可以被设置为true 默认是false 或者设置为一个对象
作用:当设置为true时候,会从父作用域继承并创建一个新的作用域 新的作用域代表了什么意思,代表了它是独立的
关于这点 下篇文章详细讲解
transclude:Boolean 布尔型
参数可选,可以被设置为true 默认是false
作用:嵌入 创造可复用的组件 或者叫 创建一个可以复用的指令
详细说:可以将整个模板包括其中的指令 嵌入 另外一个 指令中
实现的目的就是:指令的内部可以访问外部指令的作用域
这个时候有个前提条件就是:scope选项必须是通过{}或者true设置成隔离作用域(独立作用域)
controller:String or function(scope,element,attrs,transclude,otherInjectables){},
字符串或者函数
字符串:当设置为字符串时 会以字符串的值为名字来查找注册在应用中的控制器的构造函数
作用是:将一些特殊的服务注入到本指令中
函数:
function(scope,element,attrs,transclude,otherInjectables)
scope:与指令元素相关的当前的作用域 被注入到指令中
element 当前指令对应的元素
attrs 当前元素 属性 组成的对象 比如id class 等,是键值对的形式
transclude 嵌入连接函数
controllerAs:String
参数设置控制器别名