将 jQuery 数据从 View 传递到 Controller 并将其保存为多对多
Pass jQuery data from View to Controller and save it as many-to-many
我有一个多对多的关系。我从 asp.net 3.0 和 ef core 3.1
中的脚手架为以下 2 个实体(产品和发票)生成了控制器和视图
我可以从两个实体进行 CRUD。
在发票视图页面中,我需要有一个从产品 table 提供的下拉列表,并将 ItemName 添加到下拉列表中。
我已经通过 ViewData["Products"] 做到了,它工作正常。
当用户从那个下拉列表中选择时,旁边有一个 'Add item' 按钮,
如果用户单击“添加项目”按钮,则必须在页面下方添加项目名称。我已经通过 jquery 及其作品
做到了
页面底部有一个保存按钮,点击后,它只会通过绑定将发票模型传递给控制器(这是正确的行为),
但我不确定如何将所有添加的项目(仅它们的 ID)传递给控制器以保存在 join-table (ProductInvoice).
不确定,也许我没有正确设计应用程序的体系结构,这就是为什么我写了整个 scenario/use-case 也许你可以建议我重新设计。
简而言之,用例是:用户必须将 itemName(从产品 table 中获取)添加到发票并将其保存为多对多关系。
**如何保存我在发票页面上添加的所有 ItemId,将它们保存到 ProductInvoice table 作为多对多,
如何将它们从视图传递给控制器?**
我搜索了一整天,我找不到怎么做,这就是我 post.
的原因
public class Product
{
public int ProductId { get; set; }
public int Price { get; set; }
public string ItemName { get; set; }
public IList<ProductInvoice> ProductInvoices { get; set; }
}
public class Invoice
{
public int InvoiceId { get; set; }
public DateTime InvoiceDate { get; set; }
public IList<ProductInvoice> ProductInvoices { get; set; }
}
public class ProductInvoice
{
[Key]
public int ProductId { get; set; }
public Product Product { get; set; }
[Key]
public int InvoiceId { get; set; }
public Invoice Invoice { get; set; }
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("InvoiceId,InvoiceDate")] Invoice invoice)
{
if (ModelState.IsValid)
{
_context.Add(invoice);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(invoice);
}
<script>
$(document).ready(function () {
var totalInvoice = 0;
$("#btn-add-item").click(function () {
var selectedItem = $('#SelectedProducts :selected').text();
var getCostPerItem = $('#SelectedProducts :selected').val();
getCostPerItem = getCostPerItem.split("-")[1];
getCostPerItem = getCostPerItem.split(".")[0];
totalInvoice = parseInt(totalInvoice) + parseInt(getCostPerItem);
$('<div id="created_div">' + '<b>+</b> ' + selectedItem + ' : $ ' + ' ' + getCostPerItem + '<a href="#" class="btn btn-danger btn-sm btn-remove-item float-right">Remove</a></div><br>').insertAfter('#main-body-card');
$("#total-invoice-input").val(totalInvoice);
});
});
</script>
这是您可以遵循的完整工作演示:
型号:
public class Product
{
public int ProductId { get; set; }
public int Price { get; set; }
public string ItemName { get; set; }
public IList<ProductInvoice> ProductInvoices { get; set; }
}
public class Invoice
{
public int InvoiceId { get; set; }
public DateTime InvoiceDate { get; set; }
public IList<ProductInvoice> ProductInvoices { get; set; }
}
public class ProductInvoice
{
[Key]
public int ProductId { get; set; }
public Product Product { get; set; }
[Key]
public int InvoiceId { get; set; }
public Invoice Invoice { get; set; }
}
查看:
首先,在我的项目中,产品下拉列表值为 ProductId
,文本为 ItemName
。
然后,要传递相关的 ProductId
并添加到 Invoice
模型,您需要添加隐藏(或不隐藏)输入,名称如下:ProductInvoices[index].ProductId
.
最后,绑定属性([Bind("InvoiceId,CreatedDate,CreateByUser,TotalInvoice")]
)中的参数必须匹配模型Invoice
。
@model Invoice
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div id="main-body-card"></div>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="InvoiceDate" class="control-label"></label>
<input asp-for="InvoiceDate" class="form-control" />
<span asp-validation-for="InvoiceDate" class="text-danger"></span>
</div>
<div class="form-group">
<select id="SelectedProducts" asp-items="(SelectList)@ViewData["Products"]"></select>
<button type="button" id="btn-add-item">Add</button>
</div>
<label>total: </label><input id="total-invoice-input" />
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
@section Scripts
{
<script>
$(document).ready(function () {
var totalInvoice = 0;
var i = 0; //add this...
$("#btn-add-item").click(function () {
var selectedItem = $('#SelectedProducts :selected').text();
var getCostPerItem = $('#SelectedProducts :selected').val();
totalInvoice = parseInt(totalInvoice) + parseInt(getCostPerItem);
$('<div id="created_div">' + '<b>+</b> ' + selectedItem + ' : $ ' + ' ' + getCostPerItem + '<a href="#" class="btn btn-danger btn-sm btn-remove-item float-right">Remove</a></div><br>').insertAfter('#main-body-card');
//add this....
$("<input value='"+getCostPerItem+"' name='ProductInvoices[" + i + "].ProductId' hidden/>").insertAfter('#created_div');
$("#total-invoice-input").val(totalInvoice);
i++; //add this...
});
});
</script>
}
控制器:
public IActionResult Create()
{
ViewData["Products"] = new SelectList(_context.Product.ToList(), "ProductId", "ItemName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("InvoiceId,InvoiceDate,ProductInvoices")] Invoice invoice)
{
if (ModelState.IsValid)
{
_context.Add(invoice);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(invoice);
}
结果:
我有一个多对多的关系。我从 asp.net 3.0 和 ef core 3.1
中的脚手架为以下 2 个实体(产品和发票)生成了控制器和视图我可以从两个实体进行 CRUD。
在发票视图页面中,我需要有一个从产品 table 提供的下拉列表,并将 ItemName 添加到下拉列表中。 我已经通过 ViewData["Products"] 做到了,它工作正常。
当用户从那个下拉列表中选择时,旁边有一个 'Add item' 按钮, 如果用户单击“添加项目”按钮,则必须在页面下方添加项目名称。我已经通过 jquery 及其作品
做到了页面底部有一个保存按钮,点击后,它只会通过绑定将发票模型传递给控制器(这是正确的行为), 但我不确定如何将所有添加的项目(仅它们的 ID)传递给控制器以保存在 join-table (ProductInvoice).
不确定,也许我没有正确设计应用程序的体系结构,这就是为什么我写了整个 scenario/use-case 也许你可以建议我重新设计。
简而言之,用例是:用户必须将 itemName(从产品 table 中获取)添加到发票并将其保存为多对多关系。
**如何保存我在发票页面上添加的所有 ItemId,将它们保存到 ProductInvoice table 作为多对多,
如何将它们从视图传递给控制器?**
我搜索了一整天,我找不到怎么做,这就是我 post.
的原因public class Product
{
public int ProductId { get; set; }
public int Price { get; set; }
public string ItemName { get; set; }
public IList<ProductInvoice> ProductInvoices { get; set; }
}
public class Invoice
{
public int InvoiceId { get; set; }
public DateTime InvoiceDate { get; set; }
public IList<ProductInvoice> ProductInvoices { get; set; }
}
public class ProductInvoice
{
[Key]
public int ProductId { get; set; }
public Product Product { get; set; }
[Key]
public int InvoiceId { get; set; }
public Invoice Invoice { get; set; }
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("InvoiceId,InvoiceDate")] Invoice invoice)
{
if (ModelState.IsValid)
{
_context.Add(invoice);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(invoice);
}
<script>
$(document).ready(function () {
var totalInvoice = 0;
$("#btn-add-item").click(function () {
var selectedItem = $('#SelectedProducts :selected').text();
var getCostPerItem = $('#SelectedProducts :selected').val();
getCostPerItem = getCostPerItem.split("-")[1];
getCostPerItem = getCostPerItem.split(".")[0];
totalInvoice = parseInt(totalInvoice) + parseInt(getCostPerItem);
$('<div id="created_div">' + '<b>+</b> ' + selectedItem + ' : $ ' + ' ' + getCostPerItem + '<a href="#" class="btn btn-danger btn-sm btn-remove-item float-right">Remove</a></div><br>').insertAfter('#main-body-card');
$("#total-invoice-input").val(totalInvoice);
});
});
</script>
这是您可以遵循的完整工作演示:
型号:
public class Product
{
public int ProductId { get; set; }
public int Price { get; set; }
public string ItemName { get; set; }
public IList<ProductInvoice> ProductInvoices { get; set; }
}
public class Invoice
{
public int InvoiceId { get; set; }
public DateTime InvoiceDate { get; set; }
public IList<ProductInvoice> ProductInvoices { get; set; }
}
public class ProductInvoice
{
[Key]
public int ProductId { get; set; }
public Product Product { get; set; }
[Key]
public int InvoiceId { get; set; }
public Invoice Invoice { get; set; }
}
查看:
首先,在我的项目中,产品下拉列表值为 ProductId
,文本为 ItemName
。
然后,要传递相关的 ProductId
并添加到 Invoice
模型,您需要添加隐藏(或不隐藏)输入,名称如下:ProductInvoices[index].ProductId
.
最后,绑定属性([Bind("InvoiceId,CreatedDate,CreateByUser,TotalInvoice")]
)中的参数必须匹配模型Invoice
。
@model Invoice
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div id="main-body-card"></div>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="InvoiceDate" class="control-label"></label>
<input asp-for="InvoiceDate" class="form-control" />
<span asp-validation-for="InvoiceDate" class="text-danger"></span>
</div>
<div class="form-group">
<select id="SelectedProducts" asp-items="(SelectList)@ViewData["Products"]"></select>
<button type="button" id="btn-add-item">Add</button>
</div>
<label>total: </label><input id="total-invoice-input" />
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
@section Scripts
{
<script>
$(document).ready(function () {
var totalInvoice = 0;
var i = 0; //add this...
$("#btn-add-item").click(function () {
var selectedItem = $('#SelectedProducts :selected').text();
var getCostPerItem = $('#SelectedProducts :selected').val();
totalInvoice = parseInt(totalInvoice) + parseInt(getCostPerItem);
$('<div id="created_div">' + '<b>+</b> ' + selectedItem + ' : $ ' + ' ' + getCostPerItem + '<a href="#" class="btn btn-danger btn-sm btn-remove-item float-right">Remove</a></div><br>').insertAfter('#main-body-card');
//add this....
$("<input value='"+getCostPerItem+"' name='ProductInvoices[" + i + "].ProductId' hidden/>").insertAfter('#created_div');
$("#total-invoice-input").val(totalInvoice);
i++; //add this...
});
});
</script>
}
控制器:
public IActionResult Create()
{
ViewData["Products"] = new SelectList(_context.Product.ToList(), "ProductId", "ItemName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("InvoiceId,InvoiceDate,ProductInvoices")] Invoice invoice)
{
if (ModelState.IsValid)
{
_context.Add(invoice);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(invoice);
}
结果: