javascript - 通过 Ajax 在 React 中提交表单
问题描述
我的程序是这样工作的:
您从视频的选择选项菜单中选择一个视频。
选择适当的视频(onChange 事件)后,将显示它的字幕列表,再次选择 subs 的选项菜单。
选择适当的字幕后(onChange 事件),一个带有文本区域的表单,预填充来自字幕文件的文本内容。
这东西像宣传的那样工作。当我提交(提交事件)以第三种形式更改内容时出现问题,其中包含带有字幕文本的文本区域。我需要它按两次提交按钮来提交需要写入文件的更新内容。
注意:它仅适用于第二次提交。读取文件和其他东西是在 Laravel 中完成的,一切正常。只有这个AJAX部分给我带来了问题。
这是我的带有 AJAX 代码的 React 组件:
import React from 'react';
import ReactDOM from 'react-dom';
class Modsub extends React.Component {
constructor(props) {
super(props);
this.state = {
videos: null,
subtitles: null,
subText: null,
subTextFormId: null,
};
this.select = this.select.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.getCkEditor = this.getCkEditor.bind(this);
this.getSubText = this.getSubText.bind(this);
}
getSubText(e){
this.setState({
subText: e.target.value,
});
}
getCkEditor(){
console.log("got ckeditor");
CKEDITOR.replace("ckeditor");
}
select(e){
this.handleSubmit(e);
}
handleSubmit(e) {
e.preventDefault();
let token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
let formId = e.target.id==="subText" ? e.target.id : e.target.parentElement.parentElement.id;
let url = "";
let formElements = {};
let myformData = new FormData();
if(formId==="videos"){
url = "/modSubOfVideo";
formElements.videoId = e.target.value;
myformData.append('videoId', formElements.videoId);
}
if(formId==="subtitles"){
url = "/openSubOfVideo";
formElements.subId = e.target.value;
this.setState({
subTextFormId: formElements.subId,
});
myformData.append('subId', formElements.subId);
}
if(formId==="subText"){
url = "/writeSubOfVideo";
formElements.subId = e.target.elements[0].value;
formElements.subText = e.target.elements[1].value;
this.setState({
subText: formElements.subText,
});
myformData.append('subText', formElements.subText);
myformData.append('subId', formElements.subId);
}
myformData.append('_token', token);
myformData.append('message', "bravo");
$.ajax({
url: url,
enctype: 'multipart/form-data',
type: 'POST',
data: myformData,
dataType: 'JSON',
cache: false,
contentType: false,
processData: false,
success: (response) => {
console.log("success");
console.log(response);
if(formId==="videos"){
this.setState({
subtitles: response.subtitles,
});
}
if(formId==="subtitles"){
this.setState({
subText: response.subText,
});
//this.getCkEditor();
}
if(formId==="subText"){
this.setState({
subText: response.subText,
});
}
},
error: (response) => {
console.log("error");
console.log(response);
}
});
}
componentDidMount(){
//get all videos
let token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
$.ajax({
url: '/addSubAjax',
type: 'POST',
data: {_token: token , message: "bravo"},
dataType: 'JSON',
success: (response) => {
console.log("success");
//console.log(response);
this.setState({
videos: response.videos,
});
},
error: (response) => {
console.log("error");
//console.log(response);
}
});
}
render(){
/*console.log("****");
console.log(this.state);
console.log("****");*/
let videos = this.state.videos ? this.state.videos.map((item, index) => {
return <option key={index} value={item.id}>{item.name.substr(0, 30)+"..."}</option>
}) : null;
let subs = this.state.subtitles ? this.state.subtitles.map((item, index) => {
return <option key={index} value={item.id}>{item.name.substr(0, 30)+"..."}</option>
}) : null;
let subtitles = subs ? <form id="subtitles" encType="multipart/form-data">
<div className="form-group">
<label htmlFor="subtitles">Choose sub to modify:</label>
<select className="form-control" id="subtitlesId" name="subtitlesId" onChange={this.select} required>
{subs}
</select>
</div>
</form>
: "";
let subTextPre = "<pre>"+this.state.subText+"</pre>";
let subText = this.state.subText ? <form id="subText" onSubmit={this.handleSubmit} encType="multipart/form-data">
<div className="form-group">
<input type="hidden" name="subId" value={this.state.subTextFormId}/>
<label htmlFor="subText">Modify subtitle:</label>
<textarea className="form-control" id="ckeditor" rows="5" onChange={this.getSubText} name="subTextId" defaultValue={subTextPre}/>
</div>
<button type="submit" className="btn btn-outline-primary">Submit</button>
</form>
: "";
return (
<div className="container">
<form id="videos" encType="multipart/form-data">
<div className="form-group">
<label htmlFor="video">Choose video:</label>
<select className="form-control" id="videoId" name="videoId" onChange={this.select} required>
{videos}
</select>
</div>
</form>
{subtitles}
{subText}
</div>
);
}
}
if(document.getElementById('modsub')){
ReactDOM.render(<Modsub/>, document.getElementById('modsub'));
}
考虑到我以前的问题,我可能看不到明显的......尽管如此,如果你们中的任何一个善良的灵魂能指出我正确的方向,我将不胜感激。提前致谢 :D
编辑1:
我有点弄清楚是什么导致了这个问题。这是ckeditor的调用。通过this.getCkEditor();
从方法中的条件中删除handleSubmit()
,这一切都可以正常工作。但是如何让它与ckeditor 一起工作呢?
解决方案
我终于弄明白了。如何做到这一点,而不是为什么会发生。所以,这里是:
就在 ajax 调用handleSubmit
方法之前,我添加了
if(CKEDITOR.instances['ckeditor']){
formElements.subText = CKEDITOR.instances['ckeditor'].getData();
myformData.append('subText', formElements.subText);
}
从 ckeditor 实例手动“翻录”文本内容并myformData
使用它进行设置。我不知道为什么或如何,但它有效。通过阅读众多论坛上的大量帖子和答案,我得出的结论是,这只是 ckeditor 的一些怪癖。特别是如果您将它与 ajax 一起使用,更不用说与更多框架、前端和后端一样了。
谢谢大家的指导。
推荐阅读
- typescript - 如何使用键盘输入平滑地更新成帧器运动位置?
- python - 从数据库获取数据后,我无法在 html 中显示 MySql 数据,可以在服务器(CMD)中看到
- flutter - Flutter:如何在 Cupertino 主题中为材质小部件设置主题?
- android - Android:2个具有不同appID的应用程序,使用相同的名称.SO Lib,但同一设备上的lib版本不同
- python - 如何使用一组 {cameras} ✕ {textures}(笛卡尔积)在 c4d 中排队批量渲染?
- angular - 从 AWS API Gateway 下载时,Angular 下载 Excel 已损坏
- r - 在处理更大的栅格时处理临时目录和工作区的最佳方法是什么?
- python - 是否可以使用 python 脚本在 ABAQUS 中将分区特征从一个部分复制到另一个非常相似的部分?如果是这样,怎么做?
- http - 通过 nginx 和 hls 流式传输无法完全正常工作
- javascript - 在 React 应用程序中嵌入 JavaScript 游戏