1, 利用作用域的继承方式

由于作用域的继承是基于js的原型继承方式,所以这里分为两种情况,当作用域上面的值为基本类型的时候,修改父作用域上面的值会 影响到子作用域,反之,修改子作用域只会影响子作用域的值,不会影响父作用域上面的值;如果需要父作用域与子作用域共享一个值 的话,就需要用到后面一种,即作用域上的值为对象,任何一方的修改都能影响另一方,这是因为在js中对象都是引用类型。

基本类型

function Sandcrawler($scope) {
$scope.location = "Mos Eisley North";
$scope.move = function(newLocation) {
$scope.location = newLocation;
}
}
function Droid($scope) {
$scope.sell = function(newLocation) {
$scope.location = newLocation;
}
}
// html
<div ng-controller="Sandcrawler">
<p>Location: {{location}}</p>
<button ng-click="move('Mos Eisley South')">Move</button>
<div ng-controller="Droid">
<p>Location: {{location}}</p>
<button ng-click="sell('Owen Farm')">Sell</button>
</div>
</div>

对象

function Sandcrawler($scope) {
$scope.obj = {location:"Mos Eisley North"};
}
function Droid($scope) {
$scope.summon = function(newLocation) {
$scope.obj.location = newLocation;
}
}
// html
<div ng-controller="Sandcrawler">
<p>Sandcrawler Location: {{location}}</p>
<div ng-controller="Droid">
<button ng-click="summon('Owen Farm')">
Summon Sandcrawler
</button>
</div>
</div>

2, 基于事件的方式

在一般情况下基于继承的方式已经足够满足大部分情况了,但是这种方式没有实现兄弟控制器之间的通信方式,所以引出了事件的方式 。基于事件的方式中我们可以里面作用的$on,$emit,$boardcast这几个方式来实现,其中$on表示事件监听,$emit表示向父级以上的 作用域触发事件, $boardcast表示向子级以下的作用域广播事件。参照以下代码:

向上传播事件

function Sandcrawler($scope) {
$scope.location = "Mos Eisley North";
$scope.$on('summon', function(e, newLocation) {
$scope.location = newLocation;
});
}
function Droid($scope) {
$scope.location = "Owen Farm";
$scope.summon = function() {
$scope.$emit('summon', $scope.location);
}
}
// html
<div ng-controller="Sandcrawler">
<p>Sandcrawler Location: {{location}}</p>
<div ng-controller="Droid">
<p>Droid Location: {{location}}</p>
<button ng-click="summon()">Summon Sandcrawler</button>
</div>
</div>

向下广播事件

function Sandcrawler($scope) {
$scope.location = "Mos Eisley North";
$scope.recall = function() {
$scope.$broadcast('recall', $scope.location);
}
}
function Droid($scope) {
$scope.location = "Owen Farm";
$scope.$on('recall', function(e, newLocation) {
$scope.location = newLocation;
});
}
//html
<div ng-controller="Sandcrawler">
<p>Sandcrawler Location: {{location}}</p>
<button ng-click="recall()">Recall Droids</button>
<div ng-controller="Droid">
<p>Droid Location: {{location}}</p>
</div>
</div>

从这个用法我们可以引申出一种用于兄弟控制间进行通信的方法,首先我们一个兄弟控制中向父作用域触发一个事件,然后在父作用域 中监听事件,再广播给子作用域,这样通过事件携带的参数,实现了数据经过父作用域,在兄弟作用域之间传播。这里要注意的是,通过父元素作为中介进行传递的话,兄弟元素用的事件名不能一样,否则会进入死循环。请看代码:

兄弟作用域之间传播

function Sandcrawler($scope) {
$scope.$on('requestDroidRecall', function(e) {
$scope.$broadcast('executeDroidRecall');
});
}
function Droid($scope) {
$scope.location = "Owen Farm";
$scope.recallAllDroids = function() {
$scope.$emit('requestDroidRecall');
}
$scope.$on('executeDroidRecall', function() {
$scope.location = "Sandcrawler"
});
}
// html
<div ng-controller="Sandcrawler">
<div ng-controller="Droid">
<h2>R2-D2</h2>
<p>Droid Location: {{location}}</p>
<button ng-click="recallAddDroids()">Recall All Droids</button>
</div>
<div ng-controller="Droid">
<h2>C-3PO</h2>
<p>Droid Location: {{status}}</p>
<button ng-click="recallAddDroids()">Recall All Droids</button>
</div>
</div>

3, angular服务的方式

在ng中服务是一个单例,所以在服务中生成一个对象,该对象就可以利用依赖注入的方式在所有的控制器中共享。参照以下例子,在一个控制器修改了服务对象的值,在另一个控制器中获取到修改后的值:

var app = angular.module('myApp', []);
app.factory('instance', function(){
return {};
});
app.controller('MainCtrl', function($scope, instance) {
$scope.change = function() {
instance.name = $scope.test;
};
});
app.controller('sideCtrl', function($scope, instance) {
$scope.add = function() {
$scope.name = instance.name;
};
});
//html
<div ng-controller="MainCtrl">
<input type="text" ng-model="test" />
<div ng-click="change()">click me</div>
</div>
<div ng-controller="sideCtrl">
<div ng-click="add()">my name {{name}}</div>
</div>
 

利用$watch监听模型变化

$watch是一个scope函数,用于监听模型变化,当你的模型部分发生变化时它会通知你。

$watch(watchExpression, listener, objectEquality);

每个参数的说明如下:

watchExpression:监听的对象,它可以是一个angular表达式如'name',或函数如function(){return $scope.name}。

listener:当watchExpression变化时会被调用的函数或者表达式,它接收3个参数:newValue(新值), oldValue(旧值), scope(作用域的引用)

objectEquality:是否深度监听,如果设置为true,它告诉Angular检查所监控的对象中每一个属性的变化. 如果你希望监控数组的个别元素或者对象的属性而不是一个普通的值, 那么你应该使用它

var watch = $scope.$watch('被监听模型',function(newValue,oldValue, scope){

        console.log(newValue);

        console.log(oldValue);

});

$watch性能问题

太多的$watch将会导致性能问题,$watch如果不再使用,我们最好将其释放掉。

$watch函数返回一个注销监听的函数,如果我们想监控一个属性,然后在稍后注销它,可以使用下面的方式:

var watch = $scope.$watch('someModel.someProperty', callback);

//调用:

 

angular中控制器之间的通讯方式的更多相关文章

  1. angular中控制器之间传递参数的方式

    在angular中,每个controller(控制器)都会有自己的$scope,通过为这个对象添加属性赋值,就可以将数据传递给模板进行渲染,每个$scope只会在自己控制器内起作用,而有时候需要用到其 ...

  2. angular开发控制器之间的通信

    一.指令与控制器之间通信,无非是以下几种方法: 基于scope继承的方式 基于event传播的方式 service的方式(单例模式) 二.基于scope继承的方式: 最简单的让控制器之间进行通信的方法 ...

  3. AngularJS中控制器之间通信方法

    在同个angular应用的控制器之间进行通信可以有很多种不同的方式,本文主要讲两种: 基于scope继承的方式和基于event传播的方式 基于scope继承的方式 最简单的让控制器之间进行通信的方法是 ...

  4. java 中多线程之间的通讯之生产者和消费者 (多个线程之间的通讯)

    在真实开发 中关于多线程的通讯的问题用到下边的例子是比较多的 不同的地方时if 和while 的区别 如果只是两个线程之间的通讯,使用if是没有问题的. 但是在多个线程之间就会有问题 /* * 这个例 ...

  5. React中组件之间通信的方式

    一.是什么 我们将组件间通信可以拆分为两个词: 组件 通信 回顾Vue系列的文章,组件是vue中最强大的功能之一,同样组件化是React的核心思想 相比vue,React的组件更加灵活和多样,按照不同 ...

  6. angularjs中控制器之间的通信----$on、$emit和$broadcast解析

    $on.$emit和$broadcast使得event.data在controller之间的传递变的简单. $emit只能向parent controller传递event与data $broadca ...

  7. Angular中Controller之间的信息传递(第二种办法):$emit,$broadcast,$on

    $emit只能向parent controller传递event与data( $emit(name, args) ) $broadcast只能向child controller传递event与data ...

  8. java 中多线程之间的通讯之等待唤醒机制

    wait notify () nitifyAll () 都使用在同步中,因为要对持有监视器(锁)的线程操作 所以要使用在同步中,因为只有同步才具有锁 为什么这些操作线程的方法要定义object类中呢 ...

  9. Angular1.x组件通讯方式总结

    Angular1开发模式 这里需要将Angular1分为Angular1.5之前和Angular1.5两个不同的阶段来讲,两者虽然同属Angular1,但是在开发模式上还是有较大区别的.在Angula ...

随机推荐

  1. ccw-ide

    有bug,会把working set弄乱,整理后能重启一次正常,再次重启又乱了.

  2. storm serializable

    http://www.programgo.com/article/68283366567/

  3. 。net MVC 序列化 反序列化

           序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象 ...

  4. DZY Loves Partition

    问题描述 DZY喜欢拆分数字.他想知道能否把nn拆成恰好kk个不重复的正整数之和. 思考了一会儿之后他发现这个题太简单,于是他想要最大化这kk个正整数的乘积.你能帮帮他吗? 由于答案可能很大,请模10 ...

  5. Android中自定义veiw使用Java中的回调方法

    //------------------MainActivity----中---------------------------------- import android.os.Bundle;imp ...

  6. math ceil以及math floor,math:round

    ◎Math.ceil()执行向上舍入,即它总是将数值向上舍入为最接近的整数:◎Math.floor()执行向下舍入,即它总是将数值向下舍入为最接近的整数:◎Math.round()执行标准舍入,即它总 ...

  7. Mac机上安装虚拟机

    1.首先要下载虚拟机VMware.网址http://pan.baidu.com/share/init?shareid=1519279671&uk=1434905687,连接该网址,下载里边的这 ...

  8. hadoop yarn 易理解

    Hadoop 和 MRv1 简单介绍 Hadoop 集群可从单一节点(其中所有 Hadoop 实体都在同一个节点上运行)扩展到数千个节点(其中的功能分散在各个节点之间,以增加并行处理活动).图 1 演 ...

  9. CNS数据库网站开发环境的配置

    1)下载wamp服务器.使用php来开发 2)配置mysql服务器,主要把原来已有的数据导入到wamp服务器的mysql.改mysql的my.ini里德datadir的地址即可,将datadir设为已 ...

  10. Android开发实现HttpClient工具类

    在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们使用各种Http服务.你可以把HttpClient想 ...