Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

Я не знаю о наилучшей практике, но я предпочитаю включать любые распространенные js-файлы внутри masterpage, а затем определять отдельный 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>

Привет, Чарльз

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);
    }

Другие советы

Причина, по которой вы разместили скрипт внизу страницы, заключается в том, чтобы убедиться, что dom был загружен, прежде чем пытаться выполнять какие-либо манипуляции.Это также может быть достигнуто с помощью чего-то вроде $(document).готово (обратный вызов);Метод 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, который может найти любой тег данных сервера:$(содержащий элемент).Данные сервера("loadScript");// возвращает массив декодированных объектов json, подобный jQuery.

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

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

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

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

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

Ниже приведен мой класс 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 будут отображать выходные данные еще до того, как вы добавите ссылку.

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

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

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

хейдиг.

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

<script src="@Url.Content(" ~="" Scripts="" User="" List.js")"="" type="text/javascript"></script>

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

/ИЗ

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top