Как загрузить частичное представление, содержащее JavaScript? - PullRequest
13 голосов
/ 06 сентября 2011

На одной из моих страниц просмотра у меня есть asp.net mvc PartialView.PartialView содержит некоторый JavaScript (и JQuery).В моем главном представлении asp.net я загружаю PartialView, используя ajax, внутри тега div, как указано ниже.То есть, из контроллера я возвращаю PartialView ("_ DonorEdit") и на своей главной странице я использую javascript для замены содержимого тега div на ответ PartialView.

<div class="content" id="content">
    @{Html.RenderPartial("_DonorEdit");}   
</div>

Все работает нормально, кроме содержащегося в javascriptв частичном представлении (_DonorEdit).Таким образом, вопрос сводится к следующему: как мне встроить javascript в тег div и по-прежнему заставить его работать правильно.

Эта проблема возникает, только когда частичное представление возвращается из вызова ajax.В приведенном выше коде, если я напрямую включаю PartialView (по запросу без ajax), то JavaScript работает правильно.Но если я позже заменю содержимое div с помощью ajax-запроса, JavaScript, включенный в PartialView, не будет работать.Встроенный JavaScript просто не отображается вместе с частичным представлением.Так что, похоже, есть еще одна причина, почему javascript, встроенный в частичное представление, не передается в браузер после успешного выполнения запроса ajax.

Часть моего кода javascript

<script type=...>
//Date Picker. This works. I get Calendar popup as expected

$(document).ready(function () {
    $("#Donor_BirthDate").datepicker({
        dateFormat: "dd-mm-yy",
        changeMonth: true,
        changeYear: true,
        yearRange: "-75:+0"
    });

    $("#Donor_DateLastDonated").datepicker({
        dateFormat: "dd-mm-yy",
        changeMonth: true,
        changeYear: true,
        yearRange: "-20:+1"
    });
});


//Dropdown handler. Does not make it in my final View.

function residenceStateChanged(e) {
    var url = '@Url.Action("_GetCities", "DropDown")';
    var cmbResidenceCityId = $('#ResidenceCityId').data('tDropDownList');
    cmbResidenceCityId.loader.showBusy();

    $.ajax({
        type: 'GET',
        url: url,
        data: { StateId: e.value, AddSelectOption: true, SelectOption: 'Select' },
        traditional: true,
        success: function (resp, textStatus, jqXHR) {
            cmbResidenceCityId.dataBind(resp);
            cmbResidenceCityId.select(0);
            cmbResidenceCityId.trigger.change();
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert(jqXHR.responseText);
        },
        complete: function () {
            cmbResidenceCityId.loader.hideBusy();
        }
    });
}

....//Some other code omitted. Does not make it in final view.
</script>

Ответы [ 4 ]

1 голос
/ 25 июля 2013

Другим способом решения проблемы является визуализация частичного представления в контроллере с возвратом html-объекта в объекте json в качестве результата вызова ajax.

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

private string RenderPartialView(string viewName, object model)
{
    if (string.IsNullOrEmpty(viewName))
    {
        viewName = this.ControllerContext.RouteData.GetRequiredString("action");
    }
    this.ViewData.Model = model;
    using (var sw = new StringWriter())
    {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(this.ControllerContext, viewName);
        var viewContext = new ViewContext(this.ControllerContext, viewResult.View, this.ViewData, this.TempData, sw);
        viewResult.View.Render(viewContext, sw);
        viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
        return sw.GetStringBuilder().ToString();
    }
}

Затем вам нужно будет добавить новый метод действия в ваш контроллер, который возвращает визуализированное представление, т. Е .:

public JsonResult GetDonorEdit()
{
    return Json(new 
    { 
        DonorEditContent = RenderPartialView("_DonorEdit", null) 
    });
}

На стороне клиента вызов ajax можно изменить примерно так:

$.ajax({
    type: "POST",
    url: "GetDonorEdit",  // get the correct url of GetDonorEdit action
    cache: false
})
.success(function (result) {
    $("#content").html(result.DonorEditContent); 
})
.error(function (xhr, errStatus, errThrown) {
    //...
});

Я использую эту технику, потому что обычно приходится возвращать более одного частичного представления в одном и том же вызове ajax, а также потому, что он правильно выполняет код javascript внутри частичных представлений.

Надеюсь, это поможет.

1 голос
/ 06 сентября 2011

Я считаю, что ваша проблема связана с этим:

Вызов функции jQuery внутри html, возвращаемой из вызова AJAX

Посмотрите, поможет ли это.

0 голосов
/ 02 декабря 2012

Если вы используете эту функцию на нескольких страницах, почему бы не включить ее в файл сценария (возможно, с именем _DonorEdit.js) и в том числе для тех страниц, которые используют частичное?

Вы можете использовать что-то вроде require.js, чтобы упростить управление.В качестве альтернативы require.js вы можете использовать связывание ресурсов, такое как Cassette.net, чтобы управлять зависимостями для страниц и любыми частями, которые вы загружаете через ajax.

Затем, как и в ваших вызовах привязки / триггера внутри вашего обработчика успеха ajax, вы можете зарегистрировать любые события / обработчики, которые вам нужны для частичного.

В долгосрочной перспективе вы можете захотеть взглянуть на knockout.js: создание модели представления в этом файле _DonorEdit.js, который связывается с шаблоном, возвращенным в вашей части, может быть чрезвычайно мощными ремонтопригоден.Если вы предпочитаете по-прежнему отображать все данные для частичной части сервера, вы все равно можете в некоторой степени воспользоваться привязкой событий нокаута.

0 голосов
/ 06 сентября 2011

Вызовите функцию javascript в вашей успешной части ajax

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...