feat(events): pub/sub event system

This commit is contained in:
Max Lynch
2015-09-23 13:43:38 -05:00
parent cfa906dfde
commit 27373e0448
5 changed files with 100 additions and 6 deletions

View File

@ -3,7 +3,7 @@ import {Control, ControlGroup} from 'angular2/forms';
import {IonicApp, App, Http} from 'ionic/ionic'; import {IonicApp, App, Http} from 'ionic/ionic';
import {Camera, Geolocation, Vibration, Battery, Device} from 'ionic/ionic'; import {Camera, Geolocation, Vibration, Battery, Device, Events} from 'ionic/ionic';
import {CameraPage} from 'pages/camera'; import {CameraPage} from 'pages/camera';
import {BatteryPage} from 'pages/battery'; import {BatteryPage} from 'pages/battery';
@ -20,9 +20,27 @@ import {VibrationPage} from 'pages/vibration';
templateUrl: 'main.html' templateUrl: 'main.html'
}) })
class MyApp { class MyApp {
constructor(app: IonicApp) { constructor(app: IonicApp, events: Events) {
this.app = app; this.app = app;
console.log('Events', events);
events.subscribe('user:created', (user) => {
console.log('User created', user);
})
setInterval(() => {
events.publish('user:created', {
name: 'Max Lynch',
id: 1
})
}, 2000);
setTimeout(() => {
events.unsubscribe('user:created');
console.log(events.channels);
}, 6000);
this.firstPage = CameraPage; this.firstPage = CameraPage;
this.plugins = [ this.plugins = [

View File

@ -12,6 +12,7 @@ import {ActionSheet} from '../action-sheet/action-sheet';
import {Modal} from '../modal/modal'; import {Modal} from '../modal/modal';
import {Popup} from '../popup/popup'; import {Popup} from '../popup/popup';
import {FocusHolder} from '../form/focus-holder'; import {FocusHolder} from '../form/focus-holder';
import {Events} from '../../util/events';
/** /**
* @name IonicApp * @name IonicApp
@ -282,6 +283,7 @@ export function ionicBootstrap(rootComponentType, config) {
let actionSheet = new ActionSheet(app, config); let actionSheet = new ActionSheet(app, config);
let modal = new Modal(app, config); let modal = new Modal(app, config);
let popup = new Popup(app, config); let popup = new Popup(app, config);
let events = new Events();
// add injectables that will be available to all child components // add injectables that will be available to all child components
let appBindings = Injector.resolve([ let appBindings = Injector.resolve([
@ -292,6 +294,7 @@ export function ionicBootstrap(rootComponentType, config) {
bind(ActionSheet).toValue(actionSheet), bind(ActionSheet).toValue(actionSheet),
bind(Modal).toValue(modal), bind(Modal).toValue(modal),
bind(Popup).toValue(popup), bind(Popup).toValue(popup),
bind(Events).toValue(events),
ROUTER_BINDINGS, ROUTER_BINDINGS,
bind(LocationStrategy).toClass(HashLocationStrategy) bind(LocationStrategy).toClass(HashLocationStrategy)
]); ]);

View File

@ -9,13 +9,12 @@ export * from './components'
export * from './platform/platform' export * from './platform/platform'
export * from './platform/registry' export * from './platform/registry'
export * from './platform/plugins'
export * from './storage/storage' export * from './platform/storage'
export * from './storage/local-storage'
export * from './storage/sql'
export * from './util/click-block' export * from './util/click-block'
export * from './util/focus' export * from './util/focus'
export * from './util/events'
export * from './animations/animation' export * from './animations/animation'
export * from './animations/builtins' export * from './animations/builtins'

View File

@ -0,0 +1,3 @@
export * from './storage/storage'
export * from './storage/local-storage'
export * from './storage/sql'

71
ionic/util/events.ts Normal file
View File

@ -0,0 +1,71 @@
import {Injectable} from 'angular2/angular2';
/**
* Event is a pub/sub style event system for sending and responding to application-level
* events across your app.
*/
@Injectable()
export class Events {
constructor() {
console.log('Events constructed');
this.channels = [];
}
/**
* Subscribe to an event topic. Events that get posted to that topic
* will trigger the provided handler.
*
* @param topic the topic to subscribe to
* @param handler the event handler
*/
subscribe(topic, ...handlers) {
if(!this.channels[topic]) {
this.channels[topic] = [];
}
handlers.forEach((handler) => {
this.channels[topic].push(handler);
});
}
/**
* Unsubscribe the given handler from the given topic. Your handler will
* no longer receive events published to this topic.
*
* @param topic the topic to unsubscribe from
* @param handler the event handler
*/
unsubscribe(topic, handler) {
var t = this.channels[topic];
if(!t) {
return null;
}
t.splice(t.indexOf(handler), 1);
// If the channel is empty now, remove it from the channel map
if(!t.length) {
delete this.channels[topic];
}
return true;
}
/**
* Publish an event to the given topic.
*
* @param topic the topic to publish to
* @param eventData the data to send as the event
*/
publish(topic, ...args) {
var t = this.channels[topic];
if(!t) {
return null;
}
let responses = [];
t.forEach((handler) => {
responses.push(handler(args));
});
return responses;
}
}