MVC视图有两个模型和一个parital视图

时间:2016-02-04 04:01:38

标签: c# jquery asp.net-mvc asp.net-mvc-partialview

MVC创建视图有两个部分用于Invoice和InvoiceItem表。

  1. 发票明细部分包含用于创建的默认脚手架代码。

  2. 发票项目部分有一个按钮"添加项目"和部分观点。当用户点击"添加项目"时,将显示jQuery UI pop以创建Invoice项目,并调用/ Invoice / GetInvoiceItems操作。此方法将新发票项附加现有项(如果有),并返回在Div(viewAPInvoiceIndex)中加载的局部视图。此部分视图具有列表的默认脚手架代码。

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

    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);
         }
        });
    });
    

    另外请告知这是否是实现上述场景的正确方法(创建Invoice和InvoiceItems)。

    感谢您的时间。

1 个答案:

答案 0 :(得分:0)

由于视图在后期加载到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的建议,我们可以将事件附加到已加载element加载的最近的DOM,而不是将其附加到document,这将更多高效。

  

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

更改为@Rule public ActivityTestRule<HomePageActivity> homePageActivityTestRule = new ActivityTestRule<>(HomePageActivity.class);