AngularJS源码学习一 :directive
标题党了。其实这篇文章是为了记录一个我对AngularJS compile过程的一个问题。
基础:
directive有个重要特性是transclude。这个特性主要用途是:当页面的dom元素要进行复杂变化时,将原本的dom暴露给用户以供变形时或变形后使用。例如我有个选项卡directive,写法是:
< div tabs> < div tab title="title1">content1</ div > < div tab title="title2">content2</ div > </ div > |
这个directive在执行时肯定要变换,变换结果是:
< div <div class="tab-titles"> < span class="tab-title">title1</ span > < span class="tab-title">title2</ span > </ div > < div class="tab-contents"> < div class="tab-content">content1</ div > < div class="tab-content">content2</ div > </ div > </ div > |
里面还有一些用来表示title和content对应的属性我省略了。
在变换的时候,可以看到原来的dom结构和变化后的content部分几乎是一样。因此可以直接transclude过来重用。其他例子可以看AngularJS官方文档的指南,也可以看ngRepeat源码。
这里要先提一下的概念是,AngularJS会给transclude的元素自动绑定一个新的scope。这个scope不是当前directive scope的child,而是sibling。也就以为它直接继承了当前这个directive的父scope的所有属性。所以当一个direcitve有transclude属性时,它会创建两个scope。第一个scope取决于用户对于scope属性的定义。第二个scope就是直接继承自父scope。
问题:
我遇到的问题是,当我试图调用transclude元素子元素(例如content1的div)的remove方法时,它会引起整个transclude的scope(上文中提到的第二个scope)都销毁。我翻了AngularJS源码。在compile.js文件419行找到了答案,答案是源码中在编译时给transclude元素绑定相应的scope时,还注册一个$destroy事件,当事件触发时就调用相应scope的$destroy()。而在AngularJS的jqLite中,当调用元素的remove方法时会主动触发$destroy事件。整个事件的触发也就清楚了。
不懂的是,没有transclude的directive所在的元素,即使指定了scope,绑定了新的scope,移除这个元素也不会造成相应scope被销毁。那为什么要给transclude的元素绑定了$destroy,使得元素被remove就销毁相应scope?
其他:
这里有两个点要提一下:
第一是directive的编译分为两个阶段,第一个阶段是compile,第二个是link。也就是先对元素做外所有变形,然后在将scope绑定上去,根据scope翻译其中的表达式。作者说这样做是为了提升性能,我的理解是这能尽快让页面显示出正确的dom结构,不知是否正确。
第二是,对于整个compile的过程,direcitve实际上相当于对开发者抛出的一个接口,通过这个接口,开发者就能全面地控制住视图的表现和视图与数据间的关系。这个接口设计得非常全面和合理,以至于我现在暂时想不到有什么控件用它开发不了,或者用它写不能节约大量代码。它的合理主要表现在对视图和数据这个双向连接流程的精准控制上。
欢迎任何批评和指点。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)