UNPKG

rendr

Version:

Render your Backbone.js apps on the client and the server.

134 lines (112 loc) 3.14 kB
var _ = require('underscore'), Backbone = require('backbone'), syncer = require('../syncer'), BaseModel = require('./model'), Super = Backbone.Collection, isServer = (typeof window === 'undefined'); if (!isServer) { Backbone.$ = window.$ || require('jquery'); } var BaseCollection = Super.extend({ model: BaseModel, params: undefined, meta: undefined, /** * Provide the ability to set default params for every 'fetch' call. */ defaultParams: null, constructor: function(models, options) { /** * Capture the options as instance variable. */ this.options = options || {}; /** * Store a reference to the app instance. */ this.app = this.options.app; /** * Store a reference to the params that were used to * query for these models. */ this.params = this.options.params || {}; _.defaults(this.params, this.defaultParams || {}); /** * Add 'meta' property to store the parts of the response * that aren't part of the jsonKey. */ this.meta = {}; if (_.isObject(this.options.meta)) { _.extend(this.meta, this.options.meta); delete this.options.meta; } Super.apply(this, arguments); this.store(); }, /** * Make sure that `model.app` is set for all operations like * `this.add()`, `this.reset()`, `this.set()`, `this.push()`, etc. */ _prepareModel: function() { var model; model = Super.prototype._prepareModel.apply(this, arguments); model.app = this.app; return model; }, /** * Idempotent parse */ parse: function(resp, modifyInstance) { var jsonResp, meta, parsed; if (modifyInstance == null) { modifyInstance = true; } if (resp != null && this.jsonKey && (jsonResp = resp[this.jsonKey])) { if (modifyInstance) { meta = _.omit(resp, this.jsonKey); _.extend(this.meta, meta); } parsed = jsonResp; } else { parsed = resp; } return this.parseModels(parsed); }, parseModels: function(resp) { var jsonKey, jsonKeyResp; resp = _.clone(resp); jsonKey = this.model.prototype.jsonKey; _.each(resp, function(modelResp, i) { jsonKeyResp = modelResp[jsonKey]; if (jsonKeyResp) { resp[i] = jsonKeyResp; } }); return resp; }, fetch: function(options) { options = options || {}; // Each time new models are fetched, store the params used. if (options.data) { _.defaults(options.data, this.defaultParams || {}); this.params = options.data; } return Super.prototype.fetch.apply(this, arguments); }, /** * Instance method to store the collection and its models. */ store: function() { if (this.app && this.app.fetcher) { this.each(function(model) { model.store(); }); this.app.fetcher.collectionStore.set(this); } } }); /** * Mix-in the `syncer`, shared between `BaseModel` and `BaseCollection`, which * encapsulates logic for fetching data from the API. */ _.extend(BaseCollection.prototype, syncer); module.exports = BaseCollection;