21

I have a viewcomponent that contains some reusable business logic that embed in various pages. This has been working fine. However, I now have a requirement to refresh the viewcomponent using ajax.

Is there any way to accomplish this? From what I have read, it is not possible, although that info was a bit outdated. If it is not possible, what is the best alternative?

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
czuroski
  • 4,316
  • 9
  • 50
  • 86
  • Just as a thought.. ajax need a url to get fresh content. Which means adding an action in the controller. That action could have a view which invokes the ViewComponent. – eadam Sep 17 '15 at 09:48

1 Answers1

37

On beta7 it is now possible to return a ViewComponent directly from a controller. Check the MVC/Razor section of the announcement

The new ViewComponentResult in MVC makes it easy to return the result of a ViewComponent from an action. This allows you to easily expose the logic of a ViewComponent as a standalone endpoint.

So you could have a simple view component like this:

[ViewComponent(Name = "MyViewComponent")]
public class MyViewComponent : ViewComponent
{
    public IViewComponentResult Invoke()
    {
        var time = DateTime.Now.ToString("h:mm:ss");
        return Content($"The current time is {time}");
    }
}

Create a method in a controller like:

public IActionResult MyViewComponent()
{
    return ViewComponent("MyViewComponent");
}

And do a better job than my quick and dirty ajax refresh:

var container = $("#myComponentContainer");
var refreshComponent = function () {
    $.get("/Home/MyViewComponent", function (data) { container.html(data); });
};

$(function () { window.setInterval(refreshComponent, 1000); });

Of course, prior to beta7 you could create a view as the workaround suggested by @eedam or use the approach described in these answers

Community
  • 1
  • 1
Daniel J.G.
  • 34,266
  • 9
  • 112
  • 112
  • Thanks for this answer. Due to a bit of a time crunch, I just went the route of returning a partialView from my controller which solved my issue. I may go back and refactor to this solution when we move to beta 7. – czuroski Sep 17 '15 at 13:40
  • Hi ! Can you post a detailed example of your javascript ? Can't we use old @Ajax helper ? – Christophe Gigax Apr 14 '16 at 12:22
  • As far as I know, the ajax helpers are still part of [their backlog](https://github.com/aspnet/Mvc/issues/2015). Regarding the JS, the 3rd code snippet is the most simple JS you would need to refresh the part of the html containing the view component – Daniel J.G. Apr 17 '16 at 09:45
  • would have been perfect except that,its rendering the layout. How do i make it render without layout/ – Layinka Jun 07 '16 at 14:10
  • I have just tried the solution above in RC1 and didn't return the layout. Are you using RC1 or RC2? Have you tried the exact code above or do you have additional extra code? – Daniel J.G. Jun 07 '16 at 14:30
  • Why not returning Json objects when incoming request is AJAX? This way you don't need to transfer the view for each individual request. @DanielJ.G. – Sirwan Afifi May 07 '17 at 15:24
  • Yes, that makes sense and probably is what I would do most of the times. But its a separated discussion from the original question. – Daniel J.G. May 08 '17 at 11:53
  • Not sure if I am doing something wrong, or if the latest .NET core doesn't allow it... but when I try to return ViewComponent, I get "non-invocable member viewcomponent cannot be used like a method" I see someone else with the same problem https://github.com/aspnet/Mvc/issues/7051 – Primico Oct 24 '18 at 16:43
  • Worked fine for me on VS2019 Core 3.1. Thanks – Barnsley Jun 11 '20 at 06:07