Fun with CoffeeScript and Backbone.js : Part 2

ByRyan Brubaker

Published Thu Jun 07 2012

In this post I’ll discuss the code that handles updating the UI.

See the rest of this series.

The project is a simplified morse code simulator that animates morse code being sent over a telegraph line. The complete source is available here and the running code can be seen here.

Communication Line View

class DecoderView extends Backbone.View
   initialize: ->
      @model.bind('parsedCharacter', @render)

   render: (token) =>
      messageBox = $('#messageBox')
      messageBox.val(messageBox.val() + token)

The CommunicationLineView class is a Backbone.js view class that handles the animation of signals sent across the communication line. In Part 1, I mentioned that the model representing the communication line fires a hasNewData event each time the tokens progress one step through the line. As you can see above, this view is bound to that event and rerenders itself every time it receives the event. The render method iterates over the current tokens and draws the appropriate token shape for each line position.

Decoder Model

class MorseDecoder extends Backbone.Model

   initializeKey: =>
      """
      Omitting code that initializes the morse code key 
      dictionary.
      """

   initialize: =>
      @inputTokens = []
      @numEmptyTokensInARow = 0
      @initializeKey()

   processToken: (token) =>
      if token == ''
         @parseTokens() if 
          ++@numEmptyTokensInARow >= 10
      else if token == kWordStopToken
         @parseTokens() if @inputTokens.length > 0
         @trigger('parsedCharacter', ' ')
      else
         @inputTokens.push(token)
         @numEmptyTokensInARow = 0

   parseTokens: =>
      if @inputTokens.length > 0
         token = @key[@inputTokens.join('')]
         @trigger('parsedCharacter', token) if 
          token != undefined
      @numEmptyTokensInARow = 0
      @inputTokens.length = 0

The Decoder model is responsible for determining what characters the user has sent across the line. The processToken function is called each time the tokens on the communication line progress one step through the line. The decoder processes the current tokens sent by the user anytime it sees 10 or more empty tokens in a row or receives a word-break token. If the decoder parses a known morse code sequence it fires a parsedCharacter event letting the message field know it needs to rerender itself.

Decoder View

class CommunicationLineView extends Backbone.View
   initialize: ->
      @model.bind('hasNewData', @render)

   render: (tokens) =>
      context = document.getElementById(
       "communicationLineCanvas").getContext('2d')

      context.clearRect(0, 0, context.canvas.width, 29)
      tokenNum = 0
      for token in tokens
         do (token) ->
            if kDotToken == token
               context.beginPath()
               context.moveTo((50 * tokenNum) + 15, 15)

               context.arc((50 * tokenNum) + 15, 15, 10, 
                0, Math.PI*2, false)

               context.closePath()
               context.fill()
               context.stroke()
            else if kDashToken == token
               context.fillRect((50 * tokenNum) + 15, 
                15, 25, 10)
            else if kWordStopToken == token
               context.fillRect((50 * tokenNum) + 30, 
                5, 10, 20)
            tokenNum += 1

The Decoder view is a Backbone.js view class that represents a simple text box to display the characters the user has sent across the line. Anytime the Decoder model emits a parsedCharacter event, the Decoder view appends the parsed character to the end of its text box.

Previous

Fun with CoffeeScript and Backbone.js : Part 1
CoffeeScript has been all the rage lately and I've been wanting to hop on board the bandwagon. I've also seen Backbone.js mentioned quite a bit and was even more intrigued after listening to this .NET Rocks podcast. I decided to convert some plain JavaScript code I had in a side project to use both CoffeeScript and Backbone.js and see how things went.