Reputation: 443
I've read through the Ractive Documentation and I'm scratching my head a bit, because it seems like the default events initialization option allows me to do something - create new eventtypes - far more complex than what i need but conversely, there's no hook for the simpler, (more common?) task of defining default events
Could someone advise on how to provide global events that could be fired for traditional DOM events?
Example:
I have a 3 Component application page. I want to define a getOptions event, such that any <select on-click='getOptions'>...</select>
will be handled by the same function. I don't want to have to define that function in each component.
My intuition would have been to do the following:
Ractive.events['getOptions'] = function(event){
//logic for getting the options for the value in event.keypath
}
or, if i wanted a true default that could be overridden...
Ractive.default.events['getOptions'] = function(event){
//logic for getting the options for the value in event.keypath
}
but my understanding of the documentation, is that Ractive.events
and Ractive.default.events
do not provide this, but rather provide a way to define new event plugins, that depend on a separate mechanism for getting fired:
Ractive.events.getoptions = function(node,fire){
//here goes logic for interacting with DOM event listeners, etc
}
//and then i would need to do this
ractive = Ractive.extend({...});
ractive.on('someOtherEventName',function(event){
//logic for getting the options for the value in event.keypath
});
//and then I could do this...
<select on-getoptions='someOtherEventName'>...</select>
but what would fire the getoptions
in this case - from the template, rather than js ractive.fire()?
Would something like <select on-getoptions='someOtherFunction' on-click=getoptions>...</select>
work? That seems very strange to me. Do I understand the concept correction? If not, what am i missing?
Is there a simple way to achieve the first example?
Upvotes: 1
Views: 200
Reputation: 3712
Ractive.events
refers to custom events for mediating between the dom and the template:
Ractive.events.banana = function( node, fire ) { ... };
<div on-banana="doSomething()"/>
The handler for the event can either be the name of an event to fire, or a method on the component instance.
In your case, I think defining a method on the Ractive.prototype
would be the best way to have a common handler:
Ractive.prototype.getOptions = function( /* pass in arguments */ ){
// and/or this.event will give you access
// to current event and thus context
// you can also override this method in components and
// call this base method using this._super(..)
}
// now any ractive instance can use:
<select on-click="getOptions(data)">...</select>
An event based approach usually entails letting the root instance or common parent in the view hierarchy handle same event across child components:
var app = new Ractive({
template: "<componentA/><componentB/>",
oninit(){
this.on( '*.getOptions', ( event, arg ) => {
// any child component (at any depth)
// that fires a "getOptions" event will
// end up here
});
}
});
// in component A or B:
<select on-click="getOptions">...</select>
UPDATE: If you wanted to assign an event handler to the prototype, so in essence every component is pre-wired to handle an event of a set name, you could do:
Ractive.prototype.oninit = function(){
this.on( 'getOptions', ( event ) => {
// handle any "getOptions" event that happens in the instance
});
}
Just be aware that you must call this._super();
in any component in which you also implement oninit
:
var Component = Ractive.extend({
oninit() {
// make sure we call the base or event listener won't happen!
this._super();
// do this component instances init work...
}
}
Upvotes: 2