2016-09-22 42 views
3

我試圖將一個小問題減到最小,所以我創建了新的示例web項目; VS中的mvc-empty。我在Home控制器中創建了一個名爲「Index」的視圖。索引視圖代碼:在asp.net中提交Ajax.BeginForm後,jQuery代碼無法正常工作mvc

@model WebApplication16.ViewModels.Home.IndexVM 
@{ 
    ViewBag.Title = "Index"; 
} 

@Html.Partial("~/Views/Home/_Orders.cshtml", Model.Orders) 

@section scripts{ 
    <script src="~/Scripts/jquery.validate.js"></script> 
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script> 
    <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script> 
    <script> 
     $("#Type").change(function() { 



      $('#order-current > img').remove(); 
      var currentOrder = "#Type_" + $("#Type").find('option:selected').text(); 

      var $img = $(currentOrder).clone(); 
      $img.removeClass("hidden"); 
      $("#order-current").append($img); 

      $("#ajax-form").submit(); 
     }); 
    </script> 
} 

首頁控制器代碼:

public class HomeController : Controller 
    { 
     [HttpGet] 
     public ActionResult Index() 
     { 
      IndexVM dataVM = new IndexVM(); 
      GetControlsDataSource(dataVM.Orders); 

      return View(dataVM); 
     } 

     private static void GetControlsDataSource(OrdersVM dataVM) 
     { 
      List<SelectListItem> typeControlDataSource = new List<SelectListItem>(); 
      foreach (var en in Enum.GetValues(typeof(TypeEnum))) 
      { 
       SelectListItem item = new SelectListItem(); 
       item.Text = en.ToString(); 
       item.Value = ((int)en).ToString(); 
       typeControlDataSource.Add(item); 
      } 
      dataVM.TypeControlDataSource = typeControlDataSource; 
     } 


     [HttpPost] 
     public ActionResult Pay(IndexVM dataVM) 
     { 
      GetControlsDataSource(dataVM.Orders); 
      if (ModelState.IsValid) 
      { 
       dataVM.Orders.Info = "Info bla bla bla"; 
       return PartialView("~/Views/Home/_Orders.cshtml", dataVM.Orders); 
      } 
      else 
      { 
       return View(dataVM); 
      } 

     } 
    } 

還有一個名爲「_Orders」的局部圖,這是在_Orders局部視圖的指數view.The代碼呈現:

@model WebApplication16.ViewModels.Home.OrdersVM 

@using (Ajax.BeginForm("Pay", "Home", new AjaxOptions 
{ 
    InsertionMode = InsertionMode.Replace, 
    UpdateTargetId = "result", 
}, new { id = "ajax-form" })) 
{ 
    <div id="result"> 
     <div id="order-current"> 

     </div> 


     <div> 
      @Html.TextBoxFor(x => x.Name, new { @class = "form-control", style = "margin-top:10px;", id = "Name" }) 
      @Html.ValidationMessageFor(x => x.Name) 
     </div> 

     <div> 
      @Html.DropDownListFor(x => x.Type, Model.TypeControlDataSource, new { @class = "form-control", style = "margin-top:10px;", id = "Type", }) 
      @Html.ValidationMessageFor(x => x.Type) 
     </div> 
     <div> 
      <p>@Model.Info</p> 
     </div> 
     <button type="submit" class="btn btn-primary" name="ok"> OK</button> 
    </div> 


} 

<div id="orders-container"> 
    <img id="Type_I" src="~/App_Images/Type_I.png" class="img-responsive hidden" /> 
    <img id="Type_II" src="~/App_Images/Type_II.png" class="img-responsive hidden" /> 
    <img id="Type_III" src="~/App_Images/Type_III.png" class="img-responsive hidden"/> 
</div> 
Index model is described by class IndexVM: 
public class IndexVM 
    { 
     public IndexVM() 
     { 
      this.Orders = new OrdersVM(); 
     } 

     public OrdersVM Orders { get; set; } 
    } 

_Orders模型由類OrdersVM描述:

public class OrdersVM 
    { 

     [Required] 
     public string Name { get; set; } 

     public string Info { get; set; } 

     [Required] 
     public TypeEnum Type { get; set; } 

     public List<SelectListItem> TypeControlDataSource { get; set; } 
    } 


public enum TypeEnum 
{ 
    I, 
    II, 
    III 
} 

在使用id =「Type」的DropDownListFor控件中更改值後,來自隱藏字段的圖片應該通過位於Index視圖中的jquery代碼注入到id =「order-current」的容器中,並且在該操作之後,ajax-form應該提交。它工作正常,但是從HomeController中調用

return PartialView("~/Views/Home/_Orders.cshtml", dataVM.Orders); 

後,現場信息正確更新,但是從「訂單流」的div容器注入的畫面消失了。我嘗試使用F12按鈕查看Google Chrome中出現了什麼問題,並且沒有錯誤,但在「browserLink」腳本中出現了無限循環。我無法解釋爲什麼。 我只想在提交ajax表單後在id =「order-current」容器中看到注入的圖片。如何做到這一點,我做錯了什麼?

回答

0

感謝我的朋友,我終於解決了這個問題。更新「結果」容器後,jQuery向位於此容器中的控件添加的所有事件都將取消固定。這就是它崩潰的原因。 使其正確工作的方法是創建一個函數並將其固定到AjaxBeginForm的事件OnComplete。每次通過ajax更新結果容器後,都會調用該函數。我也在Home控制器中犯了一個小錯誤,因爲我插入了錯誤的視圖模型類。在所有變化之後,它看起來像這樣; Home控制器代碼:

public class HomeController : Controller 
    { 
     [HttpGet] 
     public ActionResult Index() 
     { 
      IndexVM dataVM = new IndexVM(); 
      GetControlsDataSource(dataVM.Orders); 

      return View(dataVM); 
     } 

     private static void GetControlsDataSource(OrdersVM dataVM) 
     { 
      List<SelectListItem> typeControlDataSource = new List<SelectListItem>(); 
      foreach (var en in Enum.GetValues(typeof(TypeEnum))) 
      { 
       SelectListItem item = new SelectListItem(); 
       item.Text = en.ToString(); 
       item.Value = ((int)en).ToString(); 
       typeControlDataSource.Add(item); 
      } 
      dataVM.TypeControlDataSource = typeControlDataSource; 
     } 


     [HttpPost] 
     public ActionResult Pay(OrdersVM dataVM) 
     { 
      GetControlsDataSource(dataVM); 
      if (ModelState.IsValid) 
      { 
       dataVM.Info = "Info bla bla bla"; 
       return PartialView("~/Views/Home/_Orders.cshtml", dataVM); 
      } 
      else 
      { 
       return View(dataVM); 
      } 

     } 
    } 

索引視圖:

@model WebApplication16.ViewModels.Home.IndexVM 
@{ 
    ViewBag.Title = "Index"; 
} 

@Html.Partial("~/Views/Home/_Orders.cshtml", Model.Orders) 

<div id="orders-container"> 
    <img id="Type_I" src="~/App_Images/Type_I.png" class="img-responsive hidden" /> 
    <img id="Type_II" src="~/App_Images/Type_II.png" class="img-responsive hidden" /> 
    <img id="Type_III" src="~/App_Images/Type_III.png" class="img-responsive hidden" /> 
</div> 

@section scripts{ 
    <script src="~/Scripts/jquery.validate.js"></script> 
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script> 
    <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script> 
    <script> 

     function imageOnChangeEvent() { 
      $("#ajax-form").submit(); 
     } 

     function OnCompleteAjaxForm() { 

      $('#order-current > img').remove(); 
      var currentOrder = "#Type_" + $("#Type").find('option:selected').text(); 

      var $img = $(currentOrder).clone(); 
      $img.removeClass("hidden"); 
      $("#order-current").append($img); 
     } 

    </script> 

} 

_Orders局部視圖代碼:

@model WebApplication16.ViewModels.Home.OrdersVM 

    <div id="result"> 
     @using (Ajax.BeginForm("Pay", "Home", new AjaxOptions 
     { 
      InsertionMode = InsertionMode.Replace, 
      UpdateTargetId = "result", 
      OnComplete = "OnCompleteAjaxForm()" 
     }, new { id = "ajax-form" })) 
     { 

      <div id="order-current"> 

      </div> 


      <div> 
       @Html.TextBoxFor(x => x.Name, new { @class = "form-control", style = "margin-top:10px;", id = "Name" }) 
       @Html.ValidationMessageFor(x => x.Name) 
      </div> 

      <div> 
       @Html.DropDownListFor(x => x.Type, Model.TypeControlDataSource, new { @class = "form-control", style = "margin-top:10px;", id = "Type", onchange = "imageOnChangeEvent()" }) 
       @Html.ValidationMessageFor(x => x.Type) 
      </div> 
      <div> 
       <p>@Model.Info</p> 
      </div> 
      <button type="submit" class="btn btn-primary" id="button_ok" name="ok"> OK</button> 


     } 
    </div>