Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #1 from gordonbrander/reducers

Process enter streams to create new Todo items
  • Loading branch information...
commit 7f4a6319e49bc8223d659a44ba0c943069092c18 2 parents ad9724e + 0a8ae98
@Gozala authored
View
135 architecture-examples/reducers/main.js
@@ -3,25 +3,132 @@
forin: true latedef: false globalstrict: true */
'use strict';
-var open = require('reducers/dom').open
+// Imports
+// -----------------------------------------------------------------------------
+
+var open = require('reducers/dom').open;
var core = require('reducers/core'),
- filter = core.filter, map = core.map
+ filter = core.filter,
+ map = core.map;
+
+var reduce = require('reducers/accumulator').reduce;
+
+// Helper Functions
+// -----------------------------------------------------------------------------
+
+var each = function (source, f) {
+ reduce(source, function (_, item) {
+ f(item);
+ });
+ return null;
+};
+
+// Generate a unique client ID.
+var cid = function () {
+ return (Date.now()).toString(16);
+};
+
+var isTruthy = function (thing) {
+ return !!thing;
+};
+
+// Mutates an element by capturing, removing and returning it's value.
+var removeValue = function (el) {
+ var value = el.value;
+ el.value = '';
+ return value;
+};
+
+var isEnterKey = function (event) {
+ return event.keyCode === 13;
+};
+
+// Create a new Todo element from a template by passing an
+// object as a data model.
+var createTodo = function (model) {
+ var liEl = document.createElement('li');
+ liEl.setAttribute('id', model.cid);
+ liEl.innerHTML = '<div class="view"><input class="toggle" type="checkbox"><label>' +
+ model.title +
+ '</label><button class="destroy"></button></div><input class="edit" value="' +
+ model.title +
+ '">';
+
+ return liEl;
+}
+
+// Prepend an element to the top of a parent element.
+// This helper could be replaced if you decide to use jQuery.
+var prepend = function (parentEl, childEl) {
+ var firstChild = parentEl.firstChild;
+ parentEl.insertBefore(childEl, firstChild);
+}
+
+var updateCount = function (count) {
+ document.getElementById('todo-count').textContent = count;
+}
+
+// Create new TODO
+// -----------------------------------------------------------------------------
+
+var docEl = document.documentElement;
+
+var presses = open(docEl, 'keypress');
+
+var enters = filter(presses, isEnterKey);
+
+var incomingTitles = map(enters, function (event) {
+ return event.target.value;
+});
+
+var validTitles = filter(incomingTitles, isTruthy);
+
+var newTodos = map(validTitles, function (title) {
+ return {
+ // Generate a client ID for this TODO.
+ cid: cid(),
+ title: title,
+ done: false
+ };
+});
+
+var newTodoEls = map(newTodos, createTodo);
+
+var todosEl = document.getElementById('todo-list');
+
+// Add the todo elements to the DOM as they stream in.
+each(newTodoEls, function (todoEl) {
+ prepend(todosEl, todoEl);
+});
+
+// Clear each value after it's processed.
+each(enters, function (event) {
+ event.target.value = '';
+});
+
+// Update the item count for each item entered.
+reduce(enters, function (count) {
+ count = count + 1;
+ updateCount(count);
+ return count;
+}, 0);
-var reduce = require('reducers/accumulator').reduce
+// Mouse Mover
+// -----------------------------------------------------------------------------
+var moves = open(docEl, 'mousemove');
-var mouseEvents = open(document.documentElement, 'mousemove')
-var mousePositions = map(mouseEvents, function(event) {
- return { x: event.clientX, y: event.clientY }
-})
+var positions = map(moves, function(event) {
+ return { x: event.clientX, y: event.clientY };
+});
-var element = document.createElement('span')
-element.textContent = 'hello world 3'
-element.style.position = 'absolute'
-element.style.top = 0
-document.body.appendChild(element)
+var element = document.createElement('span');
+element.textContent = 'hello world 3';
+element.style.position = 'absolute';
+element.style.top = 0;
+document.body.appendChild(element);
-reduce(mousePositions, function(result, position) {
+reduce(positions, function(result, position) {
element.style.top = position.y + 'px'
element.style.left = position.x + 'px'
-})
+});
View
2  architecture-examples/reducers/package.json
@@ -18,6 +18,6 @@
"url": "https://github.com/addyosmani/todomvc/issues/"
},
"dependencies": {
- "reducers": "git://github.com/gozala/reducers.git#experiment/browser"
+ "reducers": "git://github.com/Gozala/reducers.git#experiment/browser"
}
}
View
24 architecture-examples/reducers/readme.md
@@ -1,18 +1,37 @@
# [TodoMVC](http://todomvc.com) using reducers
+Reducers is a reactive programming approach to creating applications.
+
+Reducers allow you to process streams of data in real time by using and transforming processing functions. You don't have to create a bunch of interim array containers for that data, because your functions react to it *as it streams in*.
+
+There are a bunch of happy side-effects to this approach as well:
+
+* You don't need to do data-binding. Since you're mapping and filtering from the same live stream, everything stays in sync automatically.
+* You don't need to allocate memory to store your data if you don't want to. Your program reacts to the data as it streams in.
+
## Install
+You'll need [Node][node] with [NPM][npm]. Once you've got that:
+
```sh
+cd todomvc/architecture-examples/reducers
npm install
```
+You'll also need [Browserify][].
+
+```sh
+npm install -g browserify
+```
+
## Usage
```sh
+cd todomvc/architecture-examples/reducers
npm run browserify
```
-Unfortunately [browserify][] watch is [broken on OSX 10.7][watch bug], but
+Unfortunately [Browserify][browserify] watch is [broken on OSX 10.7][watch bug], but
there is a [fix][watch fix] that did not made it to upstream yet. As a
temporary workaround you could use that fix to get watch working:
@@ -23,7 +42,8 @@ curl https://github.com/substack/node-browserify/pull/190.patch | git am
npm install -g
```
-
+[node]:http://nodejs.org/
+[npm]:http://npmjs.org/
[browserify]:https://github.com/substack/node-browserify
[watch bug]:https://github.com/substack/node-browserify/issues/166
[watch fix]:https://github.com/substack/node-browserify/pull/190
Please sign in to comment.
Something went wrong with that request. Please try again.