angularJS的controller之间如何正确的通信

AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为。

当我们在创建新的控制器时,angularJS会帮我们生成并传递一个新的$scope对象给这个controller,在angularJS应用的中的任何一个部分,都有父级作用域的存在,顶级就是ng-app所在的层级,它的父级作用域就是$rootScope。

每个$scope的$root指向$rootScope, $cope.$parent指向父级作用域。

cotroller之间的通信本质上是当前的controller所在的$scope如何跟其他controller上的$scope进行通信。

通常有3中解决方式:

  • 利用作用域继承的原理,子控制器访问父级控制器中的内容。
  • 使用angularJS中的事件,也就是使用$on,$emit,$broadcast进行消息传递
  • 使用angularJS中的服务

第一种方式

即作用域嵌套作用域,有一定的使用限制,需要作用域嵌套起来,在实际开发中这种场景相对比较少,但也不是没有,这种方式更简单直接。

angularJS中默认情况下,当前作用域中无法找到某个属性时,就会在父级作用域中进行查找,若找不到直至查找到$rootScope。 如果在$rootScope中也无法找到程序依旧运行,但视图不会更新。

示例

JavaScript

 1 //Javascript
 2
 3     app.controller(‘ParentController‘, function($scope) {
 4
 5         $scope.person = {greeted: false};
 6
 7     });
 8
 9     app.controller(‘ChildController‘, function($scope) {
10
11         $scope.sayHello = function() {
12
13              $scope.person.name = ‘Ari Lerner‘;
14
15         };
16
17     });
18
19     //HTML
20
21      <div ng-controller="ParentController">
22
23        <div ng-controller="ChildController">
24
25          <a ng-click="sayHello()">Say hello</a>
26
27        </div>
28
29        {{ person }}
30
31      </div>
32
33     //result
34
35     {"greeted":true, "name": "Ari Lerner"}

第二种方式

因为作用域是有层次的,所以可以利用作用域链传递事件。

传递事件有2种方式: * $broadcast: 触发的事件要通知整个事件系统(允许任意作用域处理这个事件)就要向下传播。 * $emit: 如果要提醒一个全局模块,需要通知更高层次的作用域时(例如$rootscope)需要把事件向上传递。

作用域上使用$on进行事件监听。

示例

JavaScript

 1 app.controller(‘ParentController‘, function($scope) {
 2         $scope.$on(‘$fromSubControllerClick‘, function(e,data){
 3             console.log(data); // hello
 4         });
 5     });
 6
 7     app.controller(‘ChildController‘, function($scope) {
 8         $scope.sayHello = function() {
 9             $scope.$emit(‘$fromSubControllerClick‘,‘hello‘);
10         };
11     });
12
13     //HTML
14      <div ng-controller="ParentController">
15        <div ng-controller="ChildController">
16          <a ng-click="sayHello()">Say hello</a>
17        </div>
18      </div>

在这里想要说的另外一个问题就是事件传播的性能问题,$broadcast+$on的方式回通知所有的子作用域,这里就会有性能问题,所以推荐使用$emit+$on的方式,为了进一步提升性能,定义的事件处理函数要在作用域销毁时一起释放掉。

使用$emit+$on的方式需要我们将事件监听绑定在$rootScope上,例如:

JavaScript

1 angular
2     .module(‘MyApp‘)
3     .controller(‘MyController‘, [‘$scope‘, ‘$rootScope‘, function MyController($scope, $rootScope) {
4             var unbind = $rootScope.$on(‘someComponent.someCrazyEvent‘, function(){
5                 console.log(‘foo‘);
6             });
7             $scope.$on(‘$destroy‘, unbind);
8         }
9     ]);

但是这种方式有点繁琐,定义多个事件处理函数时整个人都不好了,所以我们来改进一下

利用装饰器来定义一个新的事件绑定函数:

JavaScript

 1 angular
 2     .module(‘MyApp‘)
 3     .config([‘$provide‘, function($provide){
 4         $provide.decorator(‘$rootScope‘, [‘$delegate‘, function($delegate){
 5             Object.defineProperty($delegate.constructor.prototype, ‘$onRootScope‘, {
 6                 value: function(name, listener){
 7                     var unsubscribe = $delegate.$on(name, listener);
 8                     this.$on(‘$destroy‘, unsubscribe);
 9                     return unsubscribe;
10                 },
11                 enumerable: false
12             });
13             return $delegate;
14         }]);
15     }]);

那么我们在控制器中定义事件处理函数时:

JavaScript

angular
    .module(‘MyApp‘)
    .controller(‘MyController‘, [‘$scope‘, function MyController($scope) {
            $scope.$onRootScope(‘someComponent.someCrazyEvent‘, function(){
                console.log(‘foo‘);
            });
        }
    ]);

个人强烈推荐此种做法

第三种方式

利用angularJS中service单例模式的特性,服务(service)提供了一种能在应用的整个生命周期内保持数据的方式,能够在控制器之间进行通信,且能保证数据的一致性。

一般我们都会封装server来为应用提供访问数据的接口,或者跟远程进行数据交互。

示例

JavaScript

var myApp = angular.module("myApp", []);
myApp.factory(‘Data‘, function() {
  return {
    name: "Ting"
  }
});

myApp.controller(‘FirstCtrl‘, function($scope, Data) {
  $scope.data = Data;
  $scope.setName = function() {
    Data.name = "Jack";
  }
});

myApp.controller(‘SecondCtrl‘, function($scope, Data) {
  $scope.data = Data;
  $scope.setName = function() {
    Data.name = "Moby";
  }
});
时间: 2024-10-20 04:32:11

angularJS的controller之间如何正确的通信的相关文章

(转) angularJS的controller之间如何正确的通信

AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为. 当我们在创建新的控制器时,angularJS会帮我们生成并传递一个新的$scope对象给这个controller,在angularJS应用的中的任何一个部分,都有父级作用域的存在,顶级就是ng-app所在的层级,它的父级作用域就是$rootScope. 每个$scope的$root指向$rootScope, $cope.$parent指向父

AngularJS 中 Controller 之间的通信

用 Angular 进行开发,基本上都会遇到 Controller 之间通信的问题,本文对此进行一个总结. 在 Angular 中,Controller 之间通信的方式主要有三种: 1)作用域继承.利用子 Controller 控制父 Controller 上的数据.(父 Controller 中的数据要为引用类型,不能是基本类型,原因参见 AngularJS中的作用域 一文) 2)注入服务.把需要共享的数据注册为一个 service,在需要的 Controller 中注入. 3)基于事件.利用

angularjs关于controller之间如何通讯

场景一: 父子controller 子可以继承父controller的变量. 场景二: 兄弟controller 可以通过angular提供的$emit.$on.$broadcast ,借助父controller 实现之间的通讯 场景三: 可以借助共同的 service 实现 两者之间的通讯.(借助angular的service是单例模式的特点)

angularJS中directive与controller之间的通信

当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的指令. 1.指令作用域中的"@" 作用:把当前属性作为字符串传递实现指令与html页面元素关联. 1 <!DOCTYPE html> 2 <html ng-app="demoapp"> 3 <head lang="en"

跟我学AngularJs:Controller数据共享、继承、通信使用具体解释

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主讲了AngularJs中的Controller中数据共享.继承.通信的具体使用 本教程使用AngularJs版本号:1.5.3 AngularJs GitHub: https://github.com/angular/angular.js/ AngularJs下载地址:https://angularjs.org/ 一.controller基础与使用方法 AngularJS中的co

AngularJS(三)——在多个AngularJS controller之间共享数据

在MVC中,为了方便维护,针对不同业务会使用不同的controller.有时我们需要在不同的controller中共享数据,本文旨在解决这一问题. 1. 使用$rootScope直接绑定 AngularJS中有一个$rootScope对象,它是AngularJS中最接近全局作用域的对象,是所有$scope对象的最上层,可以简单理解为BOM中的window对象或Node.js中的global对象.最简单的方式是直接将要共享的数据绑定到$rootScope对象中: <!DOCTYPE html>

跟我学AngularJs:Controller数据共享、继承、通信使用详解

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主讲了AngularJs中的Controller中数据共享.继承.通信的详细使用 本教程使用AngularJs版本:1.5.3 AngularJs GitHub: https://github.com/angular/angular.js/ AngularJs下载地址:https://angularjs.org/ 一.controller基础与用法 AngularJS中的contr

angularjs 中使用 service 在controller 之间 share 对象和数据

在做angularjs 的UI 时,我们经常会遇到一个页面之间有几个controller,在controller 之间share 公共的一些数据和方法就变得比较困难,目前推荐的做法是使用创建一个service, 在service 中存储公共的数据,然后把service 注入到controller中来达到share 数据的目的. 下面是最简单的一个sample 列子 angularjs 模板页面, 有userContoller 和 customerController,我们将在这两个control

【MVC架构】——怎样利用Json在View和Controller之间传递数据

在MVC架构中,尽管非常多东西和三层非常相似,可是也有非常大的差别.就比方传递数据.在三层架构中,传递数据就仅仅要一层返回,另外一层用同样类型的变量来接收即可了.在MVC中,事实上原理是一样的,Controller中的方法返回Json字符串.然后View来接收.或者反过来,不同的就是这之间须要一个序列化和反序列化的过程. 本文就简介利用Json在View和Controller之间传递数据的一个方面,大致从双方面介绍,一是什么是Json,二是怎样实现. 什么是Json 一.概念 百度百科说:JSO