首页 > 解决方案 > 在视图上自动更新 ViewComponent

问题描述

我目前有这个观点:

大车

但是每当我向购物车添加东西时,它都不会自动更新计数。仅当我刷新页面时。

我怎样才能让它自动更新?它在 _Layout 视图上有一个视图组件。

购物车视图组件

public class CartViewComponent : ViewComponent
    {
        private readonly ApplicationDbContext _context;
        private readonly SignInManager<UserModel> _signInManager;
        private readonly UserManager<UserModel> _userManager;

        public CartViewComponent(
            ApplicationDbContext context, 
            SignInManager<UserModel> signInManager, 
            UserManager<UserModel> userManager)
        {
            _context = context;
            _signInManager = signInManager;
            _userManager = userManager;
        }

        public int CheckIfOrderExists()
        {
            var userId = Request.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);

            OrderMain orderMain = _context.OrderMains.Where(o => o.user_id == userId).FirstOrDefault();
            if (orderMain != null)
            {
                return orderMain.id;
            }
            else
            {
                return 0;
            }

        }

        public int CountItemsInShoppingCart(int order_id)
        {
            var result = (from orderlines in _context.OrderLines
                          join items in _context.Items on orderlines.item_id equals items.id
                          join ordermains in _context.OrderMains on orderlines.order_id equals ordermains.id
                          where orderlines.order_id == order_id
                          select orderlines).Count();

            return result;
        }

        public IViewComponentResult Invoke()
        {
            int order_id = CheckIfOrderExists();
            int count = CountItemsInShoppingCart(order_id);
            ViewBag.count = count;

            return View(ViewBag.count);
        }
    }

默认.cshtml

<span class="badge">@ViewBag.count</span>

_Layout.cshtml

...
<li>
    <a asp-area="" asp-controller="ShoppingCart" asp-action="Index">
        <span style="color:black;" class="glyphicon glyphicon-shopping-cart"></span>
        @await Component.InvokeAsync("Cart")
    </a>
</li>
...

标签: c#htmlrazorasp.net-core-mvcasp.net-core-viewcomponent

解决方案


这里有一个服务器端和客户端组件。首先,视图组件只是服务器端的东西。一旦它被渲染并且服务器将响应返回给客户端,它是一个视图组件的事实是完全无关紧要的。它的所有客户端都是 DOM 中的节点集合。

在客户端,如果您只想使用来自服务器的新信息更新页面的某些部分,则需要发出 AJAX 请求。这背后的 JavaScript 对象XMLHttpRequest,就是您所说的“瘦客户端”。它只是发出请求并接收响应,但它不做任何事情,如渲染、向 DOM 添加东西等。这取决于您作为开发人员来确定如何处理来自服务器的响应以及如何处理它。

在这方面,您有几个选择。首先,您可以让服务器返回带有一些 HTML 的部分内容。您不能直接请求或返回您的视图组件,因此您需要一个返回的操作PartialView,以及一个调用您的视图组件的相应部分视图:

public IActionResult GetCart() =>
    PartialView("_Cart");

然后,在_Cart.cshtml

@await Component.InvokeAsync("Cart");

然后,在对 AJAX 请求的回调中,您将选择页面上现有的“Cart”父元素,并将其替换为从服务器返回的新 HTML。

第二个选项是简单地使用一个端点,将当前购物车项目计数作为 JSON 返回。例如:

{
    "items": 3
}

然后,在您的 AJAX 回调中,您可以将徽章的文本替换为该数字。


推荐阅读