3

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: enter image description here

8
  • 2
    Do not put scripts in partial views. If your dynamically loading a partial after the page has been rendered, then you need to use event delegation (using .on() to handle events from elements in the partial) Commented Mar 15, 2016 at 22:16
  • What do you mean "affect partial views"? Commented Mar 15, 2016 at 22:16
  • @StephenMuecke I can't use .on(). I am using dropzone plugin in my view and it gets bound as soon as it loads. I need another way. Commented Mar 15, 2016 at 22:48
  • 2
    As I noted in my previous comment. In the success callback, after you have added the partial to the DOM, then attach the plugin. You have not shown anything relating to the partial, but it would be something like $(someElementYouJustAdded).dropzone({ .... }); Commented Mar 15, 2016 at 23:26
  • 2
    Just make sure your not reattaching the plugin to existing elements - e.g. if the elements has class="dropzone", then use $('.dropone:last').dropzone(); Commented Mar 15, 2016 at 23:40

1 Answer 1

5

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
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.