Model Events

Whenever a data model object is modified, either by the local client or by another collaborator, an event describing the change is fired.

All changes to collaborative objects, such as modifying a string, list, or custom collaborative object, emit events. Because changes can originate from either the local application or a remote collaborator, it is important that applications properly listen for and respond to these events to keep the view in sync with the model.

The type of event that is fired depends on the collaborative object that was modified and what change was made to it. For example, adding a value to a string will fire a TextInsertedEvent.

For details about event types, see the EventType enum in the API reference.

Event dispatching

Events are dispatched after the completion of the current synchronous block rather than executed immediately. This ensures all changes to the model are applied prior to executing the event handlers. Consider the following example.

var onValueAdded = function(event) {
  console.log("Items added", event.values);
};

var list = model.createList();
list.addEventListener(gapi.drive.realtime.EventType.VALUES_ADDED, onValueAdded);

console.log("Adding item 1");
list.push("Hello");
console.log("Adding item 2");
list.push("World");

The console for the current collaborator will show:

Adding item 1
Adding item 2
Items added, ["Hello"]
Items added, ["World"]

Other collaborators may receive these changes intermixed with other changes. To ensure the events are received together, applications should mark the boundaries of dependant operations using Model.beginCompoundOperation() and Model.endCompoundOperation(). See Conflict Resolution and Compound Operations for more information on compound events.

Event bubbling and ObjectChangedEvents

Most events are emitted on the specific object that changed and do not bubble. There is one exception: the ObjectChangedEvent is a bubbling event that is additionally emitted for every change. The ObjectChangedEvent is sent to the object that changed and all of its ancestors. One ObjectChangedEvent is emitted for every object that changed within a compound operation. The specific changes are described in the events field.

An ObjectChangedEvent is not as specific as other events, but can simplify management of event listeners when using MVC frameworks that have other mechanisms for detecting changes. For example, an ObjectChangedEvent listener added to the root will be informed whenever any change is made in any part of the model.

function displayObjectChangedEvent(evt) {
  var events = evt.events;
  var eventCount = evt.events.length;
  for (var i = 0; i < eventCount; i++) {
    console.log('Event type: '  + events[i].type);
    console.log('Local event: ' + events[i].isLocal);
    console.log('User ID: '     + events[i].userId);
    console.log('Session ID: '  + events[i].sessionId);
}

doc.getModel().getRoot().addEventListener(gapi.drive.realtime.EventType.OBJECT_CHANGED, displayObjectChangedEvent);

All other collaborative events do not bubble through the model. Only listeners that are attached directly to the modified object are executed.

Local vs. remote events

All events include a property isLocal which can be used to check if the event originated locally. If your application is applying local view changes directly, instead of in response to a collaborative object event, any event handlers should check the source of the event to avoid applying local changes multiple times.

function filterLocalEvents(evt) {
  var isLocal = evt.isLocal;
  if (!isLocal) {
    console.log("Non-local event.");
    //Insert UI update code here.
  } else {
    console.log("Local event.");
  }
}

Enviar comentarios sobre…