我在会话中存储了一个购物车数组:
我让我的用户可以选择要删除的所有项目,也可以通过复选框选择单个项目。
我通过表单发送数组索引到arrayDeleteAt
。
现在如果我选择底部的3个项目,它就不会删除它。
这是我的删除代码:
<cfif isDefined("form.leadId") AND listLen(form.leadId)>
<cfloop from="#listLen(form.leadId)#" to="1" step="-1" index="i">
<cfset temp = arrayDeleteAt(session.shoppingcart, #i#)>
</cfloop>
</cfif>
答案 0 :(得分:7)
这种管理购物车的方法会遇到更多问题。使用ArrayDeleteAt后,将重新计算数组的索引,因此当您很可能从数组中删除错误的项时,或者在尝试删除超出范围的项时可能会出错。
看到你试图通过列表向后工作来解决这个问题,但Dan对于你上面代码的问题是正确的,但是如果列表以错误的顺序传递,那么你就是受伤的世界。
我建议使用带有代理键的结构(例如UUID),而不是使用数组,然后通过该键删除项目。
答案 1 :(得分:5)
问题是你在计数器的位置删除,而不是正在传入的表单字段。请尝试改为:
<cfset temp = arrayDeleteAt(session.shoppingcart, ListGetAt(FORM.leadID, i) />
更新:要解决Tyler提到的问题,您可以使用FORM.leadID
然后ListToArray
将索引列表从ArraySort
转换为数组,以便按照必要的顺序将它们转换为确保你的删除是正确的。
虽然我的回答确实解决了你的问题,但你肯定会更好地遵循泰勒的建议,并为购物车中的每件商品使用钥匙,以确保你管理的是你认为自己应该管理的那个:)
答案 2 :(得分:0)
在CF 10或Railo 4中,可以使用most recent version的Underscore.cfc library完成此操作:
<cfscript>
if (structKeyExists(form, 'leadId') && listlen(form.leadId)) {
_ = new Underscore();
variables.shoppingCart = duplicate(session.shoppingCart);
variables.newCart = _.reject(variables.shoppingCart, function(val, index){
return _.include(form.leadId, index);
});
}
</cfscript>
<cfif structKeyExists(variables, "newCart") >
<cflock scope="session" type="exclusive" timeout="10">
<cfset session.shoppingCart = variables.newCart>
</cflock>
</cfif>
你会看到我正在将购物车复制到变量范围,编辑它,然后在必要时将其复制回(带锁)。如果可以在cfscript中编写cflocks,我会在cfscript中完成所有这些。
(免责声明:我写过Underscore.cfc)