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

Reply via email to