Observing a form
Apotomo introduces an event-driven approach for Rails applications. Some widgets fire events, other register handlers for these events. I’ll demonstrate this with an example, where one small widget observes a form and acts upon a certain event from this form.
Taking our simple form example, I add one line to the form processing state.
app/cells/simple_form_cell.rb
14 15 16 17 18 19 20 | def _process_form res = @user.update_attributes(param(:user)) return state_view :form unless res trigger(:userCreated) state_view :user_created end |
Easy: if the user can successfully be created, the form widget informs all other (interested!) widgets about this spectacular incident by triggering a generic :userCreated event (line 18).
That’s all for this form widget. It no longer is actively involved in the following steps.
The Observer
Another widget is interested in that user creation and registers an observer for that.
app/cells/form_observer_cell.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class FormObserverCell < Apotomo::StatefulWidget def transition_map { :lurk => [:_observe_form] } end def lurk "lurking..." end def _observe_form "I smell a userCreated event!" end end |
Normally the widgets lurks around in the state :lurk. When the :userCreated event is fired, it wants itself to go into the state :_observe_form. How to do that?
A common place to attach observers is the application widget tree. I love this word.
app/apotomo/application_widget_tree.rb
playgrd << simple_form = cell(:simple_form, :form, 'simple_form') playgrd << cell(:form_observer, :lurk, 'form_observer') simple_form.watch(:userCreated, 'form_observer', :_observe_form)
I first add the simple_form widget to the page. Then the form_observer widget with start state :lurk.
The watch call attaches the observer to simple_form, instructing the event system to invoke :_observe_form on the widget form_observer whenever an userCreated event is triggered.
This sounds confusing but it makes sense. In GUI architectures, it is common to attach callbacks as event handlers - in our case, we assigned a state method of a widget as an event handler.
