LocalStorage продолжает возвращать удаленные значения - PullRequest
0 голосов
/ 14 июля 2020

Я использую API локального хранилища для хранения товаров в корзине, но у меня возникла проблема. Сначала, когда я добавляю в него элемент, он работает нормально, а когда я удаляю элемент, он работает нормально. но когда я пытаюсь добавить один элемент в корзину, localStorage возвращает все удаленные элементы.

Ниже приведены две функции:

  • AddToCart() - для добавления элемента из домашняя страница и отдельная страница товара,
  • removeFromCart() - удалить товар из корзины.
function AddToCart(){
  // Home page 
  var data = JSON.parse(localStorage.getItem('zysod_cart'))
  $('.addcart').on('click', function(){
    var $this = $(this).closest('.single-product-content')
    var productId = parseInt($this.attr('data-product-id'))
    var productName = $this.find('.product-title').text()
    var productImg = $this.attr('data-product-src')
    var productPrice = $this.find('.product-price .regular-price').text()
    var found = data.products.some(function(el){
      return parseInt(el.id) === productId
    })

    if (!found) {
      data.items = parseInt(data.items) + 1;          
      data.products.push({
        id: productId,
        name: productName,
        quantity: 1,
        image: productImg,
        price: productPrice
      });
      var total = 0
      for(var item in data.products){
        total += (data.products[item].price === 'Price not available'? 0 : parseInt(data.products[item].price.replace(',','').slice(1))) * data.products[item].quantity
      }
      data.total = total
      localStorage.setItem('zysod_cart', JSON.stringify(data));
      UpdateCart()
    } else {
      for (var i = 0; i < data.products.length; i++) {
        if (parseInt(data.products[i].id) === productId) {
          data.products[i].quantity = parseInt(data.products[i].quantity + 1);
          var total =0;
          for(var item in data.products){
            total += (data.products[item].price === 'Price not available'? 0 : parseInt(data.products[item].price.replace(',','').slice(1))) * data.products[item].quantity
          }
          data.total = total              
          localStorage.setItem('zysod_cart', JSON.stringify(data));
          UpdateCart()
        }
      }

    }
  })
  // Single Product Page
  $('.h-addcart').on('click',function(){
    var $this = $(this).closest('.single-product')
    var productId = parseInt($this.attr('data-product-id'))
    var productName = $this.find('.product-title').text()
    var productImg = $this.attr('data-product-src')
    var productPrice = $this.find('.product-price .price-sale').text()
    var found = data.products.some(function(el){
      return parseInt(el.id) === productId
    })

    if (!found) {
      
      data.items = parseInt(data.items) + 1;          
      data.products.push({
        id: productId,
        name: productName,
        quantity: 1,
        image: productImg,
        price: productPrice              
      });
      var total =0;
      for(var item in data.products){
        total += (data.products[item].price === 'Price not available'? 0 : parseInt(data.products[item].price.replace(',','').slice(1))) * data.products[item].quantity
      }
      data.total = total          
      localStorage.setItem('zysod_cart', JSON.stringify(data));
      
    } else {
      for (var i = 0; i < data.products.length; i++) {
        if (parseInt(data.products[i].id) === productId) {
          data.products[i].quantity = parseInt(data.products[i].quantity + 1);
          var total =0;
          for(var item in data.products){
            total += (data.products[item].price === 'Price not available'? 0 : parseInt(data.products[item].price.replace(',','').slice(1))) * data.products[item].quantity
          }
          data.total = total              
          localStorage.setItem('zysod_cart', JSON.stringify(data));
          
        }
      }

    }

  })
}

function removeFromCart(){
  $(document).on('click','.dropcart__product-remove',function(){        
    var $this = $(this).closest('.dropcart__product')
    var productId = parseInt($this.attr('data-product-id'))
    var data = JSON.parse(localStorage.getItem('zysod_cart'));        
    data.products = $.grep(data.products, function (e) {
      if(e.id == productId){
        data.total-= e.price === 'Price not available'? parseInt(0): (parseInt(e.price.replace(',','').slice(1))*parseInt(e.quantity))
      }
      return e.id != productId;
    }); 
      data.items = data.products.length
      localStorage.setItem('zysod_cart', JSON.stringify(data));          
      
    })
}

1 Ответ

1 голос
/ 14 июля 2020

Это потому, что data считывается один раз при вызове AddToCart.

function AddToCart() {
   var data = JSON.parse(localStorage.getItem('zysod_cart'))
   // ...
}

ℹ️ Это из-за замыканий, которые относятся к самой верхней переменной data в верхний прицел. Подробнее о закрытии читайте в статье Mozilla Developer Network .

Если вы хотите решить эту проблему, вы должны читать data из localStorage каждый раз, когда вы меняете данные, как вы это делаете в removeFromCart() внутри каждого click обработчика событий:

function removeFromCart(){
  $(document).on('click','.dropcart__product-remove',function(){        
    var $this = $(this).closest('.dropcart__product')
    var productId = parseInt($this.attr('data-product-id'))
    var data = JSON.parse(localStorage.getItem('zysod_cart')); 
    // ...
  })
}

⚠️ Следует отметить, что несколько вкладок могут одновременно обновлять localStorage, что может вызвать конфликты. Чтобы избежать этого, рекомендуется использовать SharedWorker для синхронизации различных вкладок.

Совет

Я бы предложил сделать ваш код модульным и поддерживаемым, если это необходимо. Вы можете разделить обработку событий и манипуляции с localStorage, например:

class Storage {
  constructor(name, data) {
    this.name = name
    if (data) {
      this.save(data)
    } else {
      if (name in localStorage) {
        this.data = JSON.parse(localStorage.getItem(name))
      } else {
        this.save({})
      }
    }
  }
  
  save(data) {
    this.data = data
    this.updateStorage()
  }

  updateStorage() {
    localStorage.setItem(this.name, JSON.stringify(this.data))
  }
}

const storage = new Storage('zysod_cart')

function bindAddToCart(storage) {
  $('#addButton').on('click', function () {
     // Copy data
     const data = {...storage.data}
     
     // Add cart logic here ...

     // Save changes

     storage.save(data)
  })
}

function bindRemoveFromCard(storage) {
  $('#removeButton').on('click', function () {
     // Copy data
     const data = {...storage.data}

     // Remove card logic here ...

     // Save changes
     storage.save(data)
  })
}

Но учтите, что на странице должен быть только один экземпляр Storage со значением name zysod_cart.

...