У меня есть представление, Contact
, которое загружает n
количество Caller
частичных представлений, m
количество Child
частичных представлений и одно CallNote
частичное представление - все загружается через Ajax после того, как документготов.
Я также могу добавлять и удалять Callers
и Children
, поэтому эти числа не являются статичными.
Contact.cshtml
, с некоторыми удаленными компонентами:
@using Birth_To_Five.ViewModels
@model CallDetailViewModel
<div class="container">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-1" role="tab" data-toggle="tab">Call Detail</a></li>
@* Other tabs not shown here *@
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="tab-1">
@using (Html.BeginForm("SubmitCallDetailsAsync", "Home", FormMethod.Post))
{
<div class="well">
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.Id)
@Html.HiddenFor(m => m.CallThreadViewModel.Id)
<span style="color: red">
@Html.ValidationSummary()
</span>
@* Call Details *@
<div class="row">
<fieldset>
<legend>Call Details</legend>
</fieldset>
</div>
<div class="row">
<div class="form-group">
@Html.LabelFor(m => m.EnteredByEmail, new { @class = "control-label" })
@Html.ValidationMessageFor(m => m.EnteredByEmail, "", new { @class = "text-danger" })
@Html.TextBoxFor(m => m.EnteredByEmail, new { @class = "form-control", placeholder = "Who took the call" })
</div>
@* Other stuff *@
</div>
@* Caller Details *@
<div class="row">
<fieldset>
<legend>Callers</legend>
</fieldset>
</div>
@* Render each existing caller. Each caller gets their own well to create a visual separation between them. *@
@foreach (var callerViewModel in Model.CallerViewModels)
{
<div class="progress" id="callerLoadingBar-@callerViewModel.Id" data-callerid="@callerViewModel.Id" data-calldetailid="@Model.Id">
<div class="progress-bar progress-bar-striped active" role="progressbar" style="width: 100%">Loading Caller...</div>
</div>
}
<div id="newCaller"></div>
<div class="row">
@* Button to search for and add a caller *@
</div>
@* Children Details *@
<div class="row">
<fieldset>
<legend>Children</legend>
</fieldset>
</div>
@* Render each existing child. Each child gets their own well to create a visual separation between them. *@
@foreach (var childViewModel in Model.ChildViewModels)
{
<div class="progress" id="childLoadingBar-@childViewModel.Id" data-childid="@childViewModel.Id" data-calldetailid="@Model.Id">
<div class="progress-bar progress-bar-striped active" role="progressbar" style="width: 100%">Loading Child...</div>
</div>
}
<div id="newChild"></div>
<div class="row">
@* Button to search for and add a child *@
</div>
<div class="progress" id="callNoteLoadingBar">
<div class="progress-bar progress-bar-striped active" role="progressbar" style="width: 100%">Loading Call Note...</div>
</div>
</div>
<div class="row">
<div class="form-group">
<button class="btn btn-danger" type="reset">Reset</button>
</div>
<div class="form-group">
<button class="btn btn-primary" type="submit">Submit</button>
</div>
</div>
}
</div>
</div>
</div>
@section scripts
{
@Scripts.Render("~/bundles/jqueryval")
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
@Scripts.Render("~/bundles/calldetailscripts")
}
Фрагмент из моего скрипта JS, callDetailFunctions
:
$(document).ready(function () {
getCallNote('#callNoteLoadingBar', $('#Id').val());
getAllCallers();
getAllChildren();
});
// function getAllWhatever(){ Foreach loading bar, addCaller/Child/CallNotePartialView(..., ..., ..., etc.); }
function addWhateverPartialView(divToReplace, thingIWantId, callDetailId) {
$.ajax({
url: '/Home/GetWhateverPartialViewAsync',
data: {
thingIWantId,
callDetailId
},
type: "GET",
error: function (xmlHttpRequest, textStatus, errorThrown) {
alert("Request: " + xmlHttpRequest.toString() + "\n\nStatus: " + textStatus + "\n\nError: " + errorThrown);
},
success: function (data) {
$(divToReplace).replaceWith(data);
}
});
}
Здесь, в моем HomeController
, у меня есть метод SubmitCallDetailsAsync
:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SubmitCallDetailsAsync(CallDetailViewModel callDetailViewModel)
{
using (var unitOfWork = new UnitOfWork(ApplicationDbContext))
{
// Call Details
var callDetailServices = new CallDetailServices();
await callDetailServices.AddOrUpdateCallDetailFromCallDetailViewModelAsync(callDetailViewModel, ModelState, unitOfWork);
// Callers
var callerServices = new CallerServices();
await callerServices.AddOrUpdateCallersFromCallDetailsViewModelAsync(callDetailViewModel, ModelState, unitOfWork);
// Children
var childServices = new ChildServices();
await childServices.AddOrUpdateChildrenFromCallDetailsViewModelAsync(callDetailViewModel, ModelState, unitOfWork);
// Call Note
var callNoteServices = new CallNoteServices();
await callNoteServices.AddOrUpdateCallNoteFromCallDetailsViewModelAsync(callDetailViewModel, ModelState, unitOfWork);
// Check the model state (returns true if it's good, false otherwise.
// Also spits out some debug text for me to tell me what broke the Model)
if (!UtilityServices.CheckModelState(ModelState))
{
callDetailViewModel.DirectionChoices =
await unitOfWork.DirectionChoiceRepo.GetAllAsSelectListItemsAsNoTrackingAsync();
return View("Contact", callDetailViewModel);
}
await unitOfWork.CompleteAsync();
}
return RedirectToAction("Index");
}
Суть того, что происходит, заключается в том, что у меня есть полоса загрузки в качестве заполнителя для каждого Caller
, Child
и Call Note
, а затем, когда документ загружается, я иду и получаю их на $(document).ready()
Моя проблема в том, что, когда я отправляю Contact.cshtml
и нажимаю на ошибку проверки модели, меня отправляют обратно на мою страницу Contact
, которая перезагружает все Callers
, Children
и Call Note
, таким образом теряя все изменения.
Что я должен / могу сделать, чтобы справиться с этим сценарием?