如何避免将javascript放入此EditorTemplate?

如何避免将javascript放入此EditorTemplate?,javascript,asp.net-mvc,razor,asp.net-mvc-4,razor-2,Javascript,Asp.net Mvc,Razor,Asp.net Mvc 4,Razor 2,我写了以下EditorTemplate,它松散地基于其他一些SO问题和Google结果: @model Nullable<DateTime> @{ var metadata = ModelMetadata.FromStringExpression("", ViewData); string value; if(!String.IsNullOrEmpty(metadata.EditFormatString)) { if(Model.HasValu

我写了以下EditorTemplate,它松散地基于其他一些SO问题和Google结果:

@model Nullable<DateTime>
@{
    var metadata = ModelMetadata.FromStringExpression("", ViewData);
    string value;
    if(!String.IsNullOrEmpty(metadata.EditFormatString)) {
        if(Model.HasValue) {
            value = String.Format(metadata.EditFormatString, Model.Value);
        }
        else {
            value = metadata.NullDisplayText;
        }
    }
    else {
        value = Model.ToString();
    }
}
@Html.TextBox("", value, new { @class = "textBoxDate" })
<script type ="text/javascript">
    $(document).ready(function () {
        $('.textBoxDate').datepicker();
    });
</script>
@模型可为空
@{
var metadata=ModelMetadata.FromStringExpression(“,ViewData”);
字符串值;
如果(!String.IsNullOrEmpty(metadata.EditFormatString)){
if(Model.HasValue){
value=String.Format(metadata.EditFormatString,Model.value);
}
否则{
value=metadata.NullDisplayText;
}
}
否则{
value=Model.ToString();
}
}
@TextBox(“,value,new{@class=“textBoxDate”})
$(文档).ready(函数(){
$('.textBoxDate').datepicker();
});

我不喜欢的是,脚本会在每个
textBoxDate
的下面编写。我理解为什么,我知道一个可能的解决方案是将脚本放到一个.js文件中,并在我的页面上引用它。这不是很难,但我希望能有一个解决办法,再多一点。。。无缝/魔术(为什么?有趣,很整洁,因为…)。有什么想法吗?

我认为将脚本放入.js文件并在页面上引用它是解决此问题最有趣、最简洁的方法

如果您正在寻找一个不太整洁的解决方案,那么可以添加几个HtmlHelper扩展,以便在模板引擎遇到注册表依赖项时添加它们,然后在页面末尾打印出一组脚本标记

private const string requiredJavascriptIncludesContextItemsKey = "requiredJavascriptIncludesContextItemsKey";

public static void Require(this HtmlHelper html, string src)
{
    var collection = (HashSet<string>) html.ViewContext.HttpContext.Items[requiredJavascriptIncludesContextItemsKey] ?? new HashSet<string>();
    collection.Add(src);
    html.ViewContext.HttpContext.Items[requiredJavascriptIncludesContextItemsKey] = collection;
}

public static HtmlString RequiredJavascriptIncludes(this HtmlHelper html)
{
    var sb = new StringBuilder();
    foreach (var src in (HashSet<string>) html.ViewContext.HttpContext.Items[requiredJavascriptIncludesContextItemsKey] ?? new HashSet<string>())
    {
        sb.Append(string.Format("<script type='text/javascript' src='{0}></script>", src));
    }

    return new HtmlString(sb.ToString());
}

然后,在基本模板页面的底部,调用
@Html.RequiredJavascriptIncludes()
,您注册的所有js依赖项将在Html文档的末尾呈现为脚本标记。

@Xander正确吗?我知道一个替代方案,我不一定知道这个替代方案是否“正确”。特别是考虑到MVC所做的所有“automagic”事情。我很好奇是否有什么方法可以在不编写javascript函数的情况下将
.datepicker()
应用于这些日期模型项。虽然不是我想要的,但这是一个有趣且详细的答案。它比您的具体案例要求的更通用,但它应该能处理你和其他类似的情况。如果您有时间尝试,请告诉我它对您的作用。如果我正确理解它的效果,这仍然会为每个日期选择器框打印一个脚本标记,否?否。因为集合存储在
HttpContext中。Items
哈希集
,通过
@Html.RequiredJavascriptIncludes()
呈现的集合是唯一的。因此,你可以调用
@Html.Require
方法多次,只要你想引用你的javascript文件,它只会呈现脚本一次。这是一个有趣的解决方案。我可能不使用,但它肯定回答了我的问题,并给了我一些其他的想法,如果我想的话,如何实现这一点。非常感谢。
@model Nullable<DateTime>
@{
    var metadata = ModelMetadata.FromStringExpression("", ViewData);
    string value;
    if(!String.IsNullOrEmpty(metadata.EditFormatString)) {
        if(Model.HasValue) {
            value = String.Format(metadata.EditFormatString, Model.Value);
        }
        else {
            value = metadata.NullDisplayText;
        }
    }
    else {
        value = Model.ToString();
    }
}
@Html.TextBox("", value, new { @class = "textBoxDate" })
@Html.Require(Html.Content("scripts/datepicker.js"))