欢迎使用CSDN-markdown编辑器

Angular scope rootScope事件机制之 emit broadcast和 onu010730126AngularIonicAngular/使退退 scope和 rootScope emit、 broadcast on方法。本文介绍Angular的事件机制,包括 scope rootScope处理事件上的异同, broadcast emit和 on使 scope与 scope scope与 rootScopeAngular scope与 scope scope与 rootScope rootScope是唯一真神,是万域起源,是所有 scope scope与 scopecontrollerAngularcontroller scope,controller之间的关系也对应着$scope之间的关系:
{{ parent.data }}
{{ sib1.data }}
{{ sib2.data }}

1
2
3
4
5
6
7
8
9
发布、订阅、退订
broadcast emit用于发布事件,他们将事件名称和事件内容发布出去,就像是高考榜单一样,事件名称相当于考生的名字,而事件内容相当于考生的成绩等信息:

scope. broadcast(‘EVENT_NAME’, ‘Data to send’);
scope. emit(‘EVENT_NAME’, ‘Data to send’);
1
2
$on用于订阅事件,事件名称是订阅的唯一标识,每个考生看榜单时都要寻找自己的名字,然后根据自己的成绩等信息决定下一步应该报考什么学校:

scope. on(‘EVENT_NAME’, function(event, args) {
// balabala
});
1
2
3
Angular的退订事件有些奇怪,并没有类似于其他语言的$off方法,所以不要想当然的按照如下方式进行事件的退订操作:

// 不要这样做
scope. off(‘EVENT_NAME’);
1
2
事实上,Angular的事件退订方法隐藏在事件订阅里面:使用$on订阅事件时会返回一个函数,而此函数就是用来退订事件的方法,就像是考生看到了自己的成绩后禀告父母大人,“商量着”选取学校填报志愿,而此志愿单就是结束整个高考榜单的结束:

// 订阅事件返回用于退订事件的函数
var deregister = scope. on(‘EVENT_NAME’, function(event, args) {
// balabala
});

// 退订事件
deregister();
1
2
3
4
5
6
7
broadcast emit相当于射箭
broadcast emit都用于发布事件,但从名字就可以看出他们的不同点: broadcast广 emit是自下而上的射箭,只有在箭矢的轨迹上才能对其做出反应。

具体到Angular上,即从一个 scope broadcast发布的事件,他的所有后代$scope都可以对此事件做出响应:

// 父 scope broadcast发布事件
app.controller(‘ParentCtrl’, [‘ scope,function( scope) {
scope. broadcast(“parent”, ‘Data to Send’);
}])
//所有子 scope on订阅事件
.controller(‘SiblingOneCtrl’, [‘ scope,function( scope) {
scope. on(“parent”, function(event, ‘Data to Send’) {
// balabala
});
}])
.controller(‘SiblingTwoCtrl’, [‘ scope,function( scope) {
scope. on(“parent”, function(event, ‘Data to Send’) {
// balabala
});
}]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
而通过 emit scope可以做出响应,并且其中任一祖先都可以将此事件终结掉,不让其继续传播:

// 子 scope emit发布事件
app.controller(‘SiblingOneCtrl’, [‘ scope,function( scope) {
scope. emit(“sib1”, ‘Data to Send’);
}])
// 父 scope on订阅事件
.controller(‘ParentCtrl’, [‘ scope,function( scope) {
scope. on(“sib1”, function(event, ‘Data to Send’) {
// balabala
});
}])
// 其兄弟 scope emit的事件一无所知,所以不能订阅其事件
.controller(‘SiblingTwoCtrl’, [‘ scope,function( scope) {
// 不要这样做
scope. on(“sib1”, function(event, ‘Data to Send’) {
// balabala
});
}]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在$emit发布事件的响应道路上,其任一祖先如果感觉不再需要此事件了,就可以通过如下方式终结此事件:

app.controller(‘ParentCtrl’, [‘ scope,function( scope) {
scope. on(“sib1”, function(event, ‘Data to Send’) {
// balabala
event.stopPropagation(); // 终止事件继续“冒泡”
});
}])
1
2
3
4
5
6
rootScope broadcast和 emit rootScope是所有 scope rootScope的 broadcast scope接收到,包括$rootScope:

app.controller(‘SomeCtrl’, [‘ rootScope,function( rootScope) {
rootScope. broadcast(“rootEvent”, ‘Data to Send’);

// $rootScope也可以通过$on订阅从$rootScope.$broadcast发布的事件
$rootScope.$on("rootEvent", function(event, 'Data to Send') {
    // balabala
});

}])
// 所有 scope on订阅从 rootScope. broadcast发布的事件
.controller(‘ParentCtrl’, [‘ scope,function( scope) {
scope. on(“rootEvent”, function(event, ‘Data to Send’) {
// balabala
});
}])
.controller(‘SiblingOneCtrl’, [‘ scope,function( scope) {
scope. on(“rootEvent”, function(event, ‘Data to Send’) {
// balabala
});
}])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
rootScope emit就有些怪异了,按照上面的描述, rootScope emit会没有任何作用,但事实并不如此: rootScope. emit发布的事件,只能通过 rootScope. on订阅,而其他$scope对此一无所知:

app.controller(‘SomeCtrl’, [‘ rootScope,function( rootScope) {
rootScope. emit(“rootEvent”, ‘Data to Send’);

// 只有$rootScope可以通过$on订阅从$rootScope.$emit发布的事件
$rootScope.$on("rootEvent", function(event, 'Data to Send') {
    // balabala
});

}])
// scope on订阅从 rootScope. emit发布的事件
.controller(‘ParentCtrl’, [‘ scope,function( scope) {
// 不要这样做
scope. on(“rootEvent”, function(event, ‘Data to Send’) {
// balabala
});
}]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
退订 rootScope使 rootScope. on退 scope的$destory事件中退订:

app.controller(‘SomeCtrl’, [‘ rootScope, scope’, function( rootScope, scope) {
var deregister = rootScope. on(“rootEvent”, function(event, ‘Data to Send’) {
// balabala
});

$scope.$on('$destory', function() {
    deregister(); // 退订事件
});

}])
1
2
3
4
5
6
7
8
9
那通过 scope. on订阅的事件呢?一般不需要手动退订,因为Angular会帮我们退订,但是如果需要自己控制何时退订事件,也可以通过上述方式进行退订。

事件命名的建议
在开发中,对于变量的命名、函数的命名、文件的命名都有一定的规范,既要保证可读性,也需要保证无混淆性。在Angular的事件机制中,因为事件可能会跨函数,甚至可能跨文件,所以对于事件名一定要保证唯一性,所以建议事件名都加上特定的前缀,以便区分。如下几个例子:

scope. emit(‘trash:delete’, data);
scope. on(‘trash:delete’, function (event, data) {…});

scope. broadcast(‘trash:clear’, data);
scope. on(‘trash:clear’, function (event, data) {…});
1
2
3
4
5
结语
Angular的事件机制很智能,而且一般来说总能符合我们的预期,但是如果不能深入理解其背后的机制,可能会踏入某些深坑,本文尝试说明Angular的事件机制,如果有理解不正确的地方,请留言告知。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值