riblet

0.0.9 • Public • Published

What

Riblet.js is a lightweight Backbone framework. It is not meant to be a competitor with something like Marionette. It's use case is to round out some of the sharper edges of Backbone such as it's lack of subviews, associations, and a true view lifecycle.

NOTE: This is a developer preview. Not all features in the docs are complete or implemented yet.

API

Riblet.Model

Getters

The Riblet.Model provides a getters. This allows for more advanced gets for certain properties. Getters are especially useful for doing simple associations.

Getters and templating

Getters also work as expected with templates. If you add a fullName getter to the getters hash for example, you could then do {{fullName}} in your template and it'll use the getter lookup to figure it out.

Note, however, that getters can be overridden by templateHelpers which are part of Riblet.View. So, if you had a fullName getter that returned firstName + lastName and then a templateHelper that returned lastName + ', ' + firstName and you had a {{fullName}} tag it'd return Godson, Oscar (templateHelper) instead of Oscar Godson (getter)

Simple Example:

var myModel = Riblet.Model.extend({
  getters: {
    fullName: function () {
      return this.get('firstName') + ' ' this.get('lastName');
    }
  }
});

In your view you can now do:

this.model.get('fullName'); // => Oscar Godson

Advanced Example:

A useful thing with getters is you can overwrite the basic lookups Backbone does with more advanced ones. A common example of this is to do basic associations.

Your group.json:

{
  "id": "3",
  "name": "Widget Group",
  "members": [
    {
      "id": "1",
      "permissions": 0
    }
  ]
}

user.json

{
  "firstName": "Oscar",
  "lastName": "Godson",
  "username": "oscargodson",
  "id": "1"
}

Now you want to get the member's name in a view where the model is set to a Group model.

var myModel = Riblet.Model.extend({
  getters: {
    members: function () {
      var members = this.attributes.members;
      members.forEach(function (member, key) {
        var userModel = app.collection.Users.findWhere({ id: member.id });
        if (userModel) {
          members[key] = _.extend(userModel.attributes, member);
        }
      });
      return members;
    }
  }
});

In your view, instead of members returning an array of just the member's id and permissions you'd get this:

this.model.get('members')[0];
{
  "firstName": "Oscar",
  "lastName": "Godson",
  "username": "oscargodson",
  "id": "1",
  "permissions": 0
}

Riblet.View

Overview

Riblet.View provides basic life cycle, subview, and rendering features. It tries to not be too magical and requires you to be explicit in most cases. For example, while it may handle some of the "magic" in destroying all subviews or rendering from templates using getters and templateHelpers, you need to explicitly attach subviews and tell them where to attach to. You also need tell all views (including subviews) when to render. Nothing is rendered automagically.

The Life Cycle

Whenever you initialize a Riblet.View it sets up a handful of life cycle methods for you to hook into. These are only fired when the corresponding method is fired. In other words, when you initialize a Riblet.View it will only fire beforeInit and afterInit. Riblet does not guess when you want to render or destroy your components. You explicitly tell it to .render() when you want it rendered or .destroy() when you want it destroyed and so on.

The following before and after methods are currently supported and are fired whenever the matching method is called.

  • beforeInit
  • afterInit
  • beforeRender
  • afterRender
  • beforeDestroy
  • afterDestroy
  • beforeAddSubview
  • afterAddSubview
  • beforeDestroySubview
  • afterDestroySubview

initialize()

Riblet.View#initialize does some minor setup for you. You can pass in optional attachTo and attachMethod options and it will take care of caching the selector and then later where and how to render the view.

As a reminder, initialize fires when you initialize a view like var myView = new app.views.MyView();.

Note: As with any Backbone or Riblet method, you can override this, but it's preferable to use beforeInit or, more commonly, afterInit.

Options

  • attachTo - Where to inject the view at using the attachMethod attachment method using a jQuery selector.
  • attachMethod (default: append) - The jQuery method to use to attach the view at the attachTo location. In pseudo code, if you set it to html it'd call $(attachTo).html(templateHtml).
// By default app.views.Foo will always render to #app-container and
// replace all of the innerHTML with this view
app.views.Foo = Riblet.View.extend({
  attachTo: '#app-container',
  attachMethod: 'html'
});
 
// However, you could override this or require you give these options
// during initialization like:
var foo = new app.views.Foo({ attachTo: '#another-part-of-the-app' });

templateHelpers()

templateHelpers allow you to either override data or getters with some other functionality to use specifically for your templates. Say you want to display a formatted date but your model's date property is 1390378558475. Simply create a date templateHelper and do the conversion of that to January 22nd, 2014 in your templateHelper. These are specifically meant for templating and don't affect model data lookups at all like getters do. This makes it nice for defining data presentation logic.

app.views.Foo = Riblet.View.extend({
  templateHelpers: {
    // Uses made up Date methods to give an example...
    time: function () {
      var d = new Date(this.model.get('date'));
      return d.getMonthName() + d.getDayName() + '' + d.getFullYear();
    }
  }
});

templateData()

Overwrite this method if your view doesn't have a model associated with it, or the model data isn't the data you want to use for the view. By default, this method will check for this.model.attributes and if that does not exist it will just return an empty object.

app.views.Foo = Riblet.View.extend({
  fakeData: { foo: 'bar' }
  // Use the fakeData object as the source of data for the view/templates
  templateData: function () {
    return this.fakeData;
  }
});

render()

The .render() method in Riblet does a bunch for you to make rendering easy and more intuitive than pure Backbone. The render process goes like this:

  1. First, as always, it calls beforeRender
  2. It clones the this.templateData() (so it doesn't muck with the model data directly)
  3. Goes through all the getters and applies them to the template data. This will overwrite any model.properties that were being passed in from step 2.
  4. Goes through all the templateHelpers and applies them to the template data. This will overwrite any model.properties or getters that were being passed in from 2 or 3.
  5. It sets the Backbone's this.el / this.$el to the first element in your template rather than creating a new div or forcing you to make one during your view setup like Backbone does normally.
  6. Attaches the rendered template to the location you specified in the attachTo method using the attachMethod given.
  7. Sets the view to rendered
  8. Calls afterRender

Since this method does all of this it's advised you do not overwrite this, however, you can and nothing will break aside from the fact nothing will be rendered.

app.views.Foo = Riblet.View.extend({
  afterInit: function () {
    var bar = new app.views.Bar({ attachTo: '.bar' });
  },
  afterRender: function () {
    bar.render();
  }
});

isRendered()

Returns true if .render() has been called on the view. Returns false if it has not.

app.views.Foo = Riblet.View.extend({
  afterInit: function () {
    var bar = new app.views.Bar({ attachTo: '.bar' });
    // this.isRendered() => false
  },
  afterRender: function () {
    bar.render();
    // this.isRendered() => true
  }
});

destroy()

The .destroy() method will simply call remove on itself. If there are subviews attached to itself, it will call .destroy() on them, which in turn, calls destroy on the subviews' subviews (and so on). It'll call beforeDestroy before anything has happened and afterDestroy after everything is removed from the DOM.

app.views.Foo = Riblet.View.extend({
  events: {
    'click .delete': 'itemDelete' 
  },
  afterInit: function () {
    var bar = new app.views.Bar({ attachTo: '.bar' });
    bar.render();
  },
  itemDelete: function () {
    bar.destroy();
  }
});

Readme

Keywords

none

Package Sidebar

Install

npm i riblet

Weekly Downloads

4

Version

0.0.9

License

MIT

Last publish

Collaborators

  • oscargodson
  • adamisdead