Commit 28bdc919 authored by Cheng Lou's avatar Cheng Lou

add changes form review

parent d80d1432
......@@ -3,13 +3,16 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>React • TodoMVC</title>
<title>React + Backbone • TodoMVC</title>
<link rel="stylesheet" href="bower_components/todomvc-common/base.css">
</head>
<body>
<section id="todoapp"></section>
<footer id="info"></footer>
<div id="benchmark"></div>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://github.com/petehunt/">petehunt</a></p>
<p>Part of<a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script src="bower_components/todomvc-common/base.js"></script>
<script src="bower_components/react/react-with-addons.js"></script>
......@@ -21,6 +24,9 @@
<script src="js/todo.js"></script>
<script src="js/todos.js"></script>
<!-- jsx is an optional syntactic sugar that transforms methods in React's
`render` into an HTML-looking format. Since the two models above are
unrelated to React, we didn't need those transforms. -->
<script type="text/jsx" src="js/todoItem.jsx"></script>
<script type="text/jsx" src="js/footer.jsx"></script>
<script type="text/jsx" src="js/app.jsx"></script>
......
......@@ -5,15 +5,17 @@
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/*global Utils, ALL_TODOS, ACTIVE_TODOS, COMPLETED_TODOS,
TodoItem, TodoFooter, React, Router*/
/*global React, Backbone */
var app = app || {};
(function (window, React) {
(function () {
'use strict';
window.ALL_TODOS = 'all';
window.ACTIVE_TODOS = 'active';
window.COMPLETED_TODOS = 'completed';
app.ALL_TODOS = 'all';
app.ACTIVE_TODOS = 'active';
app.COMPLETED_TODOS = 'completed';
var TodoFooter = app.TodoFooter;
var TodoItem = app.TodoItem;
var ENTER_KEY = 13;
......@@ -29,7 +31,10 @@
componentDidMount: function () {
// Whenever there may be a change in the Backbone data, trigger a
// reconcile.
this.getBackboneCollections().forEach(function (collection, i) {
this.getBackboneCollections().forEach(function (collection) {
// explicitly bind `null` to `forceUpdate`, as it demands a callback and
// React validates that it's a function. `collection` events passes
// additional arguments that are not functions
collection.on('add remove change', this.forceUpdate.bind(this, null));
}, this);
},
......@@ -60,9 +65,9 @@
'active': 'active',
'completed': 'completed'
},
all: this.setState.bind(this, {nowShowing: ALL_TODOS}),
active: this.setState.bind(this, {nowShowing: ACTIVE_TODOS}),
completed: this.setState.bind(this, {nowShowing: COMPLETED_TODOS})
all: this.setState.bind(this, {nowShowing: app.ALL_TODOS}),
active: this.setState.bind(this, {nowShowing: app.ACTIVE_TODOS}),
completed: this.setState.bind(this, {nowShowing: app.COMPLETED_TODOS})
});
var router = new Router();
......@@ -112,7 +117,7 @@
},
save: function (todo, text) {
todo.save({'title': text});
todo.save({title: text});
this.setState({editing: null});
},
......@@ -127,15 +132,15 @@
},
render: function () {
var footer = null;
var main = null;
var footer;
var main;
var todos = this.props.todos;
var shownTodos = todos.filter(function (todo) {
switch (this.state.nowShowing) {
case ACTIVE_TODOS:
case app.ACTIVE_TODOS:
return !todo.get('completed');
case COMPLETED_TODOS:
case app.COMPLETED_TODOS:
return todo.get('completed');
default:
return true;
......@@ -208,17 +213,7 @@
});
React.renderComponent(
<TodoApp todos={new Todos()} />,
<TodoApp todos={app.todos} />,
document.getElementById('todoapp')
);
React.renderComponent(
<div>
<p>Double-click to edit a todo</p>
<p>Created by{' '}
<a href="http://github.com/petehunt/">petehunt</a>
</p>
<p>Part of{' '}<a href="http://todomvc.com">TodoMVC</a></p>
</div>,
document.getElementById('info'));
})(window, React);
})();
......@@ -5,11 +5,13 @@
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/*global React, ALL_TODOS, ACTIVE_TODOS, Utils, COMPLETED_TODOS */
(function (window) {
/*global React */
var app = app || {};
(function () {
'use strict';
window.TodoFooter = React.createClass({
app.TodoFooter = React.createClass({
render: function () {
var activeTodoWord = this.props.count === 1 ? 'item' : 'items';
var clearButton = null;
......@@ -24,13 +26,9 @@
);
}
var show = {
ALL_TODOS: '',
ACTIVE_TODOS: '',
COMPLETED_TODOS: ''
};
show[this.props.nowShowing] = 'selected';
// React idiom for shortcutting to `classSet` since it'll be used often
var cx = React.addons.classSet;
var nowShowing = this.props.nowShowing;
return (
<footer id="footer">
<span id="todo-count">
......@@ -39,15 +37,27 @@
</span>
<ul id="filters">
<li>
<a href="#/" className={show[ALL_TODOS]}>All</a>
<a
href="#/"
className={cx({selected: nowShowing === app.ALL_TODOS})}>
All
</a>
</li>
{' '}
<li>
<a href="#/active" className={show[ACTIVE_TODOS]}>Active</a>
<a
href="#/active"
className={cx({selected: nowShowing === app.ACTIVE_TODOS})}>
Active
</a>
</li>
{' '}
<li>
<a href="#/completed" className={show[COMPLETED_TODOS]}>Completed</a>
<a
href="#/completed"
className={cx({selected: nowShowing === app.COMPLETED_TODOS})}>
Completed
</a>
</li>
</ul>
{clearButton}
......@@ -55,4 +65,4 @@
);
}
});
})(window);
})();
(function (window, Backbone) {
/*global Backbone */
var app = app || {};
(function () {
'use strict';
window.Todo = Backbone.Model.extend({
// Todo Model
// ----------
// Our basic **Todo** model has `title`, `order`, and `completed` attributes.
app.Todo = Backbone.Model.extend({
// Default attributes for the todo
// and ensure that each todo created has `title` and `completed` keys.
defaults: {
......@@ -16,4 +23,4 @@
});
}
});
})(window, Backbone);
})();
......@@ -5,14 +5,16 @@
/*jshint white: false */
/*jshint trailing: false */
/*jshint newcap: false */
/*global React, Utils */
(function (window) {
/*global React */
var app = app || {};
(function () {
'use strict';
var ESCAPE_KEY = 27;
var ENTER_KEY = 13;
window.TodoItem = React.createClass({
app.TodoItem = React.createClass({
getInitialState: function () {
return {editText: this.props.todo.get('title')};
},
......@@ -42,10 +44,10 @@
},
handleKeyDown: function (event) {
if (event.keyCode === ESCAPE_KEY) {
if (event.which === ESCAPE_KEY) {
this.setState({editText: this.props.todo.get('title')});
this.props.onCancel();
} else if (event.keyCode === ENTER_KEY) {
} else if (event.which === ENTER_KEY) {
this.handleSubmit();
}
},
......@@ -84,4 +86,4 @@
);
}
});
})(window);
})();
(function (window, Backbone) {
/*global Backbone */
var app = app || {};
(function () {
'use strict';
window.Todos = Backbone.Collection.extend({
// Todo Collection
// ---------------
// The collection of todos is backed by *localStorage* instead of a remote
// server.
var Todos = Backbone.Collection.extend({
// Reference to this collection's model.
model: Todo,
model: app.Todo,
// Save all of the todo items under the `"todos"` namespace.
localStorage: new Backbone.LocalStorage('todos-react-backbone'),
// Filter down the list of all todo items that are finished.
completed: function () {
return this.filter(function(todo) {
return this.filter(function (todo) {
return todo.get('completed');
});
},
// Filter down the list to only todo items that are still not finished.
remaining: function () {
return this.without.apply(this, this.completed());
},
......@@ -34,4 +42,7 @@
return todo.get('order');
}
});
})(window, Backbone);
// Create our global collection of **Todos**.
app.todos = new Todos();
})();
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment