前文中實現了用戶添加與用戶列表展示的功能,本篇帶大家來完成用戶的編輯與刪除。
編輯與刪除功能都是針對已存在的某一個用戶執行的操作,所以在用戶列表中需要再加一個“操作”列來展現【編輯】與【刪除】這兩個按鈕。
修改/src/pages/UserList.js
文件,添加方法handleEdit與handleDel,并在table中添加一列:
點擊編輯(刪除)時,會把該行的user對象作為參數傳給handleEdit(handleDel)方法,在handleEdit(handleDel)方法中我們就可以根據傳入的user對象進行相應的操作了。
用戶刪除比較簡單,先解決它。
在執行刪除數據的操作時,通常需要對操作進行進一步的確認以避免誤刪數據釀成慘劇。
所以在handleDel方法中我們應該先確認用戶是否想要執行刪除操作,在用戶確認后調用刪除用戶的接口來刪除用戶:
... handleDel (user) { const confirmed = confirm(`確定要刪除用戶 ${user.name} 嗎?`); if (confirmed) { fetch('http://localhost:3000/user/' + user.id, { method: 'delete' }) .then(res => res.json()) .then(res => { this.setState({ userList: this.state.userList.filter(item => item.id !== user.id) }); alert('刪除用戶成功'); }) .catch(err => { console.error(err); alert('刪除用戶失敗'); }); } } ...用戶編輯和用戶添加基本上是一樣的,不同的地方有:
用戶編輯需要將用戶的數據先填充到表單用戶編輯在提交表單的時候調用的接口和方法不同頁面標題不同頁面路由不同那么我們可以復制UserAdd.js文件的代碼到一個新的UserEdit.js文件中,再對上述四點進行修改…嗎?
當然不行!在前文中我們費盡心思對重復代碼進行優化,更不能為了偷懶直接復制代碼完事啦。
想辦法讓原來的代碼既能夠支持添加操作又能夠支持編輯操作!
為了達到這一個目標,我們需要:
升級formProvider使其返回的表單組件支持傳入表單的值(用于主動填充表單)將UserAdd.js中的大部分代碼抽離到一個通用組件UserEditor,通過傳入不同的props來控制組件的行為是添加還是編輯修改/src/utils/formProvider.js
文件:
給表單組件傳入了一個setFormValues的方法,用于在組件中主動設置表單的值。
接下來新建/src/components/UserEditor.js
文件,將表單處理代碼從UserAdd.js里搬過去(省略號部分與原來的代碼相同):
然后再handleSubmit方法中,通過檢查是否收到一個editTarget的props來判斷這次的操作是添加操作還是編輯操作,并根據當前的操作切換調用接口的url和method:
... handleSubmit (e) { e.preventDefault(); const {form: {name, age, gender}, formValid, editTarget} = this.props; if (!formValid) { alert('請填寫正確的信息后重試'); return; } let editType = '添加'; let apiUrl = 'http://localhost:3000/user'; let method = 'post'; if (editTarget) { editType = '編輯'; apiUrl += '/' + editTarget.id; method = 'put'; } fetch(apiUrl, { method, body: JSON.stringify({ name: name.value, age: age.value, gender: gender.value }), headers: { 'Content-Type': 'application/json' } }) .then((res) => res.json()) .then((res) => { if (res.id) { alert(editType + '用戶成功'); this.context.router.push('/user/list'); return; } else { alert(editType + '失敗'); } }) .catch((err) => console.error(err)); } ...同時,我們也需要在UserEditor加載的時候檢查是否存在props.editTarget
,如果存在,使用props.setFormValues
方法將editTarget的值設置到表單:
這樣我們的UserEditor就基本完成了,當我們要作為一個用戶添加器使用時,只需要:
... <UserEditor/> ...而作為一個用戶編輯器使用時,則需要將編輯的目標用戶對象傳給editTarget這個屬性:
... <UserEditor editTarget={user}/> ...所以現在就可以將UserAdd.js文件改成這樣了:
import React from 'react';import HomeLayout from '../layouts/HomeLayout';import UserEditor from '../components/UserEditor';class UserAdd extends React.Component { render () { return ( <HomeLayout title="添加用戶"> <UserEditor/> </HomeLayout> ); }}export default UserAdd;現在需要添加一個/src/pages/UserEdit.js
文件作為編輯用戶的頁面:
在這個頁面組件里,我們根據路由中名為id的參數(this.context.router.params.id
)來調用接口獲取用戶數據(保存在this.state.user
中)。
當user數據未就緒時,我們不應該展示出編輯器以避免用戶混亂或者誤操作:使用三元運算符,當this.state.user
有值時渲染UserEditor組件,否則顯示文本“加載中…”。
注意:任何使用this.context.xxx的地方,必須在組件的contextTypes里定義對應的PropTypes。
別忘了在/src/index.js
中給頁面添加路由,路由的path中使用:id來定義路由的參數(參數名與頁面組件中獲取參數時的參數名相對應):
最后,來補上UserList頁面組件的handleEdit方法:
class UserList extends React.Component { constructor (props) { ... } componentWillMount () { ... } handleEdit (user) { this.context.router.push('/user/edit/' + user.id); } handleDel (user) { ... }UserList.contextTypes = { router: React.PropTypes.object.isRequired};在handleEdit方法中只需要使用router.push方法跳轉到該用戶的編輯頁面,別忘了加上contextTypes。
看看效果:
大功告成!
|
新聞熱點
疑難解答