index.jsx(父组件):
import React from 'react'
import { Row, Col, Card, Input, Button, Table, Tag, Modal, message, Tooltip } from 'antd';
import moment from 'moment'
import axios from 'axios'
import 'moment/locale/zh-cn';
import "./question.css"
import CreateQuestionForm from './create-question'
export default class MenuCom extends React.Component {
state = {
// 创建问题
createQuestion_visible: false,
}
/**
* 新建问题
*/
createQuestion_onSelectTime = (value, dateString) => {
console.log('value:', value)
console.log('dateString:', dateString)
}
createQuestion_showModal = () => {
this.setState({
createQuestion_visible: true
})
}
createQuestion_onOk = (values, editorContent) => {
let params = {
title: values.createQuestion_title,
devices: values.createQuestion_equipment,
asset: values.createQuestion_asset,
priority: values.createQuestion_priority,
type: values.createQuestion_type,
description: editorContent,
assign_by: values.createQuestion_assignedTo,
status: values.createQuestion_status,
release: values.createQuestion_version,
model: values.createQuestion_model,
user: localStorage.getItem('nickname'),
start_time: moment(values.createQuestion_time[0]).format("YYYY-MM-DD"),
finish_time: moment(values.createQuestion_time[1]).format("YYYY-MM-DD")
}
axios({
method: "POST",
url: "/api/bug/buginfo/",
data: JSON.stringify(params)
}).then(resp => {
this.getData(1, 5);
message.success('添加问题成功。');
this.setState({
createQuestion_visible: false
});
}, err => {
message.error("添加问题失败。");
});
}
createQuestion_onCancel = () => {
this.setState({
createQuestion_visible: false
})
}
render() {
return (<div>
<Card>
<Row>
<Col span={8}>
<Input.Search placeholder="搜索问题" onSearch={this.onSearchTitle} enterButton />
</Col>
<Col span={6} offset={10} style={{ "textAlign": 'right' }}>
<Button type="primary" icon="zoom-in" style={{ marginRight: 15 }} onClick={() => this.setState({
advancedSearch_visible: true
})}>高级搜索</Button>
<Button type="primary" icon="plus" onClick={() => this.createQuestion_showModal()}>新建问题</Button>
</Col>
</Row>
</Card>
<Modal
title="新建问题"
visible={this.state.createQuestion_visible}
width={900}
onOk={this.createQuestion_onOk}
onCancel={this.createQuestion_onCancel}
okText="确认"
cancelText="取消"
style={{ top: 5 }}
// afterClose={this.createQuestion_onAfterClose}
maskClosable={false}
destroyOnClose={true}
footer={null}
>
<CreateQuestionForm get_createQuestion_onOk={this.createQuestion_onOk} assignByUser={this.state.assign_by_user}/>
</Modal>
</div >)
}
}
表单组件create-question.jsx(子组件):
import React from 'react'
import { Row, Col, Form, Input, Button, Select, DatePicker, message } from 'antd';
import E from 'wangeditor'
import 'moment/locale/zh-cn';
import locale from 'antd/es/date-picker/locale/zh_CN';
import "./question.css"
class CreateQuestion extends React.Component {
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
const editorContent = this.createQuestion_descriptionWangEditor.txt.html();
if(editorContent.length !== 0){
this.props.get_createQuestion_onOk(values, editorContent);
}else{
message.error("描述不能为空。");
}
}
});
};
createQuestion_descriptionWangEditor = {}; // 编辑器
componentDidMount() {
this.createQuestion_descriptionWangEditor = new E(document.getElementById("createQuestion_description"));
this.createQuestion_descriptionWangEditor.config.uploadImgServer = `/api/bug/create_upload/?x-token=${localStorage.getItem('token')}`;
this.createQuestion_descriptionWangEditor.config.uploadFileName = 'createQuestion_descriptionImg';
this.createQuestion_descriptionWangEditor.config.height = 100;
this.createQuestion_descriptionWangEditor.config.showLinkImg = false;
this.createQuestion_descriptionWangEditor.config.uploadImgTimeout = 60 * 1000;
this.createQuestion_descriptionWangEditor.config.placeholder = '请输入描述内容(必填)';
this.createQuestion_descriptionWangEditor.config.menus = [
'head', // 标题
'bold', // 粗体
'fontSize', // 字号
'fontName', // 字体
'italic', // 斜体
'underline', // 下划线
'strikeThrough', // 删除线
'foreColor', // 文字颜色
'backColor', // 背景颜色
//'link', // 插入链接
'list', // 列表
'justify', // 对齐方式
'quote', // 引用
'emoticon', // 表情
'image', // 插入图片
//'table', // 表格
//'video', // 插入视频
'code', // 插入代码
'undo', // 撤销
'redo' // 重复
]
this.createQuestion_descriptionWangEditor.config.uploadImgHooks = {
customInsert: function (insertImg, result) {
if (!result.error) {
insertImg(result.data.url);
} else {
message.error(result.error);
}
}
}
/**一定要创建 */
this.createQuestion_descriptionWangEditor.create()
}
render() {
const { getFieldDecorator } = this.props.form;
return (
<Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} onSubmit={this.handleSubmit}>
<Form.Item labelCol={{ span: 3 }} wrapperCol={{ span: 21 }} label="主题">
{getFieldDecorator('createQuestion_title', {
rules: [{ required: true, message: '请输入主题!' }],
})(
<Input />
)}
</Form.Item>
<Row>
<Col span={12}>
<Form.Item label="资产">
{getFieldDecorator('createQuestion_asset', {
rules: [{ required: true, message: '请输入资产名称!' }],
})(
<Input placeholder="请输入资产名称" />
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="设备">
{getFieldDecorator('createQuestion_equipment', {
rules: [{ required: true, message: '请输入设备名称!' }],
})(
<Input placeholder="请输入设备名称" />
)}
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item label="优先级">
{getFieldDecorator('createQuestion_priority', {
rules: [{ required: true, message: '请选择优先级!' }],
})(
<Select placeholder="请选择优先级" style={{ width: '100%' }}>
<Select.Option value="0">低</Select.Option>
<Select.Option value="1">中</Select.Option>
<Select.Option value="2">高</Select.Option>
</Select>
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="时间">
{getFieldDecorator('createQuestion_time', {
rules: [{ required: true, message: '时间不能为空!' }],
})(
<DatePicker.RangePicker locale={locale} style={{ width: '100%' }} onChange={() => this.createQuestion_onSelectTime} />
)}
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item label="状态">
{getFieldDecorator('createQuestion_status', {
rules: [{ required: true, message: '请选择状态!' }],
})(
<Select placeholder="请选择状态" style={{ width: '100%' }}>
<Select.Option value="0">新建</Select.Option>
<Select.Option value="1">处理中</Select.Option>
<Select.Option value="2">已解决</Select.Option>
<Select.Option value="3">已忽略</Select.Option>
<Select.Option value="4">待反馈</Select.Option>
<Select.Option value="5">已关闭</Select.Option>
<Select.Option value="6">重新打开</Select.Option>
<Select.Option value="7">已指定</Select.Option>
</Select>
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="类型">
{getFieldDecorator('createQuestion_type', {
rules: [{ required: true, message: '请选择类型!' }],
})(
<Select placeholder="请选择类型" style={{ width: '100%' }}>
<Select.Option value="0">Bug</Select.Option>
<Select.Option value="1">任务</Select.Option>
<Select.Option value="2">功能</Select.Option>
</Select>
)}
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item label="版本">
{getFieldDecorator('createQuestion_version', {
rules: [{ required: true, message: '请选择版本!' }],
})(
<Select placeholder="请选择版本" style={{ width: '100%' }}>
<Select.Option value="0">无</Select.Option>
</Select>
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="模块">
{getFieldDecorator('createQuestion_model', {
rules: [{ required: true, message: '请选择模块!' }],
})(
<Select placeholder="请选择模块" style={{ width: '100%' }}>
<Select.Option value="0">无</Select.Option>
</Select>
)}
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item label="指派给">
{getFieldDecorator('createQuestion_assignedTo', {
rules: [{ required: true, message: '请选择指派人!' }],
})(
<Select placeholder="请选择指派人" style={{ width: '100%' }}>
{
this.props.assignByUser.map((value, index) => (<Select.Option value={value} key={value}>{value}</Select.Option>))
}
</Select>
)}
</Form.Item>
</Col>
<Col span={12}>
</Col>
</Row>
<Form.Item labelCol={{ span: 3 }} wrapperCol={{ span: 21 }} label="描述" name="createQuestion_description">
<div id="createQuestion_description"></div>
</Form.Item>
<Form.Item wrapperCol={{ span: 24 }} style={{textAlign: "right", paddingBottom: 15}}>
<Button type="primary" htmlType="submit">
新建
</Button>
</Form.Item>
</Form>
);
}
}
const CreateQuestionForm = Form.create({ name: 'create_question' })(CreateQuestion);
export default CreateQuestionForm;
其中:
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
const editorContent = this.createQuestion_descriptionWangEditor.txt.html();
if(editorContent.length !== 0){
this.props.get_createQuestion_onOk(values, editorContent);
}else{
message.error("描述不能为空。");
}
}
});
};
<Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} onSubmit={this.handleSubmit}>
<Form.Item labelCol={{ span: 3 }} wrapperCol={{ span: 21 }} label="主题">
{getFieldDecorator('createQuestion_title', {
rules: [{ required: true, message: '请输入主题!' }],
})(
<Input />
)}
</Form.Item>
<Row>
<Col span={12}>
<Form.Item label="资产">
{getFieldDecorator('createQuestion_asset', {
rules: [{ required: true, message: '请输入资产名称!' }],
})(
<Input placeholder="请输入资产名称" />
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="设备">
{getFieldDecorator('createQuestion_equipment', {
rules: [{ required: true, message: '请输入设备名称!' }],
})(
<Input placeholder="请输入设备名称" />
)}
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item label="优先级">
{getFieldDecorator('createQuestion_priority', {
rules: [{ required: true, message: '请选择优先级!' }],
})(
<Select placeholder="请选择优先级" style={{ width: '100%' }}>
<Select.Option value="0">低</Select.Option>
<Select.Option value="1">中</Select.Option>
<Select.Option value="2">高</Select.Option>
</Select>
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="时间">
{getFieldDecorator('createQuestion_time', {
rules: [{ required: true, message: '时间不能为空!' }],
})(
<DatePicker.RangePicker locale={locale} style={{ width: '100%' }} onChange={() => this.createQuestion_onSelectTime} />
)}
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item label="状态">
{getFieldDecorator('createQuestion_status', {
rules: [{ required: true, message: '请选择状态!' }],
})(
<Select placeholder="请选择状态" style={{ width: '100%' }}>
<Select.Option value="0">新建</Select.Option>
<Select.Option value="1">处理中</Select.Option>
<Select.Option value="2">已解决</Select.Option>
<Select.Option value="3">已忽略</Select.Option>
<Select.Option value="4">待反馈</Select.Option>
<Select.Option value="5">已关闭</Select.Option>
<Select.Option value="6">重新打开</Select.Option>
<Select.Option value="7">已指定</Select.Option>
</Select>
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="类型">
{getFieldDecorator('createQuestion_type', {
rules: [{ required: true, message: '请选择类型!' }],
})(
<Select placeholder="请选择类型" style={{ width: '100%' }}>
<Select.Option value="0">Bug</Select.Option>
<Select.Option value="1">任务</Select.Option>
<Select.Option value="2">功能</Select.Option>
</Select>
)}
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item label="版本">
{getFieldDecorator('createQuestion_version', {
rules: [{ required: true, message: '请选择版本!' }],
})(
<Select placeholder="请选择版本" style={{ width: '100%' }}>
<Select.Option value="0">无</Select.Option>
</Select>
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="模块">
{getFieldDecorator('createQuestion_model', {
rules: [{ required: true, message: '请选择模块!' }],
})(
<Select placeholder="请选择模块" style={{ width: '100%' }}>
<Select.Option value="0">无</Select.Option>
</Select>
)}
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item label="指派给">
{getFieldDecorator('createQuestion_assignedTo', {
rules: [{ required: true, message: '请选择指派人!' }],
})(
<Select placeholder="请选择指派人" style={{ width: '100%' }}>
{
this.props.assignByUser.map((value, index) => (<Select.Option value={value} key={value}>{value}</Select.Option>))
}
</Select>
)}
</Form.Item>
</Col>
<Col span={12}>
</Col>
</Row>
<Form.Item labelCol={{ span: 3 }} wrapperCol={{ span: 21 }} label="描述" name="createQuestion_description">
<div id="createQuestion_description"></div>
</Form.Item>
<Form.Item wrapperCol={{ span: 24 }} style={{textAlign: "right", paddingBottom: 15}}>
<Button type="primary" htmlType="submit">
新建
</Button>
</Form.Item>
</Form>
const CreateQuestionForm = Form.create({ name: 'create_question' })(CreateQuestion);
export default CreateQuestionForm;
是关键。
子组件如何调用父组件的方法?
通过props,比如:
父组件中:
<CreateQuestionForm get_createQuestion_onOk={this.createQuestion_onOk} />
子组件中:
this.props.form.validateFields((err, values) => {
if (!err) {
const editorContent = this.createQuestion_descriptionWangEditor.txt.html();
if(editorContent.length !== 0){
this.props.get_createQuestion_onOk(values, editorContent);
}else{
message.error("描述不能为空。");
}
}
});
中通过
this.props.get_createQuestion_onOk(values, editorContent);
调用父组件的“createQuestion_onOk”方法。