关于ArkUI必须在@Builder中(不推荐)更新参数的和触发外部方法的一种操作方法

        实际任务中因为部分逻辑操作已经在@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中了。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值