angular 多点嵌入举例
先看html1
2
3
4
5
6
7<transclude-multi-slot-point>
我是不用指定插入点名称的内容部分
<multi-slot-point-tile>我是自定义的标题</multi-slot-point-tile>
<multi-slot-point-content>我是自定义的内容</multi-slot-point-content>
<multi-slot-point-footer>我是自定义的页脚</multi-slot-point-footer>
<multi-slot-point-footer>我是自定义的页脚1</multi-slot-point-footer>
</transclude-multi-slot-point>
再上指令1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19app.directive("transcludeMultiSlotPoint", function () {
var dir = [];
dir.replace = false;//看的容易 //不替换也可以
dir.restrict = "E";
dir.transclude = {
title: "?multiSlotPointTile", //注释这行会报 no parent directive的错误
content: "?multiSlotPointContent",
footer: "?multiSlotPointFooter"
};
dir.template = "<div>" +
"<div>我是模版中的内容</div>" + //重复属性没用
"<div ng-transclude='title' ng-transclude='footer'>我是模版中的插入点的标题</div>" +
//搞错了 ,ng-transclude不会使hasTranscludeDirective为true 反而因为有compile方法 ,导致会加入postLinkFn 最终执行的事postLinkFn
"<div ng-transclude='content'>我是模版中的插入点的内容</div>" +
"<div class='ng-transclude:footer'>我是模版中的插入点页脚</div>" +
"<div ng-transclude>我是模版中的默认插入点的内容</div>" +
"</div>";
return dir;
});
angular内部首先通过collectDirectives方法会收集到transcludeMultiSlotPoint 指令,然后在applyDirectivesToNode方法中
会把多嵌入点放到当前nodeLinkFn上
applyDirectivesToNode -> transclude -> slots
1 | if (directiveValue = directive.transclude) { |
其中节点会把模板的html内容当作子节点添加进去
nodeLinkFn.transclude = childTranscludeFn
1 | //template 字符串 |
然后在执行当前节点的compositeLinkFn的时候 去 创建 boundTranscludeFn
然后调用childLinkFn(也就是compositeLinkFn方法)时 传递给 parentBoundTranscludeFn参数
createBoundTranscludeFn -> boundTranscludeFn
1 | //判断当前节点 指令的 transclude属性是否为true |
nodeLinkFn -> postLinkFn -> controllersBoundTransclude
nodeLinkFn 函数里 会调用postLinkFn 方法,传递controllersBoundTransclude函数
这里的postLinkFn 也就是 ngTransclude内置指令返回的方法
当前节点的模板是在applyDirectivesToNode时通过template属性来调用的
directive.template
1 | //template 字符串 |
所以ngTransclude内置指令是在编译当前节点的模板子节点时 执行的,我们来看看angular内置的ngTransclude指令
ngTransclude
1 | var ngTranscludeMinErr = minErr('ngTransclude'); |