Batman.js is no longer in production at Shopify and is not actively maintained.

This website is left for reference (and for old times' sake).

batman.js

App

Your app is the namespace for all your other components. It extends Batman.App and defines routes.

You can define global accessors and functions on the app, too.

# gotham.coffee
    class Gotham extends Batman.App
      @root 'superheros#index'
      @resources 'superheros', 'villains'
      @route '/404', -> alert("Page not found!")

      @classAccessor 'cityIsSafe', ->
        heroCount = Gotham.Superhero.get('all.length')
        villainCount = Gotham.Villain.get('all.length')
        heroCount > villainCount
# models/superhero.coffee
    class Gotham.Superhero extends Batman.Model
      @resourceName: 'superhero'
      @persist Batman.RestStorage
      @encode 'name', 'wears_cape'

      @validate 'name', presence: true

      @belongsTo 'hero_group'
      @hasMany 'superpowers', saveInline: true

      @accessor 'canSaveGotham', ->
        @get('superpowers.length') > 3

Models

Models represent the "business objects" in your app and connect those objects to a backend, like a JSON API. Models usually include:

Controllers

Controller actions are executed by routes in your app. They load data and render views.

# controllers/superheros_controller.coffee
    class Gotham.SuperherosController extends Gotham.ApplicationController
      routingKey: 'superheros'

      index: (params) ->
        @set 'superheros', Gotham.Superhero.get('all')

      show: (params) ->
        Gotham.Superhero.find params.id, (err, record) =>
          @set 'superhero', record

      edit: (params) ->
        Gotham.Superhero.find params.id, (err, record) =>
          @set 'superhero', record.transaction()
<!-- html/superheros/index.html -->
    <h1 data-bind='"Superhero" | pluralize heroCount'></h1>

    <div data-foreach-superhero='superheros'>
      <h2 data-bind='superhero.name'></h2>
      <span data-showif='superhero.wears_cape'>
        (Wears a Cape)
      </span>
      <a data-event-click='removeHero | withArguments superhero'>
        Remove this superhero
      </a>
    </div>

    <a data-route='routes.superheros.new'>Add a Superhero</a>
# views/superheros/superheros_index_view.coffee
    class Gotham.SuperherosIndexView extends Batman.View
      @accessor 'heroCount', ->
        Gotham.Superhero.get('all.length')

      removeHero: (superhero) ->
        superhero.destroy()

Views

The view layer includes two parts: HTML templates and views.

HTML Templates

Templates connect your app the DOM with data bindings. Batman.js maintains bindings, so the DOM and your app are always in sync.

Views

Views provide context to HTML templates by defining:

You can also hook into the view lifecycle to setup, teardown and transition your views.

Batman Rdio

The demo app from the live tutorial on this site. Live example and source code.

TodoMVC

A great place to get started with batman.js. Live example and source code.

Batman.js MVC Cookbook

Quick how-tos for common patterns in a batman.js app. Read Online.

Additional resources:

Mailing List

For the sake of asynchronous communication, most discussion and announcements about batman.js will take place via the mailing list, hosted on Google Groups.

Source

batman.js is released as open source software under the MIT license. We invite you to download, modify, and use the code. If you do anything you think other people would find useful, we love pull requests!

Issues

Found a bug or other nasty in batman.js? It's still new, so it's bound to happen! We use GitHub's issue tracker to manage our issues.