如何防止脚本在局部视图中多次加载,并且在同一页面中多次使用局部视图时导致错误 [英] 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

查看:123
本文介绍了如何防止脚本在局部视图中多次加载,并且在同一页面中多次使用局部视图时导致错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在ASP.NET MVC中,我创建了一个局部视图,该视图在同一页面上呈现了2次.我的问题是 JavaScript包含的视图与部分视图一样多,并且JavaScript不喜欢重新定义类.

Working in ASP.NET MVC, I created a partial view which is rendered on the same page 2 times. My problem is the JavaScript is included as many times as the partial view is and JavaScript does not like classes to be redefined.

我的问题是:如何在部分视图中包含JavaScript,以使其保持模块化,但仅将其包含在页面中一次?我对需要与部分视图内容分开包含.js文件的解决方案不感兴趣,例如

My question is: How do I include the JavaScript in the partial view so it remains modular, but only have it included in the page once? I am not interested in solutions which require including the .js file separately from the content of the partial view, like

<script src="some.js"></script>
@Html.Partial("some/partial.cshtml")
@Html.Partial("some/partial.cshtml")

但是我可以接受部分视图中包含的单独的.js文件.局部视图应在其中包含使其正常工作所需的一切.

but I am okay with a separate .js file that is included inside the partial view. The partial view should include within it everything that is needed to make it work.

我的代码的结构如下:

<div id=@ViewBag.id></div>
<script>
    class MyClass{ 
        constructor(divName){
            this._divId = divId;
        }

        doSomething(){
            /* do stuff with element that has id of divId */ 
        }
    }
</script>

然后,在调用文件中,我有

Then, in the calling file, I have

<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和其他包含的文件).

One solution is to implement an Html helper extension function which will only load a script once. See below. (this can work for CSS and other included files, too).

每个HttpContext的HtmlHelper类的扩展和私有支持类的实现.

Implement an extension for the HtmlHelper class and a private backing class as a singleton per HttpContext.

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和其他代码分成单独的文件.

Then, separate the JavaScript and other code into separate files.

.js文件示例内容

class MyClass{
    myFunction() {
        constructor(divId){
            this._divId = divId
        }

        doSomething() {
            // do something with a div with id == divId
        }
    }
}

用于部分视图的示例.cshtml文件内容

Example .cshtml file contents for partial view

<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文件

Example .cshtml file that consumes the partial view

...
<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被声明了多次.

The partial view may have been included more than once and the JavaScript is packaged with the partial view, but the .js file is only included in the page once, hence no complaining by the browser that MyClass was declared more than once.

这篇关于如何防止脚本在局部视图中多次加载,并且在同一页面中多次使用局部视图时导致错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆