5

I have a Razor PartialView that works with Metro-UI-style tiles. It's a very simple PartialView that allows me to display tiles bound to a ViewModel, really nothing spectacular.

Since it's not used in all pages, I don't want to include the jQuery block on every page load. Instead I prefer that the script is declared inline with the PartialView, but registered once in the pagecode.

The view is the following (I have reenginered Metrofy template)

@model IEnumerable<MetroStyleTile>


<div class="container tiles_hub">
    <div class="sixteen columns alpha">
        @foreach (MetroStyleTile tile in Model)
        {
            <div class="tile_item four columns alpha">
                <a href="@Url.Action(tile.Action, tile.Controller, routeValues: tile.MvcArea != null ? new { area = tile.MvcArea } : null)" class="tile">
                    @Html.Label(tile.Description)
                    @if (tile.ImageUrl != null)
                    {
                        @Html.Image(tile.ImageUrl.ToString(), tile.Title, htmlAttributes: new { @class = "tile_img" })
                    }
                </a>
            </div>
        }
    </div>

    @section Scripts{



        <script type="text/javascript">

            $(document).ready(function ($) {
                //Tiles hover animation
                $('.tile').each(function () {
                    var $span = $(this).children('span');
                    $span.css('bottom', "-" + $span.outerHeight() + 'px');
                });

                var bottom = 0;

                $('.tile').hover(function () {
                    var $span = $(this).children('span');
                    if (!$span.data('bottom')) $span.data('bottom', $span.css('bottom'));
                    $span.stop().animate({ 'bottom': 0 }, 250);
                }, function () {
                    var $span = $(this).children('span');
                    $span.stop().animate({ 'bottom': $span.data('bottom') }, 250);
                });
            });
        </script>
    }
</div>

The above code is fine when I use the PartialView only once in the page, but if I use the @Html.Partial twice I get the script twice.

Now let me clarify: I often ask question on StackOverflow to learn more from the platform, and I don't usually like workaround solutions.

I could use a Javascript global variable to see if the function must be declared again or not.

I could register the script in the Layout to make it appear in all pages and not worry.

I'm asking how to print the script to Response only once. Learning how to do this allows me to lighten page payload when multiple PartialViews are developed like this (so the client gets the script only when needed, and only once if needed).

How can I do that?

Jim O'Neil
  • 23,344
  • 7
  • 42
  • 67
usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305
  • Maybe you can use a wrapper view where you could put all your scripts and required jquery statements, which will load only once. and then render the above partial views either using @html.Partial or ajax as per the requirement. – vinodpthmn May 04 '13 at 18:23
  • This is a very good question. In my experience, it's better practice to render your JS in a JS file referenced in your parent view. It's tempting to encapsulate partials with their JS dependencies; But then you will more easily lose track of what JS is relevant to your View. – Dave Alperovich May 04 '13 at 20:56
  • 1
    I had a similar problem. Maybe this will help you too? http://stackoverflow.com/questions/5433531/using-sections-in-editor-display-templates – user1987392 May 27 '13 at 15:00

0 Answers0