Tips for Binding Events

Plugins register for events emitted from various sources within wiki. Here we consider coding strategies based on the lifetime of emitters and the handlers that listen to them. Examples from Graph plugin.

Plugins typically register for events in the bind portion of the emit/bind cycle. Many emits may separate a given item's emit and its corresponding bind. But the same arguments are provided with both calls.

emit = ($item, item) -> ... bind = ($item, item) -> ...

Once loaded, the plugin code remains resident for the remaining lifetime of the web page. However, the dom elements that hold listeners and emit are more varied.

# Item

The $item is created for the plugin when a page containing an item is rendered. Bind handlers to $item that should be forgotten when the page is discarded.

$item.dblclick -> wiki.textEditor $item, item

# Emits

The dom elements rendered into $item are often replaced through editing operations. Some logic will be required to rebind these to fresh content.

rebind = -> $item.find('a').on 'hover', (e) -> ...

The Factory plugin is careful to unbind menu click handlers before becoming a new type of item.

$item.unbind()

# Body

Some asynchronous events are unrelated to specific $item elements but still find need to affect them. In this case the first item bound can register the handling of all others.

unless bound bound = true $('body').on 'new-neighbor-done',(e, map) -> ...

We introduce one variable, 'bound', in the outer scope of the plugin but avoid dom manipulation on load so that the plugin can be loaded in non-dom context like tests.

# Afterthought

A somewhat simpler approach is used by the RSS plugin. Each instance binds an event handler to the dom element. With each new-neighbor-done a package level handler finds and invoke these.