Angular中的自定义指令
什么是指令?
- 百度上是这样定义的:
- 指令是指示计算机执行某种操作的命令,它由一串二进制数码组成。
- 当然我们这里并不是深究这个概念的,下面主要讲讲Angular中的指令:
- AngularJS中的指令是对 HTML 标签属性的扩展,比如说为 DOM 元素调用方法、定义行为绑定数据等;
- AngularJS最大程度减少DOM操作,实现数据绑定,与业务逻辑进行交互,其本质上就是AngularJS扩展了具有自定义功能的HTML元素;
- 指令就是DOM与逻辑行为的媒介,本质就是DOM绑定的独立逻辑行为函数,调用指令意味着执行指令背后与之相关联的JavaScript代码,这些代码是我们用指令定义写出来的;
- 值得一说的是,AngularJS与jQuery的区别?
- jq大量操作DOM,而ng则避免操作DOM;
- 我个人理解ng的MVC的开发思想,还是在于指令封装了一系列操作DOM的操作,只是我们看不到,ng最大的亮点在数据双向绑定,实质就是DOM的操作形式不一样。
- JQuery通过选择器找到DOM元素,再赋予元素的行为;
而AngularJS则是,将指令与DOM绑定在一起,再扩展指令的行为。
指令怎么创建?
- 我们可以通过AngularJS模块API中的内置的.directive()方法;
- 通过传入一个字符串,用来定义指令名称和一个函数,也就是这个指令要实现某种功能对应的一段html代码来注册一个新指令。
- 其中字符串是这个指令的名字,指令名应该是驼峰命名风格的,
- 函数应该返回一个对象。
自定义指令的写法
- 使用.directive()方法
- return 一个对象,这个对象可以完成某些功能
- 参数都有那些,什么含义
angular.module('app', [])
.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(...) { ... }
}
};
});
关于参数可以分三大类
- 描述指令或DOM本身特性的内部参数
- 连接指令外界、与其他指令或控制器沟通的对外参数
- 描述指令本身行为的行为参数
常用的内部参数及其含义:
- restrict:String,可以为EAMC的任何一种,也可以混搭,它指明了指令是以什么方式来使用
- priority: Number,指令执行优先级
- template: String,指令链接DOM模板,例如
<h1>{{head}}</h1>
- templateUrl:String,DOM模板路径
- replace: Boolean,指令链接模板是否替换原有元素,
下面是关于这些参数的详细解释
restrict: String,
-
指明这个指令是以什么形式被声明;
A 是Attribute,以属性形式使用
<div my-directive></div>
E 是Element,以标签形式使用
<my-directive></my-directive>
C 是class,以类名形式使用
<div class="my-directive"></div>
M 是Commons,以注释形式使用,不建议使用
<--directive: my-directive-->
这些选项可以单独使用,也可以混合在一起使用:
举个栗子: 定义一个my-directive
的指令,指定以标签和属性形式使用:
angular.module('myApp', [])
.directive('myDirective', function(){
return {
restrict: 'EA' // 输入元素或属性
}
})
priority: Number,
- 设置优先级的,可忽略不写,默认值为0,这样就可以保证在同一元素上,它总是在其他指令之前被调用。
terminal: Boolean,
- 属性值为布尔型,也就是true或false,
- 如果为false,则这个参数用来告诉AngularJS停止运行当前元素上比本指令优先级低的指令。
- 优先级相同的指令还是会被执行。
template: String or Template Function:
-
属性值为一段字符串或者是一个函数,必须被设置其中一种
- 一段HTML文本;
- 可以接收两个参数的函数,参数为 tElement 和 tAttrs
-
注意:
在html模板中必须只有一个根html标签,且如果有换行则需要使用“\”
举个栗子:
template: '\
<div> <--div作为它的根节点 -->\
<a href="http://blog.zhouminghang.xyz">我的博客地址</a>\
<h1>多个标签时,要使用同一个根节点包裹</h1>\
</div>\'
templateUrl: String,
- 字符串或函数
- 外部路径的字符串,
- 接受两个参数的函数,参数为 tElement 和 tAttrs ,并返回一个外部HTML文件路径的字符串
- 模板加载后,AngularJS会将它默认缓存到 $templateCache 服务中。(可以提前加载模块到缓存中,提高加载速度)
replace: Boolean or String,
- 为false时模板内容会加载到标签内部;
- 如果不设置,默认为false;
- 为true,模板内容会替换当前标签,也就是在页面中没有指令,只有替换模板;
scope: Boolean or Object,
*(布尔型或对象),默认为false
- 设置为true 时,会从父作用域继承并创建一个新的作用域对象。
- ng-controller 的作用,就是从父级作用域继承并创建一个新的子作用域。
- 如果要创建一个能够从外部原型继承作用域的指令,将 scope 属性设置为 true
- 设置为一个对象,则设置了一个隔离的作用域。
* 如果scope属性设置为一个空对象{},指令的模板就无法访问外部作用域
.directive('myDirective', function() {
return {
restrict: 'A',
scope: {},
priority: 100,
template: '<div>Inside myDirective {{ myProperty }}</div>'
};
});
- 在scope对象中,还可以使用“@” “=” “&”,来设置模板中数据的作用域和绑定规则
- "@" 本地作用域属性:使用当前指令中的数据和DOM属性的值进行绑定
- “=” 双向绑定:本地作用域上的属性同父级作用域上的属性进行双向的数据绑定。
- “&” 父级作用域绑定:通过 & 符号可以对父级作用域进行绑定
举个栗子:
scope: {
ngModel: '=', // 将ngModel同指定对象绑定
onSend: '&', // 将引用传递给这个方法
fromName: '@' // 储存与fromName相关联的字符串
}
transclude: Boolean,
- 默认为false.
- 只有当你希望创建一个可以包含任意内容的指令时,才使用
transclude: true
;
注意:
如果指令使用了 transclude 参数,那么在控制器中就无法正常监听数据模型的变化了。
controller: String or function(scope, element, attrs, transclude, otherInjectables) { ... },
- 字符串或函数,注册在应用中的控制器的构造函数
- 使用函数创建内联控制器,
angular.module('myApp',[])
.directive('myDirective', function() {
restrict: 'A',
controller:
function($scope, $element, $attrs, $transclude) {
// 控制器逻辑放在这里
}
})
controllerAs: String,
- 用来在指令中创建匿名控制器;
- 类似于设置别名;
举个栗子:
.directive('myDirective', function() {
return {
restrict: 'A',
template: '<h4>{{ myController.msg }}</h4>',
controllerAs: 'myController',
controller: function() {
this.msg = "Hello World"
}
};
});
require: String,
- 字符串或数组
- 字符串代表另外一个指令的名字,如果没有前缀,指令将会在自身所提供的控制器中进行查找,如果没有找到任何控制器(或具有指定名字的指令)就抛出一个错误。
- 如果不使用 ^ 前缀,指令只会在自身的元素上查找控制器。
require: 'ngModel'
- 使用 ?
- 如果在当前指令中没有找到所需要的控制器,会将 null 作为传给 link 函数的第四个参数
require: '?ngModel'
- 使用 ^
- 如果添加了 ^ 前缀,指令会在上游的指令链中查找 require 参数所指定的控制器。
require: '^ngModel'
- 使用 ^?
- 将前面两个选项的行为组合起来,我们可选择地加载需要的指令并在父指令链中进行查找。
require: '^?ngModel',
link: function(scope, iElement, iAttrs) { ... },
- compile 选项本身并不会被频繁使用,但是 link 函数则会被经常使用。
- 当我们设置了 link 选项, 实际上是创建了一个 postLink() 链接函数, 以便 compile() 函数可以定义链接函数。
- compile 和 link 选项是互斥的。如果同时设置了这两个选项,那么会把 compile所返回的函数当作链接函数,而 link 选项本身则会被忽略。
- 通常情况下,如果设置了 compile 函数,说明我们希望在指令和实时数据被放到DOM中之前进行DOM操作,在这个函数中进行诸如添加和删除节点等DOM操作是安全的。
- 用 link 函数创建可以操作DOM的指令。
require 'SomeController',
link: function(scope, element, attrs, SomeController) {
//在这里操作DOM,可以访问required指定的控制器
}
compile: function(tElement, tAttrs, transclude) {
return {
pre: function(scope, iElement, iAttrs, controller) { ... },
post: function(scope, iElement, iAttrs, controller) { ... }
}
// 或者
return function postLink(...) { ... }
}
};
});
上一篇: angular 样式
下一篇: 第一章、python基础
推荐阅读
-
IOS 中NSUserDefaults读取和写入自定义对象的实现方法
-
c#中自定义Base16编码解码的方法示例
-
在ASP.NET 2.0中操作数据之十一:基于数据的自定义格式化
-
DevExpress实现自定义GridControl中按钮文字内容的方法
-
iOS中UIAlertController设置自定义标题与内容的方法
-
在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button
-
wxpython中自定义事件的实现与使用方法分析
-
在ASP.NET 2.0中操作数据之六十:创建一个自定义的Database-Driven Site Map Provider
-
iOS逆向工程之Hopper中的ARM指令详解
-
sqlserver中的自定义函数的方法小结