HarmonyOS Next中实现嵌套购物车功能(下) 原创
一、背景
上一节我们实现了嵌套购物车的创建实体类、模拟数据的添加、嵌套商品列表的展示,以及底部自定义结算组件等功能,是不是觉得我们已经距离成功实现了一大步?看起来我们的模块已经有模有样,其实业务逻辑还有很多需要实现,我们需要对各种情况都要进行判断,最后真正的实现我们的嵌套购物车功能,我们最终要实现的内容如下:
二、业务逻辑分析
首先我们看单独条目距离功能还缺少什么内容?
从页面展示角度看,我们还缺少商品右侧的三个组件,商品添加和减少按钮、已添加的商品数量展示,我们来实现一下这部分内容
Blank()
Row(){
Text("-")
.border({width:1,color:Color.Gray,radius:5})
.width(30)
.height(20)
.textAlign(TextAlign.Center)
.onClick(()=>{
if (child.num==1) {
showToast("该宝贝不能减少了!")
}else {
child.num--
}
})
Text(String(child.num))
.padding({left:3,right:3})
Text("+")
.border({width:1,color:Color.Gray,radius:5})
.width(30)
.height(20)
.textAlign(TextAlign.Center)
.onClick(()=>{
child.num++
})
我们在实体类中已经把商品数量用装饰器@Trace进行修饰,所以我们可以监听到深层次数据的变化,我们直接使用child.num++或者child.num--页面就会同步我们的数据,我们来执行代码测试一下
可以看到我们的活动以及非活动商品的数量已经合理的展示,因为我们活动商品最多购买三台,其余部分就是原价商品,已添加商品数量展示也已经更新
三、品类及商品状态联动
我们已经实现了商品数量的添加和减少,并且成功运行,接下来我们就要梳理清楚当我们选择商品时,我们的选择按钮都需要实现什么内容,我们需要分清楚商品的选择,和品类的选择, 当我们选择品类的时候,品类是true的情况下 我们先要对商品状态进行便利,然后取消全部选中,当品类为false ,商品部分为true,品类不做变化,当商品全部为true ,这时候要控制上层的品类进行选中。这里的逻辑比较复杂,要设计多层计算我们来实现一下,因为逻辑都是根据选择按钮来实现的,所以我们需要在checkbox中实现
我们先实现外层
Checkbox({ name: 'checkbox1' + index, group: 'checkboxGroup'+index})
.selectedColor("#ffd95112")
.select(item.check)
.shape(CheckBoxShape.CIRCLE)
.onChange((value: boolean) => {
if (value) {
for (let i = 0; i < item.childList.length; i++) {
if (item.pos==item.childList[i].child_pos) {
item.childList[i].child_check=true
}
}
} else {
const hasFalseChildCheck = item.childList.some(child => !child.child_check);
if (hasFalseChildCheck) {
for (let i = 0; i < item.childList.length; i++) {
if (!item.childList[i].child_check) {
item.childList[i].child_check=false
}
}
}else {
for (let i = 0; i < item.childList.length; i++) {
if (item.pos==item.childList[i].child_pos) {
item.childList[i].child_check=false
}
}
}
}
})
.width(20)
.height(20)
外层的checkbox我们来进行内部商品状态的处理
我们接下来实现内层
Checkbox({ name: 'checkbox1' + child_index, group: 'checkboxGroup' + child_index })
.select(child.child_check)
.selectedColor("#ffd95112")
.shape(CheckBoxShape.CIRCLE)
.onChange((value: boolean) => {
if (value) {
item.childList[child_index].child_check=true
const hasFalseChildCheck = item.childList.some(child => !child.child_check);
if (!hasFalseChildCheck) {
item.check=true
}
}else {
item.check=false
item.childList[child_index].child_check=false
}
})
.width(20)
.height(20)
内层主要对商品状态自身做处理以及全选之后修改外层分类状态
可以看到当我们选择外层数码电器时,内层所有商品的checkbox全部选中
四、结算组件与商品逻辑串联
我们已经实现了品类和商品的选择,以及商品数量的加减,这时候我们就需要拿到当前所有已选中的商品价格和数量以及活动非活动商品价格和数量来进行一个计算,这时候我们的结算组件不能只是静态的展示,我们先改造一下我们的组件,让他可以显示已选中的商品数量以及价格。
Row(){
Column(){
Row(){
if (this.getSelectedChildCount()>0){
Text("已选"+this.getSelectedChildCount())
.fontSize(14)
.fontColor("#ffc1bebe")
}
Text(){
Span("合计:")
.fontSize(16)
Span("¥")
.fontSize(14)
.fontColor(Color.Orange)
.fontWeight(FontWeight.Bold)
Span(String(this.getCheckProductPrice()))
.fontSize(20)
.fontColor(Color.Orange)
.fontWeight(FontWeight.Bold)
}
.margin({right:10})
}
Row(){
}
}
Text("提交")
.border({radius:20})
.width(90)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor(this.getSelectedChildCount()>0?"#ffe5570b":"#ffc3bdbd")
.height(45)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.onClick(()=>{
if (this.getSelectedChildCount()>0) {
showToast("提交数据源"+JSON.stringify(this.arrAy))
}else {
showToast("未选择商品")
}
})
.margin({right:10})
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
现在我们对结算组件进行了一个改造,我们运行看一下效果
可以看到当我们选中一些商品,底部的组件会显示我们当前商品的价格和数量
五、添加全选按钮
身为一个购物车,怎么能没有全选功能呢?最后我们在商品结算组件的前方添加一个全选按钮,并且针对商品的选中做一个串联控制
Checkbox({ name: 'checkbox_all' , group: 'checkboxGroup_all'})
.selectedColor("#ffd95112")
.select(this.isALlCheck())
.shape(CheckBoxShape.CIRCLE)
.width(25)
.height(25)
.onChange((value: boolean) => {
if (value) {
for (let i = 0; i < this.arrAy.length; i++) {
this.arrAy[i].check=true
}
} else {
const hasFalseChildCheck = this.arrAy.some(child => !child.check);
if (hasFalseChildCheck) {
for (let i = 0; i < this.arrAy.length; i++) {
if (!this.arrAy[i].check) {
this.arrAy[i].check=false
}
}
}else {
for (let i = 0; i < this.arrAy.length; i++) {
this.arrAy[i].check=false
}
}
}
})
Text("全选").fontSize(16)
我们在最左侧实现了个一个全选控制按钮并且串联了业务逻辑,我们执行代码试一下效果
可以看到当我们点击全选,列表中的所有组件都会进行选中,并且底部会计算选中商品的价格。
到这里我们的购物车功能就完美实现啦!