通过Ajax在React中提交表单

时间:2019-11-21 23:39:04

标签: javascript ajax reactjs laravel

我的程序以这种方式工作:

  1. 您可以从视频的选择选项菜单中选择一个视频。

  2. 选择适当的视频(onChange事件)后,将显示其字幕列表,再次显示字幕的选择菜单。

  3. 在选择了适当的字幕后(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'));

}

考虑到我之前的问题,我可能看不到明显的问题。尽管如此,如果你们中任何一个善良的灵魂会向正确的方向指点我,我将不胜感激。预先向Mucho致敬:D

EDIT1:

我想出是什么原因造成的。这是ckeditor的嫉妒。通过从this.getCkEditor();方法中的条件中删除handleSubmit(),所有操作均应正常进行。但是如何使其与ckeditor 一起使用?

2 个答案:

答案 0 :(得分:0)

听起来像异步问题。尝试向ckeditor添加回调,以确保在ckeditor完成后进行Axiom调用。

答案 1 :(得分:0)

我终于明白了。怎么做,而不是为什么会发生。 因此,这里是:

我刚刚在STRICT_MATCHING方法中进行ajax调用之前,就添加了

handleSubmit

手动从ckeditor实例中“翻录”文本内容并为其设置if(CKEDITOR.instances['ckeditor']){ formElements.subText = CKEDITOR.instances['ckeditor'].getData(); myformData.append('subText', formElements.subText); } 。我不知道为什么或如何,但是它有效。通过阅读众多论坛上的大量帖子和答案,我得出的结论是,这只是ckeditor的一些怪癖。特别是如果将它与ajax一起使用,更不用说更多框架了,前端和后端都一样。

感谢大家的指导。