From 627b4f0fe1cc35ed89d291bc2e63c0e95b6b6bed Mon Sep 17 00:00:00 2001 From: Camille Reynders Date: Fri, 5 Sep 2014 13:24:22 +0200 Subject: [PATCH 1/2] Add Context#executeCommand --- backbone.geppetto.js | 31 ++++++++++++++++--------- specs/src/geppetto-specs.js | 46 +++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/backbone.geppetto.js b/backbone.geppetto.js index af103cf..d0ce709 100755 --- a/backbone.geppetto.js +++ b/backbone.geppetto.js @@ -360,6 +360,25 @@ }); }; + Geppetto.Context.prototype._executeCommand = function(CommandConstructor, eventName, eventData, wiring) { + var commandInstance = new CommandConstructor(this, eventName, eventData); + + commandInstance.context = this; + commandInstance.eventName = eventName; + commandInstance.eventData = eventData; + this.resolver.resolve(commandInstance, wiring); + if (_.isFunction(commandInstance.execute)) { + commandInstance.execute(); + } + }; + + Geppetto.Context.prototype.executeCommand = function(CommandConstructor, event) { + if (!event) { + event = {}; + } + this._executeCommand(CommandConstructor, event.eventName, event.eventData); + }; + Geppetto.Context.prototype.wireCommand = function wireCommand(eventName, CommandConstructor, wiring) { var _this = this; @@ -369,17 +388,7 @@ } this.vent.listenTo(this.vent, eventName, function(eventData) { - - var commandInstance = new CommandConstructor(_this, eventName, eventData); - - commandInstance.context = _this; - commandInstance.eventName = eventName; - commandInstance.eventData = eventData; - _this.resolver.resolve(commandInstance, wiring); - if (_.isFunction(commandInstance.execute)) { - commandInstance.execute(); - } - + _this._executeCommand(CommandConstructor, eventName, eventData, wiring); }, this); }; diff --git a/specs/src/geppetto-specs.js b/specs/src/geppetto-specs.js index ac082d2..aeb5a64 100755 --- a/specs/src/geppetto-specs.js +++ b/specs/src/geppetto-specs.js @@ -533,6 +533,52 @@ define([ expect(command.ctorArgs).to.contain(context); }); }); + + describe('when executing commands', function(){ + var context; + var CommandClass; + var command; + beforeEach(function() { + var ContextDefinition = Geppetto.Context.extend({}); + context = new ContextDefinition(); + CommandClass = function() { + this.ctorArgs = _.toArray(arguments); + }; + CommandClass.prototype.execute = function() { + command = this; + }; + + }); + afterEach(function() { + context.destroy(); + context = null; + CommandClass = null; + command = null; + }); + it("should resolve dependencies", function(){ + var value = {}; + context.wireValue('value', value); + CommandClass.prototype.wiring = ['value']; + context.executeCommand(CommandClass); + expect(command.value).to.equal(value); + }); + it("should inject event parameter as members", function(){ + var eventName = "test:event"; + var eventData = { + foo : "foo" + }; + context.executeCommand(CommandClass, { + eventName : eventName, + eventData : eventData + }); + expect(command.eventName).to.equal(eventName); + expect(command.eventData).to.equal(eventData); + }); + it("should inject the context", function(){ + context.executeCommand(CommandClass); + expect(command.context).to.equal(context); + }); + }); describe("when wiring dependencies in batch using the Context 'wiring' parameter", function() { From cb5440a3e9e90ba56d4db0bf5da72f7ce65e9a97 Mon Sep 17 00:00:00 2001 From: Camille Reynders Date: Fri, 5 Sep 2014 13:40:13 +0200 Subject: [PATCH 2/2] Update README --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 853d966..eba5f11 100644 --- a/README.md +++ b/README.md @@ -619,6 +619,21 @@ return function FooCommand(context, eventName, eventData){ N.B.: We'd strongly advise against using the context as a service locator inside commands. If your command requires any additional dependencies it's best practice to turn it into a "real" command (which exposes an `execute` method and declares its dependencies through the `wiring` property.) +### Direct command execution + +It's also possible to execute commands directly, without dispatching an event. + +```js +context.executeCommand(ComplexUpdateMechanicCommand, { + eventName : "update:complex:mechanic", + eventData: { + importantStuff: "Holy shizzles!" + } +} ); +``` + +This will execute the command in exactly the same vein as when triggered by an event. + ### Use underscore to reduce boilerplate You can use the underscore `extend` method to conform your command declarations to your other object declarations: