方案1的话 table每个item的 禁用启用交互不知道该如何操作 方案2的话 这么大的数据作为state,感觉有点大
大神们给点意见
多谢了
顶个。各位大侠们帮忙啊
把每一个tr作为一个对象,每次“操作”都是更新tr这个对象的state就可以了。
再顶
@ypmei 我 想想
话说有 react 的中文社区,你可以去那里问问。
先列举下需要的类库
react.js react-with-addons.js EventEmitter.js 事件管理 underscore.js 数据处理
Github代码地址 获取代码后,直接打开index.html即可看到效果
代码
var ID = 123459; //自增长ID
var ee = new EventEmitter();
var update = React.addons.update;
var data = [
{
id: 123456,
number: '漫道:xxxxxx',
tplName: '模板1',
content: '内容1',
inUse: true,
desc: '备注1'
},
{
id: 123457,
number: '盈信道:xxxxxx',
tplName: '模板2',
content: '内容2',
inUse: false,
desc: '备注2'
},
{
id: 123458,
number: '漫道:xxxxxx',
tplName: '模板3',
content: '内容3',
inUse: true,
desc: '备注3'
}
];
var App = React.createClass({
getInitialState: function () {
return {data: this.props.data || []};
},
componentDidMount: function () {
ee.on('update', this.handleUpdate);
ee.on('add', this.handleAdd);
ee.on('delete', this.handleDelete);
ee.on('search', this.handleSearch);
},
handleUpdate: function (index, data, callback) {
var newData = this.state.data.slice();
_.extend(newData[index], data);
this.setState({data: newData}, function () {
callback && callback();
});
},
handleAdd: function () {
if (!this.state.data[0].id) {
return;
}
var newData = update(this.state.data, {
$unshift: [{
number: '',
tplName: '',
content: '',
desc: ''
}]
});
this.setState({data: newData});
},
handleDelete: function (index) {
var newData = update(this.state.data, {
$splice: [[index, 1]]
});
this.setState({data: newData});
},
handleSearch: function (obj) {
var result = _.filter(this.state.data, function (item) {
return item[obj.searchType].indexOf(obj.searchValue) > -1;
});
this.setState({data: result});
},
render: function () {
return (
<div className="container">
<Search />
<TplBox data={this.state.data}/>
</div>
)
}
});
var Search = React.createClass({
handleSearch: function () {
ee.emit('search', {
searchType: this.refs.searchType.getDOMNode().value,
searchValue: this.refs.searchValue.getDOMNode().value
});
},
handleNew: function () {
ee.emit('add');
},
render: function () {
return (
<div className="row" style={{marginBottom:30}}>
<div className="col-lg-3">
<select className="form-control input-sm" ref="searchType">
<option value="number">模板号</option>
<option value="tplName">模板名</option>
<option value="content">短信内容</option>
<option value="desc">备注</option>
</select>
</div>
<div className="col-lg-3">
<input type="text" className="form-control input-sm" ref="searchValue"/>
</div>
<div className="col-lg-1">
<button className="btn btn-primary btn-sm" onClick={this.handleSearch}>搜索</button>
</div>
<div className="col-lg-offset-2 col-lg-2">
<button className="btn btn-warning btn-sm pull-right" onClick={this.handleNew}>新建短信模板</button>
</div>
</div>
)
}
});
var TplBox = React.createClass({
render: function () {
return (
<table className="table table-striped table-hover ">
<thead>
<tr>
<th>序号</th>
<th>模版号</th>
<th>模板名</th>
<th>短信内容</th>
<th>状态</th>
<th>备注</th>
<th>操作</th>
</tr>
</thead>
<TplList data={this.props.data}/>
</table>
)
}
});
var TplList = React.createClass({
render: function () {
return (
<tbody>
{this.props.data.map(function (tpl, index) {
return <TplItem data={tpl} index={index} key={index}/>
})}
</tbody>
)
}
});
var TplItem = React.createClass({
getInitialState: function () {
return {isEdit: false};
},
handleToggleEdit: function () {
this.setState({
isEdit: !this.state.isEdit
});
},
render: function () {
var tpl = this.props.data;
return !tpl.id ?
<TplItemNew index={this.props.index}/> :
this.state.isEdit ?
<TplItemEdit data={tpl} index={this.props.index} toggleEdit={this.handleToggleEdit}/> :
<TplItemShow data={tpl} index={this.props.index} toggleEdit={this.handleToggleEdit}/>;
}
});
var TplItemShow = React.createClass({
handleEdit: function () {
this.props.toggleEdit();
},
handleUse: function (index, use) {
ee.emit('update', index, {inUse: use});
},
render: function () {
var index = this.props.index;
var tpl = this.props.data;
return (
<tr>
<td>{index + 1}</td>
<td>{tpl.number}</td>
<td>{tpl.tplName}</td>
<td>{tpl.content}</td>
<td>{tpl.inUse ? <p className="text-success">已启用</p> : <p className="text-danger">已禁用</p>}</td>
<td>{tpl.desc}</td>
<td>
{tpl.inUse ?
<button className="btn btn-danger btn-xs" onClick={this.handleUse.bind(this,index,!tpl.inUse)}>
禁用</button> :
<button className="btn btn-success btn-xs" onClick={this.handleUse.bind(this,index,!tpl.inUse)}>
启用</button>
}
<button className="btn btn-info btn-xs" onClick={this.handleEdit}>编辑</button>
</td>
</tr>
)
}
});
var TplItemEdit = React.createClass({
handleCancel: function () {
this.props.toggleEdit();
},
handleSave: function (index) {
ee.emit('update', index, {
number: this.refs.number.getDOMNode().value,
tplName: this.refs.tplName.getDOMNode().value,
content: this.refs.content.getDOMNode().value,
desc: this.refs.desc.getDOMNode().value
}, function () {
this.props.toggleEdit();
}.bind(this));
},
render: function () {
var index = this.props.index;
var tpl = this.props.data;
return (
<tr>
<td>{index + 1}</td>
<td><input ref="number" type="text" className="form-control input-sm" defaultValue={tpl.number}/></td>
<td><input ref="tplName" type="text" className="form-control input-sm" defaultValue={tpl.tplName}/></td>
<td><input ref="content" type="text" className="form-control input-sm" defaultValue={tpl.content}/></td>
<td>{tpl.inUse ? <p className="text-success">已启用</p> : <p className="text-danger">已禁用</p>}</td>
<td><textarea ref="desc" type="text" className="form-control input-sm" defaultValue={tpl.desc}/></td>
<td>
<button className="btn btn-primary btn-xs" onClick={this.handleSave.bind(this,index)}>
保存
</button>
<button className="btn btn-default btn-xs" onClick={this.handleCancel}>取消</button>
</td>
</tr>
)
}
});
var TplItemNew = React.createClass({
handleCancel: function (index) {
ee.emit('delete', index);
},
handleCreate: function (index) {
ee.emit('update', index, {
id: ID++,
number: this.refs.number.getDOMNode().value,
tplName: this.refs.tplName.getDOMNode().value,
content: this.refs.content.getDOMNode().value,
inUse: false,
desc: this.refs.desc.getDOMNode().value
});
},
render: function () {
var index = this.props.index;
return (
<tr>
<td>{index + 1}</td>
<td><input ref="number" type="text" className="form-control input-sm"/></td>
<td><input ref="tplName" type="text" className="form-control input-sm"/></td>
<td><input ref="content" type="text" className="form-control input-sm"/></td>
<td>
<p className="text-danger">已禁用</p>
</td>
<td><textarea ref="desc" type="text" className="form-control input-sm"/></td>
<td>
<button className="btn btn-primary btn-xs" onClick={this.handleCreate.bind(this,index)}>
新增
</button>
<button className="btn btn-default btn-xs" onClick={this.handleCancel.bind(this,index)}>取消</button>
</td>
</tr>
)
}
});
React.render(<App data={data}/>, document.body);
截图
写的不好,大致一个思路吧。没有用到Flux,也没用的后端交互,然并卵啊!
@yuyang041060120 非常感谢啊。 我现在用的仅仅是react,交互也是直接传递进去的。 多谢了,我看看先。回头再聊
@yuyang041060120 刚看了下你的代码,state的方式和我的一致,但是我方法是硬生生的给传递给各个子组件,借鉴你的思路,EventEmitter 明天把它用进去。 搞好以后贴代码
@xushao0305 试着用用reflux或redux。 最好加上服务端和校验,这样才能有实际运用的意义。
虽然没在项目中用过react,但我还是要安利下这个东东riot,很好很强大
@xushao0305 马上会和服务端进行交互。得空了以后在用下flux吧