Issue with updating model on AJAX “POST”

[亡魂溺海] 提交于 2021-02-09 07:30:36

问题


I'm trying to update my model without refreshing the page. I'm using a wysiwyg inline editor that I have on many places on my page. The editor can be placed anywhere on the page, it could look like this:

<div id="1" class="click2edit">@Model.Header</div>

<div id="2" class="click2edit">@Model.Content</div>

Each editors div have a SaveButton that goes to this jquery, ajax below. What it does is: When I hit the save button for example the <div id="1" class="click2edit">@Model.Header</div> It posts the that divs id and its content (in this case @Model.Header). And my whole @model

$('.click2edit').click(function () {
    var modelDataJson = '@Html.Raw(Json.Encode(Model))';
    $(this).note({ focus: true });
    var activeId = (this.id);
    activeId = activeId.replace(/ /g, '');
    $(this).note({
        oninit: function () {
            $('#saveFileBtn').click(function (event) {
                $('#previewBtn').click(),
                $.ajax({
                    url: '/Home/SaveContent',
                    type: 'POST',
                    data: {
                        model: modelDataJson,
                        activeId: activeId,
                        contentToUpdate: $("div#" + activeId).html()
                    },
                    dataType: 'json',
                    success: function (data) {
                        alert("sucess");
                    },
                    error: function () {
                        alert("error");
                    }
                });
                $('.click2edit').destroy();
            });
        }
    });
});

Then in my mvc-controller it puts the new content in right place and saves to my db. That is done by replacing the whole old model, with the new one that is posted from the view:

[ValidateInput(false)]
public void SaveContent(string model, string activeId, string contentToUpdate)
{
    //my logic to save to db is here...
}

The problem is: My model in my razor-view don't get updated. Everything works fine if I'm just saving one of my editors content. But when I'm trying to save another before I refresh my page, it is not getting updated. That is because my razor-views @model is still holding the old values. So basiclly the only value that is updated is the last one I will save. Can I in someway refresh my views @model without refreshing the whole page?

EDIT: Iv'e now changed my success-function so it looks like this:

success: function (data) {
    $("#1").text(data.Header);
},

But the models value of this does not gets updated. the data I'm sending back from the success-function is my Model as Json.

<div id="1" class="click2edit">@Model.Header</div>

回答1:


Here is a summary of our chat:

An MVC model is an instance that contains data built by on the server that is used to control the rendering of, and provide data to, a view. HTTP's stateless nature dictates that the only time you can access this server-side data is when the view is in the process of being rendered. Once it's rendered, it is completely in the hands of the browser and whatever data that was present in the server-side object is released from memory.

After this point, you can no longer use the Razor server-side syntax of @if or @model to access the model data (the model as it existed when the page was being rendered no longer exists). Instead, you should work with the DOM and JavaScript objects to update the look and contents of the page (while saving data using Ajax on the server side). Without doing a full-page post your only option is to use client-side code (JavaScript) to manipulate what the user sees (hence the name: View) so that what they are seeing matches the changes that have occurred after the Ajax POST.

I have created a Gist here that demonstrates these concepts: https://gist.github.com/xDaevax/f5e192c03f6a2bfc2cdb

Essentially you would need code similar to the following for your controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace AjaxMvcTest.Controllers {
    public class HomeController : Controller {
        //
        // GET: /Home/


        public ActionResult Index() {
            HomeModel model = new HomeModel();
            model.Header = "Default Header";
            model.Content = "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly-wobbly... timey-wimey... stuff.";
            return View(model);
        }

        [ValidateInput(false)]
        public JsonResult SaveContent(UpdateDataModel updateRequest) {
            //Do some stuff
            HomeModel newModel = new HomeModel();
            newModel.Content = updateRequest.Content;
            newModel.Header = updateRequest.Header;

            return Json(newModel);
        }

    }
}

Here is a view that would be used with the above controller:

@model HomeModel

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

<div id="1" class="click2edit">@Model.Header</div>
<br />
<div id="2" class="click2edit">@Model.Content</div>
<br />
Header:&nbsp;&nbsp; <input type="text" name="HeaderInput" id="HeaderInput" value="@Model.Header" />
<br />
Content: <textarea name="ContentInput" id="ContentInput">@Model.Content</textarea>
<br />
<input type="button" id="saveFileBtn" value="Save" />

<script type="text/javascript">
    $(function () {

        $("#saveFileBtn").click(function (e) {
            $.ajax({
                url: '/Home/SaveContent',
                type: 'POST',
                data: getFormData(),
                dataType: 'json',
                success: function (data) {
                    $("#1").text(data.Header);
                    $("#2").text(data.Content);
                    $("#HeaderInput").val(data.Header);
                    $("#ContentInput").val(data.Content);
                },
                error: function () {
                    alert("error");
                }
            });
        });
    });

    function getFormData() {
    //Convert the form data to a javascript object
        var dataToSubmit = {
            Header: $("#HeaderInput").val(),
            Content: $("#ContentInput").val(),
            TimeStamp: new Date(),
            Id: 1
       };

       return dataToSubmit;
    }
</script>

In this way, you can see that the client-side (JavaScript) code is responsible for updating the view in the success callback of the ajax method after the controller has done the work and the getFormData() method is used to convert the form values into a JavaScript object that the MVC model binder can read and convert into a .NET server-side model. If you didn't want to do this manually, you could use JQuery's serialize method to serialize the whole form, providing the form values match your server-side model.



来源:https://stackoverflow.com/questions/25665863/issue-with-updating-model-on-ajax-post

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!