我们使用ng的时候,经常会使用到指令,大家所熟知的属性我在这里就不介绍了,讲讲大家没怎么留意的属性

  1.multiElement

    这是指定指令作用区间的功能,最常用的就是ng-repeat-start和ng-repeat-end了。

  2.priority

    指令优先级,优先级越高,指令越早执行。

  3.terminal

    是否允许优先级低的指令起作用,如果是true,那么只有比当前指令或跟当前指令等级相同的指令才可以执行。最典型的就是ngIf

  4.templateNamespace

    声明模板的格式有三种选择 svg、html、math

  5.transclude

    或许有人疑问了,transclude也算是冷门属性吗?其实大家对transclude了解并没有想象的那么深,transclude是一个挺复杂的属性,一般大家会用到的也仅仅是true,false。这两个属性我在这里就不讲了,在这里我主要讲的是transclude:element,我google了一整天都没找到正确描述这个属性的方法。我觉得google出来的答案太文档化了。最后在研究$transclude才看出来这个属性的功能究竟在哪里。再讲功能前我们先了解下$transclude

    无论在指令的compile还是link时期我们的最后一个参数就是$transclude了,这里其实我们看看源码是如何定义的,我看的源码是ng1.5.3的    

function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) {
var transcludeControllers;
// No scope passed in:
if (!isScope(scope)) {
slotName = futureParentElement;
futureParentElement = cloneAttachFn;
cloneAttachFn = scope;
scope = undefined;
} if (hasElementTranscludeDirective) {
transcludeControllers = elementControllers;
}
if (!futureParentElement) {
futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;
}
if (slotName) {
// slotTranscludeFn can be one of three things:
// * a transclude function - a filled slot
// * `null` - an optional slot that was not filled
// * `undefined` - a slot that was not declared (i.e. invalid)
var slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
if (slotTranscludeFn) {
return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
} else if (isUndefined(slotTranscludeFn)) {
throw $compileMinErr('noslot',
'No parent directive that requires a transclusion with slot name "{0}". ' +
'Element: {1}',
slotName, startingTag($element));
}
} else {
return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
}
}

还有一个另一个函数要特别指出来,就是最后返回的 boundTranscludeFn 这个方法,下面是他的源码

function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) { if (!transcludedScope) {
transcludedScope = scope.$new(false, containingScope);
transcludedScope.$$transcluded = true;
} return transcludeFn(transcludedScope, cloneFn, {
parentBoundTranscludeFn: previousBoundTranscludeFn,
transcludeControllers: controllers,
futureParentElement: futureParentElement
});
}

这两个方法到底是在做什么呢?其实就是克隆了当前指令的节点,并生成子作用域。克隆的节点由transclude定义,如果你的属性是true,则克隆的是指令模板中的ng-transclude所在的DOM节点,及其子节点。如果属性是element则克隆整个模板的节点。

这是两个指令的代码

 angular.module('MyApp', [])
.directive('dropPanel', function() {
return {
transclude: 'element',
replace: true,
template: "<div class='drop-panel'>" +
"<span ng-transclude class='111'></span>" +
"</div>",
link: function(scope, el, c, d, $transclude) {
$transclude(function ngRepeatTransclude(clone, scope) {
console.log(clone);
}) }
}
})
.directive('dropPanel2', function() {
return {
transclude: true,
replace: true,
template: "<div class='drop-panel'>" +
"<span ng-transclude class='111'></span>" +
"</div>",
link: function(scope, el, c, d, $transclude) {
$transclude(function ngRepeatTransclude(clone, scope) {
console.log(clone);
})
}
}
})

如果你觉得replace干扰了对结果的理解,你可以注释掉,然后查看控制台中打印出来的clone,你就能知道所谓transclude的属性声明为element的作用了,我们打开replace目的在于能较清楚的查看DOM节点,来获得结论,下面就是两者编译后DOM节点的区别了

  看完上面的图,你可以明显的区别到两者对DOM的克隆不一样的,另外如果在声明属性为‘element’时,需要声明replace为true,才能渲染出来。我查了很多资料,最终用断点得出了我认为对的结论,断点追踪的结果是发现如果不声明replace,好像就不会执行ngTransclude指令,这点我很奇怪,正因为这样子所以导致没有成功渲染。二归根结底其实是两者的操作的DOM元素不同,在声明transclude为element时,replace为true,你取到的DOM节点是含有transclude属性的节点(子节点),而为false你拿到的并不是含有transclude属性的节点(父节点),而ng本身不对其节点进行遍历,导致没能执行ngTransclude指令

  我看到一个观点觉得不错,大概意思就是:源于功能的考虑,在使用element属性的时候,一般都是起占位符的作用,你需要做的操作是对DOM的添加时候,才会用到这个克隆功能。

  我觉得这个观点不错,看过很多关于ngrepeat的介绍,很多文章都说ngrepeat源码是通过$scope.$new()来生成子作用域的,实际上并不完全正确,他的确是通过$scope.$new产生子作用域的,但是这个产生功能是交给$transclude函数去做得,实际上ngrepeat的源码上是通过$transclude来生成子作用域和添加DOM节点的。与上面的观点有相似之处。

  就讲到这里了,这是作者原创,转载请注明

angularJs关于指令的一些冷门属性的更多相关文章

  1. AngularJS自定义指令directive:scope属性 (转载)

    原文地址:http://blog.csdn.net/VitaLemon__/article/details/52213103 一.介绍: 在AngularJS中,除了内置指令如ng-click等,我们 ...

  2. AngularJS之指令

    紧接上篇博客“初探AngularJS” 一.前言 在AngularJS中指令尤为重要且内容庞多,固单独提炼出来,梳理一番.如有错误,请不吝讲解. 好了,言归正传,让我们一起走进Angular指令的世界 ...

  3. 带你走近AngularJS - 体验指令实例

    带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自定义指令 ------------- ...

  4. angularJS——自定义指令

    主要介绍指令定义的选项配置 //angular指令的定义,myDirective ,使用驼峰命名法 angular.module('myApp', []) .directive('myDirectiv ...

  5. AngularJs自定义指令详解(1) - restrict

    下面所有例子都使用angular-1.3.16.下载地址:http://cdn.bootcss.com/angular.js/1.3.16/angular.min.js 既然AngularJs快要发布 ...

  6. 学习AngularJs:Directive指令用法(完整版)

    这篇文章主要学习AngularJs:Directive指令用法,内容很全面,感兴趣的小伙伴们可以参考一下   本教程使用AngularJs版本:1.5.3 AngularJs GitHub: http ...

  7. 浅析AngularJS自定义指令之嵌入(transclude)

    AngularJS自定义指令的嵌入功能与vue的插槽十分类似,都可以实现一些自定义内容展现.在开始之前先简单介绍下自定义指令的transclude属性和AngularJS的内置指令ng-transcl ...

  8. AngularJs:Directive指令用法

    摘自:http://www.jb51.net/article/83051.htm 摘要:Directive(指令)是AngularJ非常强大而有有用的功能之一.它就相当于为我们写了公共的自定义DOM元 ...

  9. AngularJS:指令

    ylbtech-AngularJS:指令 1.返回顶部 1. AngularJS 指令 AngularJS 通过被称为 指令 的新属性来扩展 HTML. AngularJS 通过内置的指令来为应用添加 ...

随机推荐

  1. LoadRunner性能测试指标分析

    Memory: ·Available Mbytes 简述:可用物理内存数.如果Available Mbytes的值很小(4 MB或更小),则说明计算机上总的内存可能不足,或某程序没有释放内存. 参考值 ...

  2. 在Activity之间传递数据—简单数据/Bundle

    1.首先要知道怎么通过一个Activity 打开另一个Activity.主页面为MainActivity,另一个页面为OtherActivity.MainActivity中的按钮Id为btnStart ...

  3. 第三十一节,time时间模块

    模块简介 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...

  4. hdu_4824_Disk Schedule(dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4824 题意:中文,不解释 题解:双调欧几里德旅行商问题,具体可看dp双调欧几里德旅行商,这里注意的是起 ...

  5. FUSE and File System

    FUSE: File system in USErspace. So what is a file system? A file system maps file paths to file cont ...

  6. Angularjs Directive(指令)机制

    转:http://damoqiongqiu.iteye.com/blog/1917971 1.一点小说明 指令的作用:实现语义化标签 我们常用的HTML标签是这样的: <div> < ...

  7. 循环ip段 转载 出处不明

    public struct IP         {             public byte A;             public byte B;             public  ...

  8. 转载 C语言中volatile关键字的作用

    一.前言 1.编译器优化介绍: 由于内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存Cache,加速对内存的访问.另外在现代CPU中指令的执行并不一定严格按照顺序执行,没 ...

  9. strictmode

    最新的Android平台中(Android 2.3起),新增加了一个新的类,叫StrictMode(android.os.StrictMode).这个类可以用来帮助开发者改进他们编写的应用,并且提供了 ...

  10. C++ concepts: Compare

    The concept Compare is a set of requirements expected by some of the standard library facilities fro ...