Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
86 lines (76 sloc) 2.46 KB
title slug category tags
Easily export Backbone-relational models
web, backbonejs, coffeescript

To export a Backbone-relational model we can extend the original Backbone-relational model with three attributes and an export method.

tl;dr, coffee version:

Backbone.ExportableModel = Backbone.RelationalModel.extend
  exportAttributes: []
  exportChildren: []
  exportSiblings: [] 
  export: ->
    data = {}
    if @exportAttributes.length
      data = @pick.apply @, @exportAttributes
    if @exportSiblings.length
      for sibling in @exportSiblings
        data[sibling] = @get(sibling).export() if @get(sibling)?
    if @exportChildren.length
      for child in @exportChildren
        data[child] = @get(child).invoke 'export'

Such a model will have an export() method, which will gather all exportAttributes values, go through exportChildren (aka has-many) and exportSiblings (aka has-one) relations and call the export() method on them. That produces a nice structured JSON as result.

For an example of such a model:

@App.M.FieldInstance = Backbone.ExportableModel.extend
  defaults: {}
  relations: [
      type: Backbone.HasOne
      key: 'fieldInstanceImage'
      relatedModel: 'App.M.FieldInstanceImage'
        includeInJSON: false
        type: Backbone.HasOne
        key: 'fieldInstance'
  exportAttributes: ['type', 'width', 'height', 'x', 'y', 'points']
  exportSiblings: ['fieldInstanceImage']

To end with, I've included the compiled js version for non-coffee folk:

Backbone.ExportableModel = Backbone.RelationalModel.extend({
  exportAttributes: [],
  exportChildren: [],
  exportSiblings: [],
  "export": function() {
    var child, data, sibling, _i, _j, _len, _len1, _ref, _ref1;

    data = {};
    if (this.exportAttributes.length) {
      data = this.pick.apply(this, this.exportAttributes);
    if (this.exportSiblings.length) {
      _ref = this.exportSiblings;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        sibling = _ref[_i];
        if (this.get(sibling) != null) {
          data[sibling] = this.get(sibling)["export"]();
    if (this.exportChildren.length) {
      _ref1 = this.exportChildren;
      for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
        child = _ref1[_j];
        data[child] = this.get(child).invoke('export');
    return data;