承接part1,资料显示完后,当然下一步就是进行增删改了!
实践
更改src/dataTable.js
constructor(props) { super(props); this.booleanCell = this.booleanCell.bind(this); // cell ui this.rowEdit = this.rowEdit.bind(this); // 编辑资料事件 this.itemChange = this.itemChange.bind(this); // 资料更动事件 this.exitEdit = this.exitEdit.bind(this); // 离开编辑资料事件 this.onSaveClick = this.onSaveClick.bind(this); // 储存按钮事件 this.onCancelClick = this.onCancelClick.bind(this); // 取消更动按钮事件 this.onAddClick = this.onAddClick.bind(this); // 新增按钮事件 this.state = { gridData: JSON.parse(JSON.stringify(products)), // deep copy saveGridData: JSON.parse(JSON.stringify(products)), // deep copy changed: false, // 内文是否有被更动过 editItem: null // 保存当前编辑行 }; }
调整state初始值,关于deep copy 可以参考这篇,若不使用deep copy将会使saveGridData与gridData映射到相同元素。this.state = { gridData: JSON.parse(JSON.stringify(products)), // deep copy saveGridData: JSON.parse(JSON.stringify(products)), // deep copy changed: false, // 内文是否有被更动过 editItem: null // 保存当前编辑行};
调整 renderrender() { return ( <Grid style={{ height: '400px', width: '970px' }} data={this.state.gridData} onRowClick={this.rowEdit} onItemChange={this.itemChange} editField='inEdit' > <GridToolbar> <div onClick={this.exitEdit}> <button onClick={this.onSaveClick} disabled={!this.state.changed}> Save </button> <button onClick={this.onCancelClick} disabled={!this.state.changed}> Cancel </button> <button onClick={this.onAddClick}> Add new </button> </div> </GridToolbar > <Column field='ProductID' title='ID' width='85px' editable={false}/> // 不可更动 <Column field='ProductName' title='Product Name' width='200px' /> <Column field='UnitsInStock' title='Units In Stock' width='180px' editor='numeric'/> // 定义资料型态 <Column field='Discontinued' width='180px' cell={this.booleanCell} /> <Column field='Category.CategoryName' title='CategoryName' width='200px' /> <Column title="Edit" width='120px' cell={this.onDeleteItem}/> </Grid> ); }
定义cell显示内文,当编辑该行时,回传可编辑元件 booleanCell = (props) => { return (props.dataItem.inEdit) ? ( <td> <input onChange={ (event) => { const obj = this.state.gridData; const index = obj.findIndex((o) => {return props.dataItem.ProductID === o.ProductID;}); obj[index][props.field] = event.target.checked; this.setState({ gridData: obj, changed: true }); } } type='checkbox' checked={props.dataItem[props.field]} /> </td> ) : ( <td> <input disabled type='checkbox' checked={props.dataItem[props.field]} /> </td> ); }
定义删除行按钮 onDeleteItem=(eventItem)=>{ return (<td> <button onClick={()=>{ const data = this.state.gridData; const delIndex = data.findIndex(p => {return p.ProductID === eventItem.dataItem.ProductID;}); if (delIndex >-1){ if(window.confirm('Press a button')){ data.splice(delIndex,1); this.setState({gridData: data, changed: true}); } } }}> remove </button> </td>); }
储存按钮事件 onSaveClick = () => { const datas = this.state.gridData.map( (d) => { const data = d; data.inEdit = false; return data; } ); this.setState( { saveGridData: JSON.parse(JSON.stringify(datas)), editItem: null, changed: false } ); // deep copy };
取消更动按钮事件 onCancelClick = () => { const datas = this.state.saveGridData.map( (d) => { const data = d; data.inEdit = false; return data; } ); this.setState( { gridData: JSON.parse(JSON.stringify(datas)), editItem: null, changed: false } ); // deep copy };
新增按钮事件 onAddClick = () => { const newItem = this.state.gridData.map( (d) => { const data = d; data.inEdit = false; return data; } ); newItem.push({ ProductID: findMaxId(this.state.gridData) + 1, ProductName: '', Discontinued: false, Category: { CategoryID: 0, CategoryName: '' }, inEdit: true }); this.setState({ gridData: newItem, changed: true }); }
资料更动事件 itemChange = (event) => { const obj = this.state.gridData; const index = obj.findIndex((o) => { return event.dataItem.ProductID === o.ProductID; }); obj[index] = editJson(obj[index], event.field, event.value); this.setState({ gridData: obj, changed: true }); }
编辑资料事件 rowEdit = (e) => { if (this.state.editItem === e.dataItem.ProductID) { return; } const data = this.state.gridData.map((item) => { const result = item; result.inEdit = item.ProductID === e.dataItem.ProductID; return result; }); this.setState({ editItem: e.dataItem.ProductID, gridData: data }); }
离开编辑资料事件 exitEdit = (event) => { if (event.target === event.currentTarget) { const datas = this.state.gridData.map( (d) => { const data = d; data.inEdit = false; return data; } ); this.setState({ data: datas, editItem: null }); } }
自定义函数// 利用field设定json的属性值const editJson = (json, field, value) => { const jsonArray = json; const fields = field.split('.'); jsonArray[fields[0]] = (fields.length === 1) ? value : editJson(json[fields[0]], fields.slice(1).join('.'), value); return jsonArray;};// 取得ProductID最大值const findMaxId = (datas) => { let result = 0; datas.forEach((data) => { if (result < data.ProductID) { result = data.ProductID; } }); return result;};
一样只要执行npm start
就可以看到我们的资料表了!
顺带附上github给大家参考
结轮
使用button新增资料行,来进行资料的新增。
在资料行中新增删除button,将该笔资料进行删除。
利用Grid的onRowClick事件与editField,进行编辑资料表,再透过onItemChange事件将资料修改进行储存,达到我们对资料的修改。
这样就可以进行资料的增删改了!