AngualrJS中的scope

来源:互联网 发布:nginx ssl 无响应 编辑:程序博客网 时间:2024/06/06 13:08

本文主要内容来自angualr1API中的guide(https://docs.angularjs.org/guide/scope)的翻译

翻译来自于自己对于英语的理解(汉语拼音8级水平)

然后还有一点自己对于angualr的理解

scope的特点

1.scope提供监视模型的变化的API($watch)

2.scope通过系统从外部的angualr组件到视图的传播模型变化($apply)
3.socpe可以嵌套,在提供模型属性获取的同时限制获取权限.嵌套的scope可以是字scope或者隔离scope
4.scope提供表达式的作用域,比如{{username}}是没有意义的如果scope中没有定义
scope作为数据模型
scope是控制器和视图之间的桥梁,在模板连接阶段,指令添加$watch表达式到scope。$watch让指令知道属性的变化从而更新DOM
scope的层次结构
每个angualr app都只有一个root scope但是可能会有很多子scope,子scope会继承父scope的属性
一个app会有很多scope,因为一些指令会创建新的子scope,一个子scope被创建之后就会被添加到他的符scope,这就在他们所在的DOM中创建了一个树结构。
当angualr解析一个{{name}}表达式的时候,会首先从它所绑定的scope中去找模型,如果找不到就会到它的父级scope中找一直到根scope

<divclass="show-scope-demo">

  <div ng-controller="GreetController">    Hello {{name}}!  </div>  <div ng-controller="ListController">    <ol>      <li ng-repeat="name in names">{{name}} from {{department}}</li>    </ol>  </div></div>
angular.module('scopeExample', []).controller('GreetController', ['$scope', '$rootScope', function($scope, $rootScope) {  $scope.name = 'World';  $rootScope.department = 'Angular';}]).controller('ListController', ['$scope', function($scope) {  $scope.names = ['Igor', 'Misko', 'Vojta'];}]);
Hello World!
  1. Igor from Angular
  2. Misko from Angular
  3. Vojta from Angular

在DOM中搜索scope

1.选中页面中的一个组件,右键审查元素
2.在控制台中输入$0,可以返回当前的scope
3.为了找到相关的scope,控制台中输入angular.element($0).scope()或者直接输入$scope
scope事件传播
和DOM事件类似,cope的事件可以广播 broadcasted到子scope或者向上传递  emitted 到父级scope
一个栗子:

angular.module('eventExample', []).controller('EventController', ['$scope', function($scope) {  $scope.count = 0;  $scope.$on('MyEvent', function() {    $scope.count++;  });}]);
<div ng-controller="EventController">  Root scope <tt>MyEvent</tt> count: {{count}}  <ul>    <li ng-repeat="i in [1]" ng-controller="EventController">      <button ng-click="$emit('MyEvent')">$emit('MyEvent')</button>      <button ng-click="$broadcast('MyEvent')">$broadcast('MyEvent')</button>      <br>      Middle scope <tt>MyEvent</tt> count: {{count}}      <ul>        <li ng-repeat="item in [1, 2]" ng-controller="EventController">          Leaf scope <tt>MyEvent</tt> count: {{count}}        </li>      </ul>    </li>  </ul></div>

scope的生命周期

一般的流程是浏览器收到一个来自JavaScript的回调,当回调结束后浏览器会重新渲染DOM然后等待新得事件
在执行完一个表达式后,$apply方法会触发$digest。在digest阶段,scope检查所有的$watch表达式并和之前的值比较。这个脏数据检查是异步的,就是说当一个model发生变化时不会马上触发$watch的监控,当一个$watch监测到变化时,会强迫进入$digest循环
生命周期
1.创建(Creation
rootscope在app引导生成的时候被$injector创建
在模板链接阶段一些机灵会创建子scope
2.监测器初始化(Watcher registratio
在模板链接阶段,指令会初始化watch项到scope中。这些watch项会传播model的值到DOM中
3.模型变化(Model mutation
4.变化监测(Mutation observation
在$apply结束时,angualr开始$digest循环。所有的$watch表达式或者监测变化的函数会被检查如果产生了变化$watch的监听器会触发
5.scope销毁(Scope destruction
当子scope不在需要的时候,他们的创建者会调用angualr的api( scope.$destroy())销毁他们,然后释放内存等。
$scope $watch操作的注意事项
scope属性的脏数据检查是一个很普遍的操作,所以脏数据检查功能必须是高效的。需要注意的事脏数据检查不会做任何的DOM变化检查因为DOM的获取要比JavaScript对象的属性获取慢的多
scope $watch的深度
脏数据检查可以通过三种策略实现:
监测引用()
监测集合的内容
监测值

三种监测范围或者叫能力如图

在浏览器事件循环中的整个过程
如图:


1.浏览器事件循环等待事件的到达,事件可以是用户操作、定时器事件或者网络事件

2.事件回调步骤执行,然后进入JavaScript的范围,回调步骤可以更新DOM结构

3.当回调步骤执行后,浏览器会离开JavaScript范围然后重新渲染基于DOM变化的视图
一个HelloWorld的栗子:

<div ng-app="demo">    <input ng-model="name"></div><script>angular.module('demo', [])       .controller('democtrl', ['$scope', function($scope) {           $scope.name = "hello world";                 }]);</script>

1.在编译阶段:

1.ng-model和输入框指令设置一个keydowm监听器在<input>中
2.差值(interpolation)添加$watch来监听“name”值得变化
2.在运行时阶段:
1.当在输入框中输入时会触发keydown事件
2.input输入框捕捉到它值得变化然后调用$apply(“name = '输入内容'”),然后在angualr的内部更新app的模型
3.angualr把“name = '输入内容'”应用到模型上
4.$digest循环开始
5.$watch队列返现'name'属性的变化然后通知内部结构( interpolation)按顺序更新DOM
6.angualr退出执行范围,也就是按顺序退出JavaScript范围中的kedown事件
7.浏览器用更新过的输入框内容重新渲染视图


0 0
原创粉丝点击