【问题标题】:Reload page based on a selection from drop down list MVC根据下拉列表 MVC 中的选择重新加载页面
【发布时间】:2019-04-09 23:35:15
【问题描述】:

我有一个可行的解决方案,但我不知道如何在从下拉列表中选择某个 ID 后重新加载页面。我的列表是从数据库中填充的。当我选择它时,我可以看到它的 ID 和相应的数据。但是,屏幕上没有任何变化。

模型类:

 public List<Hello> getID()
        {
            var que = (from rel in db.Table1
                       select new Hello
                       {
                           ID = rel.R_ID
                       }).ToList();
            return que;
        }

public List<Hello> getStuff()
        {
            var que = (from wre in db.View
                       select new Hello
                       {
                           ID = wre.R_ID,
                           Summary = wre.Summary,
                           Description = wre.Description

                       }
         }

getHello() 与 getStuff() 方法完全相同,只是接受一个字符串 ID 参数。

控制器类:

public ActionResult Index()
        {
            var model = test.getStuff();
            ViewBag.IDs = new SelectList(test.getID(), "", "ID");
            return View(model);
        }

[HttpPost]
        public JsonResult getDataBySelectedID(string selectedId)
        {
            var que = test.getHello(selectedId);
             return Json(que, JsonRequestBehavior.AllowGet);

        }

Partial_View 类:

 <div class="container">
        <table id="myTable" align="left">
            <tr>
                <th>@Html.DisplayNameFor(model => model.R_ID)</th>
                <th>@Html.DisplayNameFor(model => model.Summary)</th>
                <th>@Html.DisplayNameFor(model => model.Description)</th>
            </tr>

     @foreach (var item in Model)
        {
          <tr id="Home">

              <td>@Html.DisplayFor(x => item.R_ID)</td>
              <td>@Html.DisplayFor(x => item.Summary)</td>
              <td>@Html.DisplayFor(x => item.Description)</td>
           </tr>
         }
  </table>
 </div>

查看类:

@Html.DropDownList("ID", ViewBag.IDs as SelectList) 

    <script>

     $(document).ready(function () {
         $("#ID").on("change", function () {
                var selectedId = this.value;
                var url = "/Sample/getDataBySelectedID";

                $.ajax({
                    method: "POST",
                    dataType: "json",
                    url: url,
                    data: {
                        selectedId: selectedId
                    }
                });
            });
         });
   </script>

@foreach (var item in Model)
            {
                <tr>
                    <td>
                        @{Html.RenderPartial("Partial_Index", item);}
                    </td>
                </tr>
            }

如何重新加载带有所选值及其相应数据的页面?

任何帮助将不胜感激!

谢谢。

【问题讨论】:

  • 由于您使用的是 AJAX,因此您必须在收到来自控制器的数据后以某种方式手动更新页面。您可以通过自己更新 HTML、将结果数据呈现为部分视图并将其注入页面或其他方式来完成此操作。仅通过 AJAX 加载数据不会自行更新页面上的任何内容。
  • 感谢@Jack 的洞察力。我也可以参考任何来源以获得一些指导?
  • 我推荐你走局部视图路线。我没有任何具体的链接,但我会在一秒钟内发布一个包含一些参考的答案。
  • @Jack 听起来不错,谢谢。
  • 附带说明,如果您不介意回发,则可能不需要 AJAX。一个标准的表格就可以了。我假设您需要它,因为它在您的示例中。

标签: javascript jquery ajax asp.net-mvc entity-framework


【解决方案1】:

如 cmets 中所述,您必须以某种方式将数据加载到页面中。我建议您通过部分视图来执行此操作。

1) 创建可重复使用的局部视图

首先,创建一个引用您的模型的局部视图。为此,请像往常一样为控制器创建一个视图,然后勾选“部分视图”选项。确保在模型下拉列表中选择您的模型。

然后,将引用模型的 .cshtml 从当前视图移动到局部视图。例如,如果您有一个列出模型字段的表格,您可以将整个表格剪切到局部视图中。您希望在局部视图中包含所需的最少代码(也就是说,不要将整个视图复制到其中)。

2) 在当前视图中引用局部视图

现在您已经设置了局部视图,您应该在现有视图中使用它来加载表格。在继续之前,您应该确保这首先有效。您可以使用@Html.RenderPartial(string ViewName, object Model) 辅助方法来呈现它。 Read more. 因此,您可以将这一行放在您的 now-cut-code 所在的位置:@RenderPartial("MyPartialView", model),其中“MyPartialView”是您的局部视图的名称,而模型是您想要传递到局部视图的模型对象.

3) 添加方法以在控制器上渲染部分视图

此时,您只需要能够在使用 AJAX 后更新您的局部视图。首先,您需要添加将部分视图呈现为字符串的功能,以便您可以轻松地将其注入到您的视图中。我建议您通过实现控制器接口并让您的控制器从中继承所需的方法来做到这一点。在我的程序中,我的控制器继承自以下控制器接口:

public class IBaseController : Controller
    {    
        internal string PartialViewToString(string partialViewName, object model = null)
        {
            ControllerContext controllerContext = new ControllerContext(Request.RequestContext, this);

            return ViewToString(
                controllerContext,
                ViewEngines.Engines.FindPartialView(controllerContext, partialViewName) ?? throw new FileNotFoundException("Partial view cannot be found."),
                model
            );
        }

        protected string ViewToString(string viewName, object model = null)
        {
            ControllerContext controllerContext = new ControllerContext(Request.RequestContext, this);

            return ViewToString(
                controllerContext,
                ViewEngines.Engines.FindView(controllerContext, viewName, null) ?? throw new FileNotFoundException("View cannot be found."),
                model
            );
        }

        protected string ViewToString(string viewName, string controllerName, string areaName, object model = null)
        {
            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", controllerName);

            if (areaName != null)
            {
                routeData.Values.Add("Area", areaName);
                routeData.DataTokens["area"] = areaName;
            }

            ControllerContext controllerContext = new ControllerContext(HttpContext, routeData, this);

            return ViewToString(
                controllerContext,
                ViewEngines.Engines.FindView(controllerContext, viewName, null) ?? throw new FileNotFoundException("View cannot be found."),
                model
            );
        }
        private string ViewToString(ControllerContext controllerContext, ViewEngineResult viewEngineResult, object model)
        {
            using (StringWriter writer = new StringWriter())
            {
                ViewContext viewContext = new ViewContext(
                    ControllerContext,
                    viewEngineResult.View,
                    new ViewDataDictionary(model),
                    new TempDataDictionary(),
                    writer
                );

                viewEngineResult.View.Render(viewContext, writer);

                return writer.ToString();
            }
        }
    }

然后,在你的控制器上,你可以像这样继承这个接口:

public class ExampleController : IBaseController
{

}

现在,您可以使用新方法轻松地将局部视图呈现为字符串。

在您的 getDataBySelectedID 操作中,这就是您想要做的。

[HttpPost]
public JsonResult getDataBySelectedID(string selectedId)
{
    var que = test.getHello(selectedId);
    string partialViewString = PartialViewToString("MyPartialView", que);
    return Json(partialViewString, JsonRequestBehavior.AllowGet);
}

您可能需要修改上述语句以适合您的用途,但它应该会让您接近。

4) 在 AJAX 成功时将部分视图注入页面

现在,我们已经设置了一个局部视图来处理我们想要更新的模型数据。我们已经更新了我们的视图以默认从局部视图加载。我们已经实现了一个控制器接口,它可以让使用将 Partial View 渲染为一个字符串,以便我们可以将它注入到我们的页面中。现在,我们只需要进行注入即可。

首先,将前面的 setup @Html.RenderPartial() 语句包装在一个 div 中。让我们给它 ID partialViewDiv。这将让我们轻松地使用 jQuery 定位它。

 $(document).ready(function () {
     $("#ID").on("change", function () {
            var selectedId = this.value;
            var url = "/Sample/getDataBySelectedID";

            var $partialViewDiv = $('#partialViewDiv');

            $.ajax({
                method: "POST",
                dataType: "json",
                url: url,
                data: {
                    selectedId: selectedId
                }
            })
                .done(function (response, status, jqxhr) {
                   $partialViewDiv.html(response);
                   // Do any other updates here.
                })
                .fail(function (reponse, status, error) {
                    $partialViewDiv.html('');
                    // Handle your error here.
                });
        });
     });

同样,这些主要是伪代码,因此您可能需要进行一些修改。但是,在这一点上,您应该大致处于您需要的位置。 AJAX 调用应该通过使用新模型数据重新加载局部视图来更新您的视图。

提示

  • 像这样加载局部视图可能会破坏一些 jQuery 事件处理程序,具体取决于您的应用程序。如果发生这种情况,take a look at this.
  • 您可以通过 AJAX 调用从控制器返回任何字符串。如果需要,您可以返回与最初加载的不同的局部视图。只需使用界面中的方法,您就可以渲染任何您需要的内容。

上面的代码只是一些一般性的指导方针。在不了解您的完整实现的情况下,我无法提供 100% 有效、无错误的代码。但是,如果您有任何问题,请在此处发布,我会尽力提供帮助。

【讨论】:

  • 感谢您的详细解答!我去试试看!
  • 没问题。我经常使用这种方法,一旦你弄清楚了,它就很容易实现和扩展。
  • 我更新了 View 类的代码,因此您可以看到具体显示的内容。
  • 那么你的就很简单了。您的 HTML 表格将进入部分视图,然后按上述方式继续。
  • “用户未处理 HttpCompileExecution”... 收到此错误,在代码中发布更新。
【解决方案2】:

我看到的解决方案是使用 php

location.reload();

这就是你重新加载的方式,但如果你想重新加载数据,你可以使用类似的东西

window.location.replace("PathToThePage.php?YourDataName=YourData");

【讨论】:

  • 我已经尝试过 location.reload(),但这只会将页面重新加载到其原始内容。我将使用“window.location.replace("PathToThePage.php?YourDataName=YourData");”谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-12
相关资源
最近更新 更多