Created
March 1, 2013 17:51
-
-
Save gordonbrander/5066436 to your computer and use it in GitHub Desktop.
updateState - a utility for representing/updating program state as an object.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var STATE_FILTERS = [ | |
function clampIndex(state, old, update) { | |
return extend(state, { | |
// Validate and sanitize properties. | |
index: clamp(state.index, 0, state.units - 1) | |
}); | |
}, | |
function calculateOffset(state, old, update) { | |
return extend(state, { | |
// Create calculated properties. | |
offset: state.index * state.unitWidth | |
}); | |
} | |
]; | |
// Set up state. | |
var STATE = updateState({}, { | |
index: 0, | |
units: 9, | |
unitWidth: 320 | |
}, STATE_FILTERS); | |
el.addEventListener('click', function (event) { | |
if (event.target === nextEl) { | |
// Any time a change is made to program state, use updateState. | |
STATE = render(updateState(STATE, { index: STATE.index + 1 }, STATE_FILTERS)); | |
event.preventDefault(); | |
} | |
else if (event.target === prevEl) { | |
STATE = render(updateState(STATE, { index: STATE.index - 1 }, STATE_FILTERS)); | |
event.preventDefault(); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function lambda(method) { | |
// Convert a method func that uses a `this` context into a function that takes | |
// the context object as the first parameter. | |
return function (context) { | |
var args = Array.prototype.slice.call(arguments, 1); | |
return method.apply(context, args); | |
}; | |
} | |
// A lambda approach to `Array.prototype.slice`. | |
// Used in a lot of places for slicing the arguments object into a proper array. | |
var slice = Array.slice || lambda(Array.prototype.slice); | |
var reduce = Array.reduce || lambda(Array.prototype.reduce); | |
function extend(obj/* obj1, obj2, objN */) { | |
// Copy all keys and values of obj1..objN to obj. | |
// Mutates obj. Tip: use `Object.create` to copy values to a new object. | |
return reduce(slice(arguments, 1), function (obj, objN) { | |
return reduce(Object.keys(objN), function (obj, key) { | |
obj[key] = objN[key]; | |
return obj; | |
}, obj); | |
}, obj); | |
} | |
function extendState(state, old, update) { | |
// This filter is always run first by updateState. | |
// Extends state with keys/values from update | |
return extend(state, update); | |
} | |
function updateState(old, update, filters) { | |
// Create a new "state" object from `old` by running it through a series of | |
// filter functions. | |
// Start by extending a prototypal copy of `old` with `update`. | |
return reduce([extendState].concat(filters), function (state, filter) { | |
// Filter functions receive current state, old state and update object. | |
return filter(state, old, update); | |
}, Object.create(old)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment