Связывание библиотек JavaScript в пользовательских элементах управления - PullRequest
8 голосов
/ 20 мая 2009

Я пользуюсь ASP.NET MVC около шести месяцев и проверяю пример Nerd Dinner, созданный этими парнями из Microsoft. Одна вещь, которую я заметил, когда они включили AJAX в RSVP на ужин, это вставка ссылок JavaScript в пользовательский элемент управления, используемый для RSVPing.
(ФАЙЛ: RSVPStatus.ascx)

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NerdDinner.Models.Dinner>" %>

<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>    

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

Поэтому я спрашиваю, правильное ли мое мышление, и эти ссылки на самом деле должны находиться в более центральном месте, например, на главной странице?

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

Ответы [ 2 ]

7 голосов
/ 20 мая 2009

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

HTHS, Charles

Ps. Я бы согласился с тем, что Эндрю сказал, что любой общий JS, определенный непосредственно внутри главной страницы, должен быть объединен и минимизирован.

РЕДАКТИРОВАТЬ: Моя реализация .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);
    }
0 голосов
/ 20 мая 2009

На моем веб-сайте www.trailbehind.com у нас есть набор файлов javascript, которые принадлежат всем страницам. А затем некоторые страницы включают дополнительные библиотеки.

Для файлов JS, которые используются на всех страницах (существует несколько десятков файлов), мы объединяем их и уменьшаем при сборке.

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

Вот наш код Python для объединения и минимизации:

import os
import thetrailbehind.lib.jsmin as jsmin

JS_FILES = [  'lib/json2.js',
              'lib/markermanager.js',
              'lib/labeledmarker.js',
              'lib/rsh/rsh.js', 
              'lib/showdown.js',
              'lib/yui.js',
              'lib/dragzoom.js',
              'gen/attribute_data.js', 
              'gen/national-parks.js', 
              'Widgets/CommentsWidget.js', 
              'Widgets/Search.js', 
              'Widgets/MenuWidget.js', 
              'Widgets/PhotoWidget.js', 
              'Widgets/ReportList.js', 
              'Widgets/help.js', 
              'attributes.js', 
              'rsh.js', 
              'map.js', 
              'mapcontrols.js',
              'markers.js',
              'amazon.js',
              'plan_trip.js', 
              'init.js',]


def concat(files, base_path, all_file, all_file_min):
  if os.path.exists(base_path + all_file):
    lasttime = os.path.getmtime(base_path + all_file)
  else:
    lasttime = 0
  out_of_date = False
  for file in files:
    if os.path.getmtime(base_path + file) > lasttime:
      out_of_date = True
      break
  if out_of_date:
    outfile = open(base_path + all_file, 'w')
    for file in files:
      outfile.write(open(base_path + file).read())
      outfile.write("\n")
    outfile.close()

    alljs = open(base_path + all_file)
    allminjs = open(base_path + all_file_min, "w+")
    jsmin.JavascriptMinify().minify(alljs, allminjs)
    alljs.close()
    allminjs.close()



def main():
  concat(JS_FILES, '/home/wibge/thetrailbehind/media/javascript/', 'gen/all.js', 'gen/all.min.js')


if __name__ == "__main__":
  main()

А вот шаблон Django / HTML, где мы переключаемся:

{% if use_all_js %}
  script type=text/javascript src=/site_media/javascript/gen/all.min.js> 
{% else %}
  script type="text/javascript" src="/site_media/javascript/rsh.js">
  script type="text/javascript" src="/site_media/javascript/amazon.js">
  script type="text/javascript" src="/site_media/javascript/map.js">  
  A BUNCH OF SEPARATE INCLUDES...etc
{% endif %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...