In an ASP.NET Core app, I've a dashboard with widgets. Every widget has its own PartialViews, so the full page is generated in the following way:
-Layout.cshtml
--Dashboard.cshtml
--- Widget1.cshtml
--- Widget2.cshtml
Following best practices according to fast page load times, JavaScript is loaded before the closing </body>
tag in Layout.cshtml. After that, there is a section for custom JS, which I commonly use to initiate objects on page load. So this section looks like this:
<script asp-append-version="true" type="text/javascript" src="~/clientscript/page.min.js"></script>
@RenderSection("Js", required: false)
In my Views, which are using the Layout.cshtml as layout (in this example, its Dashboard.cshtml), I can define a section like
@section Js {
// Js Code here
}
which is rendered after the script tag containing all script files. So I can be sure, that all dependencies like jQuery or custom classes are avaliable here.
But I also need to do this in widgets like Widget1.cshtml for example. The problem is: I load the PartialView Widget1.cshtml in Dashboard.cshtml. In the documentation is written, that this is not possible:
If you declare a Razor section in a partial view, it will not be visible to its parent(s); it will be limited to the partial view.
But that's exactly what I need. Is there a way to work around this limitation? Shortly, the goal is to inject JavaScript from a PartialView to the LayoutView, with an regular View between them.
The only way I know is the usage of setInterval() with a low interval like 50ms, and check there if jQuery or some of my custom class is defined in a loop until they are. Its a JS solution yes. But it makes it possible to include the script-block directly in the PartialView without making usage of sections. It fits well when you depend on a single variable like jQuery.
But I need to wait for custom classes to get loaded. They're included after jQuery. So writing a generic function like waitForTypeLoaded(type, callback)
is not possible. It would cause me to write always the raw setInterval() code, which seems not a smart solution for me.