gpt4 book ai didi

javascript - 使用部分 View 从多个位置引用相同的 js 文件

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:30:57 27 4
gpt4 key购买 nike

我正在为 MVC6 应用程序设置架构,并且我严重依赖 ViewComponents。我的目标是让每个 ViewComponent 都有自己的 javascript 部分,但是阅读 here rendersection 不适用于 ViewComponents,因此我一直在尝试以其他方式进行。

在我的_Layout.cshtml

我在 body 标签结束之前有这部分:

  @{Html.RenderPartial("_LayoutScriptsPartial"); }

_LayoutScriptsPartial

<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js">
</script>

<script src="~/js/app.min.js" asp-append-version="true"></script>
</environment>

现在在我位于/Views/Shared/Components/MyComponent/Default.cshtml 的一个组件中,我引用了另一个包含此内容的部分 View ,它用于轮播 ViewComponent

 @model MyProj.MyViewModel
@{Html.RenderPartial("_LayoutScriptsPartial"); }

@if (!string.IsNullOrEmpty(Model.ImageUrl))
{


<script type="text/javascript">

var cssClass= "@Model.cssClass";
var imageUrl = "@Model.ImageUrl";

webbCore.carouselSetBackgroundImage(cssClass, imageUrl);

</script>

}

我必须这样做的唯一原因是让所有必需的 js 文件都可用于我的 View 组件。如您所见,我多次引用 _LayoutScriptsPartial。当我使用 chrome f12 调试并观看网络部分时,我没有看到多次下载相同的 javascript 文件。我仍然对这个解决方案有不好的感觉。我环顾四周,没有找到任何我真正喜欢的处理 js 文件和 ViewComponents 的好的解决方案。像这样的东西会满足我的需要。

我的问题:这个解决方案有多好,优缺点是什么?有没有更好的方法来处理 js 文件和 ViewComponents?

最佳答案

您的问题的理想解决方案主要有 3 种情况:

  1. ViewComponent添加0次,相应的JavaScript库添加0次
  2. 添加1次ViewComponent,添加1次相应的JavaScript库,创建一次动态创建的初始化JavaScript,放在库之后。
  3. 多次添加ViewComponent,1次添加相应的JavaScript库,为每个ViewComponent创建动态创建的初始化JavaScript,都放在库之后。

因此在您的示例中,jquery 和 app.js 是您的库,而您动态创建的初始化 JavaScript 是在您的 <script type="text/javascript"> 中引用 @Model 的部分。标签。假设我们将您的组件添加到 View 中 3 次(我将用调用您的组件 3 次的 View 生成的 html 替换 @RenderBody()):

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MyProj.Web</title>

<environment names="Development,Staging,Production">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/lib/font-awesome/css/font-awesome.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/css/culture-flags.css" />
</environment>
</head>
<body>
<header>@Html.Partial("~/Views/Shared/_Header.cshtml")</header>
<main>
<nav></nav>
<article>
<div class="container body-content">
<!--@RenderBody()-->
<!--@await Component.InvokeAsync("MyComponent", new MyViewModel {cssClass="t1", ImageUrl="1.jpg"})-->
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
<script type="text/javascript">
var cssClass= "t1";
var imageUrl = "1.jpg";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
<!--@await Component.InvokeAsync("MyComponent", new MyViewModel {cssClass="t2", ImageUrl="2.jpg"}) -->
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
<script type="text/javascript">
var cssClass= "t2";
var imageUrl = "2.jpg";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
<!--@await Component.InvokeAsync("MyComponent", new MyViewModel {cssClass="t3", ImageUrl="3.jpg"}) -->
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
<script type="text/javascript">
var cssClass= "t3";
var imageUrl = "t3.jpg";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
</div>
</article>
<aside></aside>
</main>
<footer>@Html.Partial("~/Views/Shared/_Footer.cshtml")</footer>
<!-- These are the libraries that should only be loaded once -->
<environment names="Development,Staging,Production">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<!-- Ideally this is where the dynamically create scripts would go -->
@RenderSection("scripts", required: false)
</body>
</html>

如您所见,您将加载 jquery 库 4 次,一次用于布局,3 次用于 View 组件。任何好的浏览器都应该只下载一次文件,但会多次加载到内存中,并且只会多次覆盖相同的全局变量(例如 $)。

您可能还想将库移动到布局的顶部并从 View 组件中删除引用 but that is not a best practice either.

The main issue is that section doesn't work with ViewComponents and that appears to be by design.您应该将 ViewComponent 视为一个奇特的 html 助手。我还没有看到任何解决这个问题的好方法,但这里有一些想法。

  1. 在 View 中,在调用组件 (Component.InvokeAsync("MyComponent")) 之后,立即将 javascript 添加到 @section scripts {...}
  2. 创建一个库 js 来初始化这个组件并从元素中设置数据属性

$(".carousel").each(function() {
var css = $(this).data("carousel-css");
var image = $(this).data("carousel-image");
});

<input class="carousel" type=hidden data-carousel-css="@Model.cssClass" data-carousel-image="@Model.imageURL" />

关于javascript - 使用部分 View 从多个位置引用相同的 js 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43133775/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com