Ответ 1
Я считаю, что ваша проблема связана с этим:
Вызов функции jQuery внутри html возврата из вызова AJAX
Взгляните и посмотрите, помогает ли это.
На одной из моих страниц просмотра у меня есть 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, содержащегося в partialView (_DonorEdit). Таким образом, вопрос сводится к тому, что у меня есть javascript, встроенный в тег div и до сих пор работающий правильно.
Эта проблема возникает только тогда, когда частичный вид возвращается из вызова ajax. В приведенном выше коде, если я непосредственно включаю PartialView (по запросу без аякса), тогда javascript работает правильно. Но если я позже заменил содержимое div, используя запрос ajax, javascript, включенный в PartialView, не работает. Встроенный javascript просто не появляется вместе с Partial View. Так что, по-видимому, есть и другая причина, почему javascript, встроенный в Partial View, не попадает в браузер после успеха запроса 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>
Я считаю, что ваша проблема связана с этим:
Вызов функции jQuery внутри html возврата из вызова AJAX
Взгляните и посмотрите, помогает ли это.
Другим способом решения проблемы является рендеринг частичного представления в контроллере, возврат 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 внутри частичных представлений.
Надеюсь, что это поможет.
Вызов функции javascript в вашей успешной части ajax
Если вы используете эту функцию на нескольких страницах, почему бы не включить ее в файл script (может быть, имя _DonorEdit.js) и включить для тех страниц, которые используют частичный?
Вы можете использовать что-то вроде require.js, чтобы упростить управление этим процессом. В качестве альтернативы require.js вы можете использовать объединение активов, например Cassette.net, для управления зависимостями для страниц и любыми частичными данными, которые вы загружаете с помощью ajax.
Затем, как и в вашем вызове bind/trigger внутри вашего обработчика успеха ajax, вы можете зарегистрировать все события/обработчики, необходимые для частичного.
В долгосрочной перспективе вы, возможно, захотите посмотреть, это knockout.js: создание модели просмотра в этом файле _DonorEdit.js, который связывается с шаблоном, возвращаемым в вашем частичном, может быть чрезвычайно мощным и удобным. Если вы предпочитаете по-прежнему отображать все данные для частичного сервера, вы все равно можете в некоторой степени использовать привязку события нокаута.