我目前对此有看法:
但是,每当我向购物车中添加商品时,它都不会自动更新计数。仅在刷新页面时。
如何使它自动更新?它在_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>
...
答案 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>