Javascript 使用ReactJs和Node.js构建搜索过滤器
应用程序正在Node.js上运行并进行响应。在数据库(使用mongodb)中,我有收集室,其中包含关于特定房间的详细信息 我正在尝试根据例如客人数量搜索该集合,如果搜索输入中的客人数量为2,我希望显示可以有两位客人的所有房间 另外,我的问题是,是否可以对收集室中的每个字段进行搜索输入?例如客人数量、房间类型、价格等 使用搜索输入还是下拉搜索更好 服务器部分 UserModel.jsJavascript 使用ReactJs和Node.js构建搜索过滤器,javascript,node.js,reactjs,Javascript,Node.js,Reactjs,应用程序正在Node.js上运行并进行响应。在数据库(使用mongodb)中,我有收集室,其中包含关于特定房间的详细信息 我正在尝试根据例如客人数量搜索该集合,如果搜索输入中的客人数量为2,我希望显示可以有两位客人的所有房间 另外,我的问题是,是否可以对收集室中的每个字段进行搜索输入?例如客人数量、房间类型、价格等 使用搜索输入还是下拉搜索更好 服务器部分 UserModel.js const mongoose = require('mongoose'); const Schema = mong
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Define our model
const roomSchema = new Schema({
title: { type: String },
description: { type: String },
price: { type: Number },
room_type: { type: String },
nb_guests: { type: Number },
imageData: {type: String}
});
// Create the model class
const ModelClass = mongoose.model('room', roomSchema);
// Export the model
module.exports = ModelClass;
const Room = props => (
<div className = "col-md-4" >
<div className="card mb-4 shadow-sm">
<img src={room9} class="card-img-top"
alt="..." width="100%" height="225" />
<div className="card-body">
<h5 class="card-title">{props.room.title}</h5>
<p className="card-text">{props.room.description}</p>
<div className="d-flex justify-content-between align-
items-center">
<div className="btn-group">
<Link className="btn btn-sm
btn-outline-secondary" to={"/view/"+props.room._id}>View</Link>
</div>
</div>
</div>
</div>
</div >
)
function searchingFor(term){
return function(x){
return x.props.room.nb_guests.toLowerCase().includes(term.toLowerCase()) || !term;
}
}
export default class LandingPage extends React.Component {
constructor(props) {
super(props);
this.state = {
rooms: [],
term:''
}
this.onSearchHandler = this.onSearchHandler.bind(this);
}
componentDidMount() {
axios.get('http://localhost:3090/admin/')
.then(response => {
this.setState({
rooms: response.data
})
.catch(function (error) {
console.log(error);
})
})
}
roomList() {
return this.state.rooms.filter(searchingFor(this.state.term)).map(function (currentRoom, i) {
return <Room room={currentRoom} key={i} />
});
}
onSearchHandler(e){
this.setState({
term:e.target.value
})
}
render() {
return (
<div>
<LPheader />
<Carousel />
<div>
<div className="album py-5 bg-light">
<div className="container">
<div className="row">
<form>
<input
type="text"
onChange={this.onSearchHandler}
value={term}
/>
</form>
{this.roomList()}
</div>
</div>
</div>
</div>
</div>
)
}
}
客户端部分
LandingPage.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Define our model
const roomSchema = new Schema({
title: { type: String },
description: { type: String },
price: { type: Number },
room_type: { type: String },
nb_guests: { type: Number },
imageData: {type: String}
});
// Create the model class
const ModelClass = mongoose.model('room', roomSchema);
// Export the model
module.exports = ModelClass;
const Room = props => (
<div className = "col-md-4" >
<div className="card mb-4 shadow-sm">
<img src={room9} class="card-img-top"
alt="..." width="100%" height="225" />
<div className="card-body">
<h5 class="card-title">{props.room.title}</h5>
<p className="card-text">{props.room.description}</p>
<div className="d-flex justify-content-between align-
items-center">
<div className="btn-group">
<Link className="btn btn-sm
btn-outline-secondary" to={"/view/"+props.room._id}>View</Link>
</div>
</div>
</div>
</div>
</div >
)
function searchingFor(term){
return function(x){
return x.props.room.nb_guests.toLowerCase().includes(term.toLowerCase()) || !term;
}
}
export default class LandingPage extends React.Component {
constructor(props) {
super(props);
this.state = {
rooms: [],
term:''
}
this.onSearchHandler = this.onSearchHandler.bind(this);
}
componentDidMount() {
axios.get('http://localhost:3090/admin/')
.then(response => {
this.setState({
rooms: response.data
})
.catch(function (error) {
console.log(error);
})
})
}
roomList() {
return this.state.rooms.filter(searchingFor(this.state.term)).map(function (currentRoom, i) {
return <Room room={currentRoom} key={i} />
});
}
onSearchHandler(e){
this.setState({
term:e.target.value
})
}
render() {
return (
<div>
<LPheader />
<Carousel />
<div>
<div className="album py-5 bg-light">
<div className="container">
<div className="row">
<form>
<input
type="text"
onChange={this.onSearchHandler}
value={term}
/>
</form>
{this.roomList()}
</div>
</div>
</div>
</div>
</div>
)
}
}
你就快完成了。我认为
searkingfor()
函数过于复杂化了您的逻辑。查看以下沙箱,了解如何按客人数量筛选房间:
注释:
- 我注释掉了
请求,并插入了一些示例 数据。如果您用自己的代码交换回来,它应该仍然可以工作axios
术语
状态值来简化代码,导致重新渲染,并在新执行的房间列表()
中,筛选并返回与术语
匹配的适当房间
roomList = () => {
const { rooms, term } = this.state;
if (!term) {
return rooms.map(function(currentRoom, i) {
return <Room room={currentRoom} key={i} />;
});
} else {
return rooms
.filter(room => {
return room.nb_guests == term;
})
.map(matchingRoom => {
return <Room room={matchingRoom} />;
});
}
};
onSearchHandler = e => {
this.setState({
term: e.target.value
});
};
roomList=()=>{
const{rooms,term}=this.state;
如果(!术语){
返回房间。地图(功能(当前房间,i){
返回;
});
}否则{
回程室
.filter(房间=>{
返回房间.nb_客人==期限;
})
.map(火柴房=>{
返回;
});
}
};
onSearchHandler=e=>{
这是我的国家({
术语:目标值
});
};
在您的呈现
方法中,在您的表单上
标记将`value={term}`更改为`value={this.state.term}`谢谢!我不知道我怎么会错过它。但是现在它无法识别room
我认为这是我的函数searchingFor()
的问题,因为它在类组件之外,或者你怎么想?你只是在使用React和Node吗?有重做的吗?是的。不在这个组件中,但我正在使用它,明白了,我只是想知道,因为似乎您正在首页加载登录页组件中的所有数据。:)谢谢你的代码!它正在工作,但当我在搜索栏2号中输入时,它会正确显示有两位客人的房间,但当我尝试删除该号码并将其他号码放入搜索输入时,我无法执行,我得到的错误是“警告:列表中的每个孩子都应该有一个唯一的“键”属性。”并且收到了值属性的NaN。如果这是预期的,请将该值转换为字符串。
您可能知道原因吗?@user9347049 ahh是的,这是由于parseFloat()
造成的。在onSearchHandler()
中,只需去掉parseFloat
,使其看起来像术语:e.target.value
,然后在.filter()
中使用double equals==,因此return room.nb\u guests==term
也可以看到更新的沙盒:谢谢,它真的做到了!我想自己解决一个问题,但也有点卡住了,请允许我再问一个问题:/例如,如果我想同时搜索room collection中的其他字段,我将如何更改roomList()
函数。例如,一个搜索输入用于客人数量,另一个搜索输入用于价格,然后搜索房间类型等。。我已经在我的问题更新中添加了一些代码,比如如何做的想法。请检查谢谢你的详细回答和努力:)我真的很感激:)@user9347049非常欢迎!我希望这对你有帮助