/src/models/sitecollection.js
JavaScript | 197 lines | 114 code | 25 blank | 58 comment | 11 complexity | f575991825566c5a1b895d317cde355e MD5 | raw file
- define([
- 'config!',
- 'underscore',
- 'models/livecollection',
- 'models/sitemodel',
- 'models/thumbnailjobcollection',
- 'lib/translatekeys',
- 'lib/template',
- 'lib/urlhelper'
- ], function(
- config, util, LiveCollection,
- SiteModel, ThumbnailJobCollection,
- translateKeys,
- template,
- URLHelper
- ){
-
- var SiteCollection = LiveCollection.extend({
- model: SiteModel,
- resultAttributeMap: {
- // we want attributes.primaryType to be populated with the value of attributes.type
- 'primaryType': 'type',
- 'url': 'uri',
- 'thumbnailKey': 'thumbnail_key',
- 'thumbnailStatus': 'thumbnail_status'
- },
-
- initialize: function (models, options) {
- // Mix in some default options.
- options = options || {};
-
- // Create a new URL helper with defaults.
- var helper = new URLHelper({
- // Set a default template for URLHelper
- template: '{ base }{ path }{ query }',
- // Configure some default token values for URLHelper
- tokens: {
- base: config.apiRoot,
- path: 'top'
- }
- });
- // Update helper with any config passed in through options.
- helper.update(options.tokens, options.query);
-
- // Point this.url to URLHelper's url method.
- this.url = util.bind(helper.url, helper);
-
- // keep optional mapping of item data property keys to model properties
- if(options.attributeMap){
- this.attributeMap = util.defaults(this.attributeMap || {}, options.attributeMap);
- }
- // Any time a new site collection is fetched, start a new
- // thumbnail job collection for it.
- this.bind('reset', this.startThumbnailJob, this);
- this.bind('add', this.startThumbnailJob, this);
- },
-
- startThumbnailJob: function () {
- var thumbnailJob = this.thumbnailJob;
-
- if (
- // Don't start a job if the ID comes back null
- !this.thumbnailJobID ||
- (
- // Don't start the same job twice.
- thumbnailJob &&
- thumbnailJob.jobID === this.thumbnailJobID
- )
- ) return;
- // Create a new thumbnail job collection. Set the ID of the
- // thumbnail job (which ThumbnailJobCollection turns into a URL).
- var thumbnailJobCollection = new ThumbnailJobCollection({}, {
- jobID: this.thumbnailJobID
- });
- // When the thumbnails job comes back populated, update siteModels
- // in this collection.
- thumbnailJobCollection.bind(
- 'reset',
- this.updateModelsWithThumbnails,
- this
- );
- // Go get 'em tiger.
- thumbnailJobCollection.pollUntilFinishedProcessing();
-
- this.thumbnailJob = thumbnailJobCollection;
- },
-
- updateModelsWithThumbnails: function (thumbnailJobCollection) {
- var siteCollection = this;
- siteCollection.each(function (site) {
- // Get the site's thumbnail key...
- var thumbKey = site.get('thumbnailKey'),
- siteThumbStatus = site.get('thumbnailStatus'),
- siteThumbUrl = site.get('thumbnailUrl'),
- // Get the thumbnail record by its ID (same as thumbnail key)
- thumbModel = thumbnailJobCollection.get(thumbKey),
- thumbStatus = thumbModel ? thumbModel.get('status') : null,
- thumbUrl = thumbModel ? thumbModel.src() : null,
- update = {};
-
- // If status has changed or is new...
- if (siteThumbStatus !== thumbStatus)
- update.thumbnailStatus = thumbStatus;
-
- // If the URL is changed or new...
- if (siteThumbUrl !== thumbUrl)
- update.thumbnailUrl = thumbUrl;
-
- // Update the site with changes. Will fire an event
- // on the site record.
- if (!util.isEmpty(update)) site.set(update);
- });
- },
- // Get the value of an property in an object, optionally using a dot-path (some.deep.object)
- _getObject: function(name, obj){
- // TODO: could be a util/lang helper - not really class or collection-specific
- var parts = name.split('.'),
- pname = null;
-
- while((pname = parts.shift())){
- obj = obj[pname];
- }
- return obj;
- },
- // _setValue: function(name, value, obj) {
- //
- // },
- _applyAttributeMap: function(data, attributeMap){
- // translate data
- // could be a util/lang helper - not really class or collection-specific
- var mapping = attributeMap || this.attributeMap,
- getObject = this._getObject;
- // { 'alias': 'source' }
- util.each(mapping, function(name, alias, map){
- if(name in data) {
- data[alias] = name.indexOf(".") > -1 ?
- getObject(name, data) :
- data[name]
- ;
- // could *replace* by deleting the original key, but we should deep-clone the data at that point
- }
- });
- return data;
- },
- // Backbone.Collection's default parse method passes sync (xhr) results
- // directly to Collection.set. We're defining a custom parse
- // implementation that massages data from our JSON API into
- // a Backbone.Model-compatible format.
- //
- // Sample return data:
- // {
- // "results": [
- // {
- // "sortindex": 10,
- // "title": "Join.me",
- // "uri": "https://join.me/",
- // "thumbnail_key": "...",
- // "thumbnail_status": "processing",
- // "type": "suggestion",
- // "id": "...",
- // "types": ["suggestion"]
- // },
- // ...
- // ],
- // "success": true,
- // "thumbnails_job": "..."
- // }
- parse: function (resp, xhr) {
- // If the API considers this a success (different from HTTP response)...
- this.isSuccess = resp.success;
- this.thumbnailJobID = resp.thumbnails_job;
- // If API success, translate results to new format and
- // pass back. Otherwise, pass empty array.
- if(resp.success) {
- resp = util.map(resp.results, function(result) {
- return this._applyAttributeMap(result, this.resultAttributeMap);
- }, this);
- } else {
- resp = [];
- }
- return resp;
- }
- });
- return SiteCollection;
- });