Hooks API
Enyo has a pretty deep inheritance heirarcy and one of our areas of research right now is ways to flatten it to improve performance and ease debugging. We’ve discussed increasing our use of mixins (or something similar, perhaps) to add functionality to a kind without defining an entirely new one. Mixins have a couple of drawbacks regarding overriding methods, however:
- You have to use
kind.inherit
which is a bit awkward - It still increases the call stack
One common place for method overrides are the lifecycle methods (e.g. create()
, destroy()
). In
most cases, the mixin does its work either before or after the call to the super without modifying
the arguments. To make this a bit easier, I’m proposing a new HookSupport mixin.
How it works
The enyo/HookSupport
modules exports the HookSupport mixin allowing a kind to invoke a hook.
The module also provides the logic to accumulate the methods attaching to a hook via
kind.concatHandler
.
Defining a Hook
Hooks are defined at execution time using invokeHook(name, method)
where name is a String with
the name of the hook (e.g. create
) and method is either the name of a method on this
or the
method itself.
create: function () {
this.invokeHook('create', this._create);
},
_create: function () {
// actual work
}
Attaching to a Hook
You can attach to a hook from mixins, subkinds, or instances. You could even attach from the kind
that declares the hook though that’s likely not necessary. Each hook supports before and after
points to support the common use cases. To attach to a hook, add a hooks
block to your kind or
mixin with an entry for each point you want to hook.
hooks: {
beforeCreate: function () {
// this will run before the 'create' callback
},
// this will call this.afterCreateWork() after the `create` callback
afterCreate: 'afterCreateWork'
}
Notice that hook callbacks do not receive any parameters. Further, return values are ignored. There is no mechanism to stop either future callbacks from being invoked. I could forsee supported either of these scenarios if there were use cases for them.