Skip to content

Instantly share code, notes, and snippets.

@gordonbrander
Created March 1, 2013 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gordonbrander/5066436 to your computer and use it in GitHub Desktop.
Save gordonbrander/5066436 to your computer and use it in GitHub Desktop.
updateState - a utility for representing/updating program state as an object.
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();
}
});
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