簡體   English   中英

多個事件監聽器被添加到每個元素導致多個ajax調用

[英]Multiple event listener are added to each element resulting in multiple ajax call

我有一個購物車清單。 每個購物車都包含一個產品列表。

{# templates\Cart\list.twig #}
{% use 'Cart/details.twig' %}
{% extends '@templates/_base.twig' %}
   {% block body %}
      <div class="list-group" id="cart-list" role="tablist">
         {% for cart in cart_list %}
            <a class="products-list-cart list-group-item list-group-item-action {% if userCart.current %}active{% endif %}"
                               id="item-details-cart-{{ cart.id }}"
                               href="#products-list-cart-{{ cart.id }}"
                               data-href="{{ path('cart_product_list', {'cart_id':cart.id}) }}"
                               data-toggle="list" role="tab" aria-controls="products-list-cart-{{ cart.id }}"
                               {% if not first_cart %}data-product-list-loaded="true" {% set first_cart = true %}{% endif %}>
               See cart details for cart {{ cart.id }}
               {# 
                  On click, make an ajax call to filled
                  in product list '#products-list-cart-{{ cart.id }}'
               #}
            </a>
         {% endfor %}
      </div>
      <div class="tab-content" id="carts-content">
         {% for cart in cart_list %}
            {% set userCart = cart.userCart %}
            <div class="tab-pane fade {% if userCart.current %}show active{% endif %}"
                                 id="products-list-cart-{{ cart.id }}"
                                 role="tabpanel"
                                 aria-labelledby="cart-{{ cart.id }}">
               {% if not first_cart_product_list %}
                  {% block cart_details %}
                     {{ parent() }} 
                  {% endblock %}
               {% else %}
                  <i class="fa fa-cog fa-spin fa-1x fa-fw">&nbsp;</i> {{ "loading_product"|trans }}
                  ... {# 
                        Filled in on click on '.products-list-cart'.
                        Proceed to ajax call.
                      #}
               {% endif %}
            </div>
         {% endfor %}
      </div>
   {% endblock %}
{% endblock %}
{% block javascripts %}
    {{ parent() }}
    {{ encore_entry_script_tags('cart') }}
    {{ encore_entry_script_tags('product') }}
{% endblock %}

我盡量保持簡單,我使用list tab bootstrap component

當我必須包含入口點時,問題就來了。

因為我的 javascript 將事件偵聽器添加到產品詳細信息中。 因此,第一個購物車的所有產品詳細信息都可以正常工作,因為它們是在頁面加載時加載的。 此行為由first_cart_product_list變量管理。

當用戶單擊購物車以查看其詳細信息時,會顯示所有其他產品列表。 問題是包含 javascript 的入口點僅將事件添加到隨 dom 加載的元素。

我嘗試將入口點添加到我的Cart/details.twig模板,但它會在每次 ajax 調用時加載。 所以這里的問題是所有 ajax 調用都會向所有現有的$('a.products-list-cart')元素添加事件監聽器。 所以頁面上的很多元素都有越來越多的事件監聽器而不是一個。

我給你一個例子:如果我將encore_entry_script_tags添加到購物車詳細信息模板:

{# Cart/details.twig #}
{{ encore_entry_script_tags('product') }}

它會添加到每個產品列表中,因此:如果我有 4 個購物車:

在此處輸入圖片說明

我點擊每一個加載產品列表,在頁面上的每個產品上添加一個事件偵聽器。 所以對於第一個購物車,我將在每個產品元素上有 4 個事件偵聽器。

結果是,當我點擊第一個購物車的“添加到購物車”按鈕時:

在此處輸入圖片說明

有 4 次調用 ajax 函數將產品數量更新到購物車中。

// product.js entry point...
$(document).ready(
    function () {
        $('.btn-add-product-to-cart').on( // This event listener is added to every button on product list
            'click',
            function (e) {
                e.preventDefault();
                $.ajax({
                    method: 'POST',
                    url: $(this).data('href'),# Call controller route to modify product quantity in DB
                ...    

我嘗試使用.one()函數,因為我只想在每個元素上添加一個事件偵聽器。 但不幸的是它不起作用。

任何幫助將不勝感激。

我認為您可以在添加事件之前輕松完成.off事件。 對於點擊事件將是這樣的:

$('a.products-list-cart').off('click').click(function () { ... })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM