资讯专栏INFORMATION COLUMN

angular中作用域的生命周期

zombieda / 985人阅读

摘要:也就是说它的存在会把给贯穿起来,它是否处于生命周期之中,直接影响了之间是否能够彼此互通。二主题生命周期既然谈周期,那必定有开始,有过程,有结束。

先扯淡是惯例-------------生命对于人而言是再重要不过的东西了,但你不太可能每天去考虑自己离生命结束还有多久,生命周期就更谈不上了,人的生命一旦结束就不会再次开始,如果你坚持认为生命有轮回,好吧,咱俩的淡扯不到一块去。但对于angular的作用域来讲,它确实是有生命周期的,也就是说它可以死而复生,而且一定是在你需要它的时候它就生,不需要它的时候就让它死,听起来有些冷酷无情,但假如它在该死的时候没死,该活的时候没活,那结果可能就是----你被它玩死。生死这词大残酷了,我们还是文雅点,就叫它生命周期吧,开始正题。

一、## 弄清楚一个问题前我们必须知道它是个什么东西 ##

先仰视-----毕竟对于前端来讲,首次听到MVC时觉得好牛X,它是啥玩意不多说,但如果你认为$scope就是我们的数据模型的话,建议你好好的温习下google大大对它的定义,必竟这个东西不同于扯淡,我们需要一个严谨的态度。$scope只是MVC中C和V的桥梁,或者官方的说法叫做glue,我觉得这个单词很传神的表达了对$scope的定位。也就是说它的存在会把MVC给贯穿起来,它是否处于生命周期之中,直接影响了MVC之间是否能够彼此互通。那么M呢,它在哪里?别这些文字弄晕,M大多数也存在于$scope上,但又不仅在这里,也可能你把它直接扔在了HTML里,或者存在于某个DOM元素的属性上。

之所以仰视,是因为我们跪着,站起来吧-------很高大上么,no,no,no,说的直白点,$scope就是一个对象,和我们在js代码里看到的{}没什么不同,不要因为它和MVC厮混在一起就觉得它有多高大上,也不要觉得它名字叫作用域就觉得它好牛叉,它和js中的作用域完全是两个概念。既然是对象,那它也原型,有也在自己的原型链中所处的位置,事实就是这么一回事。

二、## 主题——生命周期 ##
既然谈周期,那必定有开始,有过程,有结束。

创建——在angularJS 1版本中,指令才是大boss,可以说就是它在指点的江山,所在angular应该在启动以后,第一步必须是先找到这些boss,boss能力有大小,有的可以创建scope,有的则不行,比如最常见到的ng-controller和ng-repeate都会创建自己的作用域,有些指令还会创建属于自己的隔离作用域,应用了transclude属性后还会创建隔离作用域的兄弟作用域,前面这句把angular中所有的4种作用域的类型都说了,想要弄清楚自己资料,或者等我哪天兴致来了再写吧。至于创建的过程被分成了2个阶段,第一阶段是compile,第二阶段是link,那你猜scope是在哪个阶段创建?如果真的是靠猜的,还是好好查查资料。compile的时候,angular会把指令对应的模板进行转换,并且对于一个指令的多个实例,angular只会编译一次,很显然这时候生成作用域是不合适的。这里有一个很重要的顺序就是compile从上到下,而link是从下到上的,这样的顺序保证了在进行M和V的链接时,所有的编译工作都已完成。

注册监视——作用域一旦生成,指令就会在它身上注册一个监视,就是我们平时用到的$scope.$watch(),顾名思义监视什么,肯定是去监视数据有没有变化啊,难道还监视隔壁妹子洗澡不成。

模型突变——以上两个过程完成之后,数据和视图之间的链接成功建议,这个时候一旦数据模型发生了变化,就应该做点什么了,当然做什么取决于你。这个时候比如用户在文本框里输入了数据,或者ajax取回的新的数据要应用在程序中,或者用户点击了东西需要我们更改一些数据。这里关键的东西是,假如数据在用户端发生了变化,如何从浏览器的js环境进入到angular的环境中操作在angular模型上的数据,这里偷个懒用下官网的图,但是请记住$scope.$apply,它是从js进入到angular的通道,在应该内置指令时,你不会去调用这个方法是因为angular帮你做了,等于没做。那么当你自己定义指令时,要更新数据时你唯一的选择就是它。

观察——有了变化,我们就要观察这个变化影响的范围到底有多大,那么在进入到angular环境后就会执行那个颇受诟病的脏值检查。既然作用域是原型继承下来的,而且和DOM结构平行,那显然最先应该检查就是rooScope,然后传播到所有的子作用域上,这个时候$watch,设置的一些函数,表达式等就会被执行,相应的改变发生的话就应用你设置好的函数等。

摧毁——当我们不在需要一个作用域,需要将它移除掉,原则就是谁创建谁销毁,使用的方法就是$scope.$destroy(),这里如同apply一样,这个方法一要被调用,至于谁调用,参照原则。如果不做呢?good question,不做也不会被枪毙,只是在进行digest循环时,它仍然会被加入其中,增加性能的开销。执行完这个方法后,它占用的内存才能被释放,进而被当成垃圾回收掉。

以上就是scope整个生命周期,请记住这几个关键词:link,regesit,mutation,apply,digest,destory。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81615.html

相关文章

  • [Tips on Ember 2] How components works when out of

    摘要:因为组件的存在范围被限制在以内,这就是这种机制目前存在的意义所在。组件都是可以传递参数或外部作用域的,利用此机制进行判断来执行可选行为,这是对用户友好的举措。 这一篇还是一个简单的例子所引发的思考。 你看,如今的框架和库,无论规模大小功能多少,它们在本质上都朝着组件化的思路快速演进着。Angular 有 directives,Angular 2应该也还是这个叫法;Ember 从 Vie...

    jk_v1 评论0 收藏0
  • JS变量生命周期:为什么 let 没有被提升

    摘要:请注意,就变量生命周期而言,声明阶段与变量声明是不同的概念。提升在生命周期中无效的原因如上所述,提升是变量在作用域顶部的耦合声明和初始化阶段。然而,生命周期分离声明和初始化阶段。解耦消除了的提升期限。 为了保证的可读性,本文采用意译而非直译。 提升是将变量或函数定义移动到作用域头部的过程,通常是 var 声明的变量和函数声明function fun() {...}。 当 ES6 引入l...

    hoohack 评论0 收藏0
  • JS变量生命周期:为什么 let 没有被提升

    摘要:请注意,就变量生命周期而言,声明阶段与变量声明是不同的概念。提升在生命周期中无效的原因如上所述,提升是变量在作用域顶部的耦合声明和初始化阶段。然而,生命周期分离声明和初始化阶段。解耦消除了的提升期限。 为了保证的可读性,本文采用意译而非直译。 提升是将变量或函数定义移动到作用域头部的过程,通常是 var 声明的变量和函数声明function fun() {...}。 当 ES6 引入l...

    Steven 评论0 收藏0
  • 【转】angularJS的兄弟controller之间如何正确的通信

    摘要:每个的指向指向父级作用域。之间的通信本质上是当前的所在的如何跟其他上的进行通信。传递事件有种方式触发的事件要通知整个事件系统允许任意作用域处理这个事件就要向下传播。作用域上使用进行事件监听。示例关于同级之间通信我的一个提问 原文链接:http://www.cnblogs.com/webbes... AngularJS中的controller是个函数,用来向视图的作用域($scope)添...

    forsigner 评论0 收藏0
  • 2018年前端开发回顾

    摘要:在整个年,看到发布版增加了许多功能,包括新的生命周期方法新的上下文指针事件延迟函数和。它在等待渲染异步响应时数据,是延迟函数背后用来管理组件的代码分割的。发布自第版开始将近年后,于年发布。 前端发展发展迅速,非常的快。 本文将回顾2018年一些重要的前端新闻,事件和 JavaScript 趋势。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! showImg(ht...

    crelaber 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<