2013-04-27 35 views
1

我在分部視圖內部有一個表單,它可以工作,但是如果引發服務器端驗證錯誤,它只顯示部分視圖。所以我決定使用ajax進行提交(實際上它是有道理的,因爲它插入了一個聯繫人,並且在主視圖中有一個列表)。在部分視圖驗證中的Ajax表單

事情是,如果發佈的代碼中有一個出現錯誤,它會正確顯示在視圖中(我需要再次使部分可見,但那是另一回事),但如果沒有錯誤,它會顯示該列表僅在部分視圖中顯示。我可以反過來,在沒有錯誤但沒有達到正確顯示驗證錯誤時正確顯示。

我想知道什麼是最好的方法,或者至少它們是可能性:可能更改代碼的控制器或做一些在成功回調檢查...

我編輯了我之前,因爲當沒有錯誤我應該返回列表,而不是我之前發佈的整個視圖,但無論如何,我仍然有疑問如何告訴另一個人,因爲這兩個都是成功的後動作

謝謝

查看是這一個

@model ContactListViewModel 

@{ 
    ViewBag.Title = " My Contacts" 
} 

<div id="ContactList"> 
    <h2>My Contacts</h2> 
    <hr /> 
    <div id="addContainer"> 
     @{ Html.RenderAction("AddContact"); } 
    </div> 
    <div id="editContainer" data-amp-url="@Url.Action("Edit", "Contacts")" class="initiallyHidden"></div> 
    @foreach (var group in Model.Contacts) 
    { 
     <div class="PlanContacts"> 
      <div class="PlanName">@group.Key</div> 
      @foreach (var contact in group.Values) 
      { 
       <div class="Preview"> 
        @Html.DisplayFor(m => contact, "Contact") 
       </div> 
      } 
     </div> 
    } 
</div> 

@section PageJavascript 
{ 
    <script src="~/Scripts/AMPContacts.js"></script> 
} 

控制器後行動

[HttpPost] 
public ActionResult AddContact(AddContactViewModel viewModel) 
{ 
    var partyId = (int) Session["PartyId"]; 
    if (ModelState.IsValid) 
    { 
     _contactsManager.AddContact(viewModel, partyId); 
     // Here I should return the updated list 
    } 
    var newViewModel = _createBuilder.Rebuild(viewModel, partyId); 
    return PartialView("_AddContact", newViewModel); 
} 

的時間越AMPContact.js裏面的AJAX提交代碼

$('#addForm').submit(function (e) { 
    e.preventDefault(); 
    var addContainer = $(document.getElementById('addContainer')); 
    $.ajax({ 
     url: this.action, 
     type: this.method, 
     data: $(this).serialize(), 
     success: function(result) { 
      addContainer.html(result); 
     } 
    }); 
}); 
+0

我有這個http://erraticdev.blogspot.co.uk/2010/11/handling-validation-errors-on-ajax.html看起來很有趣,我會嘗試這種方法 – mitomed 2013-04-27 19:46:41

回答

0

我知道這個答案是遠遠好,但也許這是有用的人在縮小可能的搜索範圍。因爲它最終會變得非常龐大,我寧願將這個更新發布爲我自己問題的答案,也不確定它是否符合良好的禮貌。

解釋的不是我唯一面臨的問題,困難的時候以及重置表格,特別是連續的錯誤提交(一旦我有一個錯誤,試圖再次提交錯誤),所以我結束了爲不同的問題解決不同的解決方案。希望我能夠把它清理乾淨

感謝

在我現在

<div id="myContacts"> 
<h2>My Contacts</h2> 
<hr /> 

<div id="addContainer"> 
    <div class="toggler"> 
     Add Contact 
    </div> 
    <div id="addToggling" class="initiallyHidden"> 
     @{ Html.RenderAction("AddContact"); } 
    </div> 
</div> 

<div id="editContainer" data-amp-url="@Url.Action("Edit", "Contacts")" class="initiallyHidden"></div> 

<div id="list"> 
    @{ Html.RenderPartial("_ContactList", Model); } 
</div> 

使用在.js文件

$('#addContainer').on('submit', '#addForm', ajaxCall); 

function ajaxCall(e) { 
    e.preventDefault(); 
    var addToggling = $(document.getElementById('addToggling')); 
    var contactList = $(document.getElementById('contactList')); 

    $.ajax({ 
     url: this.action, 
     type: this.method, 
     data: $(this).serialize(), 
     success: function (result) { 
      if (result.passedValidation == true) { 
       // Json is returned with flag, we get the list from the server and update the list element 
       $.get(result.action, function (partial) { 
        contactList.html(partial); 
       }); 

       // Add some effects and clear the form 
       $(document).scrollTop(0); 
       setTimeout(function() { 
        addToggling.slideUp(300, resetAddForm); 
       }, 500); 
       setTimeout(function() { 
        contactList.effect("highlight", {}, 3000); 
       }, 1000); 
      } 
      else { 
       // The form partial view is returned and displayed in the same element when there are validation errors 
       $(document).scrollTop(0); 
       addToggling.html(result); 
       $.validator.unobtrusive.parse('#addForm'); 
      } 
     } 
    }); 
} 

function resetAddForm() { 
    var addForm = $(document.getElementById('addForm')); 

    // Hhide the error messages 
    addForm.find("span.field-validation-error").hide(); 
    addForm.find("div.validation-summary-errors").hide(); 

    // Removes the class associated to errors 
    addForm[0].reset(); 

    // Clear the inputs 
    addForm.find('input:text, input:password, input:file, select, textarea').val(''); 
    addForm.find('input:radio, input:checkbox').removeAttr('checked').removeAttr('selected'); 
} 

控制器與現有的觀點行動方法略有改變,新的一個

public ActionResult ContactList() 
{ 
    var partyId = (int)Session["PartyId"]; 
    var viewModel = _displayBuilder.Build(partyId); 
    return PartialView("_ContactList", viewModel); 
} 

[HttpGet] 
public ActionResult AddContact() 
{ 
    var partyId = (int) Session["PartyId"]; 
    var viewModel = _createBuilder.Build(partyId); 
    return PartialView("_AddContact", viewModel); 
} 
[HttpPost] 
public ActionResult AddContact(AddContactViewModel viewModel) 
{ 
    var partyId = (int) Session["PartyId"]; 

    if (ModelState.IsValid) 
    { 
     _contactsManager.AddContact(viewModel, partyId); 

     if (Request.IsAjaxRequest()) 
      return Json(new { passedValidation = true, action = Url.Action("ContactList")}); 

     return RedirectToAction("Index"); 
    } 

    var newViewModel = _createBuilder.Rebuild(viewModel, partyId); 
    return PartialView("_AddContact", newViewModel); 
}