我创建了一个带有按钮的动态控制表单,用户可以使用该按钮为每次单击按钮添加新字段,如类别和上传选项。目前,我正在研究同一字段的编辑选项。从后端获取数据并在表单组件中设置其值时,我遇到了问题。请给我您的宝贵建议。下面是我的表单的代码段。
class Form extends Component {
constructor(props) {
super(props);
this.state = {
mask: this.props.currentMask,
isNew: this.props.isNew,
inProgress: false,
existingMaskFiles: [],
deletedMaskFiles: [],
isHidden: true,
maskImages: [
{
uid: '1',
mask_type_id: "",
image: ""
}
]
};
this.handleOnChange = this.handleOnChange.bind(this);
this.handleSave = this.handleSave.bind(this);
this.handleChange = this.handleChange.bind(this);
this.beforeFileUpload = this.beforeFileUpload.bind(this);
this.handleBannerFileDelete = this.handleBannerFileDelete.bind(this);
this.deleteMaskImages = this.deleteMaskImages.bind(this);
}
componentWillMount() {
if (!this.props.isNew) {
const existingMaskFiles = [];
_.forEach(this.props.currentMask.mask_images, mask => {
if (mask.image_url !== null) {
existingMaskFiles.push({
uid: mask.id,
id: mask.id,
mask_type_id: mask.point_id,
name: mask.image_url.substring(mask.image_url.lastIndexOf('/') + 1) || '',
image: mask.image_url
});
}
});
this.setState({existingMaskFiles})
} else {
this.setState({mask: Object.assign({}, this.state.mask)});
}
}
handleOnChange = (element, value, index) => {
if (element === "mask_type_id") {
let maskImages = [...this.state.maskImages]
maskImages[index][element] = value
this.setState({maskImages})
}
}
handleImageChange = (element, filelist, index) => {
const imageFile = [filelist.file];
if (element === "image") {
let maskImages = [...this.state.maskImages]
maskImages[index][element] = imageFile
this.setState({maskImages})
}
}
handleBannerFileDelete(id) {
let maskImages = [...this.state.maskImages]
maskImages[id].image = "";
this.setState({maskImages: maskImages})
}
deleteMaskImages(id) {
const key = _.find(this.state.existingMaskFiles, fileObj => id === fileObj.id);
const result = this.state.existingMaskFiles.splice(key, 1);
const deletedMaskFiles = this.state.deletedMaskFiles;
deletedMaskFiles.push(result[0].id);
this.setState({existingMaskFiles: this.state.existingMaskFiles, deletedMaskFiles})
}
addMask = (e) => {
console.log("Add mask is called");
this.setState((prevState) => ({
maskImages: [
...prevState.maskImages, {
uid: '1',
mask_type_id: "",
image: ""
}
]
}));
}
handleChange(element, value) {
this.setState({mask: Object.assign({}, this.state.mask, {[element]: value})})
}
handleSave() {
const existingMaskFiles = this.state.existingMaskFiles
this.setState({inProgress: true, maskImages: existingMaskFiles});
let maskObj = this.state.mask;
let images = [];
const obj = {
remove_images: this.state.deletedImgFiles,
mask_images: this.state.maskImages
}
if (images.length > 0) {
obj.mask_images = images;
}
const data = Object.assign({}, maskObj, obj);
this.setState({mask: data});
saveMask(this.state.isNew, data).then((result) => {
if (result.success) {
this.setState({inProgress: false});
this.props.onSuccess(I18n.t('masks.saved'));
} else {
this.setState({errors: result.errors, inProgress: false});
}
});
}
beforeFileUpload(file) {
return false;
}
render() {
const {mask} = this.state;
const uploadButton = (<Button style={{
marginTop: '5px'
}}>
<Icon type="upload"/>
Click to Upload
</Button>)
const Option = Select.Option;
return (<div>
<Row gutter={16}>
<Col xs={12}>
<FormItem label="Name">
<Input value={mask.name} onChange="onChange" {e => this.handleChange('name',
e.target.value)}/>
</FormItem>
</Col>
</Row>
<Row>
<Button onClick={this.addMask}>Add More Masks</Button>
{
this.state.maskImages.map((val, idx) => {
let ID = idx;
return (<div key={idx}>
<Row gutter={16}>
<Col xs={10} sm={10}>
<FormItem label="Category">
<Select style={{
width: 120
}} value={this.state.maskImages[idx].mask_type_id} onChange="onChange" {e=>this.handleOnChange('mask_type_id', e, ID)}>
<Option value="4">4</Option>
<Option value="5">5</Option>
<Option value="6">6</Option>
</Select>
</FormItem>
</Col>
<Col xs={10} sm={10}>
<FormItem label="Upload Image">
<Upload key={idx} fileList={[this.state.maskImages[idx]]} onChange="onChange" {e=>this.handleImageChange('image', e, ID)} beforeUpload={this.beforeFileUpload} showUploadList={{
showPreviewIcon: false,
showRemoveIcon: true
}} <Button style={{
marginTop: '5px'
}}>
<Icon type="upload"/>
Click to Upload
</Button>
</Upload>
{
this.state.existingMaskFiles[idx] && <Row>
<Col xs={24}>
<List size="small" dataSource={[this.state.existingMaskFiles[idx]]} renderItem="renderItem" { item =>
(<List.Item
className="img-list-item"
actions={[<Icon type="close"
className="close-icon"
onClick={e =>
this.deleteMaskImages(idx)} />]}>
<Icon type="paper-clip"
className="picture-img" />
{item.name !=null ?
item.name :''}
</List.Item>)
}/>
</Col>
</Row>
}
</FormItem>
</Col>
</Row>
</div>
)
})
}
</Row>
<Row>
{FormErrors(this.state.errors)}
</Row>
<Row>
<Col xs={24}>
{FormButtons(this.state.inProgress, this.handleSave, this.props.onCancel)}
</Col>
</Row>
</div>);
}
}
export default Form;
答案 0 :(得分:0)
我找到了问题的解决方案并将其实现。问题是没有处理来自数据库的数据的功能。在componentWillReceiveProps中,我试图将来自DB的props数据分配给一个Array。我试图将该Array映射到render中如果是编辑表单,则在ComponentWillReceiveProps中有数据,以便显示数据;如果是新表单,则无数据;如果他尝试再添加一个formInput,我们将有Other Array处理它。相同形式的编辑功能有点笨拙。希望它对某人有帮助
<Row>
<Button onClick={this.addMask}>Add More Masks</Button>
{
this.state.maskImages.map((val, idx)=> {
let ID=idx;
return (
<div key={idx}>
<Row gutter={16}>
<Col xs={10} sm={10}>
<FormItem label={I18n.t('masks.mask_type')}>
<Select
style={{ width: 120 }}
value={val ? val.mask_type_id : ''}
onChange={e=>this.handleOnChange('mask_type_id', e, ID)}
>
{
this.state.maskTypes.map((masktype) => {
return (
<Option key={masktype.id} value={masktype.id}>{masktype.name}</Option>
);
})
}
</Select>
</FormItem>
</Col>
<Col xs={10} sm={10}>
<FormItem label={I18n.t('masks.mask_image')}>
<Upload
key={idx}
fileList={val.image !== '' ? [val] : ''}
beforeUpload={this.beforeFileUpload}
onChange={e=>this.handleImageChange('image', e, ID)}
showUploadList={{ showPreviewIcon: false, showRemoveIcon: true }}
onRemove={e=>this.deleteNewMaskImages(ID)}
>
{ val.image == '' && uploadButton }
</Upload>
</FormItem>
</Col>
</Row>
</div>
)
})
}
{
this.state.existingMaskFiles.map((val, idx)=> {
let ID=idx;
return (
<div key={idx}>
<Row gutter={16}>
<Col xs={10} sm={10}>
<FormItem label={I18n.t('masks.mask_type')}>
<Select
style={{ width: 120 }}
value={val ? val.mask_type_id : this.state.editMaskImages.mask_type_id}
onChange={e=>this.handleOnEditChange('mask_type_id', e, ID)}
>
{
this.state.maskTypes.map((masktype) => {
return (
<Option key = {masktype.id} value = {masktype.id}>{masktype.name}</Option>
);
})
}
</Select>
</FormItem>
</Col>
<Col xs={10} sm={10}>
<FormItem label={I18n.t('masks.mask_image')}>
<Upload
key={idx}
fileList={val.image !== '' ? [val] : ''}
beforeUpload={this.beforeFileUpload}
onChange={e=>this.handleOnEditImageChange('image', e, ID)}
showUploadList={{ showPreviewIcon: false, showRemoveIcon: true }}
onRemove={e=>this.deleteMaskImages(ID)}
>
{ val.image == '' && uploadButton }
</Upload>
</FormItem>
</Col>
</Row>
</div>
)
})
}
</Row>