Skip to content

Instantly share code, notes, and snippets.

@jejacks0n
Created October 21, 2010 18:29
Show Gist options
  • Save jejacks0n/639028 to your computer and use it in GitHub Desktop.
Save jejacks0n/639028 to your computer and use it in GitHub Desktop.
WebSocketCollection inherits from Collection.Base
CollectionBase = Class.create({
resource: null,
resourceName: '',
resourceHandler: null,
collection: null,
initialize: function(resource) {
this.collection = {};
this.resource = resource;
this.resourceName = resource.prototype.resourceName;
this.resourcePath = resource.prototype.resourcePath;
this.setupResourceHandler();
},
setupResourceHandler: function() {
this.resourceHandler = Rails.resource(this.resourcePath);
$w('Index Show New Create Edit Update Destroy').each(function(action) {
var actionName = action.toLowerCase();
var actionMethod = this[actionName];
var afterMethod = this['after' + action];
this.resourceHandler.add(actionName, function(proceed, vars) {
if (typeof(this['before' + action]) == 'function' && this['before' + action](vars) === false) return false;
if (actionMethod) {
proceed({
onSuccess: function(transport) {
transport.success = true;
this[actionName].call(this, transport, vars);
}.bind(this),
onFailure: function(transport) {
transport.success = false;
this[actionName].call(this, transport, vars);
}.bind(this),
onComplete: function(transport) {
// TODO: we should tell the afterMethod if it's successful or not
if (typeof(afterMethod) == 'function') afterMethod(transport, vars)
}.bind(this)
});
return false;
}
}.bind(this));
}.bind(this));
},
index: function(transport, vars) {
},
show: function(transport, vars) {
},
// editing
edit: function(transport, vars) {
if (!transport.success) {
alert('Unable to load form for ' + this.resourceName);
}
},
update: function(transport, vars) {
if (transport.success) {
this.execute({action: 'updated', transport: transport.responseJSON});
} else {
alert('Uable to save ' + this.resourceName + '.' + (transport.responseJSON) ?
' Please resolve the following errors.\n\n' + new this.resource({errors: transport.responseJSON}).errorMessage() :
'');
}
},
updated: function(resource) {
this.collection[resource.id] = resource;
},
// creating
'new': function(transport, vars) {
if (!transport.success) {
alert('Unable to load form for ' + this.resourceName);
}
},
create: function(transport, vars) {
if (transport.success) {
this.execute({action: 'created', transport: transport.responseJSON});
} else {
alert('Uable to create ' + this.resourceName + '.' + (transport.responseJSON) ?
' Please resolve the following errors.\n\n' + new this.resource({errors: transport.responseJSON}).errorMessage() :
'');
}
},
created: function(resource) {
this.collection[resource.id] = resource;
},
// destroying
beforeDestroy: function(vars) {
if (!confirm('Are you sure?')) return false;
},
destroy: function(transport, vars) {
if (transport.success) {
this.execute({action: 'destroyed', transport: transport.responseJSON});
} else {
alert('Uable to delete ' + this.resourceName + '.' + (transport.responseJSON) ?
' Please resolve the following errors.\n\n' + new this.resource({errors: transport.responseJSON}).errorMessage() :
'');
}
},
destroyed: function(resource) {
delete this.collection[resource.id];
},
execute: function(data) {
this.executeAction(data);
},
executeAction: function(data) {
console.debug('action received:', data);
if (data.action && typeof(this[data.action]) == 'function') {
var transport = data.transport;
var view;
if (typeof(transport[this.resourceName]) == 'object') {
transport = transport[this.resourceName];
} else if (typeof(transport['resource']) == 'object' && transport['element']) {
view = transport['element'];
transport = transport['resource'][this.resourceName];
}
if (transport.id) {
// TODO: break out into a method that can be inherited
var resource = this.collection[transport.id] || new this.resource(transport);
if (view) resource.build(view);
// --
this[data.action].call(this, resource);
}
}
}
});
executeAction: function(data) {
// if we have an action to call, and it's a function on this class.
if (data.action && typeof(this[data.action]) == 'function') {
var transport = data.transport;
var view;
// find the resource from the object.
// also handle if the json response has any view data with it
if (typeof(transport[this.resourceName]) == 'object') {
transport = transport[this.resourceName];
} else if (typeof(transport['resource']) == 'object' && transport['element']) {
view = transport['element'];
transport = transport['resource'][this.resourceName];
}
// if we have what looks like a resource
if (transport.id) {
var resource = this.collection[transport.id] || new this.resource(transport);
if (view) resource.build(view);
this[data.action].call(this, resource);
}
}
}
beforeDestroy: function(vars) {
if (!confirm('Are you sure?')) return false;
}
destroy: function(transport, vars) {
if (transport.success) {
this.execute({action: 'destroyed', transport: transport.responseJSON});
} else {
alert('Uable to delete ' + this.resourceName + '.');
}
}
destroyed: function(resource) {
delete this.collection[resource.id];
}
destroyed: function($super, resource) {
var element = this.element.down('#' + this.resourceName + '_' + resource.id);
if (element) element.remove();
$super(resource);
}
WebSocketCollection = Class.create(CollectionBase, {
ws: null,
initialize: function($super, resource) {
$super(resource);
this.ws = new WebSocket('ws://localhost:10081' + this.resourcePath);
this.ws.onmessage = this.onReceive.bindAsEventListener(this);
this.ws.onerror = this.onError.bind(this);
},
execute: function($super, data) {
var message = (typeof(data) == 'string') ? data : Object.toJSON(data);
this.ws.send(message);
},
onReceive: function(e) {
var data = (e.data.isJSON()) ? e.data.evalJSON() : e.data;
// The websocket server responds initially to assign a connection id, which
// isn't used at this point, but seemed like a nice thing to have in place.
if (data.initialize && data.data) {
Object.extend(this, data.data);
return;
}
this.executeAction(data);
},
onError: function() {
alert('Sorry, but it looks like something has gone wrong with the connection to the server.');
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment