1

在 Composite C1 中,我使用 Razor 语法来创建我的主布局。为了更快的加载时间,建议将脚本放在 end body 标记之前而不是 head 标记内。这就是为什么我将 jQuery 和其他脚本放在 end body 标记之前。

当我将 Razor 函数与引用 jQuery 的 JavaScript 一起使用时,我收到一个错误,因为尚未加载 jQuery。Razor 函数的 HTML 在加载 jQuery 脚本之前输出:

未捕获的 ReferenceError:$ 未定义

在 MVC 中,我可以在主布局中使用 RenderSection 来完成此操作(在我的主布局脚本下方渲染 JavaScript

@RenderSection("FooterScripts", false)

然后在我看来,我可以定义这样的部分:

@section FooterScripts {
    <script type="text/javaScript">
        $(function () {
            ...
        });
    </script>
}

这将在最终 HTML 中的正确位置呈现 HTML。这可以在复合 C1 中做到吗?即使 Intellisence 告诉我它可用,我也无法让 RenderSection 工作。

4

1 回答 1

4

没有内置方法可以将 html 标记从 C1 函数插入到布局中的特定位置。

实现您自己的逻辑的可能方法是:

  1. 将要插入的脚本收集到 fe Context.Items 集合中,最后插入。

  2. 实现一些后处理逻辑,在渲染后将脚本标签移动到页面底部。

第一种方法更容易实现,这是一个简短的工作示例:

C1 功能码:

@inherits RazorFunction
@using Composite.Examples

@functions {
}

@{
    LayoutHelper.AddDelayedScript(Script()); 
}

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
    Inserting a script at the bottom of a page
</body>
</html>


@helper Script() {
    <script type="text/javascript">
        alert("I'm inserted!");
    </script>
}

布局代码:

....


        @LayoutHelper.RenderDelayedScripts()
    </body>
</html>

LayoutHelper 类,在 App_Code 中定义:

using System.Collections.Generic;
using System.Text;
using System.Web;

namespace Composite.Examples
{
    public static class LayoutHelper
    {
        private const string HttpItems_Key = "delayedscripts";

        public static void AddDelayedScript(IHtmlString script)
        {
            var context = HttpContext.Current;

            lock (context.Items.SyncRoot)
            {
                if (!context.Items.Contains(HttpItems_Key))
                {
                    context.Items.Add(HttpItems_Key, new List<IHtmlString>());
                }

                (context.Items[HttpItems_Key] as List<IHtmlString>).Add(script);
            }
        }

        public static IHtmlString RenderDelayedScripts()
        {
            var context = HttpContext.Current;

            var sb = new StringBuilder();

            if (context.Items.Contains(HttpItems_Key))
            {
                foreach (var delayedscript in context.Items[HttpItems_Key] as IEnumerable<IHtmlString>)
                {
                    sb.Append(delayedscript.ToHtmlString());
                }
            }

            return new HtmlString(sb.ToString());
        }
    }
}
于 2013-09-03T14:50:55.700 回答