View Basics

Creating and Attaching a View

This example demonstrates the basic usage of Giraffe.View. It can be extended just like a Backbone.View.

var MyView = Giraffe.View.extend({
  template: '#my-template',
  serialize: function() {
    return {name: 'my view'};
  }
});

Giraffe implements render so it can do some useful things, and by default render expects a view's template to be the DOM selector of an Underscore template. This can be easily configured to support any form of string templating. For more information, see template, setTemplateStrategy, and templateStrategy in the API docs or the Template Strategies example. The included strategies use a view's serialize function to get the data passed into the template.

<script id="my-template" type="text/template">
  Hello <%= name %>!
</script>

Giraffe uses the function attachTo to put views into the DOM or inside one another. If a view has not yet been rendered, attachTo will call render on it.

var myView = new MyView();
myView.attachTo('body');

Here's the result:

var MyView = Giraffe.View.extend({
  template: '#my-template',
  serialize: function() {
    return {
      name: 'my view'
    };
  }
});

var myView = new MyView();
myView.attachTo('body');
<!DOCTYPE html>
<html>
  <head>
    <link rel='stylesheet' type='text/css' href='../css/reset.css' />
    
  </head>
  <body>
    <script id="my-template" type="text/template">
  Hello <%= name %>!
</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='viewbasics0-script.js'></script>
  </body>
</html>

Creating Child Views

This example demonstrates how the attachTo function automatically sets up parent-child relationships between views.

Giraffe calls the functions beforeRender and afterRender every time a view renders. These are empty functions for your views to fill in. afterRender is a good place to create and attach child views.

var ParentView = Giraffe.View.extend({
  template: '#parent-template',
  afterRender: function() {
    var childView = new ChildView({name: 'child view'});
    childView.attachTo(this);
    // or
    // this.attach(childView);
  }
});
<script id="parent-template" type="text/template">
  parent view
</script>

The ChildView will be put inside the ParentView.

var ChildView = Giraffe.View.extend({
  template: '#child-template'
});

The ChildView simply displays the name provided in its options. We aren't defining a serialize method on the ChildView, and by default, serialize passes the view to the template function.

<script id="child-template" type="text/template">
  <%= name %>
</script>

Let's create and attach the parent view.

var parentView = new ParentView();
parentView.attachTo('body');

Now is a good time to inspect the views to see what the child-parent relationship looks like. The parent has an array of children and the children have a reference to their parent.

var childView = parentView.children[0];
console.log(parentView === childView.parent); // => true

Let's create a second child view. The method option of attachTo is the jQuery method used to insert the view. The default is 'append'. In this case we'll use 'before' to put it before the first child view we created. See attachTo in the API docs for more.

var childView2 = new ChildView({name: 'child view attached with {method: "before"}'});
childView2.attachTo(childView, {method: 'before'});

The parent of childView2 is the parentView.

console.log(childView2.parent === parentView); // => true

Here's the result:

var ParentView = Giraffe.View.extend({
  template: '#parent-template',
  afterRender: function() {
    var childView = new ChildView({
      name: 'child view'
    });
    childView.attachTo(this);
    // or
    // this.attach(childView);
  }
});

var ChildView = Giraffe.View.extend({
  template: '#child-template'
});

var parentView = new ParentView();
parentView.attachTo('body');

var childView = parentView.children[0];
console.log(parentView === childView.parent); // => true

var childView2 = new ChildView({
  name: 'child view attached with {method: "before"}'
});
childView2.attachTo(childView, {
  method: 'before'
});

console.log(childView2.parent === parentView); // => true
<!DOCTYPE html>
<html>
  <head>
    <link rel='stylesheet' type='text/css' href='../css/reset.css' />
    <link rel='stylesheet' type='text/css' href='viewbasics1-style.css' />
  </head>
  <body>
    <script id="parent-template" type="text/template">
  parent view
</script>

<script id="child-template" type="text/template">
  <%= name %>
</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='viewbasics1-script.js'></script>
  </body>
</html>
[data-view-cid] {
  position: relative;
  padding: 20px;
  margin: 20px;
  border: 1px dashed #999;
}

attachTo Sequence Diagram

MyViewGiraffe.ViewParentViewDOMattachTo #containeralt[if #container has parent view]set MyView as child of parentdetach MyView's $elalt[if method is 'html']detach views inside #containerput MyView's $el in #container using methodalt[if MyView not yet rendered or options.forceRender]alt[if beforeRender overridden]beforeRender()$el.empty()templateStrategy()return html stringappend html string to $elalt[if afterRender overridden]afterRender()