HarmonyOS鸿蒙Next中使用自定义弹窗时,用update方法没有用

HarmonyOS鸿蒙Next中使用自定义弹窗时,用update方法没有用 这是我其中一个页面的代码,而且这个页面很奇怪,aboutToapear函数会执行两次,其他导航页面都不会有这种情况

我的逻辑是进入这个界面的时候想编辑按钮,然后点击按钮会跳出弹窗,弹窗上面会显示这个按钮的文本数据,但是我发现第一次进入这个页面点击按钮只会显示初始化的时候也就是new param(0)的数据,但是我要是切换到其他页面再回来本页面点击按钮update方法又生效了,弹窗也能正确展示对应按钮的文本

@Builder
function buildText(param: Params) {
  Column() {
    Column(){
      Row({space: 5}) {
        //弹窗顶部按钮文本
        Text('按钮文本:')
          .fontColor('#ffffff')
        TextInput({text: param.data.buttonList[param.index].name})
          .width(250)
          .fontColor('#ffffff')
      }
      .padding(5)
      .backgroundColor('#639ff8')
      .width('100%')
      .height(50)
      .borderRadius({topLeft: 10, topRight: 10})
      Button('Close')
        .onClick(() => {
          PromptActionClass.closeDialog();
        })
    }
    .margin({top: '50%'})
    .width(350)
    .height(250)
    .borderRadius(10)
    .backgroundColor('#ffffff')
  }
  .width('100%')
  .height('100%')
}

@ComponentV2
export struct ButtonControl {

  typeData: GlobalType = AppStorageV2.connect(GlobalType, 'TYPE_KEY', () => new GlobalType)!

  //持久化储存UI状态
  buttonData: ButtonData = PersistenceV2.connect(ButtonData, 'BUTTON_KEY', () => new ButtonData)!

  private uiContext: UIContext = this.getUIContext();
  private promptAction: PromptAction = this.uiContext.getPromptAction();

  //弹窗相关配置
  contentNode: ComponentContent<Object> = new ComponentContent(this.uiContext, wrapBuilder(buildText), new Params(0));

  aboutToAppear(): void {
    PromptActionClass.setContext(this.uiContext);
    PromptActionClass.setContentNode(this.contentNode);
    PromptActionClass.setOptions({ alignment: DialogAlignment.Center, offset: { dx: 0, dy: 50 } });
    console.log('ready')
  }

  build() {
    Column({space: 10}){
      Row(){
        //编辑栏
        Row() {//空白占位
        }
        .layoutWeight(1)
        Row({space: 5}) {
          //编辑按钮栏
          Toggle({ type: ToggleType.Switch, isOn: this.buttonData.isEdit == false ? false : true })
            .onChange((isOn: boolean) => {
              if(isOn) {
                // 开启后需要执行的操作
                this.buttonData.isEdit = true //开启编辑按钮
                PersistenceV2.save('BUTTON_KEY') //手动存储数据
              }
              else
              {
                this.buttonData.isEdit = false //关闭编辑按钮
                PersistenceV2.save('BUTTON_KEY') //手动存储数据
              }
            })
          Text('编辑按钮')
        }
      }
      .backgroundColor('#ffffff')
      .padding(10)
      .borderRadius(15)
      .margin({bottom: 10})
      Row({space: 10}){
          Button(this.buttonData.buttonList[0].name)
            .width(100)
            .height(50)
            .onClick(() => {
              if(this.buttonData.isEdit == false)
              {
                //当不是编辑模式的时候
                if(this.typeData.connectType == 0)
                {
                  try {
                    this.promptAction.showToast({
                      message: '请先连接设备!',
                      duration: 1000
                    })
                  } catch (error) {
                    let message = (error as BusinessError).message;
                    let code = (error as BusinessError).code;
                    console.error(`showToast args error code is ${code}, message is ${message}`);
                  };
                }
                else
                {
                  //确认链接设备后才发送数据
                  sppClientManager.sendData(0x00)
                }
              }
            })
            .layoutWeight(1)
          Button(this.buttonData.buttonList[1].name)
            .width(100)
            .height(50)
            .onClick(() => {
              if(this.buttonData.isEdit == false)
              {
                //当不是编辑模式的时候
                if(this.typeData.connectType == 0)
                {
                  try {
                    this.promptAction.showToast({
                      message: '请先连接设备!',
                      duration: 1000
                    })
                  } catch (error) {
                    let message = (error as BusinessError).message;
                    let code = (error as BusinessError).code;
                    console.error(`showToast args error code is ${code}, message is ${message}`);
                  };
                }
                else
                {
                  //确认链接设备后才发送数据
                  sppClientManager.sendData(0x00)
                }
              }
              else
              {
                PromptActionClass.openDialog();
                this.contentNode.update(new Params(1)); //更新弹窗
              }
            })
            .layoutWeight(1)
          Button(this.buttonData.buttonList[2].name)
            .width(100)
            .height(50)
            .onClick(() => {
              if(this.buttonData.isEdit == false)
              {
                //当不是编辑模式的时候
                if(this.typeData.connectType == 0)
                {
                  try {
                    this.promptAction.showToast({
                      message: '请先连接设备!',
                      duration: 1000
                    })
                  } catch (error) {
                    let message = (error as BusinessError).message;
                    let code = (error as BusinessError).code;
                    console.error(`showToast args error code is ${code}, message is ${message}`);
                  };
                }
                else
                {
                  //确认链接设备后才发送数据
                  sppClientManager.sendData(0x00)
                }
              }
              else
              {
                PromptActionClass.openDialog();
                this.contentNode.update(new Params(2)); //更新弹窗
              }
            })
            .layoutWeight(1)
        }

      Row({space: 10}){
        Button(this.buttonData.buttonList[3].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
        Button(this.buttonData.buttonList[4].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
        Button(this.buttonData.buttonList[5].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
      }

      Row({space: 10}){
        Button(this.buttonData.buttonList[6].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
        Button(this.buttonData.buttonList[7].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
        Button(this.buttonData.buttonList[8].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
      }

      Row({space: 10}){
        Column() { //占位置用的空白列
        }
        .width(100)
        .height(50)
        .layoutWeight(1)
        Button(this.buttonData.buttonList[9].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
        Column() { //占位置用的空白列
        }
        .width(100)
        .height(50)
        .layoutWeight(1)
      }
      .margin({top: 15})

      Row({space: 10}){
        Button(this.buttonData.buttonList[10].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
        Button(this.buttonData.buttonList[11].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
        Button(this.buttonData.buttonList[12].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
      }

      Row({space: 10}){
        Column() { //占位置用的空白列
        }
        .width(100)
        .height(50)
        .layoutWeight(1)
        Button(this.buttonData.buttonList[13].name)
          .width(100)
          .height(50)
          .onClick(() => {
            if(this.buttonData.isEdit == false)
            {
              //当不是编辑模式的时候
              if(this.typeData.connectType == 0)
              {
                try {
                  this.promptAction.showToast({
                    message: '请先连接设备!',
                    duration: 1000
                  })
                } catch (error) {
                  let message = (error as BusinessError).message;
                  let code = (error as BusinessError).code;
                  console.error(`showToast args error code is ${code}, message is ${message}`);
                };
              }
              else
              {
                //确认链接设备后才发送数据
                sppClientManager.sendData(0x00)
              }
            }
          })
          .layoutWeight(1)
        Column() { //占位置用的空白列
        }
        .width(100)
        .height(50)
        .layoutWeight(1)
      }

      }
      .padding(10)
  }
}

更多关于HarmonyOS鸿蒙Next中使用自定义弹窗时,用update方法没有用的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

this.buttonData.isEdit == true的时候,你的update才会触发。排查下触发情况呢,多加一些日志。

更多关于HarmonyOS鸿蒙Next中使用自定义弹窗时,用update方法没有用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


有个滑块按钮,当它数值为true的时候才能触发弹窗,

在HarmonyOS Next中,自定义弹窗的update()方法失效通常是由于UI线程未刷新或状态未正确同步导致。检查以下三点:

  1. 确保在UI线程调用update()
  2. 确认自定义弹窗的Builder类正确实现了Component状态更新逻辑;
  3. 若使用@State修饰变量,需保证变量变化触发重新渲染。

可尝试调用postUpdate()替代update()强制刷新。

从代码分析,问题可能出在弹窗参数初始化和更新时机上。以下是关键点分析:

  1. aboutToAppear执行两次的问题:
  • 这通常与页面生命周期或导航机制有关,但不会直接影响弹窗功能
  1. 弹窗更新失效问题:
  • 初始化的contentNode使用了固定参数new Params(0)
  • 在按钮点击时虽然调用了update(new Params(index)),但可能未正确触发UI刷新

建议修改方案:

  1. 将contentNode改为响应式:
@State private dialogParam: Params = new Params(0);
contentNode: ComponentContent<Object> = new ComponentContent(this.uiContext, wrapBuilder(buildText), this.dialogParam);
  1. 修改按钮点击事件:
.onClick(() => {
  this.dialogParam = new Params(index); // 先更新参数
  PromptActionClass.openDialog();
})
  1. 检查PromptActionClass的实现: 确保openDialog()方法使用的是最新的contentNode实例

这种修改利用了ArkUI的响应式机制,确保参数更新能触发UI刷新。首次加载时可能因为状态未完全初始化导致显示异常,切换页面后状态恢复所以能正常工作。

回到顶部