对angularjs框架下controller间的传值方法详解


Posted in Javascript onOctober 08, 2018

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
app.controller('ParentController', function($scope) { 
$scope.person = {greeted: false};
});
app.controller('ChildController', function($scope) {
$scope.sayHello = function() {
$scope.person.name = 'Ari Lerner';
};
});
//HTML
<div ng-controller="ParentController">
<div ng-controller="ChildController">
<a ng-click="sayHello()">Say hello</a>
</div>
{{ person }}
</div>
//result
{"greeted":true, "name": "Ari Lerner"}

第二种方式

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

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

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

示例

app.controller('ParentController', function($scope) { 
$scope.$on('$fromSubControllerClick', function(e,data){
console.log(data); // hello
});
});
app.controller('ChildController', function($scope) {
$scope.sayHello = function() {
$scope.$emit('$fromSubControllerClick','hello');
};
});
//HTML
<div ng-controller="ParentController">
<div ng-controller="ChildController">
<a ng-click="sayHello()">Say hello</a>
</div>
</div>

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

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

angular
.module('MyApp')
.controller('MyController', ['$scope', '$rootScope', function MyController($scope, $rootScope) {
var unbind = $rootScope.$on('someComponent.someCrazyEvent', function(){
console.log('foo');
});
$scope.$on('$destroy', unbind);
}
]);

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

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

angular
.module('MyApp')
.config(['$provide', function($provide){
$provide.decorator('$rootScope', ['$delegate', function($delegate){
Object.defineProperty($delegate.constructor.prototype, '$onRootScope', {
value: function(name, listener){
var unsubscribe = $delegate.$on(name, listener);
this.$on('$destroy', unsubscribe);
return unsubscribe;
},
enumerable: false
});
return $delegate;
}]);
}]);

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

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

个人强烈推荐此种做法

第三种方式

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

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

示例

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";
}
});

再用简单的方法总结一下

1、父controller,负责监听并广播

//监听:若收到change,把值广播出去
$scope.$on(“change",function (event, msg) {
 $scope.$broadcast(“changeFromBody", msg);
});

2、子controller,负责把变量发给父controller

//向父controller传值$scope.value
 $scope.$emit(“change", $scope.value);

3、子controller,负责监听父controller的广播,给变量赋新值

//监听父controller的广播,得到changeFromBody广播时取$scope.value
$scope.$on(“changeFromBody",function (event, msg) {
 $scope.value = msg;
});

以上这篇对angularjs框架下controller间的传值方法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Js中setTimeout()和setInterval() 何时被调用执行的用法
Apr 12 Javascript
修改file按钮的默认样式实现代码
Apr 23 Javascript
用js实现控件的隐藏及style.visibility的使用
Jun 14 Javascript
javascript中Array()数组函数详解
Aug 23 Javascript
js实现带圆角的两级导航菜单效果代码
Aug 24 Javascript
jquery分页插件jquery.pagination.js实现无刷新分页
Apr 01 Javascript
14 个折磨人的 JavaScript 面试题
Aug 08 Javascript
JavaScript实现的联动菜单特效示例
Jul 08 Javascript
微信小程序点击view动态添加样式过程解析
Jan 21 Javascript
VUE中使用HTTP库Axios方法详解
Feb 05 Javascript
vue深度监听(监听对象和数组的改变)与立即执行监听实例
Sep 04 Javascript
js实现碰撞检测
Jan 29 Javascript
对angularJs中controller控制器scope父子集作用域的实例讲解
Oct 08 #Javascript
CKEditor4配置与开发详细中文说明文档
Oct 08 #Javascript
浅谈angularJs函数的使用方法(大小写转换,拷贝,扩充对象)
Oct 08 #Javascript
angularJs复选框checkbox选中进行ng-show显示隐藏的方法
Oct 08 #Javascript
jquery.param()实现数组或对象的序列化方法
Oct 08 #jQuery
angularJs select绑定的model取不到值的解决方法
Oct 08 #Javascript
基于AngularJs select绑定数字类型的问题
Oct 08 #Javascript
You might like
php中几种常见安全设置详解
2010/04/06 PHP
php版微信公众平台接口开发之智能回复开发教程
2016/09/22 PHP
php die()与exit()的区别实例详解
2016/12/03 PHP
老生常谈PHP位运算的用途
2017/03/12 PHP
PHP正则删除HTML代码中宽高样式的方法
2017/06/12 PHP
Laravel5.4框架使用socialite实现github登录的方法
2019/03/20 PHP
Laravel 数据库加密及数据库表前缀配置方法
2019/10/10 PHP
禁止F5等快捷键的JS代码
2007/03/06 Javascript
一款js和css代码压缩工具[附JAVA环境配置方法]
2010/04/16 Javascript
setTimeout内不支持jquery的选择器的解决方案
2015/04/28 Javascript
基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)
2016/11/17 Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
2019/11/15 Javascript
使用vue实现HTML页面生成图片的方法
2020/03/12 Javascript
VUE 实现element upload上传图片到阿里云
2020/08/12 Javascript
vant picker+popup 自定义三级联动案例
2020/11/04 Javascript
python进阶教程之循环对象
2014/08/30 Python
Python3 处理JSON的实例详解
2017/10/29 Python
Python实现接受任意个数参数的函数方法
2018/04/21 Python
django自带的server 让外网主机访问方法
2018/05/14 Python
使用Python制作自动推送微信消息提醒的备忘录功能
2018/09/06 Python
Python生成MD5值的两种方法实例分析
2019/04/26 Python
python中的列表与元组的使用
2019/08/08 Python
python3应用windows api对后台程序窗口及桌面截图并保存的方法
2019/08/27 Python
Linux下升级安装python3.8并配置pip及yum的教程
2020/01/02 Python
通过Python pyecharts输出保存图片代码实例
2020/11/25 Python
python爬虫多次请求超时的几种重试方法(6种)
2020/12/01 Python
BeautifulSoup中find和find_all的使用详解
2020/12/07 Python
详解Django中的FBV和CBV对比分析
2021/03/01 Python
Made in Design德国:设计师家具、灯具和装饰
2019/10/31 全球购物
俄罗斯三星品牌商店:GalaxyStore
2020/11/04 全球购物
工程概预算专业毕业生求职信
2013/10/04 职场文书
营销与策划专业毕业生求职信
2013/11/01 职场文书
应用外语系自荐信
2014/06/26 职场文书
小兵张嘎观后感300字
2015/06/03 职场文书
CSS中Single Div 绘图技巧的实现
2021/06/18 HTML / CSS
php png失真的原因及解决办法
2021/11/17 PHP