[英]How to keep script in partial view from loading more than once and causing errors when partial is used more than once in the same page
在 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 id=@ViewBag.id></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 輔助擴展 function ,它只會加載一次腳本。 見下文。 (這也適用於 CSS 和其他包含的文件)。
為每個 HttpContext 實現 HtmlHelper class 和私有支持 class 的擴展作為 singleton。
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 和其他代碼分離到單獨的文件中。
Example.js 文件內容
class MyClass{
myFunction() {
constructor(divId){
this._divId = divId
}
doSomething() {
// do something with a div with id == divId
}
}
}
Example.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")
使用局部視圖的 Example.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 被多次聲明。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.