Inherit hooks when nesting
Note that for now, the hook ctx.instance will be the root/entry object. Added `mounted` event - should be useful in other ways too.
This commit is contained in:
parent
cc0d376cc3
commit
539702ab3d
|
@ -269,6 +269,7 @@ app.remoteObjects = function () {
|
|||
|
||||
/*!
|
||||
* Get a handler of the specified type from the handler cache.
|
||||
* @triggers `mounted` events on shared class constructors (models)
|
||||
*/
|
||||
|
||||
app.handler = function (type) {
|
||||
|
@ -279,6 +280,11 @@ app.handler = function (type) {
|
|||
|
||||
var remotes = this.remotes();
|
||||
var handler = this._handlers[type] = remotes.handler(type);
|
||||
|
||||
remotes.classes().forEach(function(sharedClass) {
|
||||
sharedClass.ctor.emit('mounted', app, sharedClass, remotes);
|
||||
});
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
|
|
@ -538,6 +538,7 @@ Model.nestRemoting = function(relationName, options, cb) {
|
|||
opts.returns = [].concat(method.returns || []);
|
||||
opts.description = method.description;
|
||||
opts.rest = extend({}, method.rest || {});
|
||||
opts.rest.delegateTo = method.name;
|
||||
|
||||
opts.http = [];
|
||||
var routes = [].concat(method.http || []);
|
||||
|
@ -551,35 +552,66 @@ Model.nestRemoting = function(relationName, options, cb) {
|
|||
|
||||
if (relation.multiple) {
|
||||
sharedClass.defineMethod(methodName, opts, function(fkId) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
var last = args[args.length - 1];
|
||||
var cb = typeof last === 'function' ? last : null;
|
||||
this[getterName](fkId, function(err, inst) {
|
||||
if (err && cb) return cb(err);
|
||||
if (inst instanceof relation.modelTo) {
|
||||
nestedFn.apply(inst, args);
|
||||
} else if (cb) {
|
||||
cb(err, null);
|
||||
}
|
||||
});
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
var last = args[args.length - 1];
|
||||
var cb = typeof last === 'function' ? last : null;
|
||||
this[getterName](fkId, function(err, inst) {
|
||||
if (err && cb) return cb(err);
|
||||
if (inst instanceof relation.modelTo) {
|
||||
nestedFn.apply(inst, args);
|
||||
} else if (cb) {
|
||||
cb(err, null);
|
||||
}
|
||||
});
|
||||
}, method.isStatic);
|
||||
} else {
|
||||
sharedClass.defineMethod(methodName, opts, function() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var last = args[args.length - 1];
|
||||
var cb = typeof last === 'function' ? last : null;
|
||||
this[getterName](function(err, inst) {
|
||||
if (err && cb) return cb(err);
|
||||
if (inst instanceof relation.modelTo) {
|
||||
nestedFn.apply(inst, args);
|
||||
} else if (cb) {
|
||||
cb(err, null);
|
||||
}
|
||||
});
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var last = args[args.length - 1];
|
||||
var cb = typeof last === 'function' ? last : null;
|
||||
this[getterName](function(err, inst) {
|
||||
if (err && cb) return cb(err);
|
||||
if (inst instanceof relation.modelTo) {
|
||||
nestedFn.apply(inst, args);
|
||||
} else if (cb) {
|
||||
cb(err, null);
|
||||
}
|
||||
});
|
||||
}, method.isStatic);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (options.hooks === false) return; // don't inherit before/after hooks
|
||||
|
||||
self.once('mounted', function(app, sc, remotes) {
|
||||
var listenerTree = extend({}, remotes.listenerTree || {});
|
||||
listenerTree.before = listenerTree.before || {};
|
||||
listenerTree.after = listenerTree.after || {};
|
||||
|
||||
var beforeListeners = remotes.listenerTree.before[toModelName] || {};
|
||||
var afterListeners = remotes.listenerTree.after[toModelName] || {};
|
||||
|
||||
sharedClass.methods().forEach(function(method) {
|
||||
var delegateTo = method.rest && method.rest.delegateTo;
|
||||
if (delegateTo) {
|
||||
var before = method.isStatic ? beforeListeners : beforeListeners['prototype'];
|
||||
var after = method.isStatic ? afterListeners : afterListeners['prototype'];
|
||||
var m = method.isStatic ? method.name : 'prototype.' + method.name;
|
||||
if (before[delegateTo]) {
|
||||
self.beforeRemote(m, function(ctx, result, next) {
|
||||
before[delegateTo]._listeners.call(null, ctx, next);
|
||||
});
|
||||
}
|
||||
if (after[delegateTo]) {
|
||||
self.afterRemote(m, function(ctx, result, next) {
|
||||
after[delegateTo]._listeners.call(null, ctx, next);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
throw new Error('Relation `' + relationName + '` does not exist for model `' + this.modelName + '`');
|
||||
}
|
||||
|
|
|
@ -958,6 +958,17 @@ describe('relations - integration', function () {
|
|||
|
||||
expect(Book.prototype['__findById__pages__notes']).to.be.a.function;
|
||||
expect(Image.prototype['__findById__book__pages']).to.be.a.function;
|
||||
|
||||
Page.beforeRemote('prototype.__findById__notes', function(ctx, result, next) {
|
||||
ctx.res.set('x-before', 'before');
|
||||
next();
|
||||
});
|
||||
|
||||
Page.afterRemote('prototype.__findById__notes', function(ctx, result, next) {
|
||||
ctx.res.set('x-after', 'after');
|
||||
next();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
before(function createBook(done) {
|
||||
|
@ -989,7 +1000,7 @@ describe('relations - integration', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('has regular relationship routes', function(done) {
|
||||
it('has regular relationship routes - pages', function(done) {
|
||||
var test = this;
|
||||
this.get('/api/books/' + test.book.id + '/pages')
|
||||
.expect(200, function(err, res) {
|
||||
|
@ -1000,6 +1011,18 @@ describe('relations - integration', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('has regular relationship routes - notes', function(done) {
|
||||
var test = this;
|
||||
this.get('/api/pages/' + test.page.id + '/notes/' + test.note.id)
|
||||
.expect(200, function(err, res) {
|
||||
expect(res.headers['x-before']).to.equal('before');
|
||||
expect(res.headers['x-after']).to.equal('after');
|
||||
expect(res.body).to.be.an.object;
|
||||
expect(res.body.text).to.equal('Page Note 1');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('has a basic error handler', function(done) {
|
||||
var test = this;
|
||||
this.get('/api/books/unknown/pages/' + test.page.id + '/notes')
|
||||
|
@ -1047,6 +1070,8 @@ describe('relations - integration', function () {
|
|||
var test = this;
|
||||
this.get('/api/books/' + test.book.id + '/pages/' + test.page.id + '/notes/' + test.note.id)
|
||||
.expect(200, function(err, res) {
|
||||
expect(res.headers['x-before']).to.equal('before');
|
||||
expect(res.headers['x-after']).to.equal('after');
|
||||
expect(res.body).to.be.an.object;
|
||||
expect(res.body.text).to.equal('Page Note 1');
|
||||
done();
|
||||
|
|
Loading…
Reference in New Issue