Соглашение директивы ASP.NET для объявления включений на стороне клиента

Я загружаю файлы .aspx и .ascx как StreamReader.

Я хочу, чтобы каждый файл регистрировал свои зависимости javascript и таблицы стилей в некотором объявлении, например <%@ ClientDependency path="~/Scripts/jquery-1.4.1.min.js" %>.

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

Кроме того, каковы рекомендации для пользовательских блоков <%@ в ASP.NET?

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


person smartcaveman    schedule 10.03.2011    source источник
comment
Пожалуйста, опишите подробнее, что вы делаете и почему? Какой смысл читать в файлах .aspx?   -  person John Saunders    schedule 10.03.2011
comment
Я использую ASP.NET MVC, и я храню свои клиентские включения в сжатом, скомпилированном формате. Я сохраняю файлы и их необходимые включения в базу данных. Я не хочу использовать теги ‹script› или ‹link› в своих частичных представлениях, потому что тогда они будут отображаться в строке, если я не реализую собственный ViewEngine. Итак, когда я читаю файлы, чтобы создать представление db для включений, мне нужно соглашение для определения того, какие активы ассоциировать с данным представлением.   -  person smartcaveman    schedule 10.03.2011
comment
Учтите, что каждое представление может иметь зависимость от jquery, но только определенные виджеты будут иметь зависимость от jquery ui. Если я не показываю один из этих зависящих от jqueryui виджетов на своей странице, то я не хочу нести накладные расходы на включение этого скрипта. Пожалуйста, дайте мне знать, если это все еще неясно.   -  person smartcaveman    schedule 10.03.2011
comment
@ Джон Сондерс, у тебя есть лучший способ решить эту проблему?   -  person smartcaveman    schedule 10.03.2011
comment
@Джон Сондерс, это не специфично для MVC. Я просто ищу соглашение о регистрации на стороне клиента. Видите ли вы какие-либо проблемы с подходом, который я описал?   -  person smartcaveman    schedule 10.03.2011
comment
@smart: я полагаю, что файлы .ascx могут использовать ЗарегистрироватьClientScriptBlock. Я не знаю, могут ли страницы .aspx сделать то же самое.   -  person John Saunders    schedule 10.03.2011


Ответы (3)


Рассматривали ли вы Google Loader или что-то вроде этого: Включение ASP.NET Загрузчик скриптов Ajax для ваших собственных скриптов

person rick schott    schedule 10.03.2011
comment
Спасибо за ресурс. Я использую нечто подобное. Однако это не помогает при регистрации. - person smartcaveman; 10.03.2011
comment
+1 - Загрузчик скриптов, безусловно, полезный инструмент. Проблема в том, что для этого по-прежнему требуется встроенный javascript, что неприемлемо. - person smartcaveman; 10.03.2011

В основном...

Вот что я делаю в своем текущем проекте MVC:

  • Использование Telerik Web Asset Manager для регистрации всех моих общих скриптов и CSS на главной странице, которые, как я знаю, будут использоваться на каждой странице (есть загрузка с открытым исходным кодом, если вы, как и я, не знали).

  • Я инкапсулирую все функции JS (кроме нескольких строк) в функции, хранящиеся в соответствующих внешних файлах JS.

  • Я инкапсулирую все свои расширенные функциональные возможности пользовательского интерфейса в помощники HTML. Затем они используют StyleSheetRegistrar и ScriptsRegistrars для динамической загрузки любых дополнительных CSS или JS, которые требуются для этого конкретного помощника. И полагайтесь на менеджера Telerik, чтобы он не загружал их более одного раза.

  • Если я когда-либо использую встроенные стили, я указываю тег стиля вручную внутри метода Helper через объект htmlAttributes, но это редко.

  • Чтобы вызвать мои функции javascript, необходимые для элемента HTML, я использую перегруженную строку ScriptRegistrar().OnDocumentReady(), чтобы указать функцию javascript для вызова этого элемента.

  • Я также определил простой метод расширения для ScriptRegistrarBuilder в моем классе HtmlHelpers, который позволяет мне предоставить список параметров аргументов для передачи в мой вызов метода javascript при вызове < strong>OnDocumentReady(), без кучи конкатенации строк.

    public static void OnDocumentReady(this ScriptRegistrarBuilder builder, string format, params string[] args)
    {
        builder.OnDocumentReady(String.Format(format, args));
    }
    
  • И, конечно же, я визуализирую все JS в нижней части главной страницы.

Здесь вы не избегаете всех случаев использования встроенного JS, но он делает его довольно тонким, если вы все делаете правильно. Честно говоря, я не могу придумать другого способа, который не стал бы слишком сложным.

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

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

К сожалению, еще не нашел способа обойти это.

Небольшой пример

Возможно, излишне подробно для вас ... но таким образом кто-то, кто ищет, может также найти полезное решение! :)

На главной странице:

<%
    Html.Telerik().StyleSheetRegistrar().DefaultGroup(styles => styles
       .Add("~/Content/Site.css")
       .Add("~/Content/core.css")
    );

    Html.Telerik().ScriptsRegistrar().DefaultGroup(scripts => scripts
        .Add("~/Scripts/common.js")
        .Combine(true)
        .Compress(true)
        .CacheDurationInDays(30)
    );
%>

Затем где-то чуть выше закрывающего тега body:

<%:
   Html.Telerik().ScriptsRegistrar().Render();
   Html.Telerik().StyleSheetsRegistrar().Render();
%>

В вашем HTML-помощнике:

    public static MvcHtmlString AutoCompleteComboListFor<TModel, TProperty>(this HtmlHelper<TModel> Helper, Expression<Func<TModel, TProperty>> expression,
        SelectList List, string DataSource)
    {
        MvcHtmlString dropDown = SelectExtensions.DropDownListFor<TModel, TProperty>(Helper, expression, List);

        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string id = Helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName);

        //Do whatever you want

        helper.Telerik().ScriptRegistrar().DefaultGroup(scripts => scripts
            .Add("~/Scripts/extended.js")
            );
        helper.Telerik().StyleSheetRegistrar().DefaultGroup(styles => styles
            .Add("~/Content/extended.css")
            );

        helper.Telerik().ScriptRegistrar().OnDocumentReady(@"MyExtendedFunction('{0}');", id);

        return dropDown;
    }

Простой вызов этого помощника (или любого другого) приведет к аккуратному блоку в конце страницы, содержащему весь код JS, файлы и файлы CSS.

<link type="text/css" href="/Content/Site.css" rel="stylesheet"/>
<script type="text/javascript" src="/asset.axd?id=kAAAAB-LCAAAAAAABADsvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee--997o7nU4n99__P1xmZAFs9s5K2smeIYCqyB8_fnwfPyJ-8Uezjx597xd_tPro0Uevp3WxapuPRh-d82dL-uynf9E6r6-3d8f79N9P47vqo0c7v2Qk3-bv2nw5y2f2m91f8v1f8v3RR9OWvmzp27s_nV1mDcOlBpf06d7O7s743nj33u4BfTKl3u99ep9--ehRW6_zX_L_BAAA___9S_3qkAAAAA%3d%3d"></script>

<script type="text/javascript"> 
//<![CDATA[
jQuery(document).ready(function(){
myFunction('Foo');});
//]]>
</script>
person Geekman    schedule 10.03.2011
comment
Используйте Combined(true) и Compress(true) для обеих регистраций. Таким образом, вам нужно отправить только один HTTP-запрос для каждой включаемой коллекции, а не для каждого отдельного включения. - person smartcaveman; 10.03.2011
comment
@smartcaveman определенно в моем списке дел. Хотя, кстати, не правда ли, что просто объединяя ресурсы, они также неявно сжимаются? Кажется, я прочитал это где-то на сайте Telerik. В любом случае договорились. - person Geekman; 10.03.2011
comment
Нет. Посмотрите на сгенерированный образец кода, который вы опубликовали. Есть три тега скрипта. Для каждого из них требуется отдельный HTTP-запрос, как и для каждого тега ссылки. - person smartcaveman; 10.03.2011
comment
@smartcaveman Отредактировано для комбинированных запросов. Однако я имел в виду, что как только ваши запросы будут правильно объединены, я считаю, что вам не нужно вызывать Compress(), объединенный вызов автоматически сжимается. - person Geekman; 10.03.2011
comment
Только что подтвердил с помощью firebug. По крайней мере, это выглядит так... так сонно, я могу ошибаться. - person Geekman; 10.03.2011

Не существует существующего соглашения для регистрации клиентских включений с помощью директивы. Мое решение состояло в том, чтобы вместо этого создать собственный серверный элемент управления и использовать существующую функциональность TemplateParser для получения включаемых данных (что оказалось предпочтительнее, чем загрузка файла в виде потока и его разбор самостоятельно).

person smartcaveman    schedule 11.03.2011