How to load a partial view containing JavaScript?
在我的一个View页面中,我有一个asp.net mvc PartialView。 PartialView包含一些javascript(和jquery)。在我的asp.net主视图中,我使用ajax在div标签内加载PartialView,如下所示。也就是说,从控制器I返回PartialView("_ DonorEdit"),在我的主页面中,我使用javascript将Part标签的内容替换为PartialView响应。
1 | @{Html.RenderPartial("_DonorEdit");} |
除了partialView(_DonorEdit)中包含的javascript之外,一切正常。因此,问题归结为 - 如何在div标签中嵌入javascript并仍然使其正常工作。
仅当从ajax调用返回部分视图时,才会出现此问题。在上面的代码中,如果我直接包含PartialView(在非ajax请求上),那么javascript正常工作。但是如果我稍后使用ajax请求替换div的内容,则PartialView中包含的javascript不起作用。嵌入式javascript根本不会与"部分视图"一起显示。所以似乎有一些其他原因,为什么在ajax请求成功之后,部分视图中嵌入的javascript不会传递给浏览器。
我的javascript代码的一部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <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. |
解决问题的另一种方法是在控制器中渲染局部视图,返回json对象中的html作为ajax调用结果。
在Controller中,您可以使用通用方法呈现部分视图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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(); } } |
然后,您将必须向控制器添加一个新的操作方法,该方法返回渲染视图,即:
1 2 3 4 5 6 7 | public JsonResult GetDonorEdit() { return Json(new { DonorEditContent = RenderPartialView("_DonorEdit", null) }); } |
在客户端,可以将ajax调用更改为以下内容:
1 2 3 4 5 6 7 8 9 10 11 | $.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代码。
希望能帮助到你。
我相信你的问题与这个问题有关:
在一个AJAX调用中调用html内部的jQuery函数
看看它是否有帮助。
如果您在多个页面中使用此功能,为什么不将它包含在脚本文件(可能名为_DonorEdit.js)中,并包括那些使用部分的页面?
您可以使用require.js之类的东西来简化对此的管理。
作为require.js的替代,您可以使用像Cassette.net这样的资产捆绑来管理页面的依赖关系以及您通过ajax加载的任何部分。
然后,就像在ajax成功处理程序内部的绑定/触发器调用一样,您可以注册部分所需的任何事件/处理程序。
从长远来看,你可能想要看看的是knockout.js:在_DonorEdit.js文件中创建一个viewmodel,它与你局部返回的模板绑定,可以非常强大和可维护。如果您仍然希望渲染部分服务器端的所有数据,您仍然可以在某种程度上利用knockout的事件绑定。
在你的ajax成功部分调用javascript函数