ionic3-handbook
ionic3-handbook copied to clipboard
9、Events广播
当项目大了之后,我们肯定会遇到这样的需求,在某一界面发生了特定的事件,比如说修改了某个数据,执行了某个操作,希望其他界面可以接收到我们这个事件,说白了就是我们常见的发布者和订阅者模式。ionic也对其进行了封装,提供了Events这个好用的模块。
我们来模拟发布和订阅的场景,在懒加载界面中添加一个按钮,当点击此按钮,会发送一个名为changeTitle
的事件,同时传递一个ionic
字符串出去,在主页中,我们订阅此事件,当接收到此事件信息时,改变此界面中title
变量,观察界面的变化。
下面我们用代码来实现此需求,首先,在lazyload.html界面中添加点击按钮,如下:
lazyload.html
...
<button (click)="sendEvent()">发送事件</button>
然后在lazyload.ts中添加对应的方法,如下:
lazyload.ts
import { IonicPage, NavController, NavParams, Events } from 'ionic-angular';
...
export class LazyLoadPage {
...
constructor(public navCtrl: NavController, public navParams: NavParams, public events:Events) {
...
}
sendEvent(){
this.events.publish('changeTitle','ionic');
}
}
代码中我只把改动的地方写出来,其他的地方不需要任何的改动。值得注意的一点是Events
是ionic
提供的一个Service
(Angular中的概念),所以需要在constructor
中注入进来。关于Service
,我希望大家可以自己去看相关的内容,这里面就不赘述,可能以后会开一篇进行讲解。
Events.publish(topic:string,...args: any[])
中第一个参数是所要发送事件的名称,一定是个string类型,后面是所要发送的数据,是一个数组,我们同时可以发送多个数据,例如:this.events.publish('changeTitle', 'ionic', 13, {time: Date().now})
。
接着处理下订阅事件。home.ts中修改代码如下:
home.ts
...
import { NavController, Events } from 'ionic-angular';
...
export class HomePage {
title : string = '';
constructor(public navCtrl : NavController, public events:Events) {
console.log("HomePage constructor");
}
...
ionViewDidLoad() {
console.log('HomePage ionViewDidLoad');
this.events.subscribe('changeTitle',(title)=>{
this.title=title;
});
}
ionViewWillUnload() {
console.log('HomePage ionViewWillUnload');
this.events.unsubscribe('changeTitle',()=>{
console.log('取消订阅changeTitle事件');
});
}
}
同样只列出改动的部分,就像我们在声明周期这篇讲的,我们在ionViewDidLoad
中订阅此事件,ionViewWillUnload
取消订阅,记住,一定要取消,不然会造成多次订阅,导致事件混乱。
ionic serve
运行我们的项目,从主页进入懒加载界面,点击按钮,返回主页,查看下我们的输入框是不是有ionic这个单词了。看下效果:
发布订阅系统
其实Evnents
我们自己也可以写一个,这人就贴一下ionic
实现的代码,大家可以揣摩下。
var Events = (function () {
function Events() {
this._channels = [];
}
Events.prototype.subscribe = function (topic) {
var _this = this;
var handlers = [];
for (var _i = 1; _i < arguments.length; _i++) {
handlers[_i - 1] = arguments[_i];
}
if (!this._channels[topic]) {
this._channels[topic] = [];
}
handlers.forEach(function (handler) {
_this._channels[topic].push(handler);
});
};
Events.prototype.unsubscribe = function (topic, handler) {
if (handler === void 0) { handler = null; }
var t = this._channels[topic];
if (!t) {
// Wasn't found, wasn't removed
return false;
}
if (!handler) {
// Remove all handlers for this topic
delete this._channels[topic];
return true;
}
// We need to find and remove a specific handler
var i = t.indexOf(handler);
if (i < 0) {
// Wasn't found, wasn't removed
return false;
}
t.splice(i, 1);
// If the channel is empty now, remove it from the channel map
if (!t.length) {
delete this._channels[topic];
}
return true;
};
Events.prototype.publish = function (topic) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
var t = this._channels[topic];
if (!t) {
return null;
}
var responses = [];
t.forEach(function (handler) {
responses.push(handler.apply(void 0, args));
});
return responses;
};
return Events;
}());
export { Events };