diff --git a/demos/native/index.ts b/demos/native/index.ts index f4e610c8d1..2024c45e7b 100644 --- a/demos/native/index.ts +++ b/demos/native/index.ts @@ -3,7 +3,7 @@ import {Control, ControlGroup} from 'angular2/forms'; 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 {BatteryPage} from 'pages/battery'; @@ -20,9 +20,27 @@ import {VibrationPage} from 'pages/vibration'; templateUrl: 'main.html' }) class MyApp { - constructor(app: IonicApp) { + constructor(app: IonicApp, events: Events) { 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.plugins = [ diff --git a/ionic/components/app/app.ts b/ionic/components/app/app.ts index 0d15a8818c..2221631bbc 100644 --- a/ionic/components/app/app.ts +++ b/ionic/components/app/app.ts @@ -12,6 +12,7 @@ import {ActionSheet} from '../action-sheet/action-sheet'; import {Modal} from '../modal/modal'; import {Popup} from '../popup/popup'; import {FocusHolder} from '../form/focus-holder'; +import {Events} from '../../util/events'; /** * @name IonicApp @@ -282,6 +283,7 @@ export function ionicBootstrap(rootComponentType, config) { let actionSheet = new ActionSheet(app, config); let modal = new Modal(app, config); let popup = new Popup(app, config); + let events = new Events(); // add injectables that will be available to all child components let appBindings = Injector.resolve([ @@ -292,6 +294,7 @@ export function ionicBootstrap(rootComponentType, config) { bind(ActionSheet).toValue(actionSheet), bind(Modal).toValue(modal), bind(Popup).toValue(popup), + bind(Events).toValue(events), ROUTER_BINDINGS, bind(LocationStrategy).toClass(HashLocationStrategy) ]); diff --git a/ionic/ionic.ts b/ionic/ionic.ts index 571d70438e..6ccc5c4203 100644 --- a/ionic/ionic.ts +++ b/ionic/ionic.ts @@ -9,13 +9,12 @@ export * from './components' export * from './platform/platform' export * from './platform/registry' - -export * from './storage/storage' -export * from './storage/local-storage' -export * from './storage/sql' +export * from './platform/plugins' +export * from './platform/storage' export * from './util/click-block' export * from './util/focus' +export * from './util/events' export * from './animations/animation' export * from './animations/builtins' diff --git a/ionic/platform/storage.ts b/ionic/platform/storage.ts new file mode 100644 index 0000000000..50d8199b9c --- /dev/null +++ b/ionic/platform/storage.ts @@ -0,0 +1,3 @@ +export * from './storage/storage' +export * from './storage/local-storage' +export * from './storage/sql' diff --git a/ionic/util/events.ts b/ionic/util/events.ts new file mode 100644 index 0000000000..f5c7db39bd --- /dev/null +++ b/ionic/util/events.ts @@ -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; + } +}