A clean alternative to the inability to use partitions in a partial view?

Since we cannot use sections within a partial view, what is the cleanest approach to including scripts required only by a partial view?

I know that I can include my scripting section on a page that causes partial, but if there is a Javascript component in my partial component that I want to reuse on my site, then including custom scripts on each base page is a nightmare to serve.

Given that the inability to use JS within a partial design, am I even right when I want to use partial for a reusable view that includes Javascript components?

+7
javascript asp.net-mvc asp.net-core
source share
3 answers

You can make a partial signal on the layout page so that it includes a script, for example, using the IOC scope or HttpContext Bag. which is read on the layout page.

The only and main problem is that the script will only be in this package, as soon as it is partial, and then, most likely, your html head section is already closed in the layout. Thus, it is great for adding scripts at the bottom of the page, but it will not work for css.

It is best to create your own kind of components (or extend them) and specify an option to specify the necessary views. IOC these components at the top and visualize them where necessary.

The best solution

A better solution would be if half the pages needed this java-script to link it inside the main package. minifier is likely to be able to minimize more variables, and the user will need to request 1 less script (http request) for the loaded page, thereby creating less traffic, creating a faster page loading, creating a better user experience.

+2
source share

I will not pretend that this is optimal, but if you do not want to create your own extensions for viewing, you can leave the building with something like this:

public static class DeferredScripts { static IList<string> paths = new List<string>(); public static IList<string> Scripts { get; set; } public static void Add(string path) { if (Scripts == null) { Scripts = new List<string>(); } if (!paths.Any(s => s.Equals(path, StringComparison.OrdinalIgnoreCase))) { var script = new TagBuilder("script"); script.Attributes.Add("src", path); Scripts.Add(script.ToString()); paths.Add(path); } } } 

What could you use as follows in a partial view:

 @{ DeferredScripts.Add("/scripts/testscript1.js"); } 

And use this in your layout (or on the watch page):

 @foreach (var script in DeferredScripts.Scripts) { @Html.Raw(script) } 

It seems to work in a test project that I dumped together: https://github.com/tiesont/DeferredScriptsTestApp

Telerik has something similar for its KendoUI ASP.NET MVC helpers, although I assume their implementation is more reliable than what I showed here.

+2
source share

I think it would be fair, but probably the least useful answer would be to say: "You are using MVC6 incorrectly if you want to use partitions in part or mimic it."

There are 3 main cases for the perfect solution to your problem:

  • Partial / ViewComponent is added 0 times and the corresponding JavaScript library is added 0 times
  • Partial / ViewComponent is added 1 time, the corresponding JavaScript library is added 1 time, and dynamically created JavaScript initialization is created once and placed after the library.
  • Partial / ViewComponent is added many times, the corresponding JavaScript library is added 1 time, and a dynamically created JavaScript initialization script is created for each Partial / ViewComponent and placed after the library.

3 main options

  • add <hidden data-myTool-*="MyData"> and you have the main script at the bottom of the page to read all this (not perfect, because it violates # 1)
  • Make the tool Pending Scripts (Ideal, but refers to an external class)
  • Pass the partial list of strings to add your script dependencies. (Ideal, but can only work with views without a layout and assumes that partial ones do not use models).

This is an example of option 3:

Partial:

 @model List<string> FROM TEST PARTIAL @{ Model.Add("Partial.js");} 

View:

 @{ var jsfiles = new List<string>(); jsfiles.Add("View.js"); } @Html.Partial("_Test", jsfiles) @Html.Partial("_Test", jsfiles) @Html.Partial("_Test", jsfiles) @section scripts { @foreach (string file in jsfiles.Distinct().ToList()) { <script src="@file"></script> } } 

Result:

 <script src="View.js"></script> <script src="Partial.js"></script> 
+1
source share

All Articles