$scope概念###
$scope 的使用贯穿整个 Angular App 应用,它与数据模型相关联,同时也是表达式执行的上下文.有了 $scope 就在视图和控制器之间建立了一个通道,基于作用域视图在修改数据时会立刻更新 $scope,同样的 $scope 发生改变时也会立刻重新渲染视图。其实就是双向绑定。
有了 $scope 这样一个桥梁,应用的业务代码可以都在 controller 中,而数据都存放在controller 的 $scope 中。
scope对象就是一个普通的JavaScript对象,我们可以在其上随意修改或添加属性。
这个图什么意思呢?
$scope作用###
$scope 对象在 Angular 中充当数据模型的作用,也就是一般 MVC 框架中 Model 得角色.但又不完全与通常意义上的数据模型一样,因为 $scope 并不处理和操作数据,它只是建立了视图和 HTML 之间的桥梁,让视图和 Controller 之间可以友好的通讯。
Scope中,可以处理Model角色处理的逻辑
例如上图中,Scope这个"Model",拥有一个成员属性name. 初始值为world。拥有一个方法函数
然后在视图中,{{name}} 就代表了 scope 这个“Model”中取出 key为name的 value,也就是 {{name}} 相当于是 world
然后 <button ng-click = "action()"> 就相当于调用了,$scope中的function方法
标准MVC模式,它的作用和功能优点可以参考MVC架构
例如 :
通过监测$scope,间接检测Model数据模型的变化
解耦,将业务功能与数据分离出来
在 Javascript 中创建一个新的执行上下文,实际就是用函数创建了一个新的本地上下文,在 Angular 中当为子 DOM 元素创建新的作用域时,其实就是为子 DOM 元素创建了一个新的执行上下文。
$scope 生命周期###
$scope 的生命周期有4个阶段:
创建
控制器或者指令(ng-controller)创建时, Angular 会使用 $injector 创建一个新的作用域,然后在控制器或指令运行时,将作用域传递进去。
// 创建oneModule模块、注册服务
var oneModule = angular.module('oneModule', []);
oneModule.service('oneService', function() {
this.one = 0;
});
// 创建twoModule模块、注册服务
var twoModule = angular.module('twoModule', []);
twoModule.service('twoService', function() {
this.her = 1;
});
// 加载了2个模块中的服务
var injector = angular.injector(["oneModule","twoModule"]);
alert(injector.get("oneService").my);
alert(injector.get("twoService").her);
链接
Angular 启动后会将所有 $scope 对象附加或者说链接到视图上,所有创建 $scope 对象的函数也会被附加到视图上.这些作用域将会注册当 Angular content发生变化时需要运行的函数.也就是 $watch 函数, Angular 通过这些函数或者何时开始事件循环。
所谓的动态检测model数据变化,实则上就是利用了$watch这个函数
//$watch简单使用
//$watch是一个scope函数,用于监听模型变化,当你的模型部分发生变化时它会通知你。
//$watch(watchExpression, listener, objectEquality);
/*每个参数的说明如下:
watchExpression:监听的对象,它可以是一个angular表达式如'name',或函数如function(){return $scope.name}。
listener:当watchExpression变化时会被调用的函数或者表达式,它接收3个参数:newValue(新值), oldValue(旧值), scope(作用域的引用)
objectEquality:是否深度监听,如果设置为true,它告诉Angular检查所监控的对象中每一个属性的变化. 如果你希望监控数组的个别元素或者对象的属性而不是一个普通的值, 那么你应该使用它
*/
更新
一旦事件循环开始运行,就会开始执行自己的脏值检测.一旦检测到变化,就会触发 $scope 上指定的回调函数。
销毁
通常来讲如果一个 $scope 在视图中不再需要, Angular 会自己清理它.当然也可以通过 $destroy() 函数手动清理。
$scope的指令###
指令在AngularJS中被广泛使用,指令通常不会创建自己的$scope,但也有例外。比如
ng-controller和ng-repeat指令会创建自己的子作用域并将它们附加到DOM元素上。
例如 :
<ion-view view-title="Chats">
<ion-content>
<ion-list>
// ng-repeat="chat in chats" , ion-item绑定了chats这个数组,
<ion-item class="item-remove-animate item-avatar item-icon-right" ng-repeat="chat in chats" type="item-text-wrap" href="#/tab/chats/{{chat.id}}">
<img ng-src="{{chat.face}}">
<h2>{{chat.name}}</h2>
<p>{{chat.lastText}}</p>
<i class="icon ion-chevron-right icon-accessory"></i>
<ion-option-button class="button-assertive" ng-click="remove(chat)">
Delete
</ion-option-button>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
// chats数组定义在这里 , service.js
.factory('Chats', function() {
var chats = [{
id: 0,
name: 'Ben Sparrow',
lastText: 'You on your way?',
face: 'img/ben.png'
}, {
id: 1,
name: 'Max Lynx',
lastText: 'Hey, it\'s me',
face: 'img/max.png'
}, {
id: 2,
name: 'Adam Bradleyson',
lastText: 'I should buy a boat',
face: 'img/adam.jpg'
}, {
id: 3,
name: 'Perry Governor',
lastText: 'Look at my mukluks!',
face: 'img/perry.png'
}, {
id: 4,
name: 'Mike Harrington',
lastText: 'This is wicked good ice cream.',
face: 'img/mike.png'
}];
return {
all: function() {
return chats;
},
remove: function(chat) {
chats.splice(chats.indexOf(chat), 1);
},
get: function(chatId) {
for (var i = 0; i < chats.length; i++) {
if (chats[i].id === parseInt(chatId)) {
return chats[i];
}
}
return null;
}
};
});
ng-repeat : 创建自己的子作用域并将它们附加到DOM元素上
ng-controller : 创建自己的子作用域并将它们附加到DOM元素上