clockwiseq
clockwiseq

Reputation: 4229

How To Create Reusable Component in ASP.NET Core with Javascript

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

Answers (2)

Erik Philips
Erik Philips

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.

More Reading

Upvotes: 0

Christian Gollhardt
Christian Gollhardt

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

Related Questions