Reputation: 4229
Since moving to MVC I have always wondered (and now am in need of) a reusable "component" that I can stick on any view that does something that is common to every view and include jQuery within that component. I'm talking about View Components and they are neat, but I have yet to come across a viable need for them (other than displaying an address or phone number). Nothing really interactive.
So, if I can't do this with a View Component, what do I do? I have a View Component that utilizes JavaScript, but that's only because I couldn't reference the section that I defined in my Layout. I've read dozens of articles that state that this is by design. Well, in my opinion, this is a poor design and locks these components to be non-interactive (or limited).
Upvotes: 0
Views: 994
Reputation: 54628
I have always wondered (and now am in need of) a reusable "component" that I can stick on any view
I think what you are looking for is templates. It's reusable in that models can have display and editor templates. It's pretty much as simple as:
Reusable:
public class Car
{
public string Model { get; set; }
}
Controller model:
public class IndexVM
{
public Car Car { get; set; }
}
index.cshtml
@model IndexVm
@Html.DisplayFor(m => m.Car)
shared/displaytemplates/car.cshtml
@model Car
@Html.DisplayFor(m => m.Model)
As for scripts, the idea of rendering only the JS needed died a long time ago. It's why Bootstrap has bootstrap.min.js, bootstrap.min.css. There isn't a good reason to not bundle everything together so the client can cache it all-at-once.
View Components I feel are kinda hacky in MVC. They are sort of this catch all that works in MVC and WebPages but wasn't really thought out.
Upvotes: 0
Reputation: 17004
Create a service:
public class MyViewContext
{
public bool IsJqueryRequired { get; set; }
public object MyAwesomeSharedObject { get; set; }
}
Then add it to the DI Container scoped (Scoped is created every new Request):
services.AddScoped<MyViewContext, MyViewContext>();
In your view you can access it this way:
@inject MyViewContext MyViewContext
Every where else by simple using constructor injection.
Another great option is using TagHelper and the TagHelperContext
. Here is an great article about it.
Upvotes: 1