我们使用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的
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,transcludeControllers,scope<a href="https://www.jb51.cc/tag/toch/" target="_blank" class="keywords">toch</a>ild);
} 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,scope<a href="https://www.jb51.cc/tag/toch/" target="_blank" class="keywords">toch</a>ild);
}
}</pre>
还有一个另一个函数要特别指出来,就是最后返回的 boundTranscludeFn 这个方法,下面是他的源码
if (!transcludedScope) {
transcludedScope = scope.$new(false,containingScope);
transcludedScope.$$transcluded = true;
}
return transcludeFn(transcludedScope,{
parentBoundTranscludeFn: prev<a href="https://www.jb51.cc/tag/IoU/" target="_blank" class="keywords">IoU</a>sBoundTranscludeFn,transcludeControllers: controllers,futureParentElement: futureParentElement
});
}
这两个方法到底是在做什么呢?其实就是克隆了当前指令的节点,并生成子作用域。克隆的节点由transclude定义,如果你的属性是true,则克隆的是指令模板中的ng-transclude所在的DOM节点,及其子节点。如果属性是element则克隆整个模板的节点。
这是两个指令的代码
}
}
})
.directive('dropPanel2',function() {
return {
transclude: true,scope) {
console.log(clone);
})
}
}
})</pre>