Skip to content

Commit cd25126

Browse files
committed
merge changes from creynders, tagging 0.6.2
1 parent 138b12c commit cd25126

File tree

4 files changed

+67
-39
lines changed

4 files changed

+67
-39
lines changed

README.md

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,25 @@ Geppetto is an extension for [Backbone.js](http://documentcloud.github.com/backb
99
The architecture of Geppetto was greatly inspired by the popular [Robotlegs](http://robotlegs.org) framework for Actionscript.
1010

1111
### Why Another Framework?
12-
Backbone has been [called an MV* framework](http://lostechies.com/derickbailey/2011/12/23/backbone-js-is-not-an-mvc-framework/), because it's not strictly MVC, MVP, nor any other MV-something. Sure, the Backbone Router can be made to act "controllery," but it's not really a good idea to tie all your business logic to URL change events.
12+
Backbone has been [called an MV* framework](http://lostechies.com/derickbailey/2011/12/23/backbone-js-is-not-an-mvc-framework/), because it's not strictly MVC, MVP, nor any other MV-something. Sure, the Backbone Router can be made to act "controllery," but it's not really a good idea to tie all your business logic to URL change events.
1313

1414
More commonly, in Backbone applications you'll find business logic implemented directly in Backbone.View components, or sometimes in the Model. For smaller apps, it's convenient to declare your "events" and your callback functions in the same place. But as applications grow, and business logic needs to be reused across separate view components, this practice starts to get messy.
1515

16-
To solve this issue, Geppetto implements a scalable **Controller** architecture for Backbone, prescribing an MVC-style separation of concerns. This makes it possible to write code that is loosely-coupled, easy-to-reuse, and highly-testable.
16+
To solve this issue, Geppetto implements a scalable **Controller** architecture for Backbone, prescribing an MVC-style separation of concerns. This makes it possible to write code that is loosely-coupled, easy-to-reuse, and highly-testable.
1717

1818
### Getting Geppetto
1919

20-
*Latest Stable Release: 0.6.1*
20+
*Latest Stable Release: 0.6.2*
2121

22-
* Minified: [backbone.geppetto.min.js](https://github.com/ModelN/backbone.geppetto/blob/0.6.1/dist/backbone.geppetto.min.js)
23-
* Development (Uncompressed, Comments): [backbone.geppetto.js](https://raw.github.com/ModelN/backbone.geppetto/0.6.1/backbone.geppetto.js)
24-
* Full Release (Tests, Examples): [0.6.1.zip](https://github.com/ModelN/backbone.geppetto/archive/0.6.1.zip).
22+
* Minified: [backbone.geppetto.min.js](https://github.com/ModelN/backbone.geppetto/blob/0.6.2/dist/backbone.geppetto.min.js)
23+
* Development (Uncompressed, Comments): [backbone.geppetto.js](https://raw.github.com/ModelN/backbone.geppetto/0.6.2/backbone.geppetto.js)
24+
* Full Release (Tests, Examples): [0.6.2.zip](https://github.com/ModelN/backbone.geppetto/archive/0.6.2.zip).
2525

2626
*Unreleased Edge Version (master)*
2727

2828
* Minified: [backbone.geppetto.min.js](https://raw.github.com/ModelN/backbone.geppetto/master/dist/backbone.geppetto.min.js)
2929
* Development (Uncompressed, Comments): [backbone.geppetto.js](https://raw.github.com/ModelN/backbone.geppetto/master/backbone.geppetto.js)
30-
* Full Release (Tests, Examples): [master.zip](https://github.com/ModelN/backbone.geppetto/archive/master.zip).
30+
* Full Release (Tests, Examples): [master.zip](https://github.com/ModelN/backbone.geppetto/archive/master.zip).
3131

3232
Visit the [project repo](https://github.com/ModelN/backbone.geppetto) to download the latest unreleased code (may be unstable).
3333

@@ -44,7 +44,7 @@ Has Geppetto been helpful to you? If you'd like to give back, here are a few wa
4444

4545
1. Blog about your experiences using Geppetto, and let us know about it!
4646
2. Create a demo app using Geppetto and add it to the examples directory.
47-
3. Improve the docs in the README.
47+
3. Improve the docs in the README.
4848
4. Fix a bug or add a new feature and submit a pull request (see below)
4949

5050
### Pull Requests
@@ -137,14 +137,14 @@ The View is implemented with Backbone.View or extensions of it such as Marionett
137137
1) **The DOM**
138138

139139
* The truly visual portion of The View
140-
* Represented with HTML
140+
* Represented with HTML
141141
* Responds to user input
142142
* Triggers events such as "click", "keyup", etc.
143143

144144

145145
2) **The Mediator**
146146

147-
* The Javascript portion of The View
147+
* The Javascript portion of The View
148148
* Creates DOM elements by generating HTML
149149
* Listens for DOM events on the View's `el`
150150
* Responds to DOM events by triggering **Application Events** for the **Controller** to respond to
@@ -156,11 +156,11 @@ The last two points are the key differences between Geppetto Applications and tr
156156
Geppetto implements the Controller piece using the Command Pattern. Commands are automatically instantiated and executed in response to Application Events.
157157

158158
## Geppetto.Context
159-
`Geppetto.Context` has many jobs, all of which involve providing a central place to share data and communication between related components.
159+
`Geppetto.Context` has many jobs, all of which involve providing a central place to share data and communication between related components.
160160

161161
### Job #1: Event Bus
162162

163-
Each Context has an instance of Marionette.EventAggregator, exposed as the "vent" property on the Context instance. You can use this "vent" in the same way that you would use any other Event Aggregator, to loosely-couple related parts of your application together with event-based communication.
163+
Each Context has an instance of Marionette.EventAggregator, exposed as the "vent" property on the Context instance. You can use this "vent" in the same way that you would use any other Event Aggregator, to loosely-couple related parts of your application together with event-based communication.
164164

165165
### Job #2: Command Registry
166166

@@ -236,7 +236,7 @@ Geppetto.bindContext({
236236
return Backbone.View.extend({
237237
initialize: function() {
238238
Geppetto.bindContext({
239-
view: this,
239+
view: this,
240240
context: ShellContext
241241
});
242242
},
@@ -295,9 +295,14 @@ return Geppetto.Context.extend( {
295295
```javascript
296296
return Geppetto.Context.extend( {
297297
commands: {
298-
"appEventFoo": FooCommand
299-
"appEventBar": BarCommand
300-
"appEventBaz": BazCommand
298+
"appEventFoo": FooCommand,
299+
"appEventBar": BarCommand,
300+
"appEventBaz": BazCommand,
301+
"appEventFooBarBaz": [
302+
FooCommand,
303+
BarCommand,
304+
BazCommand
305+
]
301306
}
302307
});
303308

@@ -362,7 +367,7 @@ If your event has some associated data that should be available to the consumer
362367
pass that event as an object as the second parameter of the call to `dispatch` like so:
363368

364369
```javascript
365-
context.dispatch( "fooEvent",
370+
context.dispatch( "fooEvent",
366371
{
367372
payloadPropertyFoo: "payloadValueFoo",
368373
payloadPropertyBar: true,
@@ -379,7 +384,7 @@ context.unmapAll();
379384

380385
### Destroying a Context
381386

382-
A Context is automatically destroyed when the `close()` method is called on its associated View. You should already be in the habit of calling `close()` to properly clean up your View's event listeners. If not, please read Derick Bailey's [article on killing zombies](http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/). The `close()` method is available on any Marionette.View. If you're using a plain old Backbone.View with Geppetto, a `close()` method will be created on the View for you when you call `bindContext()`.
387+
A Context is automatically destroyed when the `close()` method is called on its associated View. You should already be in the habit of calling `close()` to properly clean up your View's event listeners. If not, please read Derick Bailey's [article on killing zombies](http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/). The `close()` method is available on any Marionette.View. If you're using a plain old Backbone.View with Geppetto, a `close()` method will be created on the View for you when you call `bindContext()`.
383388

384389
When a Context is destroyed, all events on the Context's event bus will be unmapped.
385390

@@ -421,7 +426,7 @@ command.prototype.execute = function () {
421426
// Injection #1: context
422427
// The Context which invoked this command will be injected automatically,
423428
// so any properties assigned to the Context will be available in the Command.
424-
// This is a good way to provide access to your Model data!
429+
// This is a good way to provide access to your Model data!
425430
this.updateModel(this.context.model);
426431

427432
// Injection #2: eventName
@@ -434,7 +439,7 @@ command.prototype.execute = function () {
434439
} else {
435440
// other stuff
436441
}
437-
442+
438443
// Injection #3: eventData
439444
// An object literal that was passed from the caller which first dispatched the application event. This is a way
440445
// to provide payload data to a Command. The Command may also dispatch an app event with payload data as a response back to the view.
@@ -452,7 +457,7 @@ return command;
452457

453458
### Responsibilities of a Command
454459

455-
* **Single Purpose**: A Command should have one purpose and one purpose only. This makes understanding and testing the command very easy.
460+
* **Single Purpose**: A Command should have one purpose and one purpose only. This makes understanding and testing the command very easy.
456461
* **Short-Lived**: A Command should "get in and get out", doing its job and exiting the `execute()` function as soon as its job is done. This allows the Command to be garbage collected.
457462
* **Respectful of its Boundaries**: A Command should never manipulate the view directly. Your Command's job is to act on Model data, and dispatch an event when it's done. The View can listen for this event and handle updating itself.
458463

@@ -512,30 +517,30 @@ Backbone.Geppetto.debug.countEvents();
512517

513518
## FAQ
514519

515-
### How Many Contexts?
520+
### How Many Contexts?
516521
How many Contexts do I need in my app?
517522

518523
Like most questions about application structure, the answer is the familiar and often-frustrating, "It depends."
519524

520-
The best way to understand Contexts is to step back and think about which pieces of your application could theoretically exist as their own totally independent applications.
525+
The best way to understand Contexts is to step back and think about which pieces of your application could theoretically exist as their own totally independent applications.
521526

522527
* Single-Context Apps: If your app has many sub-views, which all need to communicate but could not really function on their own, then you might benefit from a Single-Context app. You can still benefit from a loosely-coupled architecture using the Context's Service Locator pattern, and the Command Registry to keep your business logic neat and tidy.
523528

524529
* Multiple-Context Apps: If I have a multi-tabbed application, for instance, where each tab has its own self-contained UI, its own backing data, and its own business logic, then you might consider creating one Context per tab. After all, the tab generally doesn't need to communicate with other tabs, nor should other tabs be informed of what actions are taking place within its boundaries. Depending on your app's needs, you may choose to have one "parent" Context that represents the outer application shell, which handles global things like navigation, tab creation, etc. See the example app below for a demo of communicating between parent and child contexts.
525530

526531
## Examples
527532
### Modular Widgets
528-
Pointless? Yes.
529-
Easy-to-understand? I hope so!
530-
Fun? Probably just as much as Farmville!
533+
Pointless? Yes.
534+
Easy-to-understand? I hope so!
535+
Fun? Probably just as much as Farmville!
531536

532537
[Give it a whirl here](http://modeln.github.com/backbone.geppetto/examples/).
533538

534539
Source code available in the `examples` directory in the Github Repo.
535540

536-
## Related articles
541+
## Related articles
537542
* [Developing modular apps with backbone and Geppetto](http://niki4810.github.io/blog/2013/05/26/building-modular-apps-using-backbone-and-geppetto/)
538-
543+
539544
## Tests
540545
### About
541546
Geppetto test specs are written using [QUnit](http://docs.jquery.com/Qunit) with [BDD](http://en.wikipedia.org/wiki/Behavior_Driven_Development) syntax provided by the [Pavlov](https://github.com/mmonteleone/pavlov) plugin. Mocks, Spies, and Stubs are provided by the fantastic [SinonJS](http://sinonjs.org/) library.
@@ -545,10 +550,17 @@ Run the current Geppetto Test Specs in your browser [here](http://modeln.github.
545550

546551
## Version History
547552

553+
### 0.6.2
554+
*Released 31 July 2013*
555+
556+
* Enforce that commands are constructable.
557+
* Allow batch registration of several commands for a single event
558+
* Thanks to [creynders](https://github.com/creynders) for these enhancements!
559+
548560
### 0.6.1
549561
*Released 17 July 2013*
550562

551-
* Enforce that event payloads are objects, and not other types.
563+
* Enforce that event payloads are objects, and not other types.
552564

553565
### 0.6
554566
*Released 2 June 2013*
@@ -566,7 +578,7 @@ Run the current Geppetto Test Specs in your browser [here](http://modeln.github.
566578

567579
* Add grunt build which runs the test specs, and lints the project. See the docs section "Get Involved > Contributing" for more info.
568580
* Fixed several lint errors
569-
* Bump backbone to 1.0.
581+
* Bump backbone to 1.0.
570582
* Moved marionette and associated libs from "dependencies" to "example-dependencies" since Geppetto itself does not depend on them.
571583
* Bump Marionette versions to latest (used only by example app, not by Geppetto itself)
572584
* Refactored test specs to use plain Backbone views instead of Marionette views
@@ -590,8 +602,8 @@ Run the current Geppetto Test Specs in your browser [here](http://modeln.github.
590602
### 0.4
591603
*Released: 25 January 2013*
592604

593-
* Use new ["inversion-of-control"](http://documentcloud.github.com/backbone/#upgrading)-style Backbone `listenTo` API to allow consumers of Context events to maintain their own event references,
594-
instead of Geppetto managing all the binding/unbinding logic.
605+
* Use new ["inversion-of-control"](http://documentcloud.github.com/backbone/#upgrading)-style Backbone `listenTo` API to allow consumers of Context events to maintain their own event references,
606+
instead of Geppetto managing all the binding/unbinding logic.
595607
* Consumers of Geppetto Context events which are not views, can use `Marionette.addEventBinder()` to mix-in the `listenTo` API into themselves.
596608
* Refactored internals to work with Backbone v0.9.10.
597609
* Updated dependencies to latest versions (Backbone, Marionette, jQuery)
@@ -607,18 +619,18 @@ instead of Geppetto managing all the binding/unbinding logic.
607619
*Released: 12 November 2012*
608620

609621
* Updated Geppetto to work with Marionette v1.0.0 beta 5
610-
* Marionette can now be downloaded as a bundled build which includes EventAggregator and Wreqr, so these secondary dependencies have been removed from Geppetto. Instead, Geppetto's dependency is now on the bundled Marionette build.
622+
* Marionette can now be downloaded as a bundled build which includes EventAggregator and Wreqr, so these secondary dependencies have been removed from Geppetto. Instead, Geppetto's dependency is now on the bundled Marionette build.
611623
* Removed redundant "contexts" variable which was defined twice.
612624

613625
### 0.2.1
614626
*Released: 18 October 2012*
615627

616-
* Updated Geppetto to work with Marionette v1.0.0 beta 1
628+
* Updated Geppetto to work with Marionette v1.0.0 beta 1
617629

618630
### 0.2.0
619631
*Released: 26 April 2012*
620632

621-
* Removed Livequery and service-locator to simplify the framework and remove all ties to the DOM.
633+
* Removed Livequery and service-locator to simplify the framework and remove all ties to the DOM.
622634
* Added logic to automatically destroy a Context and unmap its events when the close() method is called on the parent View
623635

624636
### 0.1.1

backbone.geppetto.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,14 @@
153153

154154
Geppetto.Context.prototype.mapCommands = function mapCommands() {
155155
var _this = this;
156-
_.each(this.commands, function(commandClass, eventName) {
157-
_this.mapCommand(eventName, commandClass);
156+
_.each(this.commands, function(mixedType, eventName) {
157+
if(_.isArray(mixedType)){
158+
_.each(mixedType, function(commandClass){
159+
_this.mapCommand(eventName, commandClass);
160+
});
161+
}else{
162+
_this.mapCommand(eventName, mixedType);
163+
}
158164
});
159165
};
160166

0 commit comments

Comments
 (0)