英文:
ViewComponent: Do I need both the view and the component?
问题
I have a very simple view component. It is located in my ASP.NET Core project under /Views/Shared/Components/DisclosureCard. It currently consists of the files Default.cshtml and DisclosureCardViewComponent.cs, where the latter looks like this:
我有一个非常简单的视图组件。它位于我的ASP.NET Core项目中的/Views/Shared/Components/DisclosureCard目录下。它目前包括Default.cshtml和DisclosureCardViewComponent.cs两个文件,其中后者如下所示:
public class DisclosureCardViewComponent : ViewComponent
{
public IViewComponentResult Invoke(DisclosureCardViewModel disclosureCardViewModel) =>
View(disclosureCardViewModel);
}
This seems like an unnecessary "relay" to me. Is there any way I can get rid of DisclosureCardViewComponent.cs and just use Default.cs? When I try to use @await Component.InvokeAsync("DisclosureCard", disclosureCardViewModel)
without it I get the following exception:
这对我来说似乎是一个不必要的"中继"。有没有办法我可以摆脱DisclosureCardViewComponent.cs,只使用Default.cs?当我尝试在没有它的情况下使用@await Component.InvokeAsync("DisclosureCard", disclosureCardViewModel)
时,我会收到以下异常:
"System.InvalidOperationException: 'A view component named 'DisclosureCard' could not be found. A view component must be a public non-abstract class, not contain any generic parameters, and either be decorated with 'ViewComponentAttribute' or have a class name ending with the 'ViewComponent' suffix. A view component must not be decorated with 'NonViewComponentAttribute'.'"
英文:
I have a very simple view component. It is located in my ASP.NET Core project under /Views/Shared/Components/DisclosureCard. It currently consists of the files Default.cshtml and DisclosureCardViewComponent.cs, where the latter looks like this:
public class DisclosureCardViewComponent : ViewComponent
{
public IViewComponentResult Invoke(DisclosureCardViewModel disclosureCardViewModel) =>
View(disclosureCardViewModel);
}
This seems like an unnecessary "reelay" to me. Is there any way I can get rid of DisclosureCardViewComponent.cs and just use Default.cs? When I try to use @await Component.InvokeAsync("DisclosureCard", disclosureCardViewModel)
without it I get the following exception:
> "System.InvalidOperationException: 'A view component named 'DisclosureCard' could not be found. A view component must be a public non-abstract class, not contain any generic parameters, and either be decorated with 'ViewComponentAttribute' or have a class name ending with the 'ViewComponent' suffix. A view component must not be decorated with 'NonViewComponentAttribute'.'"
答案1
得分: 1
我认为Partial View 更适合你的需求,它是一个封装了模型但没有逻辑的视图。
要使用部分视图,创建一个名为_DisclosureCard.cshtml
的文件在Views/Shared
文件夹下,然后像这样调用:
@await Html.PartialAsync("_DisclosureCard", disclosureCardViewModel)
另外,你也可以使用标签辅助程序调用部分视图:
<partial name="_DisclosureCard" model="disclosureCardViewModel" />
英文:
I think a Partial View is a better fit for what you're after here, which is an encapsulated view with a model but no logic.
To use a partial view, create a _DisclosureCard.cshtml
file in Views/Shared
and then invoke like this:
@await Html.PartialAsync("_DisclosureCard", disclosureCardViewModel)
Alternatively, you can invoke the partial view using the tag-helper:
<partial name="_DisclosureCard" model="disclosureCardViewModel" />
答案2
得分: 0
当然可以。在这种情况下,您需要同时更改调用方式,共享文件夹中组件的名称也应为"Default",在其中应该有default.cshtml文件。请查看以下屏幕截图:
ViewComponents文件夹:
注意: 请记住,视图组件永远不会直接处理请求,我们总是需要一个中间类来从视图中调用它。
Shared文件夹:
当您尝试使用 @await Component.InvokeAsync("DisclosureCard", disclosureCardViewModel)
时,没有问题,您会收到以下异常消息:
您现在的错误很明显,也是预期的。因为您现在正在如下调用您的ViewComponent:
@await Component.InvokeAsync("DisclosureCard", disclosureCardViewModel)
在重命名ViewComponent后:
一旦您将您的ViewComponent从DisclosureCardViewComponent重命名为Default.cs,您需要如下调用它:
@await Component.InvokeAsync("Default", disclosureCardViewModel)
注意: 您应该保持组件的.cs文件名称不变。如果您的组件名称与之不同,您应该使用组件后缀来避免歧义。
输出:
注意: 如果您想了解更多有关View组件的详细信息,您可以在此查看我们的官方文档。
英文:
> Is there any way I can get rid of DisclosureCardViewComponent.cs and
> just use Default.cs?
Certainly you can. In that scenario, you would require to change the invocation way at the same time and your component name inside components under shared folder also should be Defult and within it you should have default.cshtml file. Have look on the following screenshot:
ViewComponents Folder:
Note: Remember that, view component never directly handles a request we always need a class in between to invoke it from view.
Shared Folder:
> When I try to use @await Component.InvokeAsync("DisclosureCard",
> disclosureCardViewModel) without it I get the following exception:
The error you are getting is pretty obvious and expected. Because, as you are now calling your ViewComponent as following:
@await Component.InvokeAsync("DisclosureCard", disclosureCardViewModel)
After Renaming viewComponent:
Once you would rename your viewComponent from DisclosureCardViewComponent to just Default.cs so you have to call it as following:
@await Component.InvokeAsync("Default", disclosureCardViewModel)
Note: You ought to matach your component.cs files name as it is. If your component name is different than you should use component Suffix to avaid ambiguity.
Output:
Note: If you would like to know more details on View components you could check our official document here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论