1 /** this is the view part of the MVC framework
  2     handle updates and creations and deletes of registered
  3     objects and classes
  4     @namespace
  5 */
  6 MBX.JsView = (function () {
  7     /**
  8         @memberof MBX.JsView
  9         @namespace
 10     */
 11     var self = {};
 12     
 13     /** @class A single view instance
 14         @constructor
 15         @name JsView
 16         @example
 17             MBX.JsView.create({
 18                 model: MBX.DesktopUpload,
 19                 onCreate: function (upload) {
 20                     //create the upload
 21                 },
 22                 onChange: function (upload) {
 23                     // any upload changes
 24                 },
 25                 onDestroy: function (upload) {
 26                     // handle destroys
 27                 }
 28             });
 29     */
 30     var View = function (opts) {
 31         opts = opts || {};
 32         _(this).extend(opts);
 33         
 34         if (this.model) {
 35             this._subscribeToEvents();
 36         }
 37         
 38         if (typeof this.initialize == 'function') {
 39             this.initialize();
 40         }
 41     };
 42     
 43     View.prototype = /** @lends JsView */{
 44         active: true,
 45         
 46         /** reactivate event listening on this view
 47         */
 48         activate: function () {
 49             this.active = true;
 50         },
 51         
 52         /** quiets all events on this view, your callbacks will
 53             not get called
 54         */
 55         deactivate: function () {
 56             this.active = false;
 57         },
 58         
 59         /** Anytime an instance changes on the model you are observing,
 60             JsView will fire a function with the object and the key
 61             @params {JsModel#instance} object the instance that changed
 62             @params {String} key the key that changed
 63         */
 64         _onInstanceChange: function (evt) {
 65             if (this.active && typeof this.onInstanceChange == 'function') {
 66                 this.onInstanceChange(evt.object, evt.key);
 67             }
 68         },
 69         
 70         _onInstanceCreate: function (evt) {
 71             if (this.active && typeof this.onInstanceCreate == 'function') {
 72                 this.onInstanceCreate(evt.object);
 73             }
 74         },
 75         
 76         _onInstanceDestroy: function (evt) {
 77             if (this.active && typeof this.onInstanceDestroy == 'function') {
 78                 this.onInstanceDestroy(evt.object);
 79             }
 80         },
 81         
 82         _onAttributeChange: function (evt) {
 83             if (this.active && typeof this.onAttributeChange == 'function') {
 84                 this.onAttributeChange(evt.key);
 85             }
 86         },
 87         
 88         /** subscribe to change, create, destroy events
 89             We assume you don't need your UI elements to update at the expense of user interaction
 90             hence the defer: true
 91         */
 92         _subscribeToEvents: function () {
 93             var changeEvent = this.model.Event.changeInstance;
 94             var newEvent = this.model.Event.newInstance;
 95             var destroyEvent = this.model.Event.destroyInstance;
 96             var attributeEvent = this.model.Event.changeAttribute;
 97             var defer = this.looselyCoupled;
 98             
 99             MBX.on(changeEvent, _(this._onInstanceChange).bind(this));
100             MBX.on(newEvent, _(this._onInstanceCreate).bind(this));
101             MBX.on(destroyEvent, _(this._onInstanceDestroy).bind(this));
102             MBX.on(attributeEvent, _(this._onAttributeChange).bind(this));
103         }
104         
105     };
106     
107     /** create a new view handler... specify a model and some
108         functions and some great magic happens.
109         
110         If your view listens to a model, but you are not dependent on real-time updates,
111         you can add the option "looselyCoupled: true" and all updates will be done with
112         setTimeout, which will be a performance enhancement.
113         
114         @name MBX.JsView.create
115         @function
116         @param {Object} opts the various options specified for a view
117         @example
118             MBX.JsView.create({
119                 model: MBX.DesktopUpload,
120                 looselyCoupled: false, // false is the default
121                 onCreate: function (upload) {
122                     //create the upload
123                 },
124                 onChange: function (upload) {
125                     // any upload changes
126                 },
127                 onDestroy: function (upload) {
128                     // handle destroys
129                 }
130             });
131     */
132     self.create = function (opts) {
133         return new View(opts);
134     };
135     
136     /**
137         call extend() to add methods and/or attributes to ALL views
138         @param {Object} methsAndAttrs
139         @name MBX.JsView.extend
140         @function
141     */
142     self.extend = function (methsAndAttrs) {
143         methsAndAttrs = methsAndAttrs || {};
144         _(View.prototype).extend(methsAndAttrs);
145     };
146 
147     _(View.prototype).extend(EventEmitter.prototype);
148     
149     return self;
150 })();
151