Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>We didn't want to add another framework to achieve that so we abstracted it away in a base model class. Here's how you declare and use it (<a href="https://gist.github.com/gaearon/6689379#file-basemodel-js" rel="nofollow">available as a gist</a>):</p> <pre><code>// Declaration window.app.viewer.Model.GallerySection = window.app.Model.BaseModel.extend({ nestedTypes: { background: window.app.viewer.Model.Image, images: window.app.viewer.Collection.MediaCollection } }); // Usage var gallery = new window.app.viewer.Model.GallerySection({ background: { url: 'http://example.com/example.jpg' }, images: [ { url: 'http://example.com/1.jpg' }, { url: 'http://example.com/2.jpg' }, { url: 'http://example.com/3.jpg' } ], title: 'Wow' }); // (fetch will work equally well) console.log(gallery.get('background')); // window.app.viewer.Model.Image console.log(gallery.get('images')); // window.app.viewer.Collection.MediaCollection console.log(gallery.get('title')); // plain string </code></pre> <p>It works equally well with <code>set</code> and <code>toJSON</code>.<br> And here's <code>BaseModel</code>:</p> <pre><code>window.app.Model.BaseModel = Backbone.Model.extend({ constructor: function () { if (this.nestedTypes) { this.checkNestedTypes(); } Backbone.Model.apply(this, arguments); }, set: function (key, val, options) { var attrs; /* jshint -W116 */ /* jshint -W030 */ // Code below taken from Backbone 1.0 to allow different parameter styles if (key == null) return this; if (typeof key === 'object') { attrs = key; options = val; } else { (attrs = {})[key] = val; } options || (options = {}); // Code above taken from Backbone 1.0 to allow different parameter styles /* jshint +W116 */ /* jshint +W030 */ // What we're trying to do here is to instantiate Backbone models and collections // with types defined in this.nestedTypes, and use them instead of plain objects in attrs. if (this.nestedTypes) { attrs = this.mapAttributes(attrs, this.deserializeAttribute); } return Backbone.Model.prototype.set.call(this, attrs, options); }, toJSON: function () { var json = Backbone.Model.prototype.toJSON.apply(this, arguments); if (this.nestedTypes) { json = this.mapAttributes(json, this.serializeAttribute); } return json; }, mapAttributes: function (attrs, transform) { transform = _.bind(transform, this); var result = {}; _.each(attrs, function (val, key) { result[key] = transform(val, key); }, this); return result; }, serializeAttribute: function (val, key) { var NestedType = this.nestedTypes[key]; if (!NestedType) { return val; } if (_.isNull(val) || _.isUndefined(val)) { return val; } return val.toJSON(); }, deserializeAttribute: function (val, key) { var NestedType = this.nestedTypes[key]; if (!NestedType) { return val; } var isCollection = this.isTypeASubtypeOf(NestedType, Backbone.Collection), child; if (val instanceof Backbone.Model || val instanceof Backbone.Collection) { child = val; } else if (!isCollection &amp;&amp; (_.isNull(val) || _.isUndefined(val))) { child = null; } else { child = new NestedType(val); } var prevChild = this.get(key); // Return existing model if it is equal to child's attributes if (!isCollection &amp;&amp; child &amp;&amp; prevChild &amp;&amp; _.isEqual(prevChild.attributes, child.attributes)) { return prevChild; } return child; }, isTypeASubtypeOf: function (DerivedType, BaseType) { // Go up the tree, using Backbone's __super__. // This is not exactly encouraged by the docs, but I found no other way. if (_.isUndefined(DerivedType['__super__'])) { return false; } var ParentType = DerivedType['__super__'].constructor; if (ParentType === BaseType) { return true; } return this.isTypeASubtypeOf(ParentType, BaseType); }, checkNestedTypes: function () { _.each(this.nestedTypes, function (val, key) { if (!_.isFunction(val)) { console.log('Not a function:', val); throw new Error('Invalid nestedTypes declaration for key ' + key + ': expected a function'); } }); }, } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload