I am using the @RenderSection("scripts", required: false)
on the _Layout.cshtml at bottom of the page after the script bundles. My View using this layout defined the scripts section (@section scripts{ //script block}
). Every thing works fine when I render the view from controller action via full page call.
But when I render the same view's content inside the container using the $.ajax call done handler like ($('#container').html(result)
) then the scripts section defined on the _Layout.cshtml page does not load and executed on the DOM. Note in this case _Layout is not loaded as the call was ajax and layout page was already on the DOM and I do not want to load layout page again to improve the page load time. I am only concerned to load the Child view's content.
Please find below setup
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
@Styles.Render("~/Content/css")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Load Full", "LoadPartial", "Home")</li>
<li><a href="#" id="lnkMenu" data-url="@Url.Action("LoadPartial","Home")">Load via SPA</a></li>
</ul>
</div>
</div>
</div>
<div id="container" class="container body-content">
@RenderBody()
<hr />
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
<script src="~/Scripts/Common.js"></script>
@RenderSection("scripts", required: false)
</body>
</html>
Controller
public ViewResult LoadPartial()
{
return View("_LoadPartial");
}
_ViewStart.cshtml:
@{
Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/_Layout.cshtml";
}
Partial View: _LoadPartial.cshtml
<div class="jumbotron">
<h2>Script loading demo</h2>
</div>
<p id="partial-id">Partial view content</p>
@section scripts
{
<script>
$(function () {
console.log("full");
$('#partial-id').css('color', 'blue');
});
</script>
}
Java script code to load the view using ajax call
$(function () {
$('#lnkMenu').click(function () {
var url = $(this).data("url");
$.ajax({
url: url,
type: 'GET',
cache: false
}).done(function (result) {
$('#container').html(result);
});
});
});
Now when I load page using with Layout in 1st case then it works fine. But If i try to load the page using jquery ajax then script section does not work.
=========================Solution I tried===============================
To fix this I tried the following solution, i.e. On my view I load the script section based on condition that if request is Ajax then run script normally and if it's full page request with Layout then run the script section. With this solution my _LoadPartial.cshtml view look like as following
<div class="jumbotron">
<h2>Script loading demo</h2>
</div>
<p id="partial-id">Partial view content</p>
@{
if (Request.IsAjaxRequest())
{
<script>
$(function () {
console.log("partial");
$('#partial-id').css('color', 'blue');
});
</script>
}
else
{
@section scripts
{
<script>
$(function () {
console.log("full");
$('#partial-id').css('color', 'blue');
});
</script>
}
}
}
This solution works fine in both the cases, but Here the problem with the solution is this that it's violating the DRY principle as I have to write same script block in both if
and else block
.
Does someone has idea what is the best way to handle such scenarios?