Move proxy creation from remote connector into base model class

This commit is contained in:
Ritchie Martori 2014-02-20 19:43:50 -08:00
parent 0632f52411
commit 64b374907a
3 changed files with 78 additions and 37 deletions

View File

@ -3,8 +3,7 @@ var client = loopback();
var CartItem = require('./models').CartItem;
var remote = loopback.createDataSource({
connector: loopback.Remote,
root: 'http://localhost:3000',
remotes: client.remotes()
root: 'http://localhost:3000'
});
client.model(CartItem);

View File

@ -20,7 +20,6 @@ function RemoteConnector(settings) {
assert(typeof settings === 'object', 'cannot initiaze RemoteConnector without a settings object');
this.client = settings.client;
this.root = settings.root;
this.remotes = settings.remotes;
this.adapter = settings.adapter || 'rest';
assert(this.root, 'RemoteConnector: settings.root is required');
@ -29,9 +28,9 @@ function RemoteConnector(settings) {
}
RemoteConnector.prototype.connect = function() {
this.remotes.connect(this.root, this.adapter);
}
RemoteConnector.initialize = function(dataSource, callback) {
var connector = dataSource.connector = new RemoteConnector(dataSource.settings);
connector.connect();
@ -41,9 +40,16 @@ RemoteConnector.initialize = function(dataSource, callback) {
RemoteConnector.prototype.define = function(definition) {
var Model = definition.model;
var className = compat.getClassNameForRemoting(Model);
var sharedClass = getSharedClass(this.remotes, className);
var url = this.root;
var adapter = this.adapter;
mixinRemoteMethods(this.remotes, Model, sharedClass.methods());
Model.remotes(function(err, remotes) {
var sharedClass = getSharedClass(remotes, className);
remotes.connect(url, adapter);
sharedClass
.methods()
.forEach(Model.createProxyMethod.bind(Model));
});
}
function getSharedClass(remotes, className) {
@ -51,35 +57,4 @@ function getSharedClass(remotes, className) {
return sharedClass.name === className;
});
}
function mixinRemoteMethods(remotes, Model, methods) {
methods.forEach(function(sharedMethod) {
var original = sharedMethod.fn;
var fn = createProxyFunction(remotes, sharedMethod.stringName);
for(var key in original) {
fn[key] = original[key];
}
if(sharedMethod.isStatic) {
Model[sharedMethod.name] = fn;
} else {
Model.prototype[sharedMethod.name] = fn;
}
});
}
function createProxyFunction(remotes, stringName) {
return function() {
var args = Array.prototype.slice.call(arguments);
var lastArgIsFunc = typeof args[args.length - 1] === 'function';
var callback;
if(lastArgIsFunc) {
callback = args.pop();
} else {
callback = noop;
}
remotes.invoke(stringName, args, callback);
}
}
function noop() {}

View File

@ -200,6 +200,73 @@ Model._getAccessTypeForMethod = function(method) {
}
}
/**
* Get the `Application` the Model is attached to.
*
* @callback {Function} callback
* @param {Error} err
* @param {Application} app
* @end
*/
Model.getApp = function(callback) {
var Model = this;
if(this.app) {
callback(null, this.app);
} else {
Model.once('attached', function() {
assert(Model.app);
callback(null, Model.app);
});
}
}
/**
* Get the Model's `RemoteObjects`.
*
* @callback {Function} callback
* @param {Error} err
* @param {RemoteObjects} remoteObjects
* @end
*/
Model.remotes = function(callback) {
this.getApp(function(err, app) {
callback(null, app.remotes());
});
}
/*!
* Create a proxy function for invoking remote methods.
*
* @param {SharedMethod} sharedMethod
*/
Model.createProxyMethod = function createProxyFunction(remoteMethod) {
var Model = this;
var scope = remoteMethod.isStatic ? Model : Model.prototype;
var original = scope[remoteMethod.name];
var fn = scope[remoteMethod.name] = function proxy() {
var args = Array.prototype.slice.call(arguments);
var lastArgIsFunc = typeof args[args.length - 1] === 'function';
var callback;
if(lastArgIsFunc) {
callback = args.pop();
} else {
callback = noop;
}
Model.remotes(function(err, remotes) {
remotes.invoke(remoteMethod.stringName, args, callback);
});
}
for(var key in original) {
fn[key] = original[key];
}
}
// setup the initial model
Model.setup();