在表单提交后,无法使用 mvc razor 中的 ajax 从其中的另一个分部视图刷新分部视图

Not able to refresh the partial view after a form submission from another partial view within it, using ajax in mvc razor

本文关键字:视图 ajax 另一个 刷新 中的 表单提交 razor mvc      更新时间:2023-09-26

在我的网站上,我有一个类似Facebook的聊天页面。我已经使用基本的表单提交方法实现了它,当我发布某些内容时,该方法将刷新整个页面。现在我需要使用 ajax/jquery 更改它,以便它只刷新我的部分视图。我为此编写了代码,并通过添加脚本更改了视图。

我的主要消息视图类似于(示例(:

 @model myModel
 <h2>
   Message Board<small class="on-right"/>
 </h2>
  // Text box for Adding Message(post)
  @Html.TextArea("Message", new { @placeholder = "Add a post", id = "Message" })      
 <input type="button" id="Post" value="Post"/>
 // partial view that displays all the messages along with its comments
 <div id="messagelist">
        @{
    Html.RenderPartial("_posts", Model.MessageList);
        }
    </div>

消息页面脚本:

 $('#Post').click(function () {
        var url = "/MyController/Messages";
        var Message = $("#Message").val();
        $("#Message").val("");
        $.post(url, { Message: Message }, function (data) {
            $("#messagelist").html(data);

_post部分视图:

 @model IEnumerable<Model.MessageList>
 //Foreach loop for displaying all the messages
 @foreach (var item in Model)
 {
  <div >
      @Html.DisplayFor(model => item.UserName)
      @Html.DisplayFor(model => item.MessageText)
      //Foreach loop for displaying all the comments related to each message
       @foreach (var item1 in item.Comments)
           {
               @item1.UserName 
               @item1.MessageText
            }
   </div>
    //partial view for adding comments each for messages
     @Html.Partial("Comment", new ModelInstance { MessageId = item.MessageId })
    }

评论部分视图(我正在使用ajax表单提交(:

  @model ModelInstance
  //form for submitting a message instance with parent message id for adding a comment to the parent message
  @using (Ajax.BeginForm("Comment", "MyController", new AjaxOptions { UpdateTargetId = "messagelist" }))
{
    @Html.AntiForgeryToken()  @Html.ValidationSummary(true)
    <div>
        @Html.HiddenFor(modelItem => Model.MessageId)
        @Html.TextBoxFor(modelItem => Model.CommentText, new { @placeholder = "leave a comment" })
 <button class="btn-file" type="submit"></button>
    </div>
}

控制器操作(示例(:

  public ActionResult Messages(string Message)
    {
            ------------------------------
            create messag object
            ---------------------
            add to database
            -------------------
            fetch again for refreshing
            ------------------------
            return PartialView("_posts", refreshed list);
        }
    public ActionResult Comment(StudiMessageDetails Comment)
    {
        ------------------------------
            create messag object
            ---------------------
            add to database
            -------------------
            fetch again for refreshing
        return PartialView("_posts", msgDetails);
        }

现在,发布消息和发布评论功能正常。 此外,当我发布消息时,它只会刷新我的主消息视图。

但是当我发表评论时,它只给了我刷新的部分视图。 它没有绑定到"div id=messagelist">也没有给我整页。谁能说出我哪里出错了?请帮忙。

您的Ajax.BeginForm()正在将<div id="messagelist">的内容替换为 return PartialView("_posts", msgDetails); 中的 html。我怀疑模型msgDetails只包含评论相关消息的详细信息,所以这就是你所看到的。

我建议重新考虑您的设计,尤其是Messages()方法,该方法在保存消息后调用数据库以获取所有消息并返回完整列表 - 您已经在页面上拥有所有数据,因此这似乎完全没有必要,只会降低性能。您可以通过以下方式简化它

部分

视图(请注意,部分视图用于一条消息,而不是集合(

@model Model.Message
<div class="message">
  <div class=username">@Model.UserName</div>
  <div class=messagetext">@Model.MessageText</div>
  <div class="commentlist">
    @foreach (var comment in Model.Comments)
    {
      <div class="comment">
        <div class="username">@comment.UserName<div>
        <div class="commenttext">@comment.MessageText<div>
      </div>
    }
  </div>
  <div>
    @Html.TextBox("CommentText", new { placeholder = "Leave a comment", id = "" }) // remove the id attribute so its not invalid html
    <button class="addcomment" data-id="@Model.MessageId">Add Comment</button>
  </div>
</div>

主视图

@model myModel
...
@Html.TextArea("Message", new { placeholder = "Add a post" })  // no point adding the id - its already added for you    
<input type="button" id="Post" value="Post" />
<div id="messagelist">
  @foreach(var message in Model.MessageList)
  {
    @{ Html.RenderPartial("_posts", message); }
  }
</div>
<div id="newmessage"> // style this as hidden
  @{ Html.RenderPartial("_posts"); }
</div>

脚本

// Add a model or ViewBag property for the current user name
var userName = JSON.parse('@Html.Raw(Json.Encode(ViewBag.UserName))');
$('#Post').click(function () {
  var url = '@Url.Action("Message", "MyController")'; // dont hardcode!
  var message = $('#Message').val();
  $.post(url, { MessageText: message }, function (data) {
    if(data) {
      // clone the new message, update message id and add to DOM
      var html = $('#newmessage').clone();
      message.children('.username').text(userName);
      message.children('.messagetext').text(message);
      message.children('.newcomment').children('button').data('id', data);
      $('#messagelist').perpend(html); // add at top of list
      $('#Message').val(''); // clear message text
    } else {
      // something went wrong
    }
  });
});
$('.addcomment').click(function() {
  var url = '@Url.Action("Comment", "MyController")';
  var comment = $(this).prev('input');
  var messageID = $(this).data('id');
  var list = $(this).closest('.message').children('.commentlist');
  $.post(url, { MessageID: messageID, CommentText comment.val() }, function (data) {
    if (data) {
      // add message
      var html = $('<div><div>').addClass('comment');
      html.append($('<div><div>').addClass('username').text(userName));
      html.append($('<div><div>').addClass('commenttext').text(commentText));
      list.append(html); // add to end of existing comments
      comment.val(''); // clear existing text
    } else {
      // something went wrong
    }
  });
});

控制器

[HttpPost]
public ActionResult Message(string MessageText)
{
  // create new message object and save to database
  int ID = // the ID of the new message
  return Json(ID); // if exception, then return null;
}
[HttpPost]
public ActionResult Comment(int MessageID, string CommentText)
{
  // create new comment object and save to database
  return Json(true); // if exception, then return null;
}