App Events

This example demonstrates how Giraffe.App helps your objects communicate. We'll create an instance of Giraffe.App with three child views that talk to each other using the app as an event aggregator.

var App = Giraffe.App.extend({
  afterRender: function() {
    this.attach(new ChildView({color: '#e99', text: 'red'}));
    this.attach(new ChildView({color: '#9e9', text: 'green'}));
    this.attach(new ChildView({color: '#99e', text: 'blue'}));
  }
});
All Giraffe objects extend their instances with everything in options. This allows for full customization of behavior for every instance. In this example, color and text are available directly on each view.

This example has a ChildView class with a particular color and a button. When the button is clicked, it sends a message to all other child views via appEvents to color them its color.

var ChildView = Giraffe.View.extend({
  className: 'child-view',
  template: '#child-template',
  initialize: function() {
    this.$el.css('background-color', this.color);
  },

Here's the ChildView template with the button. The default serialize function passes the view to the template.

<script id="child-template" type="text/template">
  <button>Color the views <%= text %>!</button>
</script>
These examples use Giraffe's templating default, Underscore templates, but Giraffe supports any form of templating. See the Template Strategies example for more.

The appEvents hash is a convenient feature that helps your app's objects communicate. It's similar to the Backbone.View events hash, but instead of mapping DOM events it maps events on an instance of Giraffe.App. If a Giraffe.App has been created, appEvents is automatically bound for all Giraffe objects (views, apps, routers, models, and collections), and is cleaned up via Backbone.Events.stopListening in dispose, which all Giraffe objects implement. When an instance of Giraffe.App is created, it stores its reference globally at Giraffe.app unless an app instance is already there, and all Giraffe objects store this reference as this.app unless you pass {app: someApp} as an option.

  appEvents: {
    'setColor': function(color) { this.$el.css('background-color', color); }
    //'someOtherAppEvent': 'someFunctionName'
  },

Clicking the view's button calls the colorChildViews method. By triggering an event on this.app, all views listening to appEvents will hear it.

  events: {
    'click button': 'colorChildViews'
  },
  colorChildViews: function() {
    this.app.trigger('setColor', this.color);
  }
});

Like all Giraffe objects, Giraffe.App can listen to its own appEvents. To help us see what's going on, let's log every event that passes through the app to the console.

App.prototype.appEvents = {
  'all': function() { console.log('app event', arguments); }
};

That's it! Let's create and attach the app.

var app = new App();
app.attachTo('body');

Try It

var App = Giraffe.App.extend({
  afterRender: function() {
    this.attach(new ChildView({
      color: '#e99',
      text: 'red'
    }));
    this.attach(new ChildView({
      color: '#9e9',
      text: 'green'
    }));
    this.attach(new ChildView({
      color: '#99e',
      text: 'blue'
    }));
  }
});

var ChildView = Giraffe.View.extend({
  className: 'child-view',
  template: '#child-template',
  initialize: function() {
    this.$el.css('background-color', this.color);
  },

  appEvents: {
    'setColor': function(color) {
      this.$el.css('background-color', color);
    }
    //'someOtherAppEvent': 'someFunctionName'
  },

  events: {
    'click button': 'colorChildViews'
  },
  colorChildViews: function() {
    this.app.trigger('setColor', this.color);
  }
});

App.prototype.appEvents = {
  'all': function() {
    console.log('app event', arguments);
  }
};

var app = new App();
app.attachTo('body');
<!DOCTYPE html>
<html>
  <head>
    <link rel='stylesheet' type='text/css' href='../css/reset.css' />
    <link rel='stylesheet' type='text/css' href='appevents0-style.css' />
  </head>
  <body>
    <script id="child-template" type="text/template">
  <button>Color the views <%= text %>!</button>
</script>

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script src="../backbone.giraffe.js" type="text/javascript"></script>
    <script type='text/javascript' src='appevents0-script.js'></script>
  </body>
</html>
.child-view {
  position: relative;
  padding: 20px;
  margin: 20px;
  border: 1px dashed #999;
}