我在项目的初期阶段并没有用到指令,现在找来这篇博客,来用于以后Angularjs的应用。
w3c制定的html标准中,html的标签以及标签的属性值有限,不能满足一些特定化的需求,在angular中可以通过指令是对html中的标签以及标签属性做的一个扩展。
首先我们来看看一个内置的指令,了解了解指令到底是一个神马东东?
我们先拿指令ng-src开刀
<img src="{{path}}"/> <img ng-src="{{path}}"/>
上面两个img标签看出来什么区别没有?好吧如果没有看出来那么我们放到浏览器里面跑一下就知道了
咦,一个图片出来了一个加载失败,仔细看一下一个标签内的属性是src,另外一个是ng-src,f12看看网页的源码
第二个img标签内并没有src属性,但是通过浏览器查看网页源代码,第二个标签内多了一个src属性,切属性值同ng-src一致,什么情况?
原来angular的加载是在网页渲染完毕之后才开始的,当浏览器加载到img标签时,angular的数据绑定并未生效,{{path}}并未被解析,当然加载不到图片。那么ng-src是如何工作的呢?欲知详情,请移步源代码进行查看吧!
下面通过一个简单的指令来了解如何创建自定义指令以及如何使用指令?
angular.module('myApp', []) .directive('myDirective', function() { return { restrict: 'E', template: '<a href="http://google.com">Click me to go to Google</a>' }; });
上面的指令执行时什么效果
<my-directive></my-directive>
我们来看看指令中restrict,template这些属性是干嘛用的吧?
通过module.directive('directivename', function(){})我们可以定义指令,该方法接受两个参数
1.name
为指令的名字,用来爱视图中引用特定的指令
2.factory_function
该函数返回对象,其中定义了指令的全部行为,$complile服务利用这个方法返回的对象来构造指令的行为
var myModule = angular.module(...); * * myModule.directive('directiveName', function factory(injectables) { * var directiveDefinitionObject = { * priority: 0, * template: '<div></div>', // or // function(tElement, tAttrs) { ... }, * // or * // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... }, * transclude: false, * restrict: 'A', * templateNamespace: 'html', * scope: false, * controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... }, * controllerAs: 'stringAlias', * require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'], * compile: function compile(tElement, tAttrs, transclude) { * return { * pre: function preLink(scope, iElement, iAttrs, controller) { ... }, * post: function postLink(scope, iElement, iAttrs, controller) { ... } * } * // or * // return function postLink( ... ) { ... } * }, * // or * // link: { * // pre: function preLink(scope, iElement, iAttrs, controller) { ... }, * // post: function postLink(scope, iElement, iAttrs, controller) { ... } * // } * // or * // link: function postLink( ... ) { ... } * }; * return directiveDefinitionObject; * });
priority
当元素上面有多个指令时,指令的执行顺序,数字越大优先级越高,越先执行。
terminal
告诉angular停止运行当前元素上比本指令优先级低的指令。
restrict
指令的调用方式
- 'E'-通过元素标签调用 <self-directive></self-directive>
- 'A'-属性调用<div self-directive></div>
- 'C'-类调用<div class='self-directive'></div>
- 'M'-注释调用 <!-- directive: self-directive -->
template
可以有以下两种形式:
- html文本,
- 函数,该函数可以接受两个参数,tElement和tAttrs
templateUrl
可以有一下类型:
- 一个代表外部html文件路径的字符串
- 一个可以接受两个参数的函数,tElement和tAttrs,并返回一个外部html路径道德字符串,对于加载过的模板angularjs会将它默认缓存到$templateCache服务中
replace
是否替换指令本省,默认为false,如果设置了该参数,那么指令本身会被指定的模板替代
scope
该参数有两种形式
- 布尔值,可以被设置为true,默认为false,如果设置为true,则会从父作用域继承并创建一个新的作用域对象
- 隔离作用域,如果被设置为一个对象,那么指令内部会创建一个隔离的作用域,这样模板无法直接访问外部的作用域了,那么有什么方法可以让内部的作用域同外界的作用域进行通信么? 可以通过三种别名方式来同外部的作用域进行一个数据的绑定: 1.@或者@attr :通过@符号可以将本地的作用域同DOM属性的值进行绑定 2.=或者=attr:通过=可以将本地作用域上的属性值同父作用域上的属性进行绑定 3.&或者&attr:通过&可以对父作用域进行绑定,以便在其中运行函数。
<input type="text" ng-model="to"/> <!-- 调用指令 --> <div scope-example ng-model="to" on-send="sendMail(email)" from-name="ari@fullstack.io" /> 在指令中我们可以这样设置scope对象 scope: { ngModel: '=', // 将ngModel同指定对象绑定 onSend: '&', // 将引用传递给这个方法 fromName: '@' // 储存与fromName相关联的字符串 }
controller
可以设置为一个字符串或者函数,如果是字符串则会在注册的控制器中寻找对应的控制器。
也可以设置为一个函数作为控制器,可以给该控制器注入任何可以被注入的服务,除此之外有几个特殊的服务可以被注入
$scope:与指令元素相关联的当前作用域
$element:当前指令对应的元素
$attrs:当前元素属性组成的对象
compile
compile可以设置为一个对象或函数,其与link函数是互斥的,如果两者同时设置,那么link会被忽略。在compile函数中,我们可以对DOM进行操作,此时指令和实时数据还没有被放置到DOM中,这个时候操作DOM性能消耗较低。
link
链接函数,其函数的签名如下
link: function(scope, element, attrs, SomeController) { // 在这里操作DOM,可以访问required指定的控制器 }
scope:指令内部的作用域
iElement:使用指令的元素
iAttrs:元素的属性
如果require选项提供了一个指令数据,那么第四个参数会是一个由每个指令所对应的控制器组成的数组。
本文来自:http://blog.csdn.net/yangnianbing110/article/details/43084671