在ASP.NET MVC中工作,我创建了一个局部视图,该视图在同一页面上呈现了2次。我的问题是JavaScript包含局部视图的次数很多,并且JavaScript不喜欢要重新定义的类。
我的问题是:如何在部分视图中包含JavaScript,使其保持模块化,而仅将其包含在页面中一次?我对需要与部分视图内容分开包含.js文件的解决方案不感兴趣,例如
<script src="some.js"></script>
@Html.Partial("some/partial.cshtml")
@Html.Partial("some/partial.cshtml")
但是我可以接受包含在局部视图中的单独的.js文件。
我的代码的结构如下:
<div [email protected]></div>
<script>
class MyClass{
constructor(divName){
this._divId = divId;
}
doSomething(){
/* do stuff with element that has id of divId */
}
}
</script>
然后,在调用文件中,我有
<body>
@Html.Partial("/Views/MyPartial.cshtml", new ViewDataDictionary() { { "id", "id_1"} })
@Html.Partial("/Views/MyPartial.cshtml", new ViewDataDictionary() { { "id", "id_2"} })
</body>
<script>
$().ready(function(){
id1Functionality = new MyClass("id_1"); // please forgive the poor naming :-)
id2Functionality = new MyClass("id_2");
id1Functionality.doSomething();
id2Functionality.doSomething();
})
</script>
一种解决方案是实现HTML助手扩展功能,该功能只会加载一次脚本。见下文。 (这也适用于CSS和其他包含的文件)。
根据每个HttpContext将HtmlHelper类的扩展和私有支持类作为单例。
public static class YourHtmlHelperExtensionClass
{
private class TagSrcAttrTracker
{
private TagSrcAttrTracker() { }
public Dictionary<string, string> sources { get; } = new Dictionary<string, string>();
public static TagSrcAttrTrackerInstance {
get {
IDictionary items = HttpContext.Current.Items;
const string instanceName = "YourClassInstanceNameMakeSureItIsUniqueInThisDictionary";
if(!items.Contains(instanceName))
items[instanceName] = new TagSrcAttrTracker();
return items[instanceName] as TagSrcAttrTracker;
}
}
}
public static MvcHtmlString IncludeScriptOnlyOnce(this HtmlHelper helper, string urlOfScript)
{
if(TagSrcAttrTracker.Instance.sources.ContainsKey(urlOfScript))
return null;
TagSrcAttrTracker.Instance.sources[urlOfScript] = urlOfScript;
TagBuilder script = new TagBuilder("script");
scriptTag.MergeAttribute("src", urlOfScript);
return MvcHtmlString.Create(script.ToString());
}
}
然后,将JavaScript和其他代码分离到单独的文件中。
示例.js文件内容
class MyClass{
myFunction() {
constructor(divId){
this._divId = divId
}
doSomething() {
// do something with a div with id == divId
}
}
}
用于部分视图的示例.cshtml文件内容
<link rel="stylesheet" type="text/css" href="~/Content/CustomCSS/MyPartialView.css"/>
<div id="@ViewBag.id">
Some content! Yay!
</div>
@Html.IncludeScriptOnlyOnce("/Scripts/CustomScripts/MyPartialView.js")
使用部分视图的示例.cshtml文件
...
<body>
<h1>Here is some content!</h1>
@Html.Partial("/Views/MyPartial.cshtml", new ViewDataDictionary() { { "id", "id_1"} })
@Html.Partial("/Views/MyPartial.cshtml", new ViewDataDictionary() { { "id", "id_2"} })
@Html.Partial("/Views/MyPartial.cshtml", new ViewDataDictionary() { { "id", "id_3"} })
</body>
<script>
$().ready(
const id1Functionality = new MyClass("id_1") // forgive the poor naming :-)
const id2Functionality = new MyClass("id_3")
const id3Functionality = new MyClass("id_2")
id1Functionality.doSomething();
id2Functionality.doSomething();
id3Functionality.doSomething();
)
</script>
部分视图可能被包含多次,并且JavaScript与部分视图打包在一起,但是.js文件仅包含在页面中一次,因此浏览器不会抱怨MyClass被声明多次。 >