1、基本概念javascript
做用域是一个指向应用模型的对象,至关于MVVM中的ViewModel,能绑定数据(属性)和行为(方法),能监控表达式和传递事件,是实现双向绑定的基础,是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带,是链接视图和控制器的一个特殊的JavaScript对象。html
做用域是一个树型层次结构,与DOM标签平行,有根做用域,多个子做用域,子做用域下又有子做用域。全部的应用都有一个 $rootScope,它做用在 ng-app 指令包含的全部 HTML 元素中。$rootScope 可做用于整个应用中。是各个 controller 中 scope 的桥梁。用 rootscope 定义的值,能够在各个 controller 中使用。ng-app 指令能够产生一个根做用域以外,一些 指令会建立新的子做用域,而且进行原型继承,如 ng-repeat、ng-include、ng-switch、ng-view、ng-controller, 另外,用 scope: true 和 transclude: true 建立自定义 directive也会产生新做用域。java
做用域变量性质,有局部变量和所有变量之分,全局变量能够在方法,或者闭包内引入,而局部变量只能在定义的方法内使用,其余方法引用不到,$rootscope至关于所有变量,不该在 $rootScope附加太多的业务逻辑数据(全局),而是用控制器显示的建立 $scope对象来管理本身相关的逻辑和数据(局部)。angularjs
做用域继承性,子做用域自动继承父做用域的属性和方法,若是本身有就用本身的同名属性和方法。有以下内部关系ajax
scope.$parent :指向scope的父做用域api
scope.$$childHead:指向scope的第一个子做用域数组
scope.$$childTail:指向scope的最后一个子做用域闭包
scope.$$nextSibling:指向scope的下一个相邻做用域app
scope.$$prevSibling:指向scope的上一个相邻做用域框架
例子:
<html> <head> <title>Angular JS</title> </head> <body> <h2>AngularJS Sample</h2>
<!--绑定ng-app产生$rootscope,还有产生一个当前做用域$scope(shapeController),这里产生两个做用域-->
<!--message和type都显示本身的--> <div ng-app="mainApp" ng-controller="shapeController"> <p>{{message}} <br/> {{type}} </p>
<!--产生一个子做用域(circleController)-->
<!--message显示本身的,type没定义,就显示继承过来的type--> <div ng-controller="circleController"> <p>{{message}} <br/> {{type}} </p> </div>
<!--产生另外一个平行子做用域(squareController)-->
<!--message和type都显示本身的,虽然和根做用域有继承关系--> <div ng-controller="squareController"> <p>{{message}} <br/> {{type}} </p> </div> </div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script> <script> var mainApp = angular.module("mainApp", []); //父控制器,产生父做用域 mainApp.controller("shapeController", function($scope) { $scope.message = "In shape controller"; $scope.type = "Shape"; }); //子做用域,没type,用父做用域的type mainApp.controller("circleController", function($scope) { $scope.message = "In circle controller"; }); //另外一个平行子做用域,有type用本身的type mainApp.controller("squareController", function($scope) { $scope.message = "In square controller"; $scope.type = "Square"; }); </script> </body> </html>
2、做用域上的$watch()、$apply()方法
一、watch()
用于监听模型变化,当模型发生变化,它会提示你的。
表达式: $watch(watchExpression, listener, objectEquality);
其参数:
watchExpression:监听的对象,它能够是一个angular表达式如'name',或函数如function(){return $scope.name}。
listener:当watchExpression变化时会被调用的函数或者表达式,它接收3个参数:newValue(新值), oldValue(旧值), scope(做用域的引用)。
objectEquality:是否深度监听,若是设置为true,它告诉Angular检查所监控的对象中每个属性的变化. 若是你但愿监控数组的个别元素或者对象的属性而不是一个普通的值, 那么你应该使用它。
$scope.name = 'hello'; var watch = $scope.$watch('name',function(newValue,oldValue, scope){ console.log(newValue); console.log(oldValue); }); $timeout(function(){ $scope.name = "world"; },1000);
在后台显示world,1秒后,会变成hello,$timeout内部会触发$scope.$apply()
二、$apply()
用于传播模型的变化,若是一些javascript方法,如setTimeout,调用了AngularJS 函数以后,必须调用$apply。
$scope.test = function() { setTimeout(function () { $scope.$apply(function () { $scope.user = "hello"; }); }, 2000); }
不能写成下边的代码,这样不能实现双向数据绑定。
$scope.test = function() { setTimeout(function () { $scope.user = "hello"; }, 2000); }
3、做用
一、提供了观察者能够监听数据模型的变化
二、能够将数据模型的变化通知给整个 App
三、能够进行嵌套,隔离业务功能和数据
四、给表达式提供上下文执行环境
4、$socpe的生命周期
scope的生命周期处理主要包含如下几个阶段:
一、建立: AngularJS启动时,会使用 $injector建立一个根做用域,将做用域传进相应的控制器或指令中
注意: AngularJS除了ng-controller和ng-repeat指令会建立本身的子做用域,通常不会建立本身的 $scope
二、连接(注册观察者): AngularJS运行时,指令会建立本身的做用域,全部的 $scope对象都会连接到视图上,经过注册 $watch函数来获取数据变化通知
三、模型状态改变:更新模型状态必须发生在scope.$apply方法中才会被观察到。Angular框架封装了$apply过程,无需咱们操心。
四、更新: AngularJS经过在顶层 $scope对象执行事件循环,每一个自做用域都会执行本身的脏值检测($digest),每一个监控函数会检查变化,若是检测到变化,则 $scope对象触发指定的回调函数
五、销毁: 当再也不须要子做用域时,$socpe上能够经过使用 $destoy()方法销毁做用域,回收资源。