在AngularJs中作用域是非常重要的。
$scope可以嵌套,存在父子作用域,兄弟作用域,那么它们这些作用域相互怎么相互发送信息了。
父子作用域:
看如下代码:(在html标签中添加ng-app='myApp')
<div ng-controller='controlFather'>
<input type='text' ng-controller='controlSonFirst' ng-model='contentFirst'>
<input type='text' ng-controller='controlSonTwo' ng-model='contentTwo'>
</div>
angular.module('myApp',[]).controller('controlFather',['$scope',function($scope){
$scope.contentFirst='sonFirst';
$scope.contentTwo='sonTwo'
}])
.controller('controlSonFirst',['$scope',function($scope){
$scope.contentFirst='sonFirst2333'
}])
.controller('controlSonTwo',['$scope',function($scope){
}])
子作用域找不到相关的变量,那么就去它的父级作用域中找,一直找到顶层作用域,找到了就停止。
不过AngularJs为了方便,给我们设置了许多很好的服务,比如$parent, childHead, childTail (记得加上'$$' 我也不知道为啥,在csdn显示不了)
$parent给了子作用域使用父作用域的权利,而childHead(第一个) childTail(最后一个)记得加上'$$' 我也不知道为啥,在csdn显示不了)给了父作用域使用子作用域的权利
<div ng-controller='controlFather'>
<input type='text' ng-controller='controlSonFirst' ng-model='contentFirst'>
<input type='text' ng-controller='controlSonTwo' ng-model='contentTwo'>
</div>
angular.module('myApp',[]).controller('controlFather',['$scope',function($scope){
window.setInterval(function() {
$scope.$$childHead.contentFirst='I can change you!';
$scope.$$childTail.contentTwo='I can change you!';
},1000);
}])
.controller('controlSonFirst',['$scope',function($scope){
$scope.contentFirst='sonFirst';
}])
.controller('controlSonTwo',['$scope',function($scope){
$scope.contentTwo='sonTwo';
}])
父级作用域改变了子作用域。
当没有写在setInterval里面时,childHead和childTail是null。
(记得加上'$$' 我也不知道为啥,在csdn显示不了,很奇怪)
为啥要加一个window.setInterval()了?浏览器在解释js文件时,已经把各个控制器都生成了,但是它们的关系和控制那一块都是不知道,只有等到解析html时才确定。html解析时(深度优先原则),父级在前,所以这个时候并不知道它的儿子有哪些,反之却可以(如上一个案例)。
放到setInterval里面为什么可以了,这是因为我们把这个函数已经放到事件队列里面了,只有执行栈空了(主线已经做完了,该确定的都确定了),才会执行事件队列里面的函数。
兄弟作用域 (nextSibling 下一个兄弟 prevSibling 前一个兄弟)(记得加上'$$' 我也不知道为啥,在csdn显示不了,很奇怪)
<div ng-controller='controlFather'>
<input type='text' ng-controller='controlSonFirst' ng-model='contentFirst'>
<input type='text' ng-controller='controlSonTwo' ng-model='contentTwo'>
</div>
angular.module('myApp',[]).controller('controlFather',['$scope',function($scope){
}])
.controller('controlSonFirst',['$scope',function($scope){
$scope.contentFirst='sonFirst';
console.log($scope.$$nextSibling)
}])
.controller('controlSonTwo',['$scope',function($scope){
$scope.contentTwo='sonTwo';
console.log($scope.$$prevSibling)
}])
我想大家应该知道输出什么了吧! 控制器的关系确定,应该很清楚了吧。
第一个是null,第二个是存在前一个兄弟的。
Angularjs为在scope中为我们提供了冒泡和隧道机制,$broadcast会把事件广播给所有子controller,而$emit则会将事件冒泡传递给父controller,$on则是angularjs的事件注册函数,有了这一些我们就能很快的以angularjs的方式去解决angularjs controller之间的通信。
<div ng-controller='controlFather'>
<input type='text' ng-controller='controlSonFirst' ng-model='contentFirst' ng-change='change(contentFirst);'>
<input type='text' ng-controller='controlSonTwo' ng-model='contentTwo' ></input>
</div>
angular.module('myApp',[]).controller('controlFather',['$scope',function($scope){
$scope.$on('fatherSolve',function(event,item) {
var string="I can't solve it, but my son can! "+item;
$scope.$broadcast('sonSolve',string);//交给子级一个名为sonSolve的函数解决
})
}])
.controller('controlSonFirst',['$scope',function($scope){
$scope.change=function(item) {
$scope.$emit('fatherSolve',item);//交给父级一个名为fatherSolve的函数处理
}
}])
.controller('controlSonTwo',['$scope',function($scope){
$scope.$on('sonSolve',function(event,item) {//我就是sonSolve
$scope.contentTwo=item;
})
}])
我们给第一个input标签加上一个ng-chang监控内容变化,当内容发生变化时触发change函数,我们注意到change函数又将把任务抛给 了父级($emit ,一个名为fatherSolve的函数处理),我们注意到父级又把任务抛给了它的子级(&broadcast,一个名为sonSolve的函数处理)。
第二个·input标签处理了该事件。
其中$on表示事件监听,$emit表示向父级以上的作用域触发事件, $boardcast表示向子级以下的作用域广播事件。
函数的第一个参数event,这是里面的内容。