0

I use ASP.NET MVC (without the Razor engine). I have an EditorTemplate which requires a script to work properly. I could just put the script within the user control, but I do not want this script to be defined multiple times when the EditorTemplate is present multiple times in a page.

I also don't want to put the script in the page because that would be a dependency the consumer (the page) cannot easily know about. It's a recipe for bugs in the long run.

I think the solution would be to put this code in the ascx :

<% if (RequestState.IsEditorScriptRendered == null) { %>
    RequestState.IsEditorScriptRendered = true;
    <script>...</script>
<% } %>

Unfortunately, there doesn't seem to be any state with a request lifetime. How could I store the "IsEditorScriptRendered" information? Is there better way of achieving my desired result?

Kevin Coulombe
  • 1,517
  • 1
  • 17
  • 35

3 Answers3

1

Pre-bundles I used my own answer to How to render a Section in a Partial View in MVC3 that was specific to scripts.

With bundles, it's cheaper to just include all my editor template JS files in a single bundle.

Community
  • 1
  • 1
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • I see you are using ViewContext.HttpContext.Items to store which scripts have already been rendered. I didn't know about this data store. It is exactly what I'm looking for! – Kevin Coulombe Jun 06 '14 at 22:13
  • It is the only *supported* data store for each HttpContext (request). – Erik Philips Jun 06 '14 at 22:15
0

You can place your javascript code to .js file and reference it from your page. Then you can call it from all editor templates.

Kirill Bestemyanov
  • 11,946
  • 2
  • 24
  • 38
0

The language you are using leads me to believe you are approaching this like Webforms. (User control, state with a request lifetime). In any case, can you explain why your page cannot easily know about the dependency? In ASP.NET MVC, typically you, as the author, know your dependencies and put them in a Bundle and/or in a master page.

I recommend just creating a separate bundle or a separate master page for the few pages that need it that particular script included. You aren't limited to just one site-wide master page.

Regardless, scripts are cached, so it'll be downloaded at most once. (I'm not saying don't tune, but jumping through hoops to avoid including a script is usually premature optimization).

codenheim
  • 20,467
  • 1
  • 59
  • 80
  • I don't mind the script loading. It's the event handlers that I don't want registered multiple times. But you just made me think that I can tell if the script was already loaded in javascript instead of trying to prevent its rendering. – Kevin Coulombe Jun 06 '14 at 21:45
  • As for the dependencies being known, the editor template I am writing can be used in a few pages, and it registers a "page load" event handler. I can't put it in the master page without registering useless event handlers in every other page. I also don't want the page to need to add it because I think the page should be able to use "Html.EditorFor" without knowing exactly which editor template will be used and what dependencies it has. But I may be over-thinking it... – Kevin Coulombe Jun 06 '14 at 21:50
  • Your editor template can have conditional Javascript in it. You can render whatever you like. Would that solve your issue? – codenheim Jun 06 '14 at 21:56
  • I was trying to wrap the event registering code in a javascript condition when I saw Erik's solution which is more elegant. I think it would have worked too. – Kevin Coulombe Jun 06 '14 at 22:15