Enyo Daily #8 - Events - Part 3
In the exciting finale on events in enyo, I'll cover the ApplicationEvents component. This built-in component handles the three window events (onload, onunload, and resize) as well as a host of webOS specific events.
For more background on events, check out Part 1 on custom events and Part 2 on DOM events.
[[MORE]]The ApplicationEvents component is really just a convenience control. It contains virtually no logic. Instead it simply overrides dispatchDomEvent (see Part 2 for details on this method) and fires its custom events instead. Not to say there isn't value using it; it's preferable to declaratively bind a handler via a component versus programmatically checking the event type in dispatchDomEvent. It also (hopefully) insulates the developer for changes to the underlying event model. For example, if HP decided to change an event type, ApplicationEvents would be able to handle that scenario and fire its original event.
Because there isn't anything to ApplicationEvents, I won't spend much time discussing its features. One notable event is onWindowRotated.
As you would expect, this is fired when you rotate the device (or emulator via keystrokes). Under the covers, this event is really just a translation of the window resize event (Search for enyo.sendOrientationChange in the enyo source to see what's going on). You'd think that you'd be able to simulate rotation in the browser by reszing the window. Unfortunately, there's check for changes to PalmSystem.screenOrientation (which I assume is set by Palm's customized WebKit since it isn't referenced elsewhere in source) so windowRotated never fires in the browser.
If you want to test how your display will scale when changing from portrait to landscape, you can add a resizeHandler method to your component (check out Part 2 for an explanation why you don't have to specifically listen for resize for resizeHandler to be called). If, however, you need to test for a specific orientation, you'll have to use the emulator.
Here's the complete example incorporating all three types of events.
var _Example = {
name:"com.technisode.example.App",
kind:"Control",
components:[
{kind:"ApplicationEvents", name:"appEvents"},
{kind:"EventSender", name:"eventSender", onSend:"sent"},
{kind:"Button", onclick:"clicked"},
{kind:"Input", onkeypress:"press"}
],
create:function() {
this.inherited(arguments);
// map all ApplicationEvents to logAppEvent
var ae = this.$.appEvents;
Object.keys(enyo.ApplicationEvents.prototype.events).forEach(function(key) {
enyo.log("setting handler for ",key);
ae[key] = "logAppEvent";
})
},
logAppEvent:function(source, e) {
enyo.log("logAppEvent",e.type);
},
resizeHandler:function() {
enyo.log("dimensions",window.document.body.offsetWidth,window.document.body.offsetHeight);
},
captureDomEvent:function(e) {
enyo.log("A DOM event occured", e.type);
// returning true would indicated the event is captured and prevent the bubble phase
// thereby preventing the declared handlers (clicked in this case) from being called
// returning false (or no explicit return) lets things continue
return false;
},
dispatchDomEvent:function(e) {
// like any other method, you could override dispatchDomEvent and implement custom routing
e.myCustomField = "This is a custom field";
return this.inherited(arguments);
},
press:function(source, event) {
enyo.log(source, event);
},
clickHandler:function(source, event) {
enyo.log("bubbled up to me", event.myCustomField);
// calling event.stopPropagation() or returning true will end the bubble phase
},
clicked:function(source, event) {
// trigger my custom events
this.$.eventSender.go();
// toggles event handler between send and secondSent ... just because ...
this.$.eventSender.onSend = (this.$.eventSender.onSend === "sent") ? "secondSent" : "sent";
// calling event.stopPropagation() or returning true will end the bubble phase
},
sent:function(source, one, two, three) {
enyo.log("sent", one, two, three)
},
handleOnAlert:function(source, obj) {
enyo.log("alerted", enyo.json.stringify(obj));
},
secondSent:function(source, one, two, three) {
enyo.log("secondSent handles onSend now", one, two, three)
}
}
var _EventSender = {
name:"EventSender",
kind:"Component",
events:{
onSend:"handleOnSend",
onAlert:{value:"handleOnAlert", caller:"sendAlert"}
},
go:function() {
this.doSend(1,2,3); // dispatchIndirectly
this.sendAlert({a:1, b:2});
}
}
enyo.kind(_EventSender);
enyo.kind(_Example);