Ajax,旧值先出现,然后新值出现

Posted

技术标签:

【中文标题】Ajax,旧值先出现,然后新值出现【英文标题】:Ajax, the old value appears first and then the new one 【发布时间】:2021-04-04 09:18:06 【问题描述】:

我有 Session::flash 通知(bootstrap toasts),用于通知将产品添加到购物车:

@if(Session::has('add-product'))
<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center">
 <div class="toast fixed-top" role="alert" aria-live="assertive" aria-atomic="true" data-delay="3000">
  <div class="toast-header bg-success">
   <span class="mr-auto notif_text"></span>
   <button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
    <span aria-hidden="true">&times;</span>
   </button>
  </div>
 </div>
</div>
@endif

CartController 与 Session:flash:

public function addCart(Request $request, $id)
    $product = Product::find($id);
    $oldCart = Session::has('cart') ? Session::get('cart') : NULL;
    $cart = new Cart($oldCart);
    $cart->add($product, $product->id);

    $request = Session::put('cart', $cart);

    Session::flash('add-product', $product->name);

    return response()->json([
         'total_quantity' => Session::has('cart') ? Session::get('cart')->totalQty : '0',
         'notif_text' => 'Product' . Session::get('add-product', $product->name) . 'added to cart'
     ]);
  

和 Ajax 请求:

$(document).ready(function() 
  $('.product-icon-container').find('.ajaxcartadd').click(function(event) 
    event.preventDefault();
    $('.toast').toast('show');
    $.ajax(
      url: $(this).attr('href'),
      dataType: 'JSON',
      success: function(response) 
        $('.prodcount').html(response.total_quantity);
        $('.notif_text').html(response.notif_text); //!!!Here I load the notification text!!
      
    );
    return false;
  );
);

我的问题是如何确保不出现旧值,而是立即出现新值。

现在它是这样工作的: img_1

然后大约 1 秒后出现一个新的通知: img_2

如何解决这个问题?

【问题讨论】:

【参考方案1】:

首先像这样删除已经分配的值,然后将值分配给该类元素。

document.getElementsByClassName("prodcount").innerHTML = ""; // or $('.prodcount').innerHTML = "";
document.getElementsByClassName("notif_text").innerHTML = ""; // or $('.notif_text').innerHTML = "";
$('.prodcount').html(response.total_quantity);
$('.notif_text').html(response.notif_text);

【讨论】:

非常感谢您的帮助,但没有奏效。我会将其标记为正确的决定,也许它会帮助某人。对于我的情况,我找到了解决方案。我将在单独的评论中描述它。【参考方案2】:

我的情况的解决方案,也许有人会觉得它有用:

原因是在 ajax 状态为成功时添加产品(这是点击“添加到购物车”按钮的处理程序所在的位置)。

我正在使用引导 toast,它们包含在:

$('.toast').toast('show');

并且由于通知的包含不在 ajax 请求中,结果证明首先加载了一个空值或旧值,然后只加载了一个新值。

解决方案是将包含“bootstrap toasts”移动到 ajax 中:

$(document).ready(function() 
  $('.product-icon-container').find('.ajaxcartadd').click(function(event) 
    event.preventDefault();
    $.ajax(
      url: $(this).attr('href'),
      dataType: 'JSON',
      success: function(response) 
        $('.prodcount').html(response.total_quantity);
        $('.notif_text').html(response.notif_text); //!!!Here I load the notification text!!
        $('.toast').toast('show');//!!!I moved it here!!!
      
    );
    return false;
  );
);

但我刚才理解了一个细微差别。 Flash 消息并不总是异步加载,因为它们依赖于会话(如果我理解正确的话),如果您的用户第一次访问该站点,flash 将无法工作。因此,值得在没有 flash 的情况下显示消息:

引导祝酒词:

<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center">
 <div class="toast fixed-top" role="alert" aria-live="assertive" aria-atomic="true" data-delay="3000">
  <div class="toast-header bg-success">
   <span class="mr-auto notif_text"></span>
   <button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
    <span aria-hidden="true">&times;</span>
   </button>
  </div>
 </div>
</div>

购物车控制器:

public function addCart(Request $request, $id)
    $product = Product::find($id);
    $oldCart = Session::has('cart') ? Session::get('cart') : NULL;
    $cart = new Cart($oldCart);
    $cart->add($product, $product->id);

    $request = Session::put('cart', $cart);

    return response()->json([
         'total_quantity' => Session::has('cart') ? Session::get('cart')->totalQty : '0',
         'notif_text' => 'Product' . $product->name . 'added to cart'
     ]);
  

附:如果您想要与我的样式相同的 bootstrap toast,请将其添加到您的 css 中:

.toast
  max-width: none;

.toast.fixed-top
  margin-top: 30px;
  left: auto;
  right: auto;

.toast-header
  border: 0;
  padding: 0.75rem 1.25rem;
  color: #fff;
  border-radius: 0.25rem;

.close
  opacity: 1;
  color: #fff;
  text-shadow: 0 1px 0 #000;

.close:hover
  color: #fff;
  opacity: 0.5;

【讨论】:

【参考方案3】:

您可以在 ajax 调用中尝试最简单的方法。您也可以使用它来代替 toast:

      $('.prodcount').empty().show().html(response.total_quantity).delay(3000).fadeOut(300);

      $('.notif_text').empty().show().html(response.notif_text).delay(3000).fadeOut(300);

【讨论】:

以上是关于Ajax,旧值先出现,然后新值出现的主要内容,如果未能解决你的问题,请参考以下文章

Ext.net 行编辑旧值和新值

SQL Server 2017 触发器将旧值作为更新后的新值

如何在 C# 中 PropertyChanged 事件的 INotifyPropertyChanged 实现中捕获旧值和新值

如何在ruby中获取旧值和新值之间的差异

SQL 用新值替换旧值

Symfony2 表单验证器 - 在刷新之前比较旧值和新值