Вот моя проблема, у меня есть Book
, который содержит List<Page>
, который содержит List<Line>
, и я пытаюсь создать представление, которое будет редактировать мою книгу.Этот вид содержит все строки из книги.Я сделал MVVM для List<Page>
, который вызывает меньший MVVM для List<Line>
.Проблема в том, что MVVM не считает все Line
как одну отдельную форму, поэтому это происходит:
<form>
<h1>Page one</h1>
<input type="hidden" name="[0].lineContent" value=""/>
<input type="hidden" name="[1].lineContent" value=""/>
<h1>Page one</h1>
<input type="hidden" name="[0].lineContent" value=""/>
<input type="hidden" name="[1].lineContent" value=""/>
<input type="hidden" name="[2].lineContent" value=""/>
</form>
Каждый раз, когда цикл for для страницы повторяется, циклы my for в строках сбрасываются в 0, этосоздает повторяющиеся записи имени.
Существует несколько способов исправить это, самый простой:
- Создание ввода вручную с уникальным идентификатором имени вместо использования помощников HTML
У меня следующий вопрос: как мне получить чистую бритву, которую можно использовать повторно и которая не будет дублировать записи имен в моей форме?
ОБНОВЛЕНИЕ:
Контекст:
Так же, как в книге приведены примеры, мои модели имеют одинаковую структуру.
в моем случае у меня есть представление, которое содержит список разделов, который содержит список подразделов, которыесодержит список SubmissionLine.
Вот мой основной вид:
@model
QuotingPlus.Models.Submission
@{
ViewData["Title"] = "Edit";
}
<form id="submission-form" asp-action="Edit">
<div>
<p class="d-inline-block">
<a class="btn btn-primary" data-toggle="collapse"
href="#multiCollapseExample1" role="button" aria-expanded="false" aria-controls="multiCollapseExample1">Edit submission details</a>
</p>
<nav aria-label="breadcrumb" class="d-inline-block">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/Clients/Details/@(Model.IdProjectNavigation.IdClientNavigation.IdClient)">@Model.IdProjectNavigation.IdClientNavigation.FirstName
@Model.IdProjectNavigation.IdClientNavigation.LastName</a>
</li>
<li class="breadcrumb-item">
<a href="/Projects/Details/@(Model.IdProjectNavigation.IdProject)">@Model.IdProjectNavigation.Name</a>
</li>
<li class="breadcrumb-item active" aria-current="page">@Model.Number</li>
</ol>
</nav>
</div>
<div class="row">
<div class="col mb-3">
<div class="collapse multi-collapse" id="multiCollapseExample1">
<div class="card card-body">
<h1>Submission details</h1>
<hr/>
<div class="row">
<div class="col-md-4">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="IdSubmission"/>
<div class="form-group">
<label asp-for="IdTypeSubmission" class="control-label"></label>
<select asp-for="IdTypeSubmission" class="form-control" asp-items="ViewBag.IdTypeSubmission"></select>
<span asp-validation-for="IdTypeSubmission" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="IdProject" class="control-label"></label>
<select asp-for="IdProject" class="form-control" asp-items="ViewBag.IdProject"></select>
<span asp-validation-for="IdProject" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Number" class="control-label"></label>
<input asp-for="Number" class="form-control"/>
<span asp-validation-for="Number" class="text-danger"></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="save-warning" style="display: none;" class="alert alert-info alert-dismissible fade show" role="alert">
<strong>WARNING!</strong> Make sure you save before leaving.
<button type="button" class="close" data-dismiss="alert" aria-label="Close" onclick="SetWarningDisplayPreferenceCookie();">
<span aria-hidden="true">×</span>
</button>
</div>
<div id="carouselIndicators" style="height: 100% !important;" class="carousel slide pb-5 mb-5" data-interval="false">
<div class="carousel-inner">
@{
Html.RenderPartial("SubmissionSectionEditor", Model.SubmissionSection.ToList());
}
</div>
<nav class="navbar navbar-light bg-secondary mb-0 pt-2 fixed-bottom">
<div>
<button type="submit" value="Save" class="btn btn-default text-white">
<i class="material-icons" style="font-size: 2em;">
save
</i>
</button>
</div>
<a class="col text-center mh-100 pt-2 pb-2" href="#carouselIndicators" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="false"></span>
</a>
<a class="col text-center mh-100 pt-2" href="#carouselIndicators" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="false"></span>
</a>
<div>
<a asp-action="Index" class="btn text-white">
<i class="material-icons" style="font-size: 2em;">
cancel
</i>
</a>
</div>
</nav>
</div>
</form>
Вот SubmissionSectionEditor.cshtml
@model List<SubmissionSection>
@{
var isFirstCarouselItem = true;
}
@for (var indexSection = 0; indexSection < Model.Count(); indexSection++)
{
<div class="carousel-item @((isFirstCarouselItem) ? "active" : "")">
@{
isFirstCarouselItem = false;
}
<h1>@Model[indexSection].IdSectionNavigation.Name</h1>
<div id="@(Model[indexSection].IdSection + "accordion")">
@{
var submissionSubSections = M odel[indexSection].SubmissionSubSection;
}
@if (submissionSubSections != null)
{
Html.RenderPartial("SubmissionSubSectionEditor", submissionSubSections.ToList());
}
</div>
</div>
}
Вот SubmissionSubSectionEditor.cshtml
@model List<SubmissionSubSection>
@for (var indexSubSection = 0; indexSubSection < Model.Count; indexSubSection++)
{
<div class="card">
<div class="card-header" id="@(Model[indexSubSection].IdSubSection + "SubSectionHeader")">
<h2 class="mb-0">
<button type="button" class="btn btn-link collapsed" data-toggle="collapse" data-target="@("#" + Model[indexSubSection].IdSubSection + "SubSectionCollapse")" aria-
expanded="true" aria-controls="@(Model[indexSubSection].IdSubSection + "SubSectionCollapse")">
@Model[indexSubSection].IdSubSectionNavigation.Name
</button>
</h2>
</div>
<div id="@(Model[indexSubSection].IdSubSection + "SubSectionCollapse")" class="collapse" aria-labelledby="@(Model[indexSubSection].IdSubSection +
"SubSectionHeader")" data-parent="@("#" + Model[indexSubSection].IdSubmissionSectionNavigation.IdSection + "accordion")">
<div class="card-body">
<table class="table w-100">
<thead class="thead-dark">
<tr>
<th>Quantity</th>
<th>Article</th>
<th>Total Material</th>
<th>Unit Price Material</th>
<th>Total Sub Contractor</th>
<th>Unit Price Sub Contractor</th>
<th>Total Workforce</th>
<th>Unit Price Workforce</th>
<th>Display</th>
</tr>
</thead>
<tbody>
@{
Html.RenderPartial("SubmissionLineEditor", Model[indexSubSection].SubmissionLine.ToList());
}
</tbody>
</table>
</div>
</div>
</div>
}
Вот SubmissionLineEditor.cshtml
@model List<SubmissionLine>
@for (var indexLine = 0; indexLine < Model.Count; indexLine++)
{
<tr>
@Html.HiddenFor(x => Model[indexLine].IdSubmissionLine)
@Html.HiddenFor(x => Model[indexLine].IdArticle)
@Html.HiddenFor(x => Model[indexLine].IdSubmissionSubSection)
<td>@Html.TextBoxFor(x => Model[indexLine].Quantity, new {@type = "number", @step = "0.5", @min="0"})</td>
<td>@Model[indexLine].IdArticleNavigation.Designation</td>
<td>@Model[indexLine].TotalMaterial</td>
<td>@Model[indexLine].IdArticleNavigation.UnitPriceMaterial</td>
<td>@Model[indexLine].TotalSubContractor</td>
<td>@Model[indexLine].IdArticleNavigation.UnitPriceSubContractor</td>
<td>@Model[indexLine].TotalWorkforce</td>
<td>@Model[indexLine].IdArticleNavigation.UnitPriceWorkforce</td>
<td>@Html.CheckBoxFor(x => Model[indexLine].IsDisplayed, new {@class = "checkbox"}).
</td>
</tr>
}
Я только хочу знать , как я могу сохранить эту структуру с помощью MVVM и избежать проблемы с дублированием входного имени ?
ОБНОВЛЕНИЕ:
Я не совсем уверен, почему это было бы полезно, так как я получаю ввод дубликатов имен, но вот мое действие сохранения:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin, SuperAdmin, Employe")]
public ActionResult Edit(int id, Submission submission, [FromForm] List<SubmissionLine> lines)
{
var test = Request.Form;
if (id != submission.IdSubmission)
{
return NotFound();
}
if (ModelState.IsValid)
{
SubmissionUpdateHelper.SaveSubmissionModifications(_context, submission, lines);
return RedirectToAction(nameof(Index));
}
ViewData["IdProject"] = new SelectList(_context.Project, "IdProject", "Name", submission.IdProject);
ViewData["IdTypeSubmission"] = new SelectList(_context.TypeSubmission, "IdTypeSubmission",
"TypeSubmission1", submission.IdTypeSubmission);
return View(submission);
}