【问题标题】:MVC controller action launched from modal crashes losing jQuery context从模态崩溃启动的 MVC 控制器操作丢失 jQuery 上下文
【发布时间】:2014-10-20 08:56:07
【问题描述】:

我遇到的问题类似于这两个 StackOverflow 帖子 herehere。但是,我的情况完全不同,以至于我无法进行所需的更正。

就像那两个帖子一样,当浏览器执行帖子控制器操作时,我似乎正在失去上下文。

场景如下:

  1. 页面加载
  2. 用户点击添加按钮。
  3. 模态对话框加载部分视图,其中包含添加新对象所需的字段。
  4. 表单已完成,用户点击保存。
  5. 添加完成的控制器操作(添加记录就好了)然后重定向到步骤 1 的控制器操作。想法是这将关闭模式并将用户返回到步骤 1 中的页面。

问题当然是重定向导致 $ (jquery) is undefined 错误。

步骤 1 控制器操作:

public ActionResult Configure()
{
  ....code...
  return View("~/FolderPath.../Configure.cshtml", model);
}

第 2 步 jQuery 启动模态:

$("#new").click(function (e)
{
   e.preventDefault();
   var window = $("#window").kendoWindow(
   {
      content: {
                 url: "@Html.Raw(Url.Action("CreateEditRecord", "Controller"))",
                 data: { .... }
                }
            });
        window.data('kendoWindow').center();
});

第 3 步和第 4 步模态提交:

$("#save").click(function (e)
{
   e.preventDefault();

   ...some validation stuff here.....

   $("#formCreateEditRecord").submit();
});

第 5 步(这些是我尝试过的不同方法,它们都失去了 jQuery 上下文)

public ActionResult CreateEditRecord(NewRecordModel model)
{
    ...add new record to db etc.....

  //return RedirectToAction("Configure");

  //return Configure();

  //return PartialView("~/FolderPath/CreateEditRecord.cshtml", model);
  //tried this last one to return to modal window just trying to figure things out.


}

编辑


@SSA 和@Ryios。你的解释很清楚,确实解决了问题,但如果你能再忍受我几秒钟......

我了解部分视图没有完整页面的全部权重(脚本标签等)。我仍然不清楚的是为什么它甚至会回到局部视图?我在第 5 步中的后控制器操作重定向到配置操作,这是一个完整视图,所以我希望页面加载完整视图。

在更改和重新加载整个页面之前,MVC 视图引擎是否仍然呈现部分视图,即使只是几毫秒?

【问题讨论】:

    标签: c# jquery asp.net-mvc asp.net-mvc-4


    【解决方案1】:

    我认为还有两步,

    1. 手动提交表单。

    2. 在数据库操作后从操作 CreateEditRecord 返回 JsonResult。

    //在控制器动作中

      public JsonResult CreateEditRecord(NewRecordModel model)
      {
       // Do your database stuff here....
       //Then return Success or Failure based on your database result.
       return new JsonResult { Data = new { Result = "Success/Failure" } };
      }
    

    然后当你调用提交表单时。

    $("#save").click(function (e)
    {
       e.preventDefault();
    
       ...some validation stuff here.....
        $("#formCreateEditRecord").submit(
        function(e){
        e.preventDefault(); //As we will manually submit the form
         $.ajax({
             type: "POST",
             url: "@Html.Raw(Url.Action("CreateEditRecord", "Controller"))",
              data: $(this).serialize(),
              success: function(data) {
                 //here we check if database called resulted in Success/Failure
                 if(data.Result === "Success")
                 {
                  //Write your code to close the dialog.
                 }else 
                 {
                  //Show error message or whatever.
                 }
               }
            })
        });
    }
    

    【讨论】:

      【解决方案2】:

      "@Html.Raw(Url.Action("CreateEditRecord", "Controller"))"

      这是渲染局部视图。部分视图就是它们,通常没有整页权重,例如他们没有你所有的脚本标签。

      当它作为模式对话框的内容加载时,它(本身)没有 jquery,因为您没有脚本标签来在局部视图上加载 jQuery。

      因此,要么将 jquery 添加到局部视图,要么在父窗口上引用 jQuery。

      "Note: I'm not sure if this next code stub will work or not as jQuery might be attached to the dom on the parent window and not find any elements on your Modal Window.  I know there is a way to do it though, you just might have to mess with your jQuery code a little bit.
      
      $ = window.parent.$;
      $("#save").click(function (e)
      {
         e.preventDefault();
      
         ...some validation stuff here.....
      
         $("#formCreateEditRecord").submit();
      });
      

      使用 Ajax,部分视图可以工作,因为它们用于更新原始页面的某些部分。但是,对于模态对话框,它是一个全新的页面(在子窗口中)。

      如果您使用的是 jQuery UI 对话框之类的 InPage 模态对话框解决方案,那么您可以从原始页面获得 jquery。

      我建议为您的局部视图设计一个基本模板,例如

      <div class="modal-dialog">
          <div class="title">@this.ViewBag.ModalTitle</div>
          <div class="body">
              @RenderBody()
          </div>
      </div>
      <!--Load Scripts/Styles Here-->
      <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
      @RenderSection("scripts", false)
      

      然后你可以创建使用它的局部视图,比如

      @{
          Layout = "~/Views/Partials/Dialogs/BaseDialog.cshtml";
      }
      <p>This is a test dialog</p>
      @section scripts 
      {
          <script src="anotherscripttoaddhere" />
      }
      

      【讨论】:

        猜你喜欢
        • 2011-11-21
        • 1970-01-01
        • 2011-06-21
        • 1970-01-01
        • 2021-05-16
        • 2018-03-20
        • 2010-09-07
        • 1970-01-01
        • 2011-09-28
        相关资源
        最近更新 更多