gpt4 book ai didi

javascript - 在 React Js 中过滤 Todo 列表

转载 作者:行者123 更新时间:2023-11-27 22:52:44 25 4
gpt4 key购买 nike

我是 React 新手(我习惯使用 Angular),目前正在根据类别选择过滤我的待办事项列表应用程序。

我从 http://todomvc.com/examples/react/#/ 克隆了待办事项列表应用程序。我添加了一个“类别”输入,该输入有效,但现在我尝试在显示列表后按类别进行过滤。

我目前没有任何类别搜索功能,正在寻找一些关于从哪里开始的指导。我将发布下面的代码,但如果您想克隆它,这里是我的存储库的链接:https://github.com/aenser/todo-react

app.jsx

    var app = app || {};

(function () {
'use strict';

app.ALL_TODOS = 'all';
app.ACTIVE_TODOS = 'active';
app.COMPLETED_TODOS = 'completed';
var TodoFooter = app.TodoFooter;
var TodoItem = app.TodoItem;

var ENTER_KEY = 13;

var TodoApp = React.createClass({
getInitialState: function () {
return {
nowShowing: app.ALL_TODOS,
editing: null,
newTodo: '',
newCategory: ''
};
},

componentDidMount: function () {
var setState = this.setState;
var router = Router({
'/': setState.bind(this, {nowShowing: app.ALL_TODOS}),
'/active': setState.bind(this, {nowShowing: app.ACTIVE_TODOS}),
'/completed': setState.bind(this, {nowShowing: app.COMPLETED_TODOS})
});
router.init('/');
},

handleChange: function (event) {
this.setState({newTodo: event.target.value});
},

handleCategoryChange: function (event) {
this.setState({newCategory: event.target.value});
},

handleNewTodoKeyDown: function (event) {
if (event.keyCode !== ENTER_KEY) {
return;
}

event.preventDefault();

var val = this.state.newTodo.trim();
var cat = this.state.newCategory.trim();

if (val, cat) {
this.props.model.addTodo(val, cat);
this.setState({newTodo: '', newCategory: ''});
}
},

toggleAll: function (event) {
var checked = event.target.checked;
this.props.model.toggleAll(checked);
},

toggle: function (todoToToggle) {
this.props.model.toggle(todoToToggle);
},

destroy: function (todo) {
this.props.model.destroy(todo);
},

edit: function (todo) {
this.setState({editing: todo.id});
},

save: function (todoToSave, text, cat) {
this.props.model.save(todoToSave, text, cat);
this.setState({editing: null});
},

cancel: function () {
this.setState({editing: null});
},

clearCompleted: function () {
this.props.model.clearCompleted();
},

render: function () {
var footer;
var main;
var todos = this.props.model.todos;

var shownTodos = todos.filter(function (todo) {
switch (this.state.nowShowing) {
case app.ACTIVE_TODOS:
return !todo.completed;
case app.COMPLETED_TODOS:
return todo.completed;
default:
return true;
}
}, this);

var todoItems = shownTodos.map(function (todo) {
return (
<TodoItem
key={todo.id}
todo={todo}
onToggle={this.toggle.bind(this, todo)}
onDestroy={this.destroy.bind(this, todo)}
onEdit={this.edit.bind(this, todo)}
editing={this.state.editing === todo.id}
onSave={this.save.bind(this, todo)}
onCancel={this.cancel}
/>
);
}, this);

var activeTodoCount = todos.reduce(function (accum, todo) {
return todo.completed ? accum : accum + 1;
}, 0);

var completedCount = todos.length - activeTodoCount;

if (activeTodoCount || completedCount) {
footer =
<TodoFooter
count={activeTodoCount}
completedCount={completedCount}
nowShowing={this.state.nowShowing}
onClearCompleted={this.clearCompleted}
/>;
}

if (todos.length) {
main = (
<section className="main">
<input
className="toggle-all"
type="checkbox"
onChange={this.toggleAll}
checked={activeTodoCount === 0}
/>
<ul className="todo-list">
{todoItems}
</ul>
</section>
);
}

return (
<div>
<header className="header">
<h1>todos</h1>
<form onKeyDown={this.handleNewTodoKeyDown}>
<input
placeholder="What needs to be done?"
value={this.state.newTodo}
autoFocus={true}
className="new-todo"
onChange={this.handleChange}
/>
<select value={this.state.newCategory} className="new-todo"
onChange={this.handleCategoryChange}>
<option value="">Select a Category</option>
<option value="Urgent">Urgent</option>
<option value="Soon">Soon</option>
<option value="Anytime">Anytime</option>
</select>

</form>
</header>
{main}
{footer}
</div>
);
}
});

var model = new app.TodoModel('react-todos');

function render() {
React.render(
<TodoApp model={model}/>,
document.getElementsByClassName('todoapp')[0]
);
}

model.subscribe(render);
render();
})();

todoModel.js

var app = app || {};

(function () {
'use strict';

var Utils = app.Utils;
// Generic "model" object. You can use whatever
// framework you want. For this application it
// may not even be worth separating this logic
// out, but we do this to demonstrate one way to
// separate out parts of your application.
app.TodoModel = function (key) {
this.key = key;
this.todos = Utils.store(key);
this.onChanges = [];
};

app.TodoModel.prototype.subscribe = function (onChange) {
this.onChanges.push(onChange);
};

app.TodoModel.prototype.inform = function () {
Utils.store(this.key, this.todos);
this.onChanges.forEach(function (cb) { cb(); });
};

app.TodoModel.prototype.addTodo = function (title, category) {
this.todos = this.todos.concat({
id: Utils.uuid(),
title: title,
category: category,
completed: false
});

this.inform();
};

app.TodoModel.prototype.toggleAll = function (checked) {
// Note: it's usually better to use immutable data structures since they're
// easier to reason about and React works very well with them. That's why
// we use map() and filter() everywhere instead of mutating the array or
// todo items themselves.
this.todos = this.todos.map(function (todo) {
return Utils.extend({}, todo, {completed: checked});
});

this.inform();
};

app.TodoModel.prototype.filterAll = function () {
this.todos = this.todos.map(function (todo) {
return Utils.extend({}, todo);
});

this.inform();
};

app.TodoModel.prototype.toggle = function (todoToToggle) {
this.todos = this.todos.map(function (todo) {
return todo !== todoToToggle ?
todo :
Utils.extend({}, todo, {completed: !todo.completed});
});

this.inform();
};

app.TodoModel.prototype.destroy = function (todo) {
this.todos = this.todos.filter(function (candidate) {
return candidate !== todo;
});

this.inform();
};

app.TodoModel.prototype.save = function (todoToSave, text, cat) {
this.todos = this.todos.map(function (todo) {
return todo !== todoToSave ? todo : Utils.extend({}, todo, {title: text}, {category: cat});
});

this.inform();
};

app.TodoModel.prototype.clearCompleted = function () {
this.todos = this.todos.filter(function (todo) {
return !todo.completed;
});

this.inform();
};

})();

todoItem.jsx

var app = app || {};

(function () {
'use strict';

var ESCAPE_KEY = 27;
var ENTER_KEY = 13;

app.TodoItem = React.createClass({
handleSubmit: function (event) {
var val = this.state.editText.trim();
var cat = this.state.editCategoryText.trim();
if (val || cat) {
this.props.onSave(val, cat);
this.setState({editText: this.props.todo.title, editCategoryText: this.props.todo.category});
} else {
this.props.onDestroy();
}
},

handleEdit: function (event) {
this.props.onEdit();
this.setState({editText: this.props.todo.title, editCategoryText: this.props.todo.category});
},

handleKeyDown: function (event) {
if (event.which === ESCAPE_KEY) {
this.setState({editText: this.props.todo.title});
this.props.onCancel(event);
} else if (event.which === ENTER_KEY) {
this.handleSubmit(event);
}
},

handleChange: function (event) {
if (this.props.editing) {
this.setState({editText: event.target.value});
}
},

handleCategoryChange: function (event) {
if (this.props.editing) {
this.setState({editCategoryText: event.target.value});
}
},

getInitialState: function () {
return {editText: this.props.todo.title, editCategoryText: this.props.todo.category};
},

/**
* This is a completely optional performance enhancement that you can
* implement on any React component. If you were to delete this method
* the app would still work correctly (and still be very performant!), we
* just use it as an example of how little code it takes to get an order
* of magnitude performance improvement.
*/
shouldComponentUpdate: function (nextProps, nextState) {
return (
nextProps.todo !== this.props.todo ||
nextProps.editing !== this.props.editing ||
nextState.editText !== this.state.editText ||
nextState.editCategoryText !== this.state.editCategoryText
);
},

/**
* Safely manipulate the DOM after updating the state when invoking
* `this.props.onEdit()` in the `handleEdit` method above.
* For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate
* and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate
*/
componentDidUpdate: function (prevProps) {
if (!prevProps.editing && this.props.editing) {
var node = React.findDOMNode(this.refs.editField);
node.focus();
node.setSelectionRange(node.value.length, node.value.length);
}
},

render: function () {
return (
<li className={classNames({
completed: this.props.todo.completed,
editing: this.props.editing
})}>
<div className="view">
<input
className="toggle"
type="checkbox"
checked={this.props.todo.completed}
onChange={this.props.onToggle}
/>
<label onDoubleClick={this.handleEdit}>
{this.props.todo.title}
</label>
<label onDoubleClick={this.handleEdit}>
{this.props.todo.category}
</label>
<button className="destroy" onClick={this.props.onDestroy} />
</div>
<input
ref="editField"
value={this.state.editText}
className="edit"
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
/>
<select value={this.state.EditCategoryText} className="edit" onChange={this.handleCategoryChange} defaultValue={this.props.todo.category} onKeyDown={this.handleKeyDown}>
<option value="Urgent">Urgent</option>
<option value="Soon">Soon</option>
<option value="Anytime">Anytime</option>
</select>
</li>
);
}
});
})();

感谢您花时间帮助我了解如何根据类别选择过滤搜索。

最佳答案

您的界面有点令人困惑,因为您似乎使用相同的输入选择来将类别分配给待办事项和过滤,我将在答案的末尾进行讨论,但现在,我只使用了类别选择器用于输入数据和按类别过滤。

你的问题的答案非常简单。您只需按类别和完成状态进行过滤即可。像这样:

            var shownTodos = todos.filter(function(todo) {
return(todo.category === this.state.newCategory);
}, this).filter(function (todo) {
switch (this.state.nowShowing) {
case app.ACTIVE_TODOS:
return !todo.completed;
case app.COMPLETED_TODOS:
return todo.completed;
default:
return true;
}
}, this);

我会在底部为当前显示的分类添加更多按钮。您还可以为 nowShowingCategory 等类别添加一组新的状态,例如 nowShowing。这些按钮会将其设置为类别的 3 个值,并且您将在上面的过滤器中使用该变量,而不是我的示例中的 newCategory

关于javascript - 在 React Js 中过滤 Todo 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37930127/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com