Passing Messages with Events
In this guide we’re gonna explore an interesting feature related with events, which is called message passing.
The example in this guide may look weird, and it actually is – let’s use it for discussion and learning a couple of things about Apotomo.
Events can transport payload
In the last chapter the :newTweet event urged our panel widget to redraw the entire tweets list. As it consumes a lot of time to reload the tweets from the database instead we could also just redraw the new tweet.
How would the panel know which tweet is the one just created? The form widget could propagate that using the event.
1class Twitter::FormWidget < Apotomo::Widget 2 responds_to_event :submit 3 4 def display 5 @tweet = Tweet.new 6 render 7 end 8 9 def submit(evt) 10 @tweet = Tweet.new 11 12 if @tweet.update_attributes(evt[:tweet]) 13 trigger :newTweet, :tweet => @tweet 14 replace :state => :display 15 else 16 replace :view => :display 17 end 18 end 19 20end
We simply append the new tweet to the triggered event (line 13). States triggered by this event can now access this payload data – cool!
The event object speaks!
Let’s see how we can query the event object for the new tweet.
1class Twitter::PanelWidget < Apotomo::Widget 2 responds_to_event :newTweet, :with => :redraw_list 3 4 has_widgets do 5 self << widget("twitter/form", :tweet_form) 6 end 7 8 9 def display 10 @tweets = Tweet.find(:all) 11 render 12 end 13 14 def list(tweets) 15 render :locals => {:tweets => tweets} 16 end 17 18 def redraw_list(evt) 19 text = evt[:tweet].text 20 21 render :text => "$(\"##{widget_id} ul\").append(\"<li>#{text}</li>\");" 22 end 23 24end
I tweaked the #redraw_list method. What re-rendered the display state now sends back one new <li>...</li> item, only (line 18-22).
By using evt[:tweet] I can access the tweet model sitting piggy-back on the event triggered in the form (line 19).
Sending back plain JavaScript
Note how I don’t use #replace anymore but send back hand-made JavaScript (line 21).
The content sent to the browser roughly looks like this.
$("#twitter ul").append("<li>boardumb</li>");
This simply appends the new tweet to the list. Nothing more.
Discussion
The alert reader with the desire for strong encapsulation will notice a small interface violation here: The panel widget knows about the HTML format of a list item. This should be handled by the list state, or by a separate tweet widget.
We’re gonna cover that in the next chapter.

