Включить файл JavaScript в частичные представления - PullRequest
69 голосов
/ 27 мая 2009

Мне интересно, как лучше всего включать файлы javascript в частичные представления. После визуализации это закончится тегом js include в середине html моей страницы. С моей точки зрения, это не очень хороший способ сделать это. Они принадлежат тегу head и поэтому не должны мешать браузеру отображать html за один раз.

Пример: Я использую плагин jquery picturegallery внутри частичного представления 'PictureGallery', так как этот частичный вид будет использоваться на нескольких страницах. Этот плагин нужно загружать только при использовании этого вида, и Мне не нужно знать, какие плагины использует каждый частичный вид ...

Спасибо за ваши ответы.

Ответы [ 8 ]

28 голосов
/ 27 мая 2009

Очень похоже на этот вопрос: Связывание библиотек JavaScript в пользовательских элементах управления

Я отвечу на этот вопрос здесь.

Я бы определенно не советовал помещать их в партиалы именно по той причине, которую вы упомянули Существует высокая вероятность того, что одно представление может получить две партиалы, которые имеют ссылки на один и тот же файл js. Вы также получили снижение производительности при загрузке js перед загрузкой остальной части html.

Я не знаю о наилучшей практике, но я решил включить в общую страницу любые распространенные js-файлы, а затем определить отдельный ContentPlaceHolder для некоторых дополнительных js-файлов, относящихся к конкретному или небольшому числу просмотров.

Вот пример главной страницы - она ​​довольно понятна.

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<head runat="server">
    ... BLAH ...
    <asp:ContentPlaceHolder ID="AdditionalHead" runat="server" />
    ... BLAH ...
    <%= Html.CSSBlock("/styles/site.css") %>
    <%= Html.CSSBlock("/styles/ie6.css", 6) %>
    <%= Html.CSSBlock("/styles/ie7.css", 7) %>
    <asp:ContentPlaceHolder ID="AdditionalCSS" runat="server" />
</head>
<body>
    ... BLAH ...
    <%= Html.JSBlock("/scripts/jquery-1.3.2.js", "/scripts/jquery-1.3.2.min.js") %>
    <%= Html.JSBlock("/scripts/global.js", "/scripts/global.min.js") %>
    <asp:ContentPlaceHolder ID="AdditionalJS" runat="server" />
</body>

Html.CSSBlock & Html.JSBlock, очевидно, являются моими собственными расширениями, но опять же, они говорят сами за себя в том, что они делают.

Тогда, скажем, в представлении SignUp.aspx у меня будет

<asp:Content ID="signUpContent" ContentPlaceHolderID="AdditionalJS" runat="server">
    <%= Html.JSBlock("/scripts/pages/account.signup.js", "/scripts/pages/account.signup.min.js") %>
</asp:Content>

HTH, Чарльз

Ps. Вот следующий вопрос, который я задал для минимизации и объединения файлов js: Объединение и сокращение JS на лету ИЛИ во время сборки - ASP.NET MVC

РЕДАКТИРОВАТЬ: В соответствии с моим другим ответом, моя реализация .JSBlock (a, b) в соответствии с запросом

public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName)
{
    return html.JSBlock(fileName, string.Empty);
}

public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName, string releaseFileName)
{
    if (string.IsNullOrEmpty(fileName))
        throw new ArgumentNullException("fileName");

    string jsTag = string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>",
                                 html.MEDebugReleaseString(fileName, releaseFileName));

    return MvcHtmlString.Create(jsTag);
}

А потом, где происходит волшебство ...

    public static MvcHtmlString MEDebugReleaseString(this HtmlHelper html, string debugString, string releaseString)
    {
        string toReturn = debugString;
#if DEBUG
#else
        if (!string.IsNullOrEmpty(releaseString))
            toReturn = releaseString;
#endif
        return MvcHtmlString.Create(toReturn);
    }
1 голос
/ 04 ноября 2010

Сегодня я создал свое собственное решение, которое идеально соответствует всем требованиям. Хороший ли это дизайн или нет, решать вам всем, но я решил поделиться с вами в любом случае!

Ниже приведен мой класс HtmlExtensions, который позволяет вам сделать это на главной странице:

<%=Html.RenderJScripts() %>

Мой класс HtmlExtensions:

public static class HtmlExtensions
{
    private const string JSCRIPT_VIEWDATA = "__js";

    #region Javascript Inclusions

    public static void JScript(this HtmlHelper html, string scriptLocation)
    {
        html.JScript(scriptLocation, string.Empty);
    }

    public static void JScript(this HtmlHelper html, string scriptLocationDebug, string scriptLocationRelease)
    {
        if (string.IsNullOrEmpty(scriptLocationDebug))
            throw new ArgumentNullException("fileName");

        string jsTag = "<script type=\"text/javascript\" src=\"{0}\"></script>";

#if DEBUG
        jsTag = string.Format(jsTag, scriptLocationDebug);
#else
        jsTag = string.Format(jsTag, !string.IsNullOrEmpty(scriptLocationRelease) ? scriptLocationRelease : scriptLocationDebug);
#endif

        registerJScript(html, jsTag);
    }

    public static MvcHtmlString RenderJScripts(this HtmlHelper html)
    {
        List<string> jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List<string>;
        string result = string.Empty; ;
        if(jscripts != null)
        {
            result = string.Join("\r\n", jscripts);
        }
        return MvcHtmlString.Create(result);
    }

    private static void registerJScript(HtmlHelper html, string jsTag)
    {
        List<string> jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List<string>;
        if(jscripts == null) jscripts = new List<string>();

        if(!jscripts.Contains(jsTag))
            jscripts.Add(jsTag);

        html.ViewContext.TempData[JSCRIPT_VIEWDATA] = jscripts;
    }

    #endregion

}

Что происходит?
Приведенный выше класс расширит HtmlHelper методами для добавления ссылок javascript в коллекцию, которая хранится в коллекции HtmlHelper.ViewContext.TempData. В конце мастер-страницы я поместил <%=Html.RenderJScripts() %>, который будет зацикливать коллекцию jscripts внутри HtmlHelper.ViewContext.TempData и отображать их на выходе.

Однако есть и обратная сторона: вы должны убедиться, что вы не отрисовываете скрипты до того, как добавите их. Если вы захотите сделать это, например, для ссылок CSS, это не сработает, потому что вы должны поместить их в тег <head> вашей страницы, и htmlhelper отобразит вывод еще до того, как вы добавите ссылку.

1 голос
/ 05 июня 2010

Причина, по которой вы поместили бы скрипт внизу страницы, заключается в том, чтобы убедиться, что dom загружен, прежде чем пытаться манипулировать. Это также может быть достигнуто чем-то вроде $ (document) .ready (callback); Метод jQuery.

Я разделяю мнение о том, что не нужно вставлять встроенный JavaScript в html. Вместо этого я использую Html помощник, чтобы создать пустой div для использования в качестве серверной инструкции. Вспомогательный сигнал - Html.ServerData (имя строки, данные объекта);

Я использую этот метод ServerData для инструкций от сервера к клиенту. Тег div сохраняет его в чистоте, а атрибут «data-» является действительным html5.

Для инструкции loadScript я могу сделать что-то подобное в моем ascx или aspx:

<%= Html.ServerData("loadScript", new { url: "pathTo.js" }) %>

Или добавьте еще одного помощника, который выглядит немного чище:

<%= Html.LoadScript("~/path/to.js") %>

Вывод html будет:

<div name="loadScript" data-server="encoded json string">

Тогда у меня есть метод jQuery, который может найти любой тег данных сервера: $ (ContainingElement) .serverData ( "loadScript"); // возвращает jQuery-подобный массив декодированных объектов json.

Клиент может выглядеть примерно так:

var script = $(containingelement").serverData("loadScript");
$.getScript(script.url, function () {
    // script has been loaded - can do stuff with it now
});

Эта методика отлично подходит для пользовательских элементов управления или сценариев, которые должны быть загружены в загруженный ajax-контент. Версия, которую я написал, немного больше связана с обработкой сценариев кэширования, поэтому они загружаются только один раз на полную загрузку страницы и содержат обратные вызовы и триггеры jQuery, поэтому вы можете подключиться к нему, когда он будет готов.

Если кто-то заинтересован в полной версии этого (от MVC до расширения jQuery), я был бы рад продемонстрировать эту технику более подробно. В противном случае - надеется, что это даст кому-то новый способ решения этой сложной проблемы.

0 голосов
/ 02 декабря 2010

hejdig.

Играя с Aspnetmvc3 На данный момент я решил просто включить мой файл javascript в частичный

Этот js-файл является специфическим для моего файла /user/List.schtml.

/ OF

0 голосов
/ 27 мая 2009

Предпочтительный подход заключается в размещении скриптов внизу , однако, если вы не можете избежать этого, тогда разумно поместить их в середину.

Браузеры обычно загружают различные элементы страницы параллельно, однако, пока браузер загружает файл Javascript, он не будет загружать другие элементы страницы параллельно, пока не завершится загрузка Javascript. Это означает, что вашим изображениям и тому, что не нужно ждать, поэтому обычно считается, что лучше переместить сценарии внизу, но если ваш сценарий маленький, я бы не стал беспокоиться об этом.

0 голосов
/ 27 мая 2009

Я предпочитаю создать страницу plugin.master, которая наследуется от вашего основного Site.master. Идея состоит в том, что вы вставляете эти плагины в plugin.master и создаете примерно 8 страниц, которые будут использовать это частичное представление для наследования от plugin.master.

0 голосов
/ 27 мая 2009

Это похоже на похожий (хотя и не совсем) вопрос. Плохо ли возвращать частичные представления, содержащие javascript?

0 голосов
/ 27 мая 2009

Разработчики MVC пережили много проблем, чтобы помешать нам использовать отстающие коды, но, создав файл с именем .aspx.cs и соответствующим образом изменив атрибут наследования страницы aspx, все еще возможно чтобы получить их.

Я бы сказал, что лучшее место для размещения включения было бы в обработчике Page_Load в коде (используя Page.ClientScript.RegisterClientScriptInclude).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...