简体   繁体   English

AJAX仅适用于页面刷新

[英]AJAX only works on page refresh

I am writing a web app that allows a user to create questions and assign answers and point values to those answers. 我正在编写一个Web应用程序,允许用户创建问题并为这些答案分配答案和分数。 I have it set up so the user enters how many questions they want to make and then I pull up all the fields needed for one question. 我已经设置好了,所以用户输入了他们想问多少个问题,然后我拉出了一个问题所需的所有字段。 When the user clicks Save & Next button those fields are cleared and they can enter their next question information. 当用户单击“保存并下一步”按钮时,这些字段将被清除,他们可以输入下一个问题信息。 I am using AJAX to post the model data to my server each time Save & Next is clicked. 每次单击“保存并下一步”时,我正在使用AJAX将模型数据发布到我的服务器。 My problem is that my AJAX will only run if I allow the page to refresh which I don't want to do. 我的问题是,仅当我允许刷新不需要的页面时,我的AJAX才会运行。

HTML 的HTML

<input type="submit" id="next" value="Save & Next" />

Javascript Java脚本

 $(document).ready(function () {
 $('#next').click(function(e) {

        var model = @Html.Raw(Json.Encode(Model));
        e.preventDefault();

        if (counter <= ques)
        {
            $.ajax({
                url: "/Questions/Create",
                type: "POST",
                data: JSON.serialize(model),
                cache: false,
                success: function (data)
                {

                }
            });
            //counter++;
        }
        else {

        }

    });
});

C# Server-Side C#服务器端

    [HttpPost]
    [ValidateAntiForgeryToken]
    public int Create(QAViewModel qa)
    {
        System.Diagnostics.Debug.WriteLine("madeit");
        if (ModelState.IsValid)
        {
            foreach (var item in qa.questions)
            {
                //add question data into the DB
                db.questions.Add(item);
            }
            foreach (var item in qa.questionAnswers)
            {
                db.answers.Add(item);
            }
            db.SaveChanges();
            return(1);
        }

        return (0);
    }

The real problem comes with e.preventDefault(); 真正的问题来自e.preventDefault(); If I remove it the code runs and my model data gets added to my database as expected. 如果删除它,代码将运行,并且模型数据将按预期添加到数据库中。 When e.preventDefault() is added the AJAX code after it is not even executed. 当添加e.preventDefault()甚至不执行它之后的AJAX代码。 I have tried used <input type="button"> since it's default action does not do anything. 我尝试使用<input type="button">因为它的默认操作不执行任何操作。

Any ideas on why this is happening? 为什么会这样?

SOLUTION After many hours the solution was to use @Html.AddAntiForgeryToken() on my view. 解决方案许多小时后,解决方案是在我的视图上使用@Html.AddAntiForgeryToken() I forgot that I was checking for anti forgery token which did not let the AJAX to post data to my controller action. 我忘记了我正在检查防伪令牌,该令牌没有允许AJAX将数据发布到我的控制器操作中。

You are using a non existent function JSON.serialize . 您正在使用不存在的函数JSON.serialize If you want to convert a javascript object or array to JSON string use JSON.stringify(object) 如果要将JavaScript对象或数组转换为JSON字符串,请使用JSON.stringify(object)

This issue can easily be found by using your browser console to check for errors thrown 通过使用浏览器控制台检查引发的错误,可以轻松找到此问题。

Submit buttons are made to submit content of the form. 提交按钮用于提交表单内容。

When you don't need to submit, you should use a normal button. 不需要提交时,应使用常规按钮。 However, if for any reason you still want to use a submit button, you may want to return false at the end of the method, in order to avoid submit button to do its work. 但是,如果出于任何原因仍要使用提交按钮,则可能希望在方法末尾return false ,以避免提交按钮完成其工作。

$(document).ready(function () {
    $('#next').click(function(e) {
        var model = @Html.Raw(Json.Encode(Model));

        if (counter <= ques)
        {
            $.ajax({
                url: "/Questions/Create",
                type: "POST",
                data: JSON.serialize(model),
                cache: false,
                success: function (data)
                {

                }
            });
            //counter++;
        } else {

        }

        return false;
    });
});

DEMO HERE 此处演示

A quick and kinda dirty fix is to hold a boolean to use whether u do the prevent default or not. 一个快速且有点肮脏的解决方法是保留一个布尔值以使用是否执行预防默认值。

var preventBoolean = false;
$(document).ready(function () {
$('#next').click(function(e) {

    var model = @Html.Raw(Json.Encode(Model));
    if(preventBoolean)
    {        
         e.preventDefault();
    }
    preventBoolean = true;

    if (counter <= ques)
    {
        $.ajax({
            url: "/Questions/Create",
            type: "POST",
            data: JSON.serialize(model),
            cache: false,
            success: function (data)
            {
                 preventBoolean = false;
            }
        });
        //counter++;
    }
    else {

    }

});
});

I'm not sure where u want to turn it on again but I have set it in the succes. 我不确定您要在哪里重新打开它,但是我已经成功设置了它。 The good solution is binding and unbinding the method but then you have to work with events. 好的解决方案是绑定和取消绑定该方法,但是随后您必须处理事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM