开发者

How to return Nested PartialViews (including their javascript) from an AJAX call in ASP.Net MVC

开发者 https://www.devze.com 2022-12-10 13:29 出处:网络
I have created a treeview of Categories using nested partial views: my Index page (that displays the treeview):

I have created a treeview of Categories using nested partial views:

my Index page (that displays the treeview):

<div>
 Category Menu:
  <input type="button" value="1" name='selectCat_btn' />
  <input type="button" value="2" name='selectCat_btn' />
</div>

<!-- Treeview -->
<% Html.RenderPartial("ItemCats_UL", Model); %>

<div id="CatSelectorOutput">
</div>

ItemCats_UL:

<div>
 <ul id="catsTree"> 
  <% Html.RenderPartial("ItemCats_LI", Model); %>
 </ul>
</div>

<script type="text/javascript" >
$(document).ready(function() {        
    $("#catsTree").treeview();
</script>

ItemCats_LI:

<%foreach (ItemCategory itemCat in Model)
 { %>
  <li>
   <%= itemCat.Name %>
    <%if (itemCat.Children != null && itemCat.Children.Count() > 0)
      { %>
       <ul>
        <% Html.RenderPartial("ItemCats_LI", itemCat.Children); %>
       </ul>
    <%} %>
 </li>
<%} %>

Now this treeview works perfectly when I return the basic View("Index", Model) from my controllers Index action on page load.

The trouble comes when I want to change the Categories Model displayed in my Treeview (the nested partialViews) from an AJAX call...

For example: I click one the 'Cats2' button and the page should display Categories with ParentID of 2 in the Treeview. I attempted this by returning a JsonResult of the html of the ItemCats_UL PartialView (using a RenderPartialToString method found here) from my Controller Action. As some of you might know Javascript won't run in your partial view when you use an AJAX form to return a PartialViewResult, and I need Javascript in my Treeview which is why I'm using the RenderPartialToString.

The category select button click handler:

<script type="text/javascript">
$("[name='selectCat_btn']").click(function() {       
    var CID = $(this).attr('value');      
    $.ajax({
        type: "POST",
        url: "SelectCat",
        dataType: "json",
        data: { "CID": CID },
        success: function(result) { $("#CatSelectorOutput").html(result.output); }
    });
    return false;
});
</script>

My Controller Action:

 [AcceptVerbs(HttpVerbs.Post)]
    [UrlRoute(Name = "SelectCat", Path = "selectCat")]
    public ActionResult SelectCat(int CID)
    {
        IQueryable<ItemCategory> c开发者_如何学Pythonats;
        cats = ItemRepo.GetItemCats().WithCID(CID);

        JsonResult result = null;
        result = new JsonResult
        {
            Data = new
            {
                success = true,
                output =
                Helpers.RenderHelper
                .RenderPartialToString("~/Views/Admin/AdminItemCatsUL.ascx",
                cats)                    
            }
        };
        return result;
    }

The result:

The ItemCats_UL partialView displays! BUT the nested PartialViews (ItemCats_LI) don't!

Error I receive when I step through the markup in the ItemCats_UL.ascx and hover over the 'Html' part of the following code:

<ul id="catsTree"> 
 <% Html.RenderPartial("ItemCats_LI", Model); %>
</ul>

Value cannot be null. Parameter name: viewContext

Html = 'Html' threw an exception of type 'System.ArgumentNullException'

I'm wondering if there's a clever guy out there who can extend the RenderPartialToString method to include nested partialviews? Or am I missing something simple?


You need to hook the newly returned HTML / JavaScript back into the DOM upon loading it.
I'm sure there are lots of ways to do this, but I found a nice jQuery add-on called LiveQuery (link) that helps me do it.

To make it work in your case, you'd set up a jQuery document.ready function in the parent page that looks something like this:

$("#catsTree").livequery(function () { this.treeview(); }, function () { /* code to destroy the treeview here */ });
0

精彩评论

暂无评论...
验证码 换一张
取 消