具有两个模型和一个平行视图的 MVC 视图

本文关键字:视图 MVC 一个 模型 两个 | 更新日期: 2023-09-27 18:33:05

MVC 创建视图有两个部分用于发票和发票项表。

  1. 发票详细信息部分使用用于创建的默认基架代码。

  2. 发票项目部分
  3. 有一个按钮"添加项目"和一个部分视图。当用户单击"添加项目"时,将显示一个 jQuery UI 弹出窗口以创建发票项,并调用/Invoice/GetInvoiceItems 操作。此方法将新发票项与现有项(如果有(追加,并返回在 Div(视图APInvoiceIndex( 中加载的部分视图。此分部视图具有列表的默认基架代码。

在用户创建完整的发票之前,创建的发票项目不会存储到数据库中。此外,用户还可以编辑/删除发票项目。

Create.chtml:

<div class="panel-body">
   <div id="viewAPInvoiceIndex">
     @{ Html.RenderPartial("_APInvoiceIndex", (IEnumerable<TransportationModule.Models.APInvoiceItem>)@ViewBag.CurrInvItems); }
   </div>
</div>

添加发票项目代码(用于弹出窗口中的按钮(:

$("#btnAddItem").click(function () {
   var currId = $('[id$=tableInvItems] tr').length;
   if (currId < 1)
      currId = 1;
   var _item = { Id: currId, InvoiceNo: $('#txtInvNo').val(), OrderQty: $('#txtOrderQty').val(), UnitPrice: $('#txtUnitPrice').val()
   };
   $("[id$=viewAPInvoiceIndex]").load("/Invoice/GetInvoiceItems", { InvItem: _item });
   $('#mdGrnList').dialog("close");
});

操作方法:

public ActionResult Create()
{
    IList<APInvoiceItem> existingItems = new List<APInvoiceItem>();
    if (Session != null && Session["ExistingItems"] != null)
       existingItems = (IList<APInvoiceItem>)Session["ExistingItems"];
    ViewBag.CurrInvItems = existingItems;
    return View();
}
// UPDATES THE MODEL WITH NEW ITEM AND RETURNS THE PARTIAL VIEW
public ActionResult GetInvoiceItems(APInvoiceItem InvItem)
{
   IList<APInvoiceItem> existingItems = new List<APInvoiceItem>();
   if (Session != null && Session["ExistingItems"] != null)
      existingItems = (IList<APInvoiceItem>)Session["ExistingItems"];
   existingItems.Add(InvItem);
   Session["ExistingItems"] = existingItems;
   return PartialView("_APInvoiceIndex", existingItems);
}
// REMOVES AN INVOICE ITEM 
public ActionResult DeleteInvItem(int id)
{
   IList<APInvoiceItem> existingItems = new List<APInvoiceItem>();
   if (Session != null && Session["ExistingItems"] != null)
     existingItems = (IList<APInvoiceItem>)Session["ExistingItems"];
   var itemToRemove = existingItems.SingleOrDefault(r => r.Id == id);
   if (itemToRemove != null)
      existingItems.Remove(itemToRemove);
   Session["ExistingItems"] = existingItems;
   return PartialView("_APInvoiceIndex", existingItems);
}

我能够创建发票项目,并且部分视图已正确加载。但是,如果我添加一个新项目并按编辑/删除,则没有任何反应。似乎在刷新页面之前不会绑定相应的jQuery方法。刷新页面后,我可以删除项目。

_APInvoiceIndex.chtml

<td>
   <button class="btn btn-danger btn-sm" id="btnDeleteItem" data-id="@item.Id" type="button"></button>
</td>
$('[id$=btnDeleteItem]').click(function () {
   var invId = $(this).attr("data-id");
   $.ajax({
     url: '/Invoice/DeleteInvItem',
     data: { id: invId },
     success: function (data) {
        $("[id$=viewAPInvoiceIndex]").html(data);
     },
     error: function (request, textStatus, errorThrown) {
        alert(textStatus + " " + errorThrown);
     }
    });
});

还请告知这是否是实现上述方案的正确方法(创建发票和发票项目(。

谢谢你的时间。

具有两个模型和一个平行视图的 MVC 视图

由于视图在后面的部分加载到DOM[即加载的DOM内容]事件将不会附加到element,除非您提供event delegation选项。因此,您可以提供如下event delegation

$('#viewAPInvoiceIndex').on('click','[id$=btnDeleteItem]',function(){
   var invId = $(this).attr("data-id");
   $.ajax({
     url: '/Invoice/DeleteInvItem',
     data: { id: invId },
     success: function (data) {
        $("[id$=viewAPInvoiceIndex]").html(data);
     },
     error: function (request, textStatus, errorThrown) {
        alert(textStatus + " " + errorThrown);
     }
    });
});

根据@StephenMuecke的建议,我们可以将事件附加到最近DOM加载的element,而不是将其附加到document,这将更有效。

注意:我还看到您可能正在使用id=btnDeleteItem创建重复的id,这不是一个有效的html。因此,最好将其更改为class然后您可以按$('#viewAPInvoiceIndex').on('click','.btnDeleteItem'///