我的 Javascript 应该去哪里查看组件?
Where should my Javascript go for View Components?
我已经习惯了 view components in MVC 6, and I asked a similar question a few years ago about partial views. If I build a view component encapsulating a common use-case that requires its own Javascript, where do I put that Javascript? I know that it is dangerous at best 在部分视图中使用 Javascript,但是将其包含在视图组件中而不是在包含视图或视图中要简单得多包含视图必须引用的单独文件。
例如,假设我有一个包含两个下拉菜单的视图组件。第一个下拉列表中的选择决定了第二个下拉列表中显示的项目。当然,这在 Javascript 中很容易处理,但是我应该把它放在哪里呢?
根据我使用 ASP.NET 5 View Components 的经验,我认为对它们做的最好的事情是将它们隔离并放在一个地方,这样它们就很容易在 long-term 项目。
在我的一个 ASP.NET 项目中,我开发了如下所示的视图组件结构:
视图、后端代码和模型都在一个地方,所以当你在文件夹中移动时,你肯定会移动整个组件。此外,当您修改它们时,您可以快速访问它们的所有部分。
把JavaScript这种与组件高度耦合的也放在这样的结构中会很方便。您可以通过简单地在组件的文件夹下创建文件,然后编写 GULP TASK 来将 JS 文件复制到 wwwroot。从那时起,您将能够 link 使用标准语法在组件的 .cshtml 上 JavaScript 代码:
<script src="~/Components/yourcomponent.js"></script>
为了在我的项目中获得这样的结构,我扩展了 Razor,以便能够在适当的位置搜索我的组件的 CSHTML。为此,我在 Startup.cs:
中添加了这段代码
public partial class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//non relevant code skipped
services.AddMvc().AddRazorOptions(ConfigureRazor);
}
public void ConfigureRazor(RazorViewEngineOptions razor)
{
razor.ViewLocationExpanders.Add(new ViewLocationExpander());
}
}
ViewLocationExpander class 是:
public class ViewLocationExpander : IViewLocationExpander
{
protected static IEnumerable<string> ExtendedLocations = new[]
{
"/{0}.cshtml"
};
public void PopulateValues(ViewLocationExpanderContext context)
{
//nothing here
}
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
//extend current view locations
return viewLocations.Concat(ExtendedLocations);
}
}
然后,您像这样调用组件(从任何 .cshtml 视图):
@await Component.InvokeAsync("NavigationComponent",new NavigationComponentModel())
我已经习惯了 view components in MVC 6, and I asked a similar question a few years ago about partial views. If I build a view component encapsulating a common use-case that requires its own Javascript, where do I put that Javascript? I know that it is dangerous at best 在部分视图中使用 Javascript,但是将其包含在视图组件中而不是在包含视图或视图中要简单得多包含视图必须引用的单独文件。
例如,假设我有一个包含两个下拉菜单的视图组件。第一个下拉列表中的选择决定了第二个下拉列表中显示的项目。当然,这在 Javascript 中很容易处理,但是我应该把它放在哪里呢?
根据我使用 ASP.NET 5 View Components 的经验,我认为对它们做的最好的事情是将它们隔离并放在一个地方,这样它们就很容易在 long-term 项目。
在我的一个 ASP.NET 项目中,我开发了如下所示的视图组件结构:
视图、后端代码和模型都在一个地方,所以当你在文件夹中移动时,你肯定会移动整个组件。此外,当您修改它们时,您可以快速访问它们的所有部分。
把JavaScript这种与组件高度耦合的也放在这样的结构中会很方便。您可以通过简单地在组件的文件夹下创建文件,然后编写 GULP TASK 来将 JS 文件复制到 wwwroot。从那时起,您将能够 link 使用标准语法在组件的 .cshtml 上 JavaScript 代码:
<script src="~/Components/yourcomponent.js"></script>
为了在我的项目中获得这样的结构,我扩展了 Razor,以便能够在适当的位置搜索我的组件的 CSHTML。为此,我在 Startup.cs:
中添加了这段代码public partial class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//non relevant code skipped
services.AddMvc().AddRazorOptions(ConfigureRazor);
}
public void ConfigureRazor(RazorViewEngineOptions razor)
{
razor.ViewLocationExpanders.Add(new ViewLocationExpander());
}
}
ViewLocationExpander class 是:
public class ViewLocationExpander : IViewLocationExpander
{
protected static IEnumerable<string> ExtendedLocations = new[]
{
"/{0}.cshtml"
};
public void PopulateValues(ViewLocationExpanderContext context)
{
//nothing here
}
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
//extend current view locations
return viewLocations.Concat(ExtendedLocations);
}
}
然后,您像这样调用组件(从任何 .cshtml 视图):
@await Component.InvokeAsync("NavigationComponent",new NavigationComponentModel())