Skip to content

Instantly share code, notes, and snippets.

@mxriverlynn
Created November 14, 2012 17:22
Show Gist options
  • Save mxriverlynn/4073465 to your computer and use it in GitHub Desktop.
Save mxriverlynn/4073465 to your computer and use it in GitHub Desktop.
Triggering events to notify of state machine state change
// This is built on top of MarionetteJS' [Controller](https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.controller.md)
// object, which includes Backbone.Events in it, to
// trigger events.
//
// I think this is a sort of statemachine. But honestly, I'm not entirely
// sure about that. I've had very little luck / experience with statemachines
// in my career.
//
// Would love to get feedback on this.
MyWorkflow = Marionette.Controller.extend({
initialize: function(workflowData){
// this is the list of available "states" or steps in this workflow
this.steps = new WorkflowStepCollection(workflowData);
},
getSteps: function(){
return this.steps;
},
nextStep: function(){
var nextStep = this.steps.getNext();
this.moveTo(nextStep);
},
previousStep: function(){
var previousStep = this.steps.getPrevious();
this.moveTo(previousStep);
},
moveTo: function(step){
step.select();
this._triggerStep(step);
},
_triggerStep: function(step){
var key = step.get("key");
this.trigger("step:" + key);
}
});
// use of this
// -----------
var workflowConfig = [
{
id: 1,
key: "first",
name: "First Step"
},
{
id: 2,
key: "second",
name: "Second Step"
}
]
var wf = new MyWorkflow(workflowConfig);
wf.on("step:first", aCallback);
wf.on("step:second", anotherCallback);
@mxriverlynn
Copy link
Author

@gilesbowkett - LOL! I generally agree with you. I've tried to use state machines many, many times over the years and I've always come away with the feeling of having been defeated, making things worse, etc.

In this case, I found this very simple implementation to be very useful.

I have a navigation system with a navbar at the top that lists each step. at the bottom, there's a Next and Previous button. i wired up the nav to the events from the workflow object.

I also have a page that goes with each step. every time the workflow object triggers a step, the correct page is shown in the content area of the screen. this is wired up by the object that knows about each of the individual pages, and is not directly related to the navigation system - so it kept both of those apart, which is what i wanted, while allowing the workflow from one "step" to the next to be centralized in to a single place.

the worry that i have, moving forward with this, is the additional complexity i need to introduce in order to determine when i can move to which step. there are rules about what has to be done before i can move in to a particular step.

i may end up regretting this and ripping it out. that has been my general experience w/ state machines. we'll see, this time around. :)

@davedx
Copy link

davedx commented Nov 14, 2012

It looks clean enough to me. Workflow engines are going to be state machines I would have thought. Maybe if I get a chance I'll try to implement it with coroutines and see if that works. Good luck with it! :)

@JohnDMathis
Copy link

Make sense for a wizard-like linear workflow. When I think of "state machine" I don't immediately think of "linear", though. Agree you'll want a "CanMoveToStep" type function that you can check to manage availability of steps. What if you kept that in the workflow controller, and various steps (views?) raised events to mark when it is ready, or not?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment