在Backbone Collections中搜索,使用React更新UI
Search in Backbone Collections, Updating UI with React
我正在花时间做一些可能很简单的事情:我想实现一个搜索栏,最好是在键入时更新项目列表。我的小应用程序使用React和Backbone(用于模型和集合)。
显示列表并不太难,它完全可以做到这一点(我使用的mixin基本上允许轻松检索集合):
var List = React.createClass ({
mixins: [Backbone.React.Component.mixin],
searchFilter: function () {
//some filtering code here, not sure how (filter method is only for arrays...)
}
}
getInitialState: function () {
initialState = this.getCollection().map(function(model) {
return {
id: model.cid,
name: model.get('name'),
description: model.get('description')
}
});
return {
init: initialState,
items : []
}
},
componentWillMount: function () {
this.setState({items: this.state.init})
},
render: function(){
var list = this.state.items.map(function(obj){
return (
<div key={obj.id}>
<h2>{obj.name}</h2>
<p>{obj.description}</p>
</div>
)
});
return (
<div className='list'>
{list}
</div>
)
}
});
现在,我尝试使用getInitialState方法首先将主干集合转换为"state",但没有成功,我的想法是通过集合的副本进行代理,然后可以保存搜索结果。为了清晰起见,我不会在这里展示我的尝试(编辑:是的,我是),有人能引导我采取正确的方法吗?提前谢谢。
有很多方法可以实现这一点,但最简单的方法(在我看来)是将搜索条件存储在List
组件的状态中,并使用它来过滤集合中显示的项目。您可以使用Backbone集合的内置filter
方法来执行此操作。
var List = React.createClass ({
mixins: [Backbone.React.Component.mixin],
getInitialState: function () {
return {
nameFilter: ''
};
},
updateSearch: function (event) {
this.setState({
nameFilter: event.target.value
});
},
filterItems: function (item) {
// if we have no filter, pass through
if (!this.state.nameFilter) return true;
return item.name.toLowerCase().indexOf(this.state.nameFilter) > -1;
},
render: function(){
var list = this.props.collection
.filter(this.filterItems.bind(this))
.map(function(obj){
return (
<div key={obj.id}>
<h2>{obj.name}</h2>
</div>
)
});
return (
<div className='list'>
{list}
<input onChange={this.updateSearch} type="text" value={this.state.nameFilter}/>
</div>
)
}
});
var collection = new Backbone.Collection([
{
name: 'Bob'
},
{
name: 'Bill'
},
{
name: 'James'
}
]);
React.render(<List collection={collection}/>, document.body);
jsbin
搜索条件可以很容易地从父组件作为道具传递下来,因此搜索输入不必存在于List
组件中。
最终我也找到了一个不同的解决方案(如下),但它涉及到将整个集合复制到状态,这可能不是一个好主意。。。
var List = React.createClass ({
mixins: [Backbone.React.Component.mixin],
searchFilter: function () {
var updatedlist = this.state.init;
var searchText = this.refs.searchbar.getDOMNode().value
updatedlist = updatedlist.filter(function (item) {
return item.name.toLowerCase().search(
searchText.toLowerCase()) !== -1
});
this.setState({items: updatedlist})
}
},
getInitialState: function () {
initialState = this.getCollection().map(function(model) {
return {
id: model.cid,
name: model.get('name'),
description: model.get('description')
}
});
return {
init: initialState,
items : []
}
},
componentWillMount: function () {
this.setState({items: this.state.init})
},
render: function(){
var list = this.state.items.map(function(obj){
return (
<div key={obj.id}>
<h2>{obj.name}</h2>
<p>{obj.description}</p>
</div>
)
});
return (
<div className='list'>
<input ref='searchbar' type="text" placeholder="Search" onChange={this.searchFilter}/>
{list}
</div>
)
}
});
相关文章:
- 为什么我的点击事件没有使用 react js 触发
- 在iOS和Android上使用React native时,我还能使用本机第三方lirbraries吗
- 如何使用React JS中的循环,根据条件渲染或不渲染表数据
- 可以't使用React.findDOMNode函数
- 在.map函数中使用react道具
- 使用react native检测应用程序终止
- 使用react router/react router redux将特定的redux操作绑定到一个路由
- 使用react js在跨域上执行事件javascript
- 使用react路由器隐藏组件
- ReactJS:如何使用react正确播放带有onClick事件的html5视频
- 使用react.js渲染其他组件内部的组件
- 使用React和Web组件
- 使用React.js+Express.js发送电子邮件
- Gulp,浏览使用react作为CommonJS不起作用.React未定义
- 使用React创建一个100K的多人互动游戏
- 使用React.createElement时出错
- 从使用react路由器的网络应用程序解析物理URL
- 配置 karma.js 以使用 react 和 ES6
- 直接使用 React Router + React + Flux 路由到 URL
- 使用 React Native 和 Redux 热重载化简器时堆栈溢出