在视图上自动更新ViewComponent

时间:2018-11-26 14:00:02

标签: c# html razor asp.net-core-mvc asp.net-core-viewcomponent

我目前对此有看法:

Cart

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

如何使它自动更新?它在_Layout视图上带有一个视图组件。

CartViewComponent

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);
        }
    }

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

2 个答案:

答案 0 :(得分:2)

这里有一个服务器端和客户端组件。首先,视图组件只是服务器端的东西。呈现后,服务器将响应返回给客户端,那么这完全是无关紧要的事实。客户端的全部是DOM中节点的集合。

客户端,如果要使用来自服务器的新信息仅更新页面的一部分,则需要发出AJAX请求。 XMLHttpRequest之后的JavaScript对象就是您所说的“瘦客户端”。它只是发出请求并接收响应,但它本身不执行任何诸如渲染,向DOM添加内容等操作。作为开发人员,您将确定如何处理服务器的响应以及如何处理。

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

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

然后,在_Cart.cshtml中:

@await Component.InvokeAsync("Cart");

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

第二个选项是简单地使用一个端点,该端点以JSON的形式返回当前购物车的商品数量。例如:

{
    "items": 3
}

然后,在您的AJAX回调中,您只需用该数字替换徽章的文本即可。

答案 1 :(得分:0)

我实际上是通过 jQuery get 函数而不是View Components来实现的。在get函数中,我从ShoppingCartController中检索public int TotalCount()

在_Layout部分视图上,我创建了jQuery脚本,一个用于呈现当前值,另一个用于每2秒更新一次值:

<script src="~/lib/jquery/dist/jquery.min.js">
</script>
<!-- rendering the current value -->
<script>
    $.get('/ShoppingCart/TotalCount', function (data) {
        $('#countCart').html(data);
    });
</script>
<!-- reloading the value every 2 seconds -->
<script>
    setInterval(function () {
        $('#countCart').load('/ShoppingCart/TotalCount');
    }, 2000)
</script>

并且徽章也在_Layout部分视图上:

<span class="badge" id="countCart"></span>