HarmonyOS development: wrapBuilder passing parameters

Foreword
the code case is based on api13.
In the previous article, we have outlined the parameters passed by wrapBuilder. Whether it is defined locally or globally, passing parameters is very simple. Just call the builder function directly. The simple case is as follows:
@Builder
function TextView(value: string) {
Text(value)
}
@Entry
@Component
struct Index {
textBuilder: WrappedBuilder<[string]> = wrapBuilder(TextView)
build() {
Column() {
this.textBuilder.builder("params")
}.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
the above parameters are passed in the UI view. It is very simple to pass parameters, but what if they are not in the UI view? This is the problem I have encountered recently. The team has used the dialog of any position I have customized, which is similar to the dialog in the following figure. One requirement is that message is not a simple text, but may be a picture and text, may be a rich text, or may be other presentations. In this case, it is not flexible enough to receive a text or other types. Therefore, I directly exposed the message component and passed it to the caller.
In this way, the rich and diverse situation of message is solved. After all, the component is passed by the caller. Although the effect is realized, the problem is raised again:
"My message is displayed according to logic, for example, to show this for true and to show another for false. How can the data be passed?"
"... Well, there are so many requirements, then forget it, you can define it yourself. "Of course, this is just your own voice, the actual situation, or nod and say, okay, solve it immediately.
Basic Case
case, here I simplified, mainly defined a pop-up window tool class.
import { ComponentContent } from "@kit.ArkUI"
import { DialogAttribute } from "./DialogAttribute"
export class DialogUtils {
private constructor() {
}
private static mDialogUtils: DialogUtils
public static get() {
if (DialogUtils.mDialogUtils == undefined) {
DialogUtils.mDialogUtils = new DialogUtils()
}
return DialogUtils.mDialogUtils
}
showDialog(context: UIContext, dialogAttribute?: DialogAttribute) {
if (dialogAttribute == undefined) {
dialogAttribute = new DialogAttribute()
}
this.show(context, dialogAttribute)
}
private show(context: UIContext, object: Object) {
let dView = wrapBuilder<Object[]>(dialogView)
let dialogContent: ComponentContent<Object> = new ComponentContent(context, dView, object)
context.getPromptAction().openCustomDialog(dialogContent)
}
}
@Builder
function dialogView(dialogAttribute?: DialogAttribute) {
Column() {
Text(dialogAttribute?.title)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin({ top: 10 })
if (dialogAttribute?.messageView != undefined) {
dialogAttribute?.messageView.builder()
}
Row() {
Text("cancel")
.height(40)
.textAlign(TextAlign.Center)
.layoutWeight(1)
Text("confirm")
.height(40)
.layoutWeight(1)
.textAlign(TextAlign.Center)
}.width("100%")
}.width("80%")
.backgroundColor(Color.White)
.borderRadius(10)
}
In the actual development, a lot of content is dynamically variable, but also need to expose these attributes, here I simply defined a property file, in the actual development, there will be a lot of attributes, here, I simply defined two, mainly for testing.
export class DialogAttribute {
title?:
messageView?: WrappedBuilder<Object[]>
}
Direct call:
import { DialogUtils } from './DialogUtils'
@Builder
function messageView() {
Text("简单测试")
.margin({ top: 20, bottom: 20 })
}
@Entry
@Component
struct Index {
build() {
Column() {
Button("click")
.onClick(() => {
DialogUtils.get()
.showDialog(this.getUIContext(), {
title: "dialog",
messageView: wrapBuilder(messageView)
})
})
}.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
through the above case, we simply created a custom pop-up window. After clicking the button, a pop-up window will pop up to support the message message custom component and realize any effect.
Then again, how do I receive parameters in the global @ Builder? That is, in the following position:
@Builder
function messageView() {
Text("test")
.margin({ top: 20, bottom: 20 })
}
passing Parameters
way one, intermediate transit
in the so-called intermediate transfer, we can define a variable in a class to receive the transferred data. This is the simplest. We assign values when passing on one side and take them out when using on the other side.
Define an assignment variable:
private mParams?: Object
private setData(params?: Object) {
this.mParams = params
}
getData(): Object | undefined {
return this.mParams
}
when receiving data, assign values
showDialog(context: UIContext, dialogAttribute?: DialogAttribute) {
if (dialogAttribute == undefined) {
dialogAttribute = new DialogAttribute()
}
this.setData(dialogAttribute.messageData)
this.show(context, dialogAttribute)
}
use:
@Builder
function messageView() {
Text(DialogUtils.get().getData()?.toString())
.margin({ top: 20, bottom: 20 })
}
one thing to know is that if multiple pop-up windows are shared and the assignment variable is single-column or static, remember to restore the original value when dialog is destroyed.
Way two, receive directly
because the wrapBuilder is passed to the ComponentContent object, when the wrapBuilder is used in the wrapBuilder, it is found that the parameters will be carried directly, and we can use it directly.
let dView = wrapBuilder<Object[]>(dialogView)
let dialogContent: ComponentContent<Object> = new ComponentContent(context, dView, object)
context.getPromptAction().openCustomDialog(dialogContent)
Define Receive Parameters
in the attribute definition file, define the data we need to receive. Because the type of data is uncertain, we can directly define it as an Object.
Transfer Data
DialogUtils.get()
.showDialog(this.getUIContext(), {
Title: "I am a dialog popup",
messageView: wrapBuilder(messageView),
MessageData: "Simply pass a string"
})
directly receive the passed object and obtain the specified field parameters.
@Builder
function messageView(attr: DialogAttribute) {
Text(attr.messageData?.toString())
.margin({ top: 20, bottom: 20 })
}
Related Summary
In this paper, the main brief introduction, non-UI use, wrapBuilder transfer data problem, in addition to the above way, there are other ways to achieve, in the actual development, or specific problems specific analysis.
Subscribe to my newsletter
Read articles from AbnerMing directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
