实际任务中因为部分逻辑操作已经在@Builder中了,但是不想修改代码,在查阅文档以及询问工程师未得到有效解决方法后,尝试用其他方法解决这个问题。
一、外部的更新操作/触发外部方法
此处为已有@Builder代码逻辑中已经含有对外部数据的更新操作,不方便更改此处代码的时候的应急手段。
此处为@Builder
// fetchData为查询新数据(或者是其他需要触发的方法),update是更新外部数据的操作
@Builder
function ShopCartList(infoList: Data[], listScroller: Scroller, fetchData?: () => void,
update?: (checkedList: string[]) => void) {
Flex({ direction: FlexDirection.Column }) {
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
Row() {
CheckboxGroup({ group: 'shopping' })
.selectedColor('#ff6827')
.onChange((itemList: CheckboxGroupResult) => {
if (update) {
update(itemList.name)
}
})
Text('全选')
}
Row() {
Image($rawfile('OrderPage/shancu.png'))
.width(18)
.height(18)
Text('删除')
}
.onClick(() => {
// TODO 删除操作
})
}
.backgroundColor('#f5f5f5')
List({ initialIndex: 0, scroller: listScroller }) {
ForEach(infoList, (item: Data, index: number) => {
ListItem() {
Row() {
Checkbox({
name: (item.sku as Data).id as string, group: 'shopping', indicatorBuilder: () => {
}
})
.select(true)
.selectedColor('#ff6827')
.width(18)
.height(18)
Image(((item.sku as Data).cover as Data[])[0].source as string)
.width(80)
.height(80)
Column() {
Text((item.sku as Data).title as string)
Text()
Row()
}
.flexGrow(1)
}
}
})
}
.onScrollStop(() => {
if (listScroller.isAtEnd()) {
if (fetchData) {
fetchData();
}
}
})
}
.padding({
top: 15,
bottom: 50,
left: 20,
right: 20
})
.height(320)
}
此处为@CustomDialog
我们需要对这个数据进行操作的时候可以点击事件在外部声明,并传递到@Builder中,例如我在这个声明弹框时做了如下处理
@CustomDialog
struct ListDialog {
// 声明占位符
@BuilderParam ShopCartContent: (List: Data[], Scroller: Scroller, fetchData?: () => void,
update?: (checkedList: string[]) => void) => void;
@Link itemList: Data[];
listScroller: Scroller = new Scroller();
fetchData?: () => void;
update?: (checkedList: string[]) => void;
controller: CustomDialogController
build() {
Column() {
// 购物车循环列表
this.ShopCartContent(this.itemList, this.listScroller, this.fetchData, this.update)
}
}
}
此处为@Component
然后在@Component中对它进行引用,这里可以通过刚才的两个回调函数分别进行更新和触发外部方法。
dialogController: CustomDialogController = new CustomDialogController({
builder: ListDialog({
ShopCartContent: ShopCartList,
itemList: this.shopCart,
fetchData: () => {
if (this.haveNext) {
this.fetchShopCart();
}
},
update: (checkedList) => {
this.checkedList = checkedList;
console.log(JSON.stringify(this.checkedList))
}
}),
alignment: DialogAlignment.Bottom,
width: '100%',
maskRect: {
// 减去底部导航栏高度
y: (-44 - this.bottom)
},
cancel: () => {
this.isOpenDialog = false;
}
})
二、总结
整个链条是@Component -> @CustomDialog -> @Builder -> @CustomDialog -> @Component,当然@Component直接操作@Builder也是可以的。不过我相当不建议这样操作,这只是作为一种手段。后面我直接去掉了@Builder,把它的内容放进@CustomDialog中了。