持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
rootScope是Angular中的一项内置服务,通过它可以获得根作用域。根作用域是Angular应用启动时创建的第一个作用域(id等于1)其它作用域都是它的子孙作用域。作用域中有parent属性指向父作用域从而将作用域连成一颗树。大部分作用域还会将原型(prototype)指向父作用域从而形成作用域链,以继承上级作用域的属性和方法。(但自定义指令和组件中的∗∗隔离作用域∗∗只有parent指向父作用域而不会将自己的原型指向父作用域,因些隔离作用域不会受上级作用域干扰,这样自定义指令和组件就可以放在页面上任何地方使用了。隔离作用域的原型指向作用域类的prototype)
在控制器构造函数中通过scope可以获取当前作用域。某些指令或组件中还存在隔离作用域,隔离作用域也在作用域树中,只是没有与上级作用域通过原型链连接起来,从而不受上级作用域的影响。使用new()方法可以创建新的作用域,需指定是否是隔离的,及指定上级作用域。
作用域有自己单独的事件传播机制,通过作用域emit()的事件会向作用域树的上级传播(含自己),通过作用域broadcast()的事件会向作用域树的下级传播(也包含自己)。
作用域最重要的是提供了数据的修改监视和通知功能,通过watch()可以监视作用域中数据的变化(当发现变化时可以更新界面或作用域中的其它数据)。watch()通常在模版编译时被Angular调用为模版插值添加监视器,也可以由程序员调用。$watch()可以监视复杂的表达式。
watch()的监视功能是由digest()推动执行的,digest()会遍历整个作用域树循环处理每一个watcher、计算watcher中被监视表达式的值,如果表达式的值与原值(缓存的)相比发生了变化则调用watcher中的函数处理变化,因为watcher变化处理函数有可能修改作用域中的其它值,因此digest会遍历多次(至少2次)直到作用域中的数据稳定(检测不到任何变化)为止。
Angular控制器及自带的指令(如ngClick等)、服务(如timeout等)都会自动调用digest()以触发监视过程,如果在非Angular执行环境中修改作用域中属性的值则不会自动激活digest()过程,这时需要使用apply()而不要自己调用digest(),apply(func)会执行func,并且在执行之后会调用$digest(),而且会恰当处理func执行过程中的错误。