Skip to content

Instantly share code, notes, and snippets.

@eschwartz
Created April 8, 2016 13:33
Show Gist options
  • Save eschwartz/c8a98275e014b43ea6f0d3b8876d67ac to your computer and use it in GitHub Desktop.
Save eschwartz/c8a98275e014b43ea6f0d3b8876d67ac to your computer and use it in GitHub Desktop.
function intent({DOM}) {
return {
addTodo: DOM.get('input', 'change').
map(evt => evt.target.value).
filter(val => val.trim().length),
removeTodo: DOM.get('button', 'click').
// Map the remove button click to the item text
map(evt => evt.target.previousElementSibling.innerText.trim())
};
}
const Operations = {
AddItem: newItem => state => ({
items: state.items.concat(newItem)
}),
RemoveItem: itemToRemove => state => ({
items: state.items.filter(item => item !== itemToRemove)
})
};
function model(intents) {
// Map our "addTodo" intent to an add operation
var addOperations$ = intents.addTodo.
map(item => Operations.AddItem(item));
// Map our "removeTodo" intent to a remove opeartion
var removeOperations$ = intents.removeTodo.
map(item => Operations.RemoveItem(item));
// Merge our operations into a single stream
// of operations on state
var allOperations$ = Rx.Observable.merge(addOperations$, removeOperations$);
// Apply operations to the state
var state$ = allOperations$.
scan({ items: [] }, (state, operation) => operation(state));
return state$;
}
function view(state$) {
const h = CycleDOM.h;
return state$.
startWith({ items: [] }).
map(state => h('div', [
h('div', [
h('input', {type: 'text', value: ''})
]),
h('ul', state.items.map(todo =>
h('li', [
h('span', todo),
h('button', 'x')
]))
)
]));
}
function main({DOM}) {
return {
DOM: view(model(intent({DOM})))
}
}
// Bootstrap the application
Cycle.run(main, {
DOM: CycleDOM.makeDOMDriver('#app')
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment