Как вернуть вложенные PartialViews (включая их javascript) из вызова AJAX в ASP.Net MVC - PullRequest
3 голосов
/ 29 октября 2009

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

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

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

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

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

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

My Controller Action:

 [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, чтобы включить вложенные частичные представления? Или я упускаю что-то простое?

1 Ответ

0 голосов
/ 18 января 2011

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

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

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