ASP.NET MVC Loading scripts in partial views

2019-07-10 03:17发布

问题:

My entire website is an Ajax website, so all of my views (apart from Layout) can either be loaded normally or via an ajax actionlink. If I put the Javascipt files in with the partial views then all of the code works as expected, but the scripts get loaded multiple times (thus making the user download more scripts, all of them aren't being cached for some reason either).

If I put the script files in my Layout, then they only get loaded once but if a partial view gets loaded then the JS code for that partial view doesn't work obviously, because the scripts were already loaded when the partial view wasn't rendered.

My question is, how can I make the scripts get loaded only once, but also somehow have them affect partial views?

Index view:

<script src="/Scripts/Build/module.min.js"></script>
<script src="/Scripts/Build/upload-index.min.js"></script>

Layout:

<li>
    @Ajax.ActionLink("Upload", "Index", "Upload", new {Area = "Music"}, new AjaxOptions {HttpMethod = "GET", UpdateTargetId = "body-wrapper", InsertionMode = InsertionMode.Replace, OnSuccess = "updateHistory", AllowCache = true }, new {@class = "nav-link"})
</li>

You can see the scripts getting loaded multiple times if they are in the partial view:

回答1:

Scripts should not be in partial views, only the main view or its layout. Not only do you have the duplicate issue you have identified your self, but it can lead to other issues such as invalidating existing scripts.

If you need to handle events associated with dynamically added items then use event delegation using the .on() function. For example

$.(container).on('click', '.someclass', function() { .... }

will handle the click event of elements with class="someclass" that have been added as a child element of container even if they are added after the DOM has been initially loaded.

If you need to attach a plugin to dynamically added elements, then attach it after the element has been added to the DOM, for example

$.get(url, function(html) {
    $(container).append(html); // append the partial view
    $(container).find('someclass:last')..dropzone({ .... }); // attach plugin
});