From bc99ccbc468452b04a61fef31606e91226511bc5 Mon Sep 17 00:00:00 2001 From: "xuewei.lxw" Date: Thu, 16 Jun 2016 09:44:15 +0800 Subject: [PATCH] =?UTF-8?q?complete=20example=20=20'action'=20and=20'filte?= =?UTF-8?q?r'=EF=BC=8Cseparate=20component=EF=BC=8Cmake=20example=20easyer?= =?UTF-8?q?=20to=20understand=EF=BC=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/todomvc/actions/FilterActions.js | 13 +++ .../actions/{index.js => TodoActions.js} | 0 examples/todomvc/components/Footer.js | 86 +++++++++++-------- examples/todomvc/components/TodoItem.js | 14 ++- .../{MainSection.js => TodosList.js} | 38 ++------ examples/todomvc/constants/TodoFilters.js | 6 +- examples/todomvc/containers/App.js | 23 +++-- examples/todomvc/reducers/filter.js | 18 ++++ examples/todomvc/reducers/index.js | 3 +- examples/todomvc/reducers/todos.js | 11 +-- 10 files changed, 124 insertions(+), 88 deletions(-) create mode 100644 examples/todomvc/actions/FilterActions.js rename examples/todomvc/actions/{index.js => TodoActions.js} (100%) rename examples/todomvc/components/{MainSection.js => TodosList.js} (58%) create mode 100644 examples/todomvc/reducers/filter.js diff --git a/examples/todomvc/actions/FilterActions.js b/examples/todomvc/actions/FilterActions.js new file mode 100644 index 0000000000..41ea3d40cb --- /dev/null +++ b/examples/todomvc/actions/FilterActions.js @@ -0,0 +1,13 @@ +import * as types from '../constants/TodoFilters' + +export function showAll() { + return {type:types.SHOW_ALL} +} + +export function showActive() { + return {type:types.SHOW_ACTIVE} +} + +export function showCompleted() { + return {type:types.SHOW_COMPLETED} +} \ No newline at end of file diff --git a/examples/todomvc/actions/index.js b/examples/todomvc/actions/TodoActions.js similarity index 100% rename from examples/todomvc/actions/index.js rename to examples/todomvc/actions/TodoActions.js diff --git a/examples/todomvc/components/Footer.js b/examples/todomvc/components/Footer.js index 8ae9c59983..0a2bed5107 100644 --- a/examples/todomvc/components/Footer.js +++ b/examples/todomvc/components/Footer.js @@ -9,65 +9,79 @@ const FILTER_TITLES = { } class Footer extends Component { + renderTodoCount() { - const { activeCount } = this.props + const { todos } = this.props; + const completedCount = todos.reduce((count, todo) => + todo.completed ? count + 1 : count, + 0 + ) + const activeCount = todos.length - completedCount + const itemWord = activeCount === 1 ? 'item' : 'items' - return ( - - {activeCount || 'No'} {itemWord} left - + return ( < span className = "todo-count" > + < strong > { activeCount || 'No' } < /strong> {itemWord} left < /span> ) } + onShow(filter) { + switch (filter) { + case SHOW_COMPLETED: + this.props.filterActions.showCompleted(); + break; + case SHOW_ACTIVE: + this.props.filterActions.showActive(); + break; + default: + this.props.filterActions.showAll(); + } + } + renderFilterLink(filter) { const title = FILTER_TITLES[filter] const { filter: selectedFilter, onShow } = this.props - - return ( - onShow(filter)}> - {title} - + return ( < a className = { classnames({ selected: filter === selectedFilter }) } + style = { + { cursor: 'pointer' } } + onClick = { + () => this.onShow(filter) } > { title } < /a> ) } + onClearCompleted() { + this.props.todoActions.clearCompleted() + } + renderClearButton() { - const { completedCount, onClearCompleted } = this.props + const { todos } = this.props; + const completedCount = todos.reduce((count, todo) => + todo.completed ? count + 1 : count, + 0 + ) + const activeCount = todos.length - completedCount if (completedCount > 0) { - return ( - + return ( < button className = "clear-completed" + onClick = { this.onClearCompleted.bind(this) } > + Clear completed < /button> ) } } render() { - return ( - - ) + return ( < footer className = "footer" > { this.renderTodoCount() } < ul className = "filters" > { + [SHOW_ALL, SHOW_ACTIVE, SHOW_COMPLETED].map(filter => + < li key = { filter } > { this.renderFilterLink(filter) } < /li> + ) + } < /ul> { this.renderClearButton() } < /footer>) } } Footer.propTypes = { - completedCount: PropTypes.number.isRequired, - activeCount: PropTypes.number.isRequired, - filter: PropTypes.string.isRequired, - onClearCompleted: PropTypes.func.isRequired, - onShow: PropTypes.func.isRequired + todos: PropTypes.array.isRequired, + todoActions: PropTypes.object.isRequired, + filterActions: PropTypes.object.isRequired } export default Footer + diff --git a/examples/todomvc/components/TodoItem.js b/examples/todomvc/components/TodoItem.js index a892951842..fa75646384 100644 --- a/examples/todomvc/components/TodoItem.js +++ b/examples/todomvc/components/TodoItem.js @@ -14,6 +14,16 @@ class TodoItem extends Component { this.setState({ editing: true }) } + handleClick(evt) { + evt.preventDefault(); + // because of linkState call in render, field will get value from this.state.editValue + setTimeout(function () { + if(!this.state.editing){ + this.refs.toggleCompleted.getDOMNode().click(); + } + }.bind(this), 200); + } + handleSave(id, text) { if (text.length === 0) { this.props.deleteTodo(id) @@ -36,11 +46,11 @@ class TodoItem extends Component { } else { element = (
- completeTodo(todo.id)} /> -