Author: jmorliaguet Date: Thu Feb 2 13:51:09 2006 New Revision: 2268 Modified: cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js Log:
- added a simple event system to make it possible for the model to send events and the views to react to events. this is needed for compound storages observers now use the event system (they subscribe to the 'modified' event) Modified: cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js ============================================================================== --- cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js (original) +++ cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js Thu Feb 2 13:51:09 2006 @@ -34,7 +34,9 @@ } var CPSSkins = { - Version: "0.5", + Version: "0.6", + + Subscribers: $H({}), Models: $H({}), @@ -73,10 +75,56 @@ return controller; }, + /* Public events */ registerHandlers: function(handlers) { Object.extend(CPSSkins.Handlers, handlers); }, + /* Internal events */ + subscribe: function(obj, event) { + if (!(event in CPSSkins.Subscribers)) { + CPSSkins.Subscribers[event] = $A([]); + } + CPSSkins.Subscribers[event].push(obj); + }, + + unsubscribe: function(obj, event) { + new_subscribers = $A([]); + CPSSkins.Subscribers[event].each(function(s) { + if (obj != s) { + new_subscribers.push(s); + } + }); + CPSSkins.Subscribers[event] = new_subscribers; + }, + + notify: function(context, event) { + var subscribers = CPSSkins.Subscribers[event]; + $A(subscribers).each(function(s) { + var handler = CPSSkins.getEventHandler(s, event); + if (handler) handler(s, context); + }); + }, + + registerEventHandler: function(subscriber, event, handler) { + var handlers = subscriber._handlers; + if (!handlers) { + subscriber._handlers = new Object(); + } + subscriber._handlers[event] = handler; + }, + + getEventHandler: function(subscriber, event) { + var handlers = subscriber._handlers; + if (handlers) { + return handlers[event]; + } else { + return null; + } + }, + + /* Document parsing */ + jsonParse: function(el) { var res = null; var text = el.innerHTML; @@ -567,8 +615,6 @@ initialize: function(node, def) { this.node = this.node; this.def = def; - // observers - this.observers = $H({}); // set the storage adapter this._setStorageAdapter(); }, @@ -589,7 +635,13 @@ }, addObserver: function(view) { - this.observers[view.id] = view; + // register an event handler for the 'modified' event + view.registerEventHandler('modified', function(v, context) { + var data = v.model.def.data; + v.render(data); + }); + // subscribe to 'modified' events + view.subscribeTo('modified'); // create a back-reference view.model = this; // initialize the view @@ -597,14 +649,7 @@ }, removeObserver: function(view) { - delete this.observers[view.id]; - }, - - notifyObservers: function(data) { - // XXX: should use notify() instead, but there is no event system. - $H(this.observers).each(function(m) { - m[1].render(data); - }); + view.unsubscribeFrom('modified'); }, _setStorageAdapter: function() { @@ -674,7 +719,6 @@ var model = this.model; $A(this.models).each(function(m) { m.storage.requestData(); - Object.extend(model.def.data, m.def.data); }); }, @@ -704,7 +748,7 @@ storeData: function(data) { /* Store the data directly */ this.model.def.data = data; - this.model.notifyObservers(data); + CPSSkins.notify(this.model, 'modified'); } }); @@ -720,7 +764,7 @@ onComplete: function(req) { var data = JSON.parse(req.responseText); model.def.data = data; - model.notifyObservers(data); + CPSSkins.notify(model, 'modified'); } }); }, @@ -738,7 +782,7 @@ onComplete: function(req) { var data = JSON.parse(req.responseText); model.def.data = data; - model.notifyObservers(data); + CPSSkins.notify(model, 'modified'); } }); } @@ -783,6 +827,18 @@ /* Private API */ + subscribeTo: function(event) { + CPSSkins.subscribe(this, event); + }, + + registerEventHandler: function(event, handler) { + CPSSkins.registerEventHandler(this, event, handler); + }, + + unsubscribeFrom: function(event) { + CPSSkins.unsubscribe(this, event); + }, + observe: function(model) { model.addObserver(this); this.model = model; @@ -1195,7 +1251,7 @@ if (confirm) { if (!window.confirm(confirm)) return; } - /* notify the controller */ + /* notify the controller to take action */ this.handleAction(this.selected, action, choice); this.active = false; }, -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins