File: ../src/maps/abstractstrategy.js
define([
'aeris/util',
'aeris/events'
], function(_, Events) {
/**
* A Strategy is created by a MapExtensionObject. It's job is
* to:
* - Render the MapExtObj
* - Listen for changes to a MapExtObj, and render
* those changes.
*
* Strategies may use mapping libraries (eg. gmaps/openlayers)
* to render a MapExtObj. In fact, strategies should be the only
* place in the library where we find direct interactions with
* specific mapping libraries.
*
* @class aeris.maps.AbstractStrategy
* @constructor
*
* @param {aeris.maps.MapObjectInterface} obj
* The aeris object to associate with the map view.
*/
var AbstractStrategy = function(obj) {
/**
* @type {aeris.maps.extensions.MapExtensionObject}
* @protected
* @property object_
*/
this.object_ = obj;
/**
* The map associated with this object
* @type {?google.maps.Map}
* @property mapView_
*/
this.mapView_;
/**
* Evens to bind the map view to the
* object.
*
* Binds object attribute 'change'
* events to strategy methods.
*
* @private
* @property objectEvents_
*/
this.objectEvents_ = _.extend({}, this.objectEvents_, {
'map:set': function(model, map) {
this.setMap(map);
},
'map:remove': this.remove
});
Events.call(this);
/**
* The view instance created by
* the map rendering API.
*
* @type {Object}
* @property view_
*/
this.view_ = this.createView_();
// Bind this.objectEvents to this.object_
this.listenTo(this.object_, this.objectEvents_);
// Set to map, if object has one
if (this.object_.hasMap()) {
this.setMap(this.object_.getMap());
}
};
_.extend(AbstractStrategy.prototype, Events.prototype);
/**
* Render an object on a map.
*
* @param {aeris.maps.Map} aerisMap
* @abstract
* @method setMap
*/
AbstractStrategy.prototype.setMap = function(aerisMap) {
// Remove the object first, if it's already
// set to a map
if (this.mapView_) { this.remove(); }
// Store a reference to the map view
this.mapView_ = aerisMap.getView();
// Child class should do something
// useful here...
};
/**
* Remove the object view from the map view.
* @method remove
*/
AbstractStrategy.prototype.remove = function() {
// If no map exists, nothing to do here.
if (!this.mapView_) { return; }
// Child class should do something
// useful in beforeRemove_
this.beforeRemove_();
// Remove reference to mapview
this.mapView_ = null;
this.afterRemove_();
};
/**
* Destroy the rendered map object view, and cease
* rendering changes to the map object.
*
* @method destroy
*/
AbstractStrategy.prototype.destroy = function() {
this.stopListening();
this.remove();
};
/**
* This method is called before
* our reference to this.mapView_ is set
* to null.
*
* This method must be overridden
* to do the actual work of un-rendering
* the map object.
*
* @method
* @protected
* @abstract
* @method beforeRemove_
*/
AbstractStrategy.prototype.beforeRemove_ = _.abstractMethod;
/**
* This method is called after
* this.mapView_ is set to null;
*
* @method
* @protected
* @method afterRemove_
*/
AbstractStrategy.prototype.afterRemove_ = function() {};
/**
* Create a view instance.
*
* @protected
* @abstract
* @return {Object} View instance.
* @method createView_
*/
AbstractStrategy.prototype.createView_ = _.abstractMethod;
/**
* Return the view instance
* created by the map-rendering API.
*
* @return {?Object}
* @method getView
*/
AbstractStrategy.prototype.getView = function() {
return this.view_;
};
return AbstractStrategy;
});