0

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).

1
  • I would add a Scoped Service MyViewContext into the Dependency Injection Container, which will let you share some elements. If you need it, simple inject it. Commented Oct 24, 2017 at 0:00

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer @Christian. The concept of using constructor injection actually makes a lot of sense and I might have to give it a go and see if I like the result.
0

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.

More Reading

1 Comment

I agree with your thoughts on View Components. I never thought about using a template. I am currently using editor templates for other models, so no reason why I can't apply the same concept for a "component" on any view. Thanks for the tips

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.