鸿蒙自定义弹出框响应式更新数据
1.原因:
openCustomDialog不支持自定义组件使用@Reusable、@Link、@Provide、@Consume等装饰器,来同步弹出框弹出的页面与ComponentContent中自定义组件的状态
2.解决
class Params { // 要调用@Component里面的方法需要使用参数接收 onClose?: () => void; // 关闭弹窗方法 selStockroom?: (index:number) => void; // 选择方法 stockroomList: IPartsStockItem[]; // 数据传入 constructor(onClose?: () => void, stockroomList?: IPartsStockItem[], selStockroom?: (index:number) => void) { // 通过constructor接收 this.onClose = onClose; this.stockroomList = stockroomList || []; this.selStockroom = selStockroom } } @Builder function shareDialog(params: Params) { // 弹框主体 Column() { Row() { Text('请选择仓库') .fontColor('#333') .fontSize(fts('33lpx')) .margin({ bottom: '40lpx' }) } .width('100%') .justifyContent(FlexAlign.Center) Column() { ForEach(params.stockroomList, (item: IPartsStockItem, i: number) => { Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { Text(item.name).fontSize(fts("32lpx")) if (item.selected) { Image($rawfile("icon/fukuanzhong_ico_select.png")).width("32lpx").height("32lpx") } else { Image($rawfile("icon/fukuanzhong_ico_noselect.png")).width("32lpx").height("32lpx") } } .onClick(() => { params.selStockroom?.(i) // 通过params调用@Component方法 }) .margin({ bottom: "24lpx" }) }) } } .backgroundColor('#FFFFFF') .width('70%') .padding('60lpx') .borderRadius('20lpx') }
@Component
export struct PartsCollection {
controller: SearchController = new SearchController();
@State stockroomList: IPartsStockItem[] = []
private contentNode: ComponentContent<Object> =
new ComponentContent(this.ctx, wrapBuilder(shareDialog), new Params((): void => this.closeDialog(), this.stockroomList)) // 创建conetntNode,此时不可以传入异步数据,否则会是undefined
private options: promptAction.BaseDialogOptions = { alignment: DialogAlignment.Center, offset: { dx: 0, dy: 50 } } // 设置弹框显示位置
openDialog() {
if (this.contentNode !== null) {
// 确保传递正确的参数类型
this.contentNode = new ComponentContent(
this.ctx,
wrapBuilder(shareDialog),
new Params((): void => this.closeDialog(), this.stockroomList, (index:number): void => this.selStockroom(index)) // 此时可以传入异步数据
);
this.ctx.getPromptAction()
.openCustomDialog(this.contentNode, this.options)
.then(() => {
Log.info('OpenCustomDialog complete.')
})
.catch((error: BusinessError) => {
let message = (error as BusinessError).message;
let code = (error as BusinessError).code;
Log.error(`OpenCustomDialog args error code is ${code}, message is ${message}`);
})
}
}
closeDialog() {
if (this.contentNode !== null) {
this.ctx.getPromptAction()
.closeCustomDialog(this.contentNode)
.then(() => {
Log.info('closeCustomDialog complete.')
})
.catch((error: BusinessError) => {
let message = (error as BusinessError).message;
let code = (error as BusinessError).code;
Log.error(`closeCustomDialog args error code is ${code}, message is ${message}`);
})
}
}
selStockroom(index: number) {
const arr = [...this.stockroomList]
for (let i = 0; i < arr.length; i++) {
arr[i].selected = index == i;
}
this.stockroomList = arr // 修改了传入的数据
if (this.contentNode) {
this.contentNode.update( // 动态修改传入的数据,让数据更新达到响应式效果
new Params(
(): void => this.closeDialog(),
this.stockroomList, // 传递已更新的列表
(index: number): void => this.selStockroom(index)
)
);
}
}
}
浙公网安备 33010602011771号