Ember.js本地存储保存购物车修改 解决数据刷新重置问题
问题根因
出现数据重置的核心原因有两个:
- 操作购物车数组时直接通过
.content拿到了原生数组引用,修改已有商品的quantity、price属性时是直接修改原生对象属性,没有走Ember.js的响应式更新API。ember-localstorage-addon只会监听被Ember响应式系统捕获的状态变更,直接改原生对象的操作不会触发插件的持久化逻辑,修改后的数据根本没有写入浏览器Local Storage,刷新页面时会从存储里读取旧值,自然出现重置。 - 添加新商品时调用的
addObject方法会触发Ember的数组变更通知,插件收到通知后会把当前数组全量写入存储,但之前直接修改的已有商品属性因为没触发过更新,存储里存的还是旧值,所以加新商品的时候也会把之前改的数量覆盖回初始值。
修复方案
- 禁止直接访问存储数组的
.content属性拿原生数组操作,所有对购物车条目、数组的修改必须通过Ember响应式API执行,确保本地存储插件能捕获到变更,实时写入Local Storage。 - 修改已有购物车条目的属性时,必须使用
set方法赋值,修改完成后主动触发数组变更通知,保证状态和本地存储同步。 - 给加购数量设置默认初始值,避免传入undefined导致价格、数量计算为NaN。
修复后完整代码
// app/service/shopping-cart.js import Service from '@ember/service'; import { set } from '@ember/object'; export default Service.extend({ // 确保itemsIds是通过ember-localstorage-addon声明的存储数组,初始值设为[] addItem(item) { const cartItems = this.itemsIds; const existItemIndex = cartItems.findIndex(cartItem => cartItem.id === item.id); if (existItemIndex !== -1) { const existItem = cartItems.objectAt(existItemIndex); // 累加数量和总价,用set修改属性触发响应式更新 const newQuantity = parseInt(existItem.quantity, 10) + parseInt(item.quantity, 10); const newTotalPrice = parseInt(existItem.price, 10) + parseInt(item.price, 10); set(existItem, 'quantity', newQuantity); set(existItem, 'price', newTotalPrice); // 替换数组对应位置元素,主动触发数组变更通知,确保本地存储写入更新 cartItems.replace(existItemIndex, 1, [existItem]); } else { cartItems.addObject(item); } } })
// app/controller/product.js import Controller from '@ember/controller'; export default Controller.extend({ quantity: 1, // 给数量选择器加默认值,避免undefined导致计算异常 actions: { addToItem(model) { const addQuantity = parseInt(this.quantity, 10) || 1; const cartItem = { id: model.id, title: model.title, price: addQuantity * model.price, quantity: addQuantity, images: model.images }; this.shoppingCart.addItem(cartItem); // 加购完成后可重置数量选择器为默认值 this.set('quantity', 1); } } })
验证方法
- 打开浏览器开发者工具,进入Application -> Local Storage面板,找到ember-localstorage-addon对应的购物车存储键,重复加购同一件商品时,确认存储里的数量、总价是实时更新的,不会停留在第一次加购的数值。
- 加购多件不同商品、重复加购同件商品后刷新页面,购物车数据和刷新前完全一致,不会出现重置。
- 可选优化:不建议在购物车条目中持久化存储累加后的总价,建议仅存储商品ID、加购数量,渲染时关联商品原数据实时计算小计和总价,避免多次累加出现浮点精度问题,也能同步商品的最新价格、标题等信息。
内容的提问来源于stack exchange,提问作者Santhana Krishna
相关产品推荐
相关产品推荐

