【问题标题】:How to refresh only part of the Index page in MVC 5?如何仅刷新 MVC 5 中的索引页面的一部分?
【发布时间】:2014-01-16 18:33:49
【问题描述】:

索引页面包含两个部分视图。一种是供用户输入搜索条件,另一种是显示结果。 如何只更新结果视图中的数据?

我正在使用 MVC 5 和 Razor。我看过一些关于这方面的例子,主要是使用 ajax 和 jquery。我在问什么是最好的(更喜欢更简单的)解决方案

// 索引视图:

<div id="div_Search"> 
@{Html.RenderPartial("~/Views/Shared/Search.cshtml", ViewBag.Model_Search );}
</div>

<div id="div_Results">
@{Html.RenderPartial("~/Views/Shared/Results.cshtml", ViewBag.Model_Results );}
</div>


// HOME CONTROLLER

公共类 HomeController: 控制器 { MainContextDB db = new MainContextDB();

public ActionResult Index()
{
    // Code to initialize ViewBag.Model_Search, etc...
    .... 

    // Code to initialize  ViewBag.Model_Results, etc... (Values empty at startup) 
    ....

    return View();
}


[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult GetResults([Bind(Include = "DropOffLoc,DropOffDate,PickUpDate")] Search search)
{

   // Retrieve results using the search parameters, etc...
   ....

   // THIS RETURNS THE VIEW WITH THE DATA, BUT IN A SEPARATE PAGE (AS EXPECTED) 
   return View("~/Views/Shared/Results.cshtml", results);            

   // THIS RETURNS THE VIEW IN THE MAIN PAGE BUT WITH EMPTY DATA (AS EXPECTED) 
   return  RedirectToAction("Index");

   // HOW TO RETURN THE VIEW WITH THE DATA IN THE MAIN PAGE ?
   ??????? 

}

}

// 这是搜索部分视图

@model Models.Results

@using (Html.BeginForm("GetResults", "Home", FormMethod.Post, new { @class = "my-form" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <div class="form-group input-group-sm">
        @Html.LabelFor(model => model.DropOffLoc)
        @Html.DropDownListFor(model => model.DropOffLoc, ViewBag.LocationList as SelectList, new { @class = "form-control"  })
        @Html.ValidationMessageFor(model => model.DropOffLoc)
    </div>

    <div class="form-group input-group-sm">
        @Html.LabelFor(model => model.DropOffDate)
        @Html.TextBoxFor(model => model.DropOffDate, new { @class = "form-control datepicker", placeholder = "Enter Drop-off date here..." })
        @Html.ValidationMessageFor(model => model.DropOffDate)
    </div>

        <div class="form-group input-group-sm">
        @Html.LabelFor(model => model.PickUpDate)
        @Html.TextBoxFor(model => model.PickUpDate, new { @class = "form-control datepicker", placeholder = "Enter Pick-up date here..." })
        @Html.ValidationMessageFor(model => model.PickUpDate)
    </div>

    <div style="text-align: center; margin-top: 10px; margin-bottom: 10px;">
        <input type="submit" id="getResults" value="GET RESULTS" class="btn btn-default btn-success" />
    </div>
}

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 razor


    【解决方案1】:

    我会在您的搜索部分中放置一个表单。然后通过 JQuery 将一些操作发布到您的 GetResults 操作,该操作应返回:

    return PartialView("~/Views/Shared/Results.cshtml", results); 
    

    然后,在您的 JQuery 帖子的成功回调中,将返回的结果吐到您的 $("#div_Results") 中,如下所示:

    $.ajax({
        url: '/Home/GetResults',
        type: "POST",
        dataType: "html",
        data: $("#FormId").serialize(),
        success: function (data) {
            //Fill div with results
            $("#div_Results").html(data);
        },
        error: function () { alert('error'); }
    });
    

    除非我有错字或什么,否则应该可以。您需要将表单选择器替换为表单标签的 ID。

    【讨论】:

    • 那是完全一样的形式。你能举个例子说明如何做“..将返回的结果吐到你的 $("#div_Results")”
    【解决方案2】:

    虽然这个问题已经有了答案,但我想我会发布另一种可行的方法。此方法使用相同的操作方法,仅检查请求是否是 Ajax 调用,然后仅替换部分正文。这里只是相关代码。

    //搜索表单

    @using (Ajax.BeginForm("Index", "Home", 
        new AjaxOptions()
        { 
            HttpMethod = "GET", UpdateTargetId = "my-posts", 
            InsertionMode = InsertionMode.Replace 
        }))
    {
        <input type="text" name="term" placeholder="Search B.I & G" />
        <input type="submit" value="" />
    }
    

    //视图的一部分

    <section>
    <div id="my-posts">
        @Html.Partial("_Posts", Model.Posts)
    </div>
    

    现在这里是 Index action 方法,如果 Request 是 AjaxRequest,它会返回一个 Partial View,它将 div 的内容替换为 id my-posts。如果 Request 不是 Ajax 请求,那么它会加载整个 View。

    public async Task<ActionResult> Index(string term)
    {
         var viewModel = new HomeFeedsViewModel();
         viewModel.Posts = await Task.Run(() =>
                       db.Posts.Include("Comments")
                       .Include("By").OrderByDescending(o => o.PostedOn)
                       .ToList());
        //Return a Partial View which replaces content on the View
        //only if the Request is an Ajax Request
        if (Request.IsAjaxRequest())
        {
            viewModel.Posts = viewModel.Posts
                .Where(a => a.Title.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0
                         || a.Message.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0
                );
            return PartialView("_Posts", viewModel.Posts);
        }
    
        return View(viewModel);
    }
    

    希望这对某人有所帮助。

    【讨论】:

    • 很棒的纯剃须刀 mvc 方式。即使我不明白 using 在那里的工作原理:)
    • using 语句确保当Ajax.BeginForm() 超出范围时,从razor 代码中解析相关html 时使用的服务器资源被释放
    • 嗨,开发者,1) 我们如何使用您的 Ajaxified approach 处理 multiple search criteria/inputdates like this link? on the left side、复选框、下拉列表等。另外,2)在返回时附加一个纯 HTML 表作为数据,或者我们要附加什么,整个表单?
    • 要让这个解决方案发挥作用,你需要 jquery.unobtrusive-ajax 库,对吗?
    【解决方案3】:

    事实上,您需要使用 AJAX。

    如我所见,最好的方法是获取局部视图并向其发出 AJAX 加载(jQuery 中的 jQuery.load)。

    【讨论】:

      猜你喜欢
      • 2015-12-22
      • 2014-12-23
      • 2013-10-28
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多