我尝试在视图组件的视图中添加一个section脚本。
@section scripts {
<script src="~/somepath" asp-append-version="true"></script>
}
我在共享布局中也有渲染部分
@RenderSection("scripts", required: false)
在部分视图和项目中的其他位置使用时,脚本加载正常。但是,在View Component中,脚本不会加载。
我想我可以将脚本包含在调用组件的每个视图的section标签中。我觉得这不符合视图组件的自包含特性。
我还有其他办法吗?
答案 0 :(得分:4)
我在viewcomponents中也遇到了section标签的问题。事实证明,据我所知,在viewcomponents中没有它的支持。见https://github.com/aspnet/Home/issues/2037
Jake Shakesworth实施了一个标签助手,如下所示: Javascript in a View Component
另一方面,您可以将它作为
包含在viewcomponent中<script defer src"...">
</script>
我的要求是从viewcomponent显示谷歌地图。问题是脚本在jquery,jquery.ui之前调用了 通过使用延迟,您告诉解析器在文档加载之前不执行它,从而避免了必须将其放入布局以便正确执行的问题。 延迟由chrome,safari支持,即(10+),ff(3.6 +),o(15+)
希望这有帮助
这是我的代码示例:
@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>
}
请注意,如果视图组件在页面上出现多次,您可能需要编写一些逻辑来防止脚本被多次包含,这不是我的情况
答案 1 :(得分:1)
从我看到的情况来看,ViewComponent中的.bio, .web {
position: relative;
}
会被忽略,并且不会在"@section Scripts {}"
的相关@RenderSection()
中呈现
为什么我不知道。
答案 2 :(得分:1)
这就是我使用 Asp.net core 2.0 将脚本插入视图组件的方法。
首先,我创建了一个局部视图,我将其置于视图组件视图文件夹中。
路径:观看/共享/组件/ CalendarWidget / _CalendarScriptsPartial.cshtml
<强> _CalendarScriptsPartial.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>
然后,我通过视图组件视图中的Html部分异步辅助方法引入了脚本。
路径:观看/共享/组件/ CalendarWidget / Default.cshtml
<强> Default.cshtml 强>
<section id="calendar"></section>
@await Html.PartialAsync( "Components/CalendarWidget/_CalendarScriptsPartial" )
为了完整起见,这里是我的视图组件类。
路径: ViewComponents / CalendarWidgetViewComponent.cs
<强> CalendarWidgetViewComponent.cs 强>
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace LodgersChoice.ViewComponents
{
public class CalendarWidgetViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync( )
{
return View( );
}
}
}
注意:我的示例中当前不需要Async,但我打算将一个存储库注入到将使用async / await的类的ctor中。
注意2:一旦我完成了这项工作,我计划将所有内容捆绑并缩小为一个脚本。
答案 3 :(得分:0)
ASP.NET Core中的视图组件的作用类似于具有单独控制器的独立视图,因此您可以在视图组件上方插入波纹管标签
@{
Layout = null;
}
在插入波纹管标签后使用相关脚本,例如:
<environment include="Development">
<script src="~/js/chart.js"></script>
</environment>
<environment exclude="Development">
<script src="~/js/chart.min.js"></script>
</environment>
答案 4 :(得分:0)
@section脚本{}将被Asp.Net渲染引擎忽略并且不进行渲染。因此,只需在视图组件的末尾使用。另外,如果在布局的末尾指定了jquery脚本,则jquery在视图组件中将不可用。当然,将jquery脚本移到layout的head部分可以解决该问题,但建议最后加载js文件。
因此,如果您希望将jquery脚本保留在布局的末尾并且仍在视图组件中使用jquery,则可以使用javascript domcontentloaded,并且可以将jquery写入domcontentloaded内。这不是永久的好方法,但对我有用。
<script>
document.addEventListener('DOMContentLoaded', function (event) {
console.log($ === jQuery)
});
</script>
或者如@Alberto L. Bonfiglio所述,您还可以尝试将脚本移动到另一个JS文件并推迟将其加载到viewcomponent中:
<script src="viewComponentScript.js" defer></script>
答案 5 :(得分:0)
我正在范围服务中注册 ViewComponents 脚本,然后在布局中的脚本部分之后呈现注册的脚本。
ViewComponentsService.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();
}
答案 6 :(得分:0)
如果在页面完全加载后被渲染的模态或其他元素中的控制器调用了 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");}
将无法加载并导致正确发布表单的问题。