问题与AJAX&QUOT修正模型; POST"模型、问题、QUOT、AJAX

2023-09-10 19:46:50 作者:怪我没看清i

我想不刷新页面来更新我的模型。我使用的是所见即所得在线编辑器,我有我的网页上很多地方。该编辑器可以放在任何地方在页面上,它可能是这样的:

 < D​​IV ID =1级=click2edit> @ Model.Header< / DIV>

< D​​IV ID =2级=click2edit> @ Model.Content< / DIV>
 

每个编辑 DIV 有SaveButton是去这个jQuery,AJAX下文。 它的作用是:当我打的保存按钮,例如< D​​IV ID =1级=click2edit> @ Model.Header< / DIV> 该职位的div的ID及其内容(在这种情况下, @ Model.Header )。而我的整个 @model

  $('。click2edit)。点击(函数(){
    VAR modelDataJson ='@ Html.Raw(Json.En code(型号));
    $(本)。注意({焦点:真});
    VAR activeId =(this.id);
    activeId = activeId.replace(/ /克,'');
    $(本)。注意({
        OnInit的:函数(){
            $('#saveFileBtn)。点击(函数(事件){
                $('#previewBtn)。点击()
                $阿贾克斯({
                    网址:/首页/ SaveContent',
                    键入:POST,
                    数据: {
                        型号:modelDataJson,
                        activeId:activeId,
                        contentToUpdate:$(#DIV+ activeId)。html的()
                    },
                    数据类型:JSON,
                    成功:功能(数据){
                        警报(sucess);
                    },
                    错误:函数(){
                        警报(错误);
                    }
                });
                $('。click2edit)的destroy()。
            });
        }
    });
});
 

然后在我的MVC控制器它把在正确的地方新的内容,并保存到我的分贝。

:这是更换整个旧模式,新一个被张贴在视图完成

  [ValidateInput(假)]
公共无效SaveContent(字符串模式,字符串activeId,串contentToUpdate)
{
    //我的逻辑来保存到数据库是在这里...
}
 
JavascriptDOM文档对象模型和Ajax技术

的问题是: 我在我的剃刀视图模型没有得到更新。一切工作正常,如果我只是节省了我的编辑内容之一。但是,当我试图拯救他人之前,我刷新我的网页,它不会得到更新。 那是因为我的剃须刀意见 @model 仍抱着旧值。 所以basiclly被更新的唯一价值是最后一个,我会保存。 我可以以某种方式刷新我的观点@Model而无需刷新整个页面?

编辑: Iv'e现在改变了我成功的功能,所以它看起来是这样的:

 成功:功能(数据){
    $(#1)文本(data.Header);
},
 

但是,这个模型值不会被更新。我是从成功的功能发回的数据是我的模型为JSON。

 < D​​IV ID =1级=click2edit> @ Model.Header< / DIV>
 

解决方案

下面是我们的聊天内容摘要:

这是MVC模式是包含在服务器上构建的数据是,用于控制的呈现,以及将数据提供给一个视图的实例。 HTTP的无状态特性决定了唯一的一次,你可以访问此服务器端的数据时,认为是被渲染的过程。一旦它的呈现时,它是完全在浏览器和任何数据,这是present在服务器侧对象的手从内存中释放

这一点后,您不能再使用的刀片服务器端的语法 @if @model 访问模型数据(模型,因为它存在,当页面正在变得不再存在)。相反,你应该使用DOM和JavaScript对象工作(保存数据使用Ajax在服务器端)更新页面的外观和内容。如果没有做一个整版发表您唯一的选择是使用客户端code(JavaScript)的操作,用户所看到的(因此得名:查看),使他们所看到的比赛之后,已经发生的变化阿贾克斯POST。

我创建了一个要点这里演示这些概念: https://gist.github.com/xDaevax / f5e192c03f6a2bfc2cdb

从本质上讲,你将需要code类似于以下的控制器:

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;
使用System.Web.Mvc;

命名空间AjaxMvcTest.Controllers {
    公共类的HomeController:控制器{
        //
        // 到家/


        公众的ActionResult指数(){
            HomeModel模式=新HomeModel();
            model.Header =缺省头;
            model.Content =人们认为时间是有严格的进步事业的效果,但实际上,从一个非线性,非主观的角度来看,它更像是wibbly,摇摆不定...... timey-wimey大球.. 。 东东。;
            返回查看(模型);
        }

        [ValidateInput(假)]
        公共JsonResult SaveContent(UpdateDataModel updateRequest){
            //做一些东西
            HomeModel newModel,并向=新HomeModel();
            newModel.Content = updateRequest.Content;
            newModel.Header = updateRequest.Header;

            返回JSON(newModel,并向);
        }

    }
}
 

下面是一个视图,将与上述控制器一起使用:

  @model HomeModel

@ {
    ViewBag.Title =指数;
    布局=〜/查看/共享/ _Layout.cshtml;
}

< H2>指数< / H>

< D​​IV ID =1级=click2edit> @ Model.Header< / DIV>
< BR />
< D​​IV ID =2级=click2edit> @ Model.Content< / DIV>
< BR />
标题:放; NBSP;&安培; NBSP; <输入类型=文本名称=HeaderInputID =HeaderInput值=@ Model.Header/>
< BR />
内容:其中,textarea的名字=ContentInputID =ContentInput> @ Model.Content< / textarea的>
< BR />
<输入类型=按钮ID =saveFileBtn值=保存/>

<脚本类型=文/ JavaScript的>
    $(函数(){

        $(#saveFileBtn)。点击(函数(五){
            $阿贾克斯({
                网址:/首页/ SaveContent',
                键入:POST,
                数据:getFormData(),
                数据类型:JSON,
                成功:功能(数据){
                    $(#1)文本(data.Header);
                    $(#2)文本(data.Content);
                    $(#HeaderInput)VAL(data.Header)。
                    $(#ContentInput)VAL(data.Content)。
                },
                错误:函数(){
                    警报(错误);
                }
            });
        });
    });

    传播getFormData(){
    //将表单数据为JavaScript对象
        VAR dataToSubmit = {
            标题:$(#HeaderInput)VAL()
            内容:$(#ContentInput)VAL()。
            时间戳:新的Date()
            ID:1
       };

       返回dataToSubmit;
    }
< / SCRIPT>
 

在这种方式,你可以看到,客户端(JavaScript)code是负责更新的成功的看法的 AJAX 控制器后,法所做的工作和 getFormData()方法来转换表单值转换为JavaScript对象MVC模型粘结剂可以读取和转换为.NET服务器端模式。如果你不想手动做到这一点,你可以使用jQuery的连载方法,将整个表单序列化,提供表单值匹配您的服务器端模型。

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>

解决方案

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.