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