Stateless Widgets

Stateless widgets are not persistent and simply disappear after the request is finished. That sounds stupid. However, in most cases less complex statelessis will do.

Apotomo provides a few methods that make using statelessis very simple, and you don’t have to care about re-establishing your stateless environment in each request.

Basically, Apotomo uses the controller or widget class instance to save widget tree structure between requests.

Let’s see how that would work.

Eh, example?

Stateless todo quickbox

For the imaginary Todo application we have a box that shows the last 5 items. To maximize usability we also provide an input field which updates the item list accordingly.

Great, isn’t it?

That feature could be implemented with 3 widgets

For the start, you’d define the widget tree in the controller.

class DashboardController < ApplicationController
  
  has_widgets do |root|
    root << box = widget('todo_widget/container', 'box')
      box << widget('todo_widget/quicklist', 'quick')
      box << widget('todo_widget/searchbox', 'search')
  end

Doing so, Apotomo will setup the widget tree in every request to DashboardController and you can instantly render your box without having to worry about the widget setup.

Fat widgets, slim controllers

Note that we called has_widgets on the controller class, not in an action. That’s the difference between stateful and -less!

However, pushing too much tree setup in the controller is no good style. If you want to ship the widget or re-use it in multiple controllers, you should extract private code from the controller and move it to the widget class.

Otherwise you’d possibly end up with multiple controllers having the same has_widgets blocks, yay. What a mess!

A DRYer approach could look like this.

class DashboardController < ApplicationController
  
  has_widgets do |root|
    root << widget('todo_widget/container', 'box')
  end

All we do is telling Apotomo to bring that one widget to our controller.

Of course, the tree setup has to be moved. In our case, I’d move it to the TodoWidget::Container class.

module TodoWidget
  class Container < Apotomo::Widget
    has_widgets do |me|
      me << widget('todo_widget/quicklist', 'quick')
      me << widget('todo_widget/searchbox', 'search')
    end

Almost the same except that we moved knowledge about an internal widget setup from the controller to the top widget.

Event Handlers

In stateless widgets, handlers should be attached in class context. Otherwise they’ll be lost in a following request.

class Searchbox < Apotomo::Widget
  responds_to_event :submit, :with => :process

The Searchbox widget will now respond to :submit events at any time, no need to take further care of that yourself.


blog comments powered by Disqus