Как вернуть вложенные PartialViews (включая их javascript) из вызова AJAX в ASP.Net MVC

Я создал древовидное представление категорий, используя вложенные частичные представления:

моя индексная страница (которая отображает древовидную структуру):

<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>
<%} %>

Теперь это древовидное представление отлично работает, когда я возвращаю базовое представление («Индекс», модель) из действия индекса моих контроллеров при загрузке страницы.

Проблема возникает, когда я хочу изменить модель категорий, отображаемую в моем дереве (вложенные частичные представления) из вызова AJAX...

Например: я нажимаю кнопку «Cats2», и на странице должны отображаться категории с ParentID, равным 2, в дереве. Я попытался это сделать, вернув JsonResult HTML-кода ItemCats_UL PartialView (используя метод RenderPartialToString здесь) из моего действия контроллера. Как некоторые из вас, возможно, знают, Javascript не будет работать в вашем частичном представлении, когда вы используете форму AJAX для возврата PartialViewResult, и мне нужен Javascript в моем дереве, поэтому я использую RenderPartialToString.

Обработчик нажатия кнопки выбора категории:

<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>

Мое действие контроллера:

 [AcceptVerbs(HttpVerbs.Post)]
    [UrlRoute(Name = "SelectCat", Path = "selectCat")]
    public ActionResult SelectCat(int CID)
    {
        IQueryable<ItemCategory> cats;
        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;
    }

Результат:

ItemCats_UL partialView displays! BUT the nested PartialViews (ItemCats_LI) нет!

Ошибка, которую я получаю, когда просматриваю разметку в ItemCats_UL.ascx и навожу курсор на часть «Html» следующего кода:

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

Значение не может быть нулевым. Имя параметра: viewContext
Html = 'Html' вызвало исключение типа 'System.ArgumentNullException'
Мне интересно, есть ли умный парень, который может расширить метод RenderPartialToString для включения вложенных частичных представлений? Или я упускаю что-то простое?


person Community    schedule 29.10.2009    source источник
comment
Не могли бы вы удалить javascript из частичных представлений (на главную страницу), а затем в методе успеха вашего вызова ajax вызвать $(#catsTree).treeview(); ?   -  person ddd    schedule 03.11.2010


Ответы (1)


Вам нужно подключить только что возвращенный HTML/JavaScript обратно в DOM после его загрузки.
Я уверен, что есть много способов сделать это, но я нашел хорошее дополнение jQuery под названием LiveQuery (ссылка), которая помогает мне в этом.

Чтобы это работало в вашем случае, вы должны настроить функцию jQuery document.ready на родительской странице, которая выглядит примерно так:

$("#catsTree").livequery(function () { this.treeview(); }, function () { /* code to destroy the treeview here */ });
person James Nail    schedule 18.01.2011
comment
Любое объяснение отрицательного голоса? Я хотел бы услышать, что вам не нравится в этом ответе, чтобы я (и другие) могли изучить лучший подход. - person James Nail; 27.04.2011