angular源码分析之多点嵌入
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'); |
csharp_delegate_event
c#委托和事件的区别
在学习object-c的委托过程中,顺便复习了下c#的委托和事件。
事件就是一个狭义的委托,也就是事件是一个用于事件驱动模型的专用委托.你可以在客户代码中直接调用委托来激发委托指向的函数,
而事件不可以,事件的触发只能由服务代码自己触发。
也就是说在你的代码里委托你不但可以安排谁是它的调用函数,还可以直接调用它,
而事件不能直接调用,只能通过某些操作触发。
除此之此,事件拥有委托的所有功能,包括多播特性。即事件可以有多个事件处理函数,委托同样也可以是个多播委托.
1 | class Program1 |
scala的协变和逆变
协变
在看到 Scala入门到精通——第二十一节 类型参数(三)-协变与逆变 这篇文章时,对协变
更加了解了。
里面提到参数如果定义成协变时会造成原来的调用不成功。我的理解是因为原来的调用的参数范围更广,
但是在父类指向子类时,因为子类的同样函数的参数范围小所以会报错。
逆变
在提到返回类型定义成逆变会报错,我的理解是如果定义成逆变,那么原来调用此函数的地方如果限定
是父类的类型的话会报错,因为父类指向子类后调用此函数后返回的类型范围更广,所以会导致报错
angular之ng-attr属性
ngAttr 绑定任意属性
官网上说是为了可以绕开浏览器的约束:
Web browsers are sometimes picky about what values they consider valid for attributes.
For example, considering this template:
1 | <svg> |
可以用ng-attr-cx来绕开浏览器的限制
当用了ngAttr属性后,$interpolate服务的allOrNothing标记被用到了,任何表达式里的值是undefined的时候,
属性会被移除且不包含到元素上。
下面的属性也会出现类似问题,select的size 属性,textarea的placeholder属性,button的type属性,
progress的value属性。