javascript 我应该在哪里包含视图组件的脚本?

eulz3vhy  于 2023-02-18  发布在  Java
关注(0)|答案(7)|浏览(167)

我尝试在视图组件的视图中添加一个section脚本。

@section scripts {
    <script src="~/somepath" asp-append-version="true"></script>
}

共享布局中还有渲染部分

@RenderSection("scripts", required: false)

当在局部视图和项目的其他地方使用时,脚本加载正常。但是,当在视图组件中使用时,脚本不加载。
我想我可以在调用组件的每个视图的section标记中包含脚本,我觉得这不符合视图组件的自包含特性。
我还有别的办法吗?

xienkqul

xienkqul1#

我在视图组件中也遇到了sections标签的问题,据我所知,视图组件中没有对它的支持,请参见https://github.com/aspnet/Home/issues/2037
Jake Shakesworth实现了一个标记帮助器,如中所示:Javascript in a View Component
另一方面,您可以将其作为

<script defer src"...">
  </script>

我的要求是从视图组件中显示谷歌Map,问题是脚本在jquery,jquery. ui之前被调用。
通过使用defer,你可以告诉解析器在文档加载之前不要执行它,从而避免了为了正确执行而必须将它放入布局中的问题。chrome,safari和ie(10+),ff(3.6+),o(15+)支持defer
希望这能帮上忙
这是我的代码的一个例子:

@using MobileVet.WebApp.Services;
@inject ISettingsService SettingsService
@{
     var Options = SettingsService.Value();

    <!--Service Area-->
    <div class="container-fluid">
         <div class="row p-3">
            <!--First column-->
            <div class="col-md-3">
                <h5 class="title">Site Navigation</h5>
                <ul>
                    <li><a href="#!">Home</a></li>
                    <li><a href="#!">Services</a></li>
                    <li><a href="#!">Link 3</a></li>
                    <li><a href="#!">Link 4</a></li>
                </ul> 

            </div>
            <!--/.First column-->
            <hr class="w-100 clearfix d-md-none">

            <!--Second column-->
            <div class="col-md-9">

                <div id="map-canvas" style="min-height: 300px; min-width: 200px;"> 
                </div>
            </div>
            <!--/.Second column-->

        </div>
    </div>
    <!--Service Area-->

<script src="http://maps.google.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXXX&sensor=false"></script>
<script type="text/javascript" src="~/js/components/servicearea.js" defer ></script>

}

注意,如果视图组件在页面上出现多次,您可能需要编写一些逻辑来防止脚本被多次包含,但我的情况并非如此

o2rvlv0m

o2rvlv0m2#

从我所看到的情况来看,ViewComponent中的"@section Scripts {}"被忽略,并且不会在ViewComponents _*layout.cshtml的相关@RenderSection()中呈现
我不知道为什么会这样。

gywdnpxw

gywdnpxw3#

@section scripts { }在视图组件中被忽略,不会被ASP.NET渲染引擎渲染。所以只在视图组件的末尾使用。另外,如果你的jquery脚本在布局的末尾指定,那么jquery在视图组件中将不可用。当然,将jquery脚本移动到布局的head部分将解决这个问题,但建议在末尾加载js文件。
因此,如果你想在布局的最后保留jquery脚本,并且仍然在视图组件中使用jquery,你可以使用javascript domcontentloaded,任何jquery都可以在domcontentloaded中编写,这不是一个永久的好方法,但对我来说很有效。

<script>
    document.addEventListener('DOMContentLoaded', function (event) {
        console.log($ === jQuery)
    });
</script>

或者像@Alberto L. Bonfiglio提到的,你也可以试着把你的脚本移到另一个JS文件中,然后延迟加载到你的视图组件中:

<script src="viewComponentScript.js" defer></script>
izj3ouym

izj3ouym4#

这就是我使用Asp.netcore2.0将脚本插入视图组件的方法。
首先,我创建了一个局部视图,并将其放置在视图零部件视图文件夹中。
路径:* 视图/共享/组件/日历小部件/_日历脚本部分.cshtml*

_日历脚本部分.cshtml

<environment include="Development">
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/moment/moment.js"></script>
    <script src="~/lib/fullcalendar/dist/fullcalendar.js"></script>
    <script src="~/js/calendarWidget.js"></script>
</environment>
<environment exclude="Development">
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/moment/min/moment.min.js"></script>
    <script src="~/lib/fullcalendar/dist/fullcalendar.min.js"></script>
    <script src="~/js/calendarWidget.js"></script>
</environment>

然后,我通过视图组件视图中的Htmlpartialasynchelper方法引入脚本。
路径:* 视图/共享/组件/日历小部件/默认.cshtml*

默认.cshtml

<section id="calendar"></section>
@await Html.PartialAsync( "Components/CalendarWidget/_CalendarScriptsPartial" )

为了完整起见,这里是我的视图组件类。
路径:* 视图组件/日历小部件视图组件.cs*

日历小部件视图组件.cs

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace LodgersChoice.ViewComponents
{
    public class CalendarWidgetViewComponent : ViewComponent
    {
        public async Task<IViewComponentResult> InvokeAsync( )
        {
            return View( );
        }
    }
}

注意:在我的例子中,异步不是必需的,但是我打算将一个存储库注入到类的ctor中,该类将使用async/await。
注2:一旦我完成了这个开发,我计划捆绑和缩小到一个脚本的一切。

yeotifhr

yeotifhr5#

我在一个作用域服务中注册ViewComponents脚本,然后在布局中的脚本部分之后呈现注册的脚本。

查看组件服务.cs

using System;
using System.Collections.Generic;

namespace YourProject.Services
{
    public class ViewComponentsService
    {
        
        private readonly List<Func<object>> _scripts = new List<Func<object>>();

        public IEnumerable<Func<object>> Scripts {
            get { 
                foreach (var script in _scripts)
                {
                    yield return script;
                }
            }
        }
        
        // A dictionary could be used as type for the _scripts collection.
        // Doing so a script Id could be passed to RegisterScript.
        // Usefull if only one script per ViewComponent type needs to be rendered.
        public void RegisterScript(Func<object> script) {
            _scripts.Add(script);
        }

    }
}

不要忘记在启动时注册服务。

services.AddScoped<ViewComponentsService>();

视图组件示例

这里我们有ViewComponent和它的脚本在同一个文件中

@model UI.FailUserFeedback
@inject Services.ViewComponentsService _viewComponentsService

@{
    var modalId = UI.Utilities.RandomId();
    var labelId = UI.Utilities.RandomId();
}

<div class="modal fade" id="@modalId" tabindex="-1" aria-labelledby="@labelId" aria-hidden="true">
    @*omitted for brevity*@
</div>

@{
    // the script is written here
    Func<dynamic, object> RenderScript =
    @<script>
            (function () {
                var modal = new bootstrap.Modal(document.getElementById('@modalId'));
                modal.show();
            })();
    </script>;
    // and registered here
    _viewComponentsService.RegisterScript(() => RenderScript(this));
}

布局

@inject Services.ViewComponentsService _viewComponentsService
...
@await RenderSectionAsync("Scripts", required: false)
@foreach(var script in _viewComponentsService.Scripts) {
    @script();
}
ugmeyewa

ugmeyewa6#

在页面完全加载后,如果控制器在模态元素或其他元素中调用ViewComponent,defer也不起作用。相反,您必须将这些脚本放在父视图或_Layout中。在我的示例中,它是一个 AJAX 表单和

<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script src="~/lib/jquery-ajax-unobtrusive/jquery.unobtrusive-ajax.js"></script>

甚至@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}都不会被加载,从而导致正确发布表单的问题。

1zmg4dgp

1zmg4dgp7#

NET核心中的视图组件就像具有独立控制器的独立视图,因此您可以在视图组件上方插入bellow标记

@{
Layout = null;
}

之后插入bellow标签以使用相关脚本,例如:

<environment include="Development">

<script src="~/js/chart.js"></script>

</environment>
 <environment exclude="Development">

<script src="~/js/chart.min.js"></script>

</environment>

相关问题