【问题标题】:ASP.NET Directive Convention for Declaring Client-Side Includes用于声明客户端包含的 ASP.NET 指令约定
【发布时间】:2011-07-12 10:20:45
【问题描述】:

我将 .aspx 和 .ascx 文件加载为 StreamReader

我希望每个文件在 <%@ ClientDependency path="~/Scripts/jquery-1.4.1.min.js" %> 之类的声明中注册它的 javascript 和样式表依赖项。

是否有现有的惯例来做这样的事情?我不需要实现,但如果已经有办法,我不想创建新语法。

另外,ASP.NET 中自定义<%@ 块的准则是什么?

另外,如果您能想到更合适的描述,请重新标记此问题。

【问题讨论】:

  • 请详细说明您在做什么以及为什么?阅读 .aspx 文件有什么意义?
  • 我正在使用 ASP.NET MVC,并且我将我的客户端包含在压缩的编译格式中。我正在将文件及其必要的包含在数据库中。我不想在部分视图中使用
  • 考虑到每个视图都可能依赖于 jquery,但只有某些小部件会依赖于 jquery ui。如果我没有在我的页面上显示其中一个依赖于 jqueryui 的小部件,那么我不想承担包含该脚本的开销。如果这仍然不清楚,请告诉我。
  • @John Saunders,你有更好的方法来解决这个问题吗?
  • @John Saunders,这不是 MVC 特定的。我只是在寻找一个客户端包含注册约定。你觉得我描述的方法有什么问题吗?

标签: javascript asp.net asp.net-mvc-2 server-side-includes page-directives


【解决方案1】:

目前没有使用指令注册客户端包含的约定。我的解决方案是创建一个自定义服务器控件,并使用现有的TemplateParser 功能来获取包含数据(这最终比将文件作为流加载并自己解析更好)。

【讨论】:

    【解决方案2】:

    基本上...

    这是我在当前 MVC 项目中所做的:

    • 使用 Telerik 的 Web 资产管理器在 Master Page 中注册我所有的常用脚本和 CSS,我知道这些脚本和 CSS 将在每​​个页面上使用 (有一个开源下载,如果像我一样,你没有'不知道)

    • 我将所有 JS 功能(除了几行之外)封装到存储在适当的外部 JS 文件中的函数中。

    • 我将所有扩展的 UI 功能封装到 HTML 帮助程序中。然后,他们使用 StyleSheetRegistrar 和 ScriptsRegistrars 动态加载该特定帮助程序所需的任何额外 CSS 或 JS。并且依靠 Telerik 管理器不要多次加载它们。

    • 如果我曾经使用过内联样式,我会通过 htmlAttributes 对象在 Helper 方法中手动指定样式标签,但这种情况很少见。

    • 为了调用 HTML 元素所需的 javascript 功能,我使用 ScriptRegistrar().OnDocumentReady() 的字符串重载来指定调用该元素的 javascript 函数。

    • 我还在 HtmlHelpers 类中为 ScriptRegistrarBuilder 定义了一个简单的扩展方法,它允许我提供参数的参数列表以传递给我的 javascript 方法调用,调用 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)
        );
    %>
    

    然后在正文结束标记上方的某个位置:

    <%:
       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>
    

    【讨论】:

    • 在两个注册上使用 Combined(true) 和 Compress(true)。这样,您只需为每个包含集合发送一个 HTTP 请求,而不是为每个单独的包含发送一个 HTTP 请求。
    • @smartcaveman 绝对在我要做的事情清单上。顺便说一句,难道仅仅通过组合资源,它们也被隐式压缩了吗?以为我在某个地方的 Telerik 网站上读到了这个。无论如何,同意。
    • 没有。查看您发布的生成的代码示例。共有三个脚本标签。每个都需要一个单独的 HTTP 请求,每个链接标签也是如此
    • @smartcaveman 针对合并请求进行了编辑。不过,我的意思是,一旦你的请求被正确组合,我相信你不需要调用 Compress(),组合的调用会自动压缩。
    • 刚刚确认使用了萤火虫。至少看起来是这样……太困了,我可能是错的。
    【解决方案3】:

    【讨论】:

    • 感谢您的资源。我正在使用类似的东西。但是,这对注册没有帮助。
    • +1 - 脚本加载器无疑是一个有用的工具。问题是它仍然需要不可接受的内联 javascript。
    猜你喜欢
    • 2023-01-11
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    相关资源
    最近更新 更多