From 9d2deccdf99ccb14356c27606139fbaeefb23cee Mon Sep 17 00:00:00 2001 From: Richard Pringle Date: Wed, 20 Apr 2016 17:26:54 -0400 Subject: [PATCH 1/4] Add controller initialization logic. --- lib/application.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/application.js b/lib/application.js index 44e35b1d..8d0254cd 100644 --- a/lib/application.js +++ b/lib/application.js @@ -395,6 +395,17 @@ app.enableAuth = function(options) { this.isAuthEnabled = true; }; +app.controller = function(controllerCtor, options) { + var self = this; + SharedClass = RemoteObjects.SharedClass; + + controllerCtor._sharedClass = new SharedClass(controllerCtor.name); + controllerCtor._sharedClass.resolve = function() { + return new controllerCtor(app, remotingContext); + }; + app.remotes().addClass(controllerCtor._sharedClass); +}; + app.boot = function(options) { throw new Error( '`app.boot` was removed, use the new module loopback-boot instead'); From a9696aeaf8f92cdde7c96963ac32604bad613914 Mon Sep 17 00:00:00 2001 From: Richard Pringle Date: Wed, 27 Apr 2016 13:28:18 -0400 Subject: [PATCH 2/4] Re-organize --- lib/application.js | 57 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/lib/application.js b/lib/application.js index 8d0254cd..36d4144e 100644 --- a/lib/application.js +++ b/lib/application.js @@ -395,17 +395,6 @@ app.enableAuth = function(options) { this.isAuthEnabled = true; }; -app.controller = function(controllerCtor, options) { - var self = this; - SharedClass = RemoteObjects.SharedClass; - - controllerCtor._sharedClass = new SharedClass(controllerCtor.name); - controllerCtor._sharedClass.resolve = function() { - return new controllerCtor(app, remotingContext); - }; - app.remotes().addClass(controllerCtor._sharedClass); -}; - app.boot = function(options) { throw new Error( '`app.boot` was removed, use the new module loopback-boot instead'); @@ -578,3 +567,49 @@ app.listen = function(cb) { return server; }; + +/* START CONTROLLER CODE*/ + +// Implementation without wrapper + +// app.controller = function(controllerCtor, options) { +// var self = this; +// SharedClass = RemoteObjects.SharedClass; + +// controllerCtor._sharedClass = new SharedClass(controllerCtor.name, controllerCtor); +// controllerCtor._sharedClass.resolve = function() { +// return new controllerCtor(app, remotingContext); +// }; +// app.remotes().addClass(controllerCtor._sharedClass); +// }; + +// Implementation with wrapper + +app.controller = function(ctor, options) { + var controller = new SharedController(ctor); + app.remotes().addClass(wrapper.sharedClass); + app.controllers[ctor.name] = wrapper; + return wrapper; +}; + +function SharedController(ctor, options) { + options = options || {}; + this.name = ctor.name; + this.ctor = ctor; + this.sharedClass = new SharedClass(this.name, ctor, options); +}; + +SharedController.remoteMethod = function(name, options) { + if (options.isStatic === undefined) { + var m = name.match(/^prototype\.(.*)$/); + options.isStatic = !m; + name = options.isStatic ? name : m[1]; + } + this.sharedClass.defineMethod(name, options); +}; + +SharedController.disableRemoteMethod = function() { + +}; + +/* END CONTROLLER CODE */ From b46b33677567fd3349d0af880067ad373faddf0d Mon Sep 17 00:00:00 2001 From: Richard Pringle Date: Fri, 29 Apr 2016 10:28:11 -0400 Subject: [PATCH 3/4] Initialize controller --- lib/application.js | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/application.js b/lib/application.js index 36d4144e..9de378c5 100644 --- a/lib/application.js +++ b/lib/application.js @@ -12,6 +12,7 @@ var classify = require('underscore.string/classify'); var camelize = require('underscore.string/camelize'); var path = require('path'); var util = require('util'); +var EventEmitter = require('events'); /** * The `App` object represents a Loopback application. @@ -284,7 +285,9 @@ app.handler = function(type, options) { var handler = this._handlers[type] = remotes.handler(type, options); remotes.classes().forEach(function(sharedClass) { - sharedClass.ctor.emit('mounted', app, sharedClass, remotes); + if (sharedClass.name !== 'ctrl') { + sharedClass.ctor.emit('mounted', app, sharedClass, remotes); + } }); return handler; @@ -587,29 +590,37 @@ app.listen = function(cb) { app.controller = function(ctor, options) { var controller = new SharedController(ctor); - app.remotes().addClass(wrapper.sharedClass); - app.controllers[ctor.name] = wrapper; - return wrapper; + this.remotes().addClass(controller.sharedClass); + app.controllers().push(controller); + return controller; +}; + +app.controllers = function() { + return this._controllers || (this._controllers = []); }; function SharedController(ctor, options) { options = options || {}; this.name = ctor.name; this.ctor = ctor; - this.sharedClass = new SharedClass(this.name, ctor, options); + util.inherits(ctor, EventEmitter); + this.sharedClass = new RemoteObjects.SharedClass(this.name, ctor, options); }; -SharedController.remoteMethod = function(name, options) { - if (options.isStatic === undefined) { - var m = name.match(/^prototype\.(.*)$/); - options.isStatic = !m; - name = options.isStatic ? name : m[1]; - } +SharedController.prototype.remoteMethod = function(name, options) { + options.isStatic = true; this.sharedClass.defineMethod(name, options); }; -SharedController.disableRemoteMethod = function() { - +SharedController.prototype.disableRemoteMethod = function(name, isStatic) { + this.sharedClass.disableMethod(name, isStatic || false); }; +// TODO +// need to add the EventEmitter to the constructor of the controller +// function ctrl() { +// // EventEmitter.call(this); +// }; +// util.inherits(ctrl, EventEmitter); + /* END CONTROLLER CODE */ From 7272f5e17e81bca4543e0f2083067871e27f78a4 Mon Sep 17 00:00:00 2001 From: Richard Pringle Date: Fri, 29 Apr 2016 12:58:28 -0400 Subject: [PATCH 4/4] Implement working controller PoC. --- lib/application.js | 73 ++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/lib/application.js b/lib/application.js index 9de378c5..7256fe25 100644 --- a/lib/application.js +++ b/lib/application.js @@ -285,6 +285,7 @@ app.handler = function(type, options) { var handler = this._handlers[type] = remotes.handler(type, options); remotes.classes().forEach(function(sharedClass) { + /* HACK!!! */ if (sharedClass.name !== 'ctrl') { sharedClass.ctor.emit('mounted', app, sharedClass, remotes); } @@ -573,49 +574,57 @@ app.listen = function(cb) { /* START CONTROLLER CODE*/ -// Implementation without wrapper - -// app.controller = function(controllerCtor, options) { -// var self = this; -// SharedClass = RemoteObjects.SharedClass; - -// controllerCtor._sharedClass = new SharedClass(controllerCtor.name, controllerCtor); -// controllerCtor._sharedClass.resolve = function() { -// return new controllerCtor(app, remotingContext); -// }; -// app.remotes().addClass(controllerCtor._sharedClass); -// }; - -// Implementation with wrapper - +// this is similar to app.model +// at the moment I haven't really used 'options' app.controller = function(ctor, options) { + var self = this; + + // the SharedController is a wrapper, see below var controller = new SharedController(ctor); this.remotes().addClass(controller.sharedClass); app.controllers().push(controller); + return controller; + + // SharedController class contains strong-remoting objects to set up the metadata + // and register the endpoint, etc + function SharedController(ctor, options) { + options = options || {}; + this.name = ctor.name; + this.ctor = ctor; + // TODO - right now there's a hack on line 289 to skip this + // util.inherits(ctor, EventEmitter); + + this.sharedClass = new RemoteObjects.SharedClass(this.name, ctor, options); + // the resolveScope method instantiates the controller upon request + // (please correct my terminology if it's wrong) + this.sharedClass.resolveScope = function(remotingContext) { + // self is the app - should it be something more obvious like appInstance? + return new ctor(self, remotingContext); + }; + + // similar to model.remoteMethod + this.remoteMethod = function(name, options) { + // I didn't dive into why, but this only worked when I set isStatic to true + // whether the controller methods were prototype methods or not + options.isStatic = true; + this.sharedClass.defineMethod(name, options); + }; + + // have not tested this method yet but it follows model.disableRemoteMethod + this.disableRemoteMethod = function(name, isStatic) { + this.sharedClass.disableMethod(name, isStatic || false); + // this.emit('remoteMethodDisabled', this.sharedClass, name); + }; + }; }; +// similar to this app.models +// the controllers still need to registered in the Registy though app.controllers = function() { return this._controllers || (this._controllers = []); }; -function SharedController(ctor, options) { - options = options || {}; - this.name = ctor.name; - this.ctor = ctor; - util.inherits(ctor, EventEmitter); - this.sharedClass = new RemoteObjects.SharedClass(this.name, ctor, options); -}; - -SharedController.prototype.remoteMethod = function(name, options) { - options.isStatic = true; - this.sharedClass.defineMethod(name, options); -}; - -SharedController.prototype.disableRemoteMethod = function(name, isStatic) { - this.sharedClass.disableMethod(name, isStatic || false); -}; - // TODO // need to add the EventEmitter to the constructor of the controller // function ctrl() {