Invoke ViewComponents using javascript
Asked Answered
I

2

5

Im trying to Invoke ViewComponent using javascript to facilitate page loading,now i invoked viewcomponent using razor but the loading of page taking long time, how to do that?

Here is the method in controller:

public async Task<IViewComponentResult> InvokeAsync(string id)
{
    //var notifications = _context.Notifications.Include(m => m.ApplicationUser).Include(m => m.Sender).OrderByDescending(m => m.Id);

    return View(await _context.Follows.Include(f=>f.User.University).Include(f=>f.User.Faculty).Where(n=>n.FollowedUserId==id).ToListAsync());
}

and method call (jQuery):

<script>
    $(document).ready(function () {
        $('#viewallfollowers').click(
            function () {

                $("#followersrefresh").load("@await Component.InvokeAsync("Follower", new { id=Model.ApplicationUser.Id })");

              });
    });
</script>
Ilona answered 4/5, 2020 at 22:54 Comment(0)
S
15

ViewComponent cannot be loaded directly in InvokeAsync in js, it will get the corresponding html when your page loads instead of when the click event is triggered, so your page will load for a long time, that is because of an error in your js.

In order to realize the click event to load the viewcomponent view, you need to use the ajax get request in the click event to apply to the controller to return the html code of the viewcomponent.

Controller:

 public IActionResult GetMyViewComponent(string uid)
        {
            return ViewComponent("Follower", new { id = uid});//it will call Follower.cs InvokeAsync, and pass id to it.
        }

View:

@model WebApplication_core_mvc.Models.MyCompModel
@{
    ViewData["Title"] = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Index</h1>

@section Scripts{
    <script>
   $(document).ready(function () {
        $('#viewallfollowers').click(function () {
            {
                $("#followersrefresh").empty();
                var _url = '@Url.Action("GetMyViewComponent", "Home")';
                $.ajax({
                    type: "GET",
                    url: _url,
                    data: { uid: $(this).prop("name") },
                    success: function (result) {
                        $("#followersrefresh").html(result);
                    },
                });
            }
        });
    });
    </script>
}
<input id="viewallfollowers" type="button" value="button" name="@Model.ApplicationUser.Id"/>
<div id="followersrefresh" >
</div>

ViewComponents.Follower.cs:

 public class Follower : ViewComponent
    {
        private readonly MyDbContext _context;
        public Follower(MyDbContext context)
        {
            _context = context;
        }
        public async Task<IViewComponentResult> InvokeAsync(string id)
        {
            return View(await _context.Follows.Include(f=>f.User.University).Include(f=>f.User.Faculty).Where(n=>n.FollowedUserId==id).ToListAsync());
        }
    }

Here is the test result: enter image description here

Senescent answered 5/5, 2020 at 3:7 Comment(5)
thanks alot for your effort ,this is a perfect answer, i just want to tell you that i have changed ajax code with code from my own , i dont know why your ajax cod didnt call "GetMyViewComponentAsync" method successfully,and another thing ,the name of method in controller is"GetMyViewComponentAsync" and in ajax code the name of method "GetMyViewComponent" so there is a different with name in controller and ajax,Ilona
here is my (jQuery , ajax) code,if you dont mind ,just replace it with the part of ajax in your answer ,because i want to mark your answer as best answerIlona
$(document).ready(function () { $('#viewallfollowers').click(function () { { $("#followersrefresh").empty(); var _url = '@Url.Action("GetMyViewComponent", "Home")'; $.ajax({ type: "GET", url: _url, data: { uid: $(this).prop("name") }, success: function (result) { $("#followersrefresh").html(result); }, }); } }); });Ilona
@mohammedalani1991, I set GetMyViewComponent to be an asynchronous operation, of course there is no effect here, async can be deleted, and I have updated my answer to be consistent with your jquery code, and the test results are feasible, you can re-reference.Senescent
This definitely will work, but it also needlessly complicates things. Why not just return a partial view from the controller?Diplomatic
R
1

View component is essentially a razor page and a razor page renders html at run time. So, you can’t invoke it using js. But, you can do a redirect to a get action in your controller and return a view component. Check similar SO:

Invoke ViewComponent using javascript

Rheinlander answered 5/5, 2020 at 2:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.