2011-07-25 57 views
9

您好我正在MVC 3(剃刀)原型的ajax嚮導。我注意到的一個怪異現象是,當您將部分視圖返回給UpdateTargetId時,插入視圖但不添加/應用Unobtrusive JavaScript。如果我在ajax塊之外加載局部視圖,例如MVC 3,(剃刀)加載部分與驗證

@Html.Partial("Company") 

它完美,所以我不會錯過任何的標準庫和 我的web配置的都好。

所以此刻我有點爲難。

我的觀點是以下內容:

@using(Ajax.BeginForm("Step", "Origination", new AjaxOptions { UpdateTargetId = "stepArea" })){ 

    <div id="stepArea"></div> 
    <input id="btnSubmit" type="submit" value="submit" /> 
} 

控制器:

public ActionResult Step(FormCollection formCollection) 
{ 
    if (this.Request.IsAjaxRequest()) 
    { 
     switch ((TempData["step"] as string)) 
     { 
      case "Company": 
       TempData["step"] = "Person"; 
       return PartialView("Company"); 

      case "Person": 
       TempData["step"] = "Pay"; 
       return PartialView("Person"); 

      case "Settlement": 
       return PartialView("Pay"); 

      default: 
       TempData["step"] = "Company"; 
       return PartialView("UserType"); 
     } 
    } 
    return View(); 
} 

我的問題是可以從局部視圖驗證被initalised /從局部刷新執行?

回答

10

閱讀了幾個論壇並做了一些實驗。 拼圖的最後一部分,在返回部分視圖後導致驗證工作。 jquery.validate.unobtrusive not working with dynamic injected elements

<script type="text/javascript"> 

    function validateAjaxForm() { 
     $("form").removeData("validator"); 
     $("form").removeData("unobtrusiveValidation"); 
     $.validator.unobtrusive.parse("form"); 
     return $('#form').valid(); 
    } 
</script> 


@{ Html.EnableClientValidation(true); } 
@using (Ajax.BeginForm("Step", "Origination", new AjaxOptions { UpdateTargetId = "stepArea", OnBegin = "return validateAjaxForm();" }, new { id = "form" })) 
{ 
    <div id="stepArea"></div> 
    <input id="btnSubmit" type="submit" value="submit" /> 
} 

完美地工作。

+0

不幸的是,這個解決方案存在一個主要問題 - 請看看我的答案。 – chris

9

嘗試初始化FormContext,如果它在視圖中爲null。這應該添加不引人注目的驗證「data-val- *」屬性以生成控件

@{ 
    if (Html.ViewContext.FormContext == null) 
    { 
     Html.ViewContext.FormContext = new FormContext(); 
    } 
} 
+2

謝謝我會放棄它。 – Nickz

+3

歡呼它添加了不顯眼的數據val- *。現在我需要找到一種方法來通過ajax.beginform提交操作來生成驗證觸發器。奇怪的是驗證不會觸發。 – Nickz

0

Nickz解決方案存在一個很大的問題,那就是讓我把我的頭髮拉出來,直到找到不同的解決方法。

// forces creation of a new validator, which in turn causes 
    // an extra submit event handler to be attached!!! 
    $("form").removeData("validator"); 
    $("form").removeData("unobtrusiveValidation"); 
    $.validator.unobtrusive.parse("form"); 

當你這樣做,每次調用$.validator.unobtrusive.parse()時間,新的事件處理程序將被附加到表單的提交事件,而留下的舊事件處理程序不變。這意味着當您多次運行上述代碼時,驗證程序將在提交事件觸發時不必要地多次運行。這對我造成了嚴重的性能問題。所以,我最後寫一個自定義的替代parse()方法,我命名爲updateParse

$.extend($.validator.unobtrusive, { 
    updateParse: function (selector) { 
     /// <summary> 
     /// Custom alternative for the built in method $.validator.unobtrusive.parse() which can updates an existing validator. 
     /// Use this only when a validator has not yet been initialized, i.e. when $.validator.unobtrusive.parse() 
     /// has not yet been called before. 
     /// This is intended for use after you dynamically add/remove/modify validatable elements to a form via AJAX. 
     /// Parses all the HTML elements in the specified selector. It looks for input elements decorated 
     /// with the [data-val=true] attribute value and enables validation according to the data-val-* 
     /// attribute values. 
     /// </summary> 
     /// <param name="selector" type="String">Any valid jQuery selector.</param> 
     var $forms = $(selector) 
      .parents("form") 
      .andSelf() 
      .add($(selector).find("form")) 
      .filter("form"); 

     $(selector).find(":input[data-val=true]").each(function() { 
      $.validator.unobtrusive.parseElement(this, true); 
     }); 

     $forms.each(function() { 
      var form = $(this); 
      var info = form.data("unobtrusiveValidation"); 
      if (info) { 
       var validator = form.data("validator"); 
       if (validator) { 
        validator.settings.rules = info.options.rules; 
       } 
       else { 
        throw "validator not yet initialized for this form yet -- use $.validator.unobtrusive.parse() instead"; 
       } 
      } 
     }); 
    } 

這將更新現有的驗證對象的驗證規則,而不是強迫一個新的驗證程序的創建,同時增加一個額外的提交事件處理器。 在我的選擇中,當驗證程序已經存在時,parse()方法應該工作。