如何使用localStorage存储简单的购物车?

时间:2014-05-08 23:42:52

标签: javascript jquery

我正在尝试为我正在制作的原型项目创建一个javascript购物车。我意识到在这种情况下,像Angular / Knockout等MVC框架将是绝对完美的,但我仍然在学习如何使用它们,所以我不能将它们用于这个特定的项目。我也意识到我可以维护购物车服务器端,但在这种情况下这不是一个选项。

目前我有一个像这样的html产品列表:

<ul id="products">
  <li data-id="1" data-name="Product 1" data-price="10.00">
    <input type="text" /><br />
    <button>Add to cart</button>
  </li>
  <li data-id="2" data-name="Product 2" data-price="15.00">
    <input type="text" /><br />
    <button>Add to cart</button>
  </li>
  <li data-id="3" data-name="Product 3" data-price="20.00">
    <input type="text" /><br />
    <button>Add to cart</button>
  </li>
</ul>

在页面加载时,我创建了一个空的&#39;购物车&#39; localStorage中的对象如下:

var cart = {};
cart.products = [];

localStorage.setItem('cart', JSON.stringify(cart));

然后我将按钮元素的click事件绑定为:

$('button').on('click', function(e) {
    var product = $(this).parent();

    var quantity = $(product).find('input[type=text]').val();

    // Ensure a valid quantity has been entered
    if (!isValidInteger(quantity) === true) {
        alert('Please enter a valid quantity');
        return;
    }

    product.id = $(product).attr('data-id');
    product.name = $(product).attr('data-name');
    product.price = $(product).attr('data-price');
    product.quantity = quantity;

    addToCart(product);
});

然后我编写了一个addToCart()函数,该函数应该使用该产品并尝试将其推入“产品”中。数组是&#39; cart&#39;:

的属性
function addToCart(product) {
    // Retrieve the cart object from local storage
    if (localStorage && localStorage.getItem('cart')) {
        var cart = JSON.parse(localStorage.getItem('cart'));            

        cart.products.push(product);

        localStorage.setItem('cart', JSON.stringify(cart));
    } 
}

这不起作用,我收到错误:

Uncaught TypeError: Converting circular structure to JSON

我不明白我哪里出错了,有人能帮忙吗?

此外,一旦解决了这个问题,我对如何保持购物车的状态感到有些困惑。我希望我可以将所有数据存储在“购物车”中。 localStorage中的对象,存储产品ID,名称,价格和数量,然后在“购物车”中反映出来。 html中的div。如果添加/删除了商品,我会更新购物车&#39;对象在本地存储中,然后反映html中的更改。

有更简单的方法吗?我真的可以用一些指向正确的方向。

我再一次意识到使用Angular甚至维护状态服务器端将是一个最佳解决方案,但对于这个项目,我只能使用jquery / javascript,所以我需要在我的边界内工作。

谢谢!

2 个答案:

答案 0 :(得分:4)

您应该为产品项声明一个单独的对象。

$('button').on('click', function(e) {
    var li = $(this).parent();

    var quantity = $(li).find('input[type=text]').val();

    // Ensure a valid quantity has been entered
    if (!isValidInteger(quantity) === true) {
        alert('Please enter a valid quantity');
        return;
    }

    var product = {};
    product.id = $(li).attr('data-id');
    product.name = $(li).attr('data-name');
    product.price = $(li).attr('data-price');
    product.quantity = quantity;

    addToCart(product);
});

答案 1 :(得分:1)

从服务器渲染产品的过程。

function productSocket(doneFn,params){
                     $.ajax({
                           type:'GET',
                           url: "http://localhost:8080/"+params,
                           contentType: "application/json; charset=utf-8",
                           dataType: "json"
                     }).done(doneFn)
                       .fail(function(err){
           console.log("AJAX failed: " + JSON.stringify(err, null, 2));
                            });
    }

function productDoneFn(data){

  console.log("Okey done"+JSON.stringify(data));

  var productContainer=$('#productContainer');

  productContainer.empty();

  var productContent="";

  $.each(data ,function(i,e){

productContent+='<div class="col-md-4 col-sm-6">'+
                    '<div class="pr">'+
                        '<div class="pr-img-div">'+
                              '<a href="detail.html#store/public/parent/detail/'+e.id+'">'+
                                  '<img src="../fs/main/'+e.image+'" alt="" class="img-responsive">'+
                              '</a>'+
                        '</div>'+
                        '<div class="pr-text">'+
                          '<h3><a href="detail.html#store/public/parent/detail/'+e.id+'">'+e.nameEn+'</a></h3>'+
                          '<p class="price">$'+e.price+'</p>'+
                          '<p class="buttons">'+
                            '<a href="detail.html#store/public/parent/detail/'+e.id+'" class="btn btn-default">View detail</a>'+
                            '<a href="#" cartBtn pr_id='+e.id+' pr_name_en="'+e.nameEn+'" pr_price="'+e.price+'" pr_image="'+e.image+
                            '" class="btn btn-primary"><i class="fa fa-shopping-cart"></i>Add to cart</a>'+
                          '</p>'+
                        '</div>'+
                    '</div>'+
                '</div>';

  });

  productContainer.html(productContent);


}

这是一个元素,如按钮,用于将项目添加到购物车,以及用于保存在Web存储中的相应属性,如localStorage。

  
var productArray=[];


$(document).on('click','[cartBtn]',function(e){
  e.preventDefault();
  $(this).html('<i class="fa fa-check"></i>Added to cart');
  console.log('Item added ');
  var productJSON={"id":$(this).attr('pr_id'), "nameEn":$(this).attr('pr_name_en'), "price":$(this).attr('pr_price'), "image":$(this).attr('pr_image')};


  if(localStorage.getObj('product')!==null){
    productArray=localStorage.getObj('product');
    productArray.push(productJSON);  
    localStorage.setObj('product', productArray);  
  }
  else{
    productArray.push(productJSON);  
    localStorage.setObj('product', productArray);  
  }


});

Storage.prototype.setObj = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObj = function(key) {
    var value = this.getItem(key);
    return value && JSON.parse(value);
}

将JSON对象添加到Array后,结果为(在LocalStorage中):

[{"id":"99","nameEn":"Product Name1","price":"767","image":"1462012597217.jpeg"},
{"id":"93","nameEn":"Product Name2","price":"76","image":"1461449637106.jpeg"},
{"id":"94","nameEn":"Product Name3","price":"87","image":"1461449679506.jpeg"}]

执行此操作后,您可以轻松地将数据作为List中的Java发送到服务器。