Viewnew Giraffe.View([options])

Giraffe.View is optimized for simplicity and flexibility. Views can move around the DOM safely and freely with the attachTo method, which accepts any selector, DOM element, or view, as well as an optional jQuery insertion method like 'prepend', 'after', or 'html'. The default is 'append'.

var parentView = new Giraffe.View();
parentView.attachTo('body', {method: 'prepend'});
$('body').find(parentView.$el).length; // => 1

The attachTo method automatically sets up parent-child relationships between views via the references children and parent to allow nesting with no extra work.

var childView = new Giraffe.View();
childView.attachTo(parentView); // or `parentView.attach(childView);`
childView.parent === parentView; // => true
parentView.children[0] === childView; // => true

Views automatically manage the lifecycle of all children, and any object with a dispose method can be added to children via addChild. When a view is disposed, it disposes of all of its children, allowing the disposal of an entire application with a single method call.

parentView.dispose(); // disposes both `parentView` and `childView`

When a view is attached, render is called if it has not yet been rendered. When a view renders, it first calls detach on all of its children, and when a view is detached, the default behavior is to call dispose on it. To overried this behavior and cache a view even when its parent renders, you can set the cached view's disposeOnDetach property to false.

var parentView = new Giraffe.View();
parentView.attach(new Giraffe.View());
parentView.attach(new Giraffe.View({disposeOnDetach: false}));
parentView.attachTo('body'); // render() is called, disposes of the first view
parentView.children.length; // => 1

Views are not automatically reattached after render, so you retain control, but their parent-child relationships stay intact unless they're disposed. See Giraffe.View#afterRender for more.

Giraffe.View gets much of its smarts by way of the data-view-cid attribute attached to view.$el. This attribute allows us to find a view's parent when attached to a DOM element and safely detach views when they would otherwise be clobbered.

Currently, Giraffe has only one class that extends Giraffe.View, Giraffe.App, which encapsulates app-wide messaging and routing.

Like all Giraffe objects, Giraffe.View extends each instance with every property in options.

childrenview.children

When one view is attached to another, the child view is added to the parent's children array. When dispose is called on a view, it disposes of all children, enabling the teardown of a single view or an entire app with one method call. Any object with a dispose method can be added to a view's children via addChild to take advantage of lifecycle management.

parentview.parent

Child views attached via attachTo have a reference to their parent view.

attachToview.attachTo(el, [options])

Attaches this view to el, which can be a selector, DOM element, or view. If el is inside another view, a parent-child relationship is set up. options.method is the jQuery method used to attach the view. It defaults to 'append' and also accepts 'prepend', 'after', 'before', and 'html'. If the view has not yet been rendered when attached, render is called. This render behavior can be overridden via options.forceRender and options.suppressRender. See the View Basics example for more. Triggers attaching and attached events.

attachparentView.attach(childView, [options])

attach is an inverted way to call attachTo. Unlike attachTo, calling this function requires a parent view. It's here only for aesthetics. Takes the same options as attachTo in addition to the optional options.el, which is the first argument passed to attachTo, defaulting to the parent view.

renderDo not override unless you know what you're doing!

Giraffe implements render so it can do some helpful things, but you can still call it like you normally would. By default, render uses a view's template, which is the DOM selector of an Underscore template, but this is easily configured. See Giraffe.View#template, Giraffe.View.setTemplateStrategy, and Giraffe.View#templateStrategy for more.

beforeRenderImplement this function as needed in your views.

This is an empty function hook for you to implement. Less commonly used than afterRender, but helpful in circumstances where the DOM has state that needs to be preserved across renders. For example, if a view with a dropdown menu is rendering, you may want to save its open state in beforeRender and reapply it in afterRender.

afterRenderImplement this function as needed in your views.

This is an empty function hook for you to implement. After a view renders, afterRender is called. Child views are normally created and attached to the DOM here. Views that are cached by setting disposeOnDetach to false will be in view.children in afterRender, but will not be attached to the parent's $el.

templateStrategyview.templateStrategy()

Giraffe implements its own render function which calls templateStrategy to get the HTML string to put inside view.$el. Your views can either define a template, which uses Underscore templates by default and is customizable via Giraffe.View#setTemplateStrategy, or override templateStrategy with a function returning a string of HTML from your favorite templating engine. See the Template Strategies example for more.

templateview.template

Consumed by the templateStrategy function created by Giraffe.View#setTemplateStrategy. By default, template is the DOM selector of an Underscore template. See the Template Strategies example for more.

// the default `templateStrategy` is 'underscore-template-selector'
view.template = '#my-template-selector';
// or
Giraffe.View.setTemplateStrategy('underscore-template');
view.template = '<div>hello <%= name %></div>';
// or
Giraffe.View.setTemplateStrategy('jst');
view.template = function(data) { return '<div>hello' + data.name + '</div>'};

serializeOverride this function to pass custom data to a view's `template`.

Gets the data passed to the template. Returns the view by default.

detachview.detach([preserve])

Detaches the view from the DOM. If view.disposeOnDetach is true, which is the default, dispose will be called on the view and its children unless the argument preserve is true. When a view renders, it first calls detach(false) on the views inside its $el.

detachChildrenview.detachChildren([preserve])

Calls detach on each object in children, passing preserve through.

addChildview.addChild(child)

Adds child to this view's children and assigns this view as child.parent. If child implements dispose, it will be called when the view is disposed. If child implements detach, it will be called before the view renders.

addChildrenview.addChildren(children)

Calls addChild on the given array of objects.

removeChildview.removeChild(child, [preserve])

Removes an object from this view's children. If preserve is false, the default, Giraffe will attempt to call dispose on the child. If preserve is true, Giraffe will attempt to call detach(true) on the child.

removeChildrenview.removeChildren([preserve])

Calls removeChild on all children, passing preserve through.

setParentview.setParent([parent])

Sets a new parent for a view, first removing any current parent-child relationship. parent can be falsy to remove the current parent.

isAttachedview.isAttached([el])

If el is null or undefined, tests if the view is somewhere on the DOM by calling $document.find(view.$el). If el is a view, tests if el contains this view. Otherwise, tests if el is the immediate parent of view.$el.

uiview.ui

ui is an optional view property that helps DRY up DOM references in views. It provides a convenient way to cache jQuery objects after every render, and the names given to these objects can be used in Backbone.View#events. Declaring this.ui = {$button: '#button'} in a view makes this.$button always available once render has been called. Typically the ui value is a string which is then searched for inside this.$el, but if it's a function, its return value will be assigned. If it's neither a string nor a function, the value itself is assigned.

Giraffe.View.extend({
  ui: {
    $someButton: '#some-button-selector'
  },
  afterRender: {
    this.$someButton; // just got cached
  },
  events: {
    '#click $someButton': 'onClickSomeButton' // ui names work here
  }
});

dataEventsview.dataEvents

Inspired by Backbone.View#events, dataEvents binds a space-separated list of events ending with the target object to methods on a view. It is a shorthand way of calling view.listenTo(targetObj, event, cb). In this example collection is used, but any object on the view that implements Backbone.Events is a valid target object. To have a view listen to itself, the keywords 'this' and '@' can be used.

Giraffe.View.extend({
  dataEvents: {
    'add remove change collection': 'render',
    'event anotherEvent targetObj': function() {},
    'eventOnThisView @': 'methodName'
  }
});

As a result of using listenTo, dataEvents accepts multiple events per definition, handlers are called in the context of the view, and bindings are cleaned up in dispose via stopListening.

There are some unfortunate restrictions to dataEvents. Objects created after initialize will not be bound to, and events fired during the constructor and initialize will not be heard. We advocate using Backbone.Events#listenTo directly in these circumstances.

See the Data Events example for more.

invokeview.invoke(methodName, [args...])

Calls methodName on the view, or if not found, up the view hierarchy until it either finds the method or fails on a view without a parent. Used by Giraffe to call the methods defined for the events bound in Giraffe.View.setDocumentEvents.

appEventsview.appEvents

See Giraffe.App#appEvents.

_disposeview._dispose()

Destroys a view, unbinding its events and freeing its resources. Calls Backbone.View#remove and calls dispose on all children.

beforeDisposeImplement this function as needed in your Giraffe and `Giraffe.configure`d objects.

This is an empty function hook for you to implement.

afterDisposeImplement this function as needed in your Giraffe and `Giraffe.configure`d objects.

This is an empty function hook for you to implement.

beforeInitializeImplement this function as needed in your Giraffe and `Giraffe.configure`d objects.

This is an empty function hook for you to implement.

afterInitializeImplement this function as needed in your Giraffe and `Giraffe.configure`d objects.

This is an empty function hook for you to implement.

detachByElGiraffe.View.detachByEl(el, [preserve])

Detaches the top-level views inside el, which can be a selector, element, or Giraffe.View. Used internally by Giraffe to remove views that would otherwise be clobbered when the option method: 'html' is used in attachTo. Uses the data-view-cid attribute to match DOM nodes to view instances.

getClosestViewGiraffe.View.getClosestView(el)

Gets the closest parent view of el, which can be a selector, element, or Giraffe.View. Uses the data-view-cid attribute to match DOM nodes to view instances.

getByCidGiraffe.View.getByCid(cid)

Looks up a view from the cache by cid, returning undefined if not found.

to$ElGiraffe.View.to$El(el, [parent], [allowParentMatch])

Gets a jQuery object from el, which can be a selector, element, jQuery object, or Giraffe.View, scoped by an optional parent, which has the same available types as el. If the third parameter is truthy, el can be the same element as parent.

setDocumentEventsGiraffe.View.setDocumentEvents(events)

Giraffe provides a convenient high-performance way to declare view method calls in your HTML markup. Using the form data-gf-eventName='methodName', when a bound DOM event is triggered, Giraffe looks for the defined method on the element's view. For example, putting data-gf-click='onSubmitForm' on a button calls the method onSubmitForm on its view on 'click'. If the view does not define the method, Giraffe searches up the view hierarchy until it finds it or runs out of views. By default, only the click and change events are bound by Giraffe, but setDocumentEvents allows you to set a custom list of events, first unbinding the existing ones and then setting the ones you give it, if any.

Giraffe.View.setDocumentEvents(['click', 'change']); // default
// or
Giraffe.View.setDocumentEvents(['click', 'change', 'keydown']);
// or
Giraffe.View.setDocumentEvents('click change keydown keyup');

removeDocumentEventsGiraffe.View.removeDocumentEvents()

Equivalent to Giraffe.View.setDocumentEvents(null).

setDocumentEventPrefixGiraffe.View.setDocumentEventPrefix(prefix)

Sets the prefix for document events. Defaults to data-gf-, so to bind to 'click' events, one would put the data-gf-click attribute on DOM elements with the name of a view method as the value.

setTemplateStrategyGiraffe.View.setTemplateStrategy(strategy)

Giraffe provides common strategies for templating.

The strategy argument can be a function returning an HTML string or one of the following:

  • 'underscore-template-selector'

    • view.template is a string or function returning DOM selector
  • 'underscore-template'

    • view.template is a string or function returning underscore template
  • 'jst'

    • view.template is an html string or a JST function

See the Template Strategies example for more.

Appnew Giraffe.App([options])

Giraffe.App is a special Giraffe.View that provides encapsulation for an entire application. Like all Giraffe views, the app has lifecycle management for all children, so calling dispose on an app will call dispose on all children that have the method. The first Giraffe.App created on a page is available globally at Giraffe.app, and by default all Giraffe objects reference this app as this.app unless they're passed a different app in options.app. This app reference is used to bind appEvents, a hash that all Giraffe objects can implement which uses the app as an event aggregator for communication and routing.

var myApp = new Giraffe.App();
window.Giraffe.app; // => `myApp`
myApp.attach(new Giraffe.View({
  appEvents: {
    'say:hello': function() { console.log('hello world'); }
  },
  // app: someOtherApp // if you don't want to use `window.Giraffe.app`
}));
myApp.trigger('say:hello'); // => 'hello world'

appEvents are also used by the Giraffe.Router. See Giraffe.App#routes for more.

The app also provides synchronous and asynchronous initializers with addInitializer and start.

Like all Giraffe objects, Giraffe.App extends each instance with every property in options.

appEventsapp.appEvents

Similar to the events hash of Backbone.View, appEvents maps events on this.app to methods on a Giraffe object. App events can be triggered from routes or by any object in your application. If a Giraffe.App has been created, every Giraffe object has a reference to the global Giraffe.app instance at this.app, and a specific app instance can be set by passing options.app to the object's constructor. This instance of this.app is used to bind appEvents, and these bindings are automatically cleaned up when an object is disposed.

// in a Giraffe object
this.appEvents = {'some:appEvent': 'someMethod'};
this.app.trigger('some:appEvent', params) // => this.someMethod(params)

routesapp.routes

If routes is defined on a Giraffe.App or passed to its constructor as an option, the app will create an instance of Giraffe.Router as this.router and set the router's triggers to the app's routes. Any number of routers can be instantiated manually, but they do require that an instance of Giraffe.App is first created, because they use appEvents for route handling. See Giraffe.Router#triggers for more.

var app = new Giraffe.App({routes: {'route': 'appEvent'}});
app.router; // => instance of Giraffe.Router
// or
var MyApp = Giraffe.App.extend({routes: {'route': 'appEvent'}});
var myApp = new MyApp();
myApp.router; // => instance of Giraffe.Router

addInitializerapp.addInitializer(fn)

Queues up the provided function to be run on start. The functions you provide are called with the same options object passed to start. If the provided function has two arguments, the options and a callback, the app's initialization will wait until you call the callback. If the callback is called with a truthy first argument, an error will be logged and initialization will halt. If the app has already started when you call addInitializer, the function is called immediately.

app.addInitializer(function(options) {
    doSyncStuff();
});
app.addInitializer(function(options, cb) {
    doAsyncStuff(cb);
});
app.start();

startapp.start([options])

Starts the app by executing each initializer in the order it was added, passing options through the initializer queue. Triggers the appEvents 'app:initializing' and 'app:initialized'.

Routernew Giraffe.Router([options])

The Giraffe.Router integrates with a Giraffe.App to decouple your router and route handlers and to provide programmatic encapsulation for your routes. Routes trigger appEvents on the router's instance of Giraffe.App. All Giraffe objects implement the appEvents hash as a shortcut. Giraffe.Router#cause triggers an app event and navigates to its route if one exists in Giraffe.Router#triggers, and you can ask the router if a given app event is currently caused via Giraffe.Router#isCaused. Additionally, rather than building anchor links and window locations manually, you can build routes from app events and optional parameters with Giraffe.Router#getRoute.

var myApp = new Giraffe.App;
var myRouter = Giraffe.Router.extend({
  triggers: {
    'post/:id': 'route:post'
  }
});
myRouter.app === myApp; // => true
myRouter.cause('route:post', 42); // goes to `#post/42` and triggers 'route:post' on `myApp`
myRouter.isCaused('route:post', 42); // => true
myRouter.getRoute('route:post', 42); // => '#post/42'

The Giraffe.Router requires that a Giraffe.App has been created on the page so it can trigger events for your objects to listen to. For convenience, if a Giraffe.App is created with a routes hash, it will automatically instantiate a router and set its triggers equal to the app's routes.

var myApp = Giraffe.App.extend({
  routes: {'my/route': 'app:event'}
});
myApp.router.triggers; // => {'my/route': 'app:event'}

Like all Giraffe objects, Giraffe.Router extends each instance with every property in options.

triggersrouter.triggers

The Giraffe.Router triggers hash is similar Backbone.Router#routes, but instead of route: method the Giraffe.Router expects route: appEvent. Backbone.Router#routes is used internally, which is why Giraffe.Router#triggers is renamed. The router also has a redirect feature as demonstrated below.

triggers: {
  'some/route/:andItsParams': 'some:appEvent', // triggers 'some:appEvent' on this.app
  'some/other/route': '-> some/redirect/route' // redirect
}

causerouter.cause(appEvent, [any])

If this.triggers has a route that maps to appEvent, the router navigates to the route, triggering the appEvent. If no such matching route exists, cause acts as an alias for this.app.trigger.

isCausedrouter.isCaused(appEvent, [any])

Returns true if the current window.location matches the route that the given app event and optional arguments map to in this router's triggers.

getRouterouter.getRoute(appEvent, [any])

Converts an app event and optional arguments into a url mapped in this.triggers. Useful to build links to the routes in your app without manually manipulating route strings.

reloadrouter.reload([url])

Performs a page refresh. If url is defined, the router first silently navigates to it before refeshing.

appEventsrouter.appEvents

See Giraffe.App#appEvents.

_disposerouter._dispose()

Removes registered callbacks.

Modelnew Giraffe.Model([attributes], [options])

Giraffe.Model and Giraffe.Collection are thin wrappers that add lifecycle management and appEvents support. To add lifecycle management to an arbitrary object, simply give it a dispose method and add it to a view via addChild. To use this functionality in your own objects, see Giraffe.dispose and Giraffe.bindEventMap.

Like all Giraffe objects, Giraffe.Model and Giraffe.Collection extend each instance with every property in options except parse which is problematic per issue 7.

appEventsmodel.appEvents

See Giraffe.App#appEvents.

_disposemodel._dispose()

Removes event listeners and removes this model from its collection.

Collectionnew Giraffe.Collection([models], [options])

See Giraffe.Model.

appEventscollection.appEvents

See Giraffe.App#appEvents.

_disposecollection._dispose()

Removes event listeners and disposes of all models, which removes them from the collection.

configureGiraffe.configure(obj, [opts])

Initializes an object with several generic features. All Giraffe objects call this function in their constructors to gain much of their functionality. Uses duck typing to initialize features when dependencies are met.

Features:

  • -pulls option defaults from the global Giraffe.defaultOptions, the static obj.constructor.defaultOptions, and the instance/prototype obj.defaultOptions
  • -extends the object with all options minus omittedOptions (omits all if true)
  • -defaults obj.dispose to Giraffe.dispose
  • -defaults obj.app to Giraffe.app
  • -binds appEvents if appEvents and app are defined and obj extends Backbone.Events
  • -binds dataEvents if dataEvents is defined and obj extends Backbone.Events
  • -wraps initialize with beforeInitialize and afterInitialize if it exists

defaultOptionsGiraffe.defaultOptions

The global defaults extended to every object passed to Giraffe.configure. Empty by default. Setting omittedOptions here globally prevents those properties from being copied over, and if its value is true extension is completely disabled.

function Foo() {
  Giraffe.configure(this);
};
Giraffe.defaultOptions = {bar: 'global'};
var foo = new Foo();
foo.bar; // => 'global'

You can also define defaultOptions on a function constructor. These override the global defaults.

Foo.defaultOptions = {bar: 'constructor'};
foo = new Foo();
foo.bar; // => 'constructor'

The instance/prototype defaults take even higher precedence:

Foo.prototype.defaultOptions = {bar: 'instance/prototype'};
foo = new Foo();
foo.bar; // => 'instance/prototype'

Options passed as arguments always override defaultOptions.

foo = new Foo({bar: 'option'});
foo.bar; // => 'option'

Be aware that the values of all defaultOptions are not cloned when copied over.

disposeGiraffe.dispose([args...])

Disposes of an object, removing event listeners and freeing resources. An instance method of dispose is added for all objects passed through Giraffe.configure, and so you will normally call dispose directly on your objects.

Calls Backbone.Events#stopListening and sets obj.app to null. Also triggers the 'disposing' and 'disposed' events and calls the beforeDispose and afterDispose hooks on obj before and after the disposal. Takes optional args that are passed through to the events and the function calls.

bindAppEventsGiraffe.bindAppEvents()

Attempts to bind appEvents for an object. Called by Giraffe.configure.

bindDataEventsGiraffe.bindDataEvents()

Binds the dataEvents hash that allows any instance property of obj to be bound to easily. Expects the form {'event1 event2 targetObj': 'handler'}. Called by Giraffe.configure.

bindEventGiraffe.bindEvent(contextObj, targetObj, eventName, cb)

Uses Backbone.Events.listenTo to make contextObj listen for eventName on targetObj with the callback cb, which can be a function or the string name of a method on contextObj.

unbindEventGiraffe.unbindEvent(contextObj, targetObj, eventName, cb)

The stopListening equivalent of bindEvent.

bindEventMapGiraffe.bindEventMap(contextObj, targetObj, eventMap)

Makes contextObj listen to targetObj for the events of eventMap in the form eventName: method, where method is a function or the name of a function on contextObj.

Giraffe.bindEventMap(this, this.app, this.appEvents);

unbindEventMapGiraffe.unbindEventMap(contextObj, targetObj, eventMap)

The stopListening equivalent of bindEventMap.

wrapFnGiraffe.wrapFn(obj, fnName, [beforeFn], [afterFn])

Wraps obj[fnName] with beforeFnName and afterFnName invocations. Also calls the optional arguments beforeFn and afterFn.