在视图上自动更新 ViewComponent

Posted

技术标签:

【中文标题】在视图上自动更新 ViewComponent【英文标题】:Auto update ViewComponent on view 【发布时间】:2018-11-26 14:00:01 【问题描述】:

我目前有这个观点:

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

我怎样才能让它自动更新?它在 _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>
...

【问题讨论】:

【参考方案1】:

这里有一个服务器端和客户端组件。首先,视图组件只是服务器端的东西。一旦它被渲染并且服务器将响应返回给客户端,它是一个视图组件的事实是完全无关紧要的。它的所有客户端都是 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 回调中,您只需将徽章的文本替换为该数字即可。

【讨论】:

【参考方案2】:

我实际上是使用 jQuery get 函数而不是视图组件来实现的。在 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>

【讨论】:

以上是关于在视图上自动更新 ViewComponent的主要内容,如果未能解决你的问题,请参考以下文章

在 xib 上,拖动视图将自动进入更大的视图

除非在视图上手动更新,否则不会自动触发视图上的更新触发器

无法自动更新表格视图

以编程方式修改自动布局约束时视图不更新

如何在使用 UIpageviewcontroller 导航页面时从另一个视图控制器自动更新视图控制器上的标签

iOS 自动布局过程