Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否可以通过编程方式将标记附加到<;头>;从城堡单轨车的车身内部/NVelocity?_Javascript_Css_Assets_Castle Monorail_Nvelocity - Fatal编程技术网

Javascript 是否可以通过编程方式将标记附加到<;头>;从城堡单轨车的车身内部/NVelocity?

Javascript 是否可以通过编程方式将标记附加到<;头>;从城堡单轨车的车身内部/NVelocity?,javascript,css,assets,castle-monorail,nvelocity,Javascript,Css,Assets,Castle Monorail,Nvelocity,我一直试图找到一种方法,通过编程将外部CSS文件的链接添加到Castle MonoRails和NVelocity视图引擎中的标记中的标记。有人知道怎么做吗 我需要解决这个问题,因为我所处理的页面可能包含许多“小部件”,每个小部件都会以最佳方式获取额外的资产,例如JS和CSS,而不是将放在body标签中,并冒着呈现问题的风险 多亏了Javascript,这才有可能!下面是我如何将样式附加到: var cssNode=document.createElement('link'); setAttri

我一直试图找到一种方法,通过编程将外部CSS文件的链接添加到Castle MonoRails和NVelocity视图引擎中的
标记中的
标记。有人知道怎么做吗


我需要解决这个问题,因为我所处理的页面可能包含许多“小部件”,每个小部件都会以最佳方式获取额外的资产,例如JS和CSS,而不是将
放在body标签中,并冒着呈现问题的风险

多亏了Javascript,这才有可能!下面是我如何将样式附加到


var cssNode=document.createElement('link');
setAttribute('rel','stylesheet');
cssNode.setAttribute('href','http://path.to/your/file.css');
setAttribute('type','text/css');
document.getElementsByTagName('head')[0].appendChild(cssNode);

您是说从视图将其添加到布局中吗?因为视图是在布局之前渲染的,这意味着如果您创建一个辅助对象来处理样式块的渲染,这将解决您的问题

也就是说,在视图或viewcomponent中,您可以调用如下内容:

$Style.Add("/static/style1.css")
$Style.Add("/static/style1.css")
在您的布局中(标题部分):

下面是一个示例帮助程序(继承AbstractHelper是可选的):

俘虏 我发现有一个组件正是我想要的

他认为:

#capturefor(capturefortest)
    Default way of printing. Use this for unique variables, such as title.
#end

#blockcomponent(CaptureFor with "id=capturefortest" "append=before")
    This will append before 1.
#end

#blockcomponent(CaptureFor with "id=capturefortest" "append")
    This will append after 1.
#end

#blockcomponent(CaptureFor with "id=capturefortest" "append")
    This will append after 1 and 3.
#end 

#blockcomponent(CaptureFor with "id=capturefortest") 
    Overrides everything defined before this. 
#end
版面/母版页: 逃逸: 例如,在jQuery ID选择器中,将#放入#blockcomponent(CaptureFor)中时,您将得到一个错误。这可以通过在AssetFilter中设置一些全局可用的变量并使用${HASH}打印#来避免。单引号和引号也很好:

controllerContext.PropertyBag.Add("HASH", "#");
controllerContext.PropertyBag.Add("Q", '"');
controllerContext.PropertyBag.Add("sq", "'");
现在,您可以安全地执行以下操作:

#blockcomponent(CaptureFor with "id=capturefortest" "append=before")
    <script type="text/javascript">
        jQuery('#container').html('Awesomeness!')
    </script>
#end
#blockcomponent(CaptureFor带有“id=capturefortest”“append=before”)
jQuery('#container').html('Awesomeness!')
#结束

此处发布的解决方案无法正常工作。更好的方法是将脚本添加到httpContext.Current.Items

使用与@jishi相同的结构:

在视图或viewcomponent中,您可以调用如下内容:

$Style.Add("/static/style1.css")
$Style.Add("/static/style1.css")
在您的布局中(标题部分):

您的助手由两个简单的方法组成,使用httpcontext存储和检索文件列表

    public class StyleHelper
{
    public static void Add(string file) {
        if (string.IsNullOrWhiteSpace(file))
            return;

        var obj = HttpContext.Current.Items["AssetFiles"] as List<string>; // get the collection which might be empty
        if (obj == null || obj.Count == 0) {
            IList<string> list = new List<string>();
            list.Add(file.ToLower());
            HttpContext.Current.Items.Add("AssetFiles", list); // adds your first asset to your collection and returns
            return;
        }

        if (obj.Contains(file.ToLower()))
            return; // asset is already added

        // new asset ready to be added to your collection
        obj.Add(file.ToLower());
        HttpContext.Current.Items.Add("AssetFiles", obj);
    }

    public string Render() {
        var obj = HttpContext.Current.Items["AssetFiles"] as List<string>;
        if (obj == null || obj.Count == 0)
            return ""; // you never added anything to the collection. Nothing more to do.

        // not using linq here for the sake of readability:
        string res = string.Empty;
        foreach (var item in obj) {
            res = res + string.Format("<link rel=\"stylesheet\" {0} />", item);
        }
        return res;
    }

}
公共类StyleHelper
{
公共静态无效添加(字符串文件){
if(string.IsNullOrWhiteSpace(文件))
返回;
var obj=HttpContext.Current.Items[“AssetFiles”]作为列表;//获取可能为空的集合
if(obj==null | | obj.Count==0){
IList list=新列表();
list.Add(file.ToLower());
HttpContext.Current.Items.Add(“AssetFiles”,list);//将第一个资产添加到集合中并返回
返回;
}
if(obj.Contains(file.ToLower()))
return;//已添加资产
//准备添加到收藏中的新资产
Add(file.ToLower());
HttpContext.Current.Items.Add(“AssetFiles”,obj);
}
公共字符串呈现(){
var obj=HttpContext.Current.Items[“资产文件”]作为列表;
if(obj==null | | obj.Count==0)
return“”;//您从未向集合中添加任何内容。无需更多操作。
//为了可读性,此处不使用linq:
string res=string.Empty;
foreach(obj中的var项目){
res=res+string.Format(“,项);
}
返回res;
}
}
在控制器(最好是基本控制器)中添加以下内容:

[Helper(typeof(StyleHelper),“Style”)]
public class YourController

JavaScript确实是一种方法,但在服务器端完成它更为理想。如果我们能够做到这一点,我会告诉您:)目前我们需要让它在不添加任何资产和多个(“节点”)的情况下工作。我们正在运行MonoRails 2.1,如果您知道在这个版本上它是可能的,请告诉我。谢谢为StyleHelper添加了一个简单的示例。我希望有帮助@jishi:在你的代码示例中,AbstractHelper的用途是什么?@Joakim:显然没什么,想想看。我从我们的StyleHelper中提取了相关部分,它可能利用了抽象类公开的一些功能。我猜我还假设我需要继承一些接口,以便在编写本文时将其注册为助手,我现在知道这是不必要的。谢谢你指出这一点!嗯,我不明白为什么需要将它们添加到Context.Items。助手对于当前请求是暂时的,因此内部状态足够好。我可以看出,如果将同一个助手同时添加到基本控制器和专用控制器中,它可能会中断。所以,出于好奇,你为什么要把它添加到上下文中呢?我遗漏了什么?这个老问题:)我真的不记得为什么我把它添加到context.items,但至少有一个巨大的好处,这取决于应用程序其余部分的设计;如果您不知道以前是否使用同一资产调用过该方法,则此代码确保您不会多次添加它:)妈的,7年后我甚至不再使用NVelocity/Monorail:)
#blockcomponent(CaptureFor with "id=capturefortest" "append=before")
    <script type="text/javascript">
        jQuery('#container').html('Awesomeness!')
    </script>
#end
$Style.Add("/static/style1.css")
$Style.Render()
    public class StyleHelper
{
    public static void Add(string file) {
        if (string.IsNullOrWhiteSpace(file))
            return;

        var obj = HttpContext.Current.Items["AssetFiles"] as List<string>; // get the collection which might be empty
        if (obj == null || obj.Count == 0) {
            IList<string> list = new List<string>();
            list.Add(file.ToLower());
            HttpContext.Current.Items.Add("AssetFiles", list); // adds your first asset to your collection and returns
            return;
        }

        if (obj.Contains(file.ToLower()))
            return; // asset is already added

        // new asset ready to be added to your collection
        obj.Add(file.ToLower());
        HttpContext.Current.Items.Add("AssetFiles", obj);
    }

    public string Render() {
        var obj = HttpContext.Current.Items["AssetFiles"] as List<string>;
        if (obj == null || obj.Count == 0)
            return ""; // you never added anything to the collection. Nothing more to do.

        // not using linq here for the sake of readability:
        string res = string.Empty;
        foreach (var item in obj) {
            res = res + string.Format("<link rel=\"stylesheet\" {0} />", item);
        }
        return res;
    }

}