Up: Chapter 2

2.2 The Chat Comet component

The Actor Model provides state in functional languages include Erlang. Lift has an Actor library and LiftActors (see 7.14↓) provides a powerful state and concurrency model. This may all seem abstract, so let’s look at the Chat class.
Chat.scala
package code
package comet
​
import net.liftweb._
import http._
import util._
import Helpers._
​
/**
 * The screen real estate on the browser will be represented
 * by this component.  When the component changes on the server
 * the changes are automatically reflected in the browser.
 */
class Chat extends CometActor with CometListener {
  private var msgs: Vector[String] = Vector() // private state
​
  /**
   * When the component is instantiated, register as
   * a listener with the ChatServer
   */
  def registerWith = ChatServer
​
  /**
   * The CometActor is an Actor, so it processes messages.
   * In this case, we're listening for Vector[String],
   * and when we get one, update our private state
   * and reRender() the component.  reRender() will
   * cause changes to be sent to the browser.
   */
  override def lowPriority = {
    case v: Vector[String] => msgs = v; reRender()
  }
​
  /**
   * Put the messages in the li elements and clear
   * any elements that have the clearable class.
   */
  def render = "li *" #> msgs & ClearClearable
}
The Chat component has private state, registers with the ChatServer, handles incoming messages and can render itself. Let’s look at each of those pieces.
The private state, like any private state in prototypical object oriented code, is the state that defines the object’s behavior.
registerWith is a method that defines what component to register the Chat component with. Registration is a part of the Listener (or Observer) pattern. We’ll look at the definition of the ChatServer in a minute.
The lowPriority method defines how to process incoming messages. In this case, we’re Pattern Matching (see ) the incoming message and if it’s a Vector[String], then we perform the action of setting our local state to the Vector and re-rendering the component. The re-rendering will force the changes out to any browser that is displaying the component.
We define how to render the component by defining the CSS to match and the replacement (See ). We match all the <li> tags of the template and for each message, create an <li> tag with the child nodes set to the message. Additionally, we clear all the elements that have the clearable in the class attribute.
That’s it for the Chat CometActor component.
Up: Chapter 2

(C) 2012 David Pollak