Giter VIP home page Giter VIP logo

modelflow's Introduction

ModelFlow->

ModelFlow is a JavaScript evented state machine written to run both in node.js and the browser.

##Design Goals

  • Easily create state machine on top of a existing data model(s).
  • Define states based on the data models attribute values.
  • Ability to listen for state changes and run callbacks.
  • Provide a mechanism to optionally enforce linear paths from state to state. This may be used an alternative to flow control libraries.

Installation / Basic Usage

ModelFlow depends on Underscore and is built as a complement to Backbone.

On the Server

Install the library using npm or add it to your package.json file as a dependancy. Instances of ModelFlow are technically Backbone Models, however the module can be used completely standalone.

  $npm install modelflow

Define a StateModel class, create an instance of it.

var ModelFlow = require('modelflow');
var CustomFlow = ModelFlow.StateModel.extend({
    states : {
        state1 : { foo : 1 },
        staet2 : { foo : 2 }
    }
});

var flow = new CustomFlow();

On the Client

Just like server, however ModelFlow will be pushed on the window as a global.

<script type="text/javascript" src="underscore.js"></script>
<script type="text/javascript" src="backbone.js"></script>
<script type="text/javascript" src="ModelFlow.js"></script>

<script type="text/javascript">
	var CustomFlow = ModelFlow.StateModel.extend({
	    states : {
	        state1 : { foo : 1 },
	        staet2 : { foo : 2 }
	    }
	});

	var flow = new CustomFlow();
</script>

Moar Usage

###Bind callbacks on state changes

	var CustomFlow = ModelFlow.StateModel.extend({
	    states : {
	        init : { foo : 1 }
	    }
	});

	var flow = new CustomFlow();
	flow.bind('state:->init', function() {
		console.log('init entered');
	});

	flow.bind('state:init->', function() {
		console.log('init exited');
	});

	flow.set({ foo : 0 });  //this does nothing
	flow.set({ foo : 1 });  //logs 'init entered' 
	flow.set({ foo : 2 });  //logs 'init exited'

###Define multiple, complex states

	var CustomFlow = ModelFlow.StateModel.extend({
	    states : {
	        state1 : { 
	        	foo : 1,
	        	bar : "testing"
	        },
	        state2 : { 
	        	foo : 1,
	        	bar : "hello"
	        },
	        state3 : {
	        	foo : 1,
	        	bar : "testing",
	        	cat : "meow"
	        }
	    }
	});

	//since this is a Backbone Model, 
	//we can pass the inital JSON data into 
	//the constructor, which will also set the state to state1
	var flow = new CustomFlow({
		foo : 1,
	    bar : "testing"
	});

	flow.bind('state:state1->', function() {
		console.log('state1 exited');
	});
	flow.bind('state:->state2', function() {
		console.log('state2 entered');
	});
	flow.bind('state:->state3', function() {
		console.log('state3 entered');
	});

	console.log(flow.inState('state1')); //logs true
	console.log(flow.inState('state2')); //logs false
	console.log(flow.inState('state3')); //logs false

	flow.set({ cat : 'meow' }); //logs 'state3 entered'

	console.log(flow.inState('state1')); //logs true
	console.log(flow.inState('state2')); //logs false
	console.log(flow.inState('state3')); //logs true

	flow.set({ bar : 'hello' }); //logs 'state 1 exited' and 'state2 entered'

	console.log(flow.inState('state1')); //logs false
	console.log(flow.inState('state2')); //logs true
	console.log(flow.inState('state3')); //logs false

###Define constraints between state changes

	var CustomFlow = ModelFlow.StateModel.extend({
	    states : {
	        first :  { foo : 1 },
	        second : { foo : 2 }
	    },
	    constrints : [ 'first->second' ]
	});

	var flow = new CustomFlow({ foo : 0});
	flow.bind('first->second', function() {
		console.log('flowing from first to second');
	});	

	flow.set('foo', 2);
	console.log(flow.inState('first'));  // logs false
	console.log(flow.inState('second')); // logs false , can't get to second without coming from first

	flow.set('foo', 1);
	console.log(flow.inState('first'));  // logs true
	console.log(flow.inState('second')); // logs false 


	flow.set('foo', 2);                  // logs 'flowing from first to second'
	console.log(flow.inState('first'));  // logs false
	console.log(flow.inState('second')); // logs true

modelflow's People

Contributors

ryanstevens avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.