HarmonyOS鸿蒙Next中在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功
HarmonyOS鸿蒙Next中在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功 我现在想在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功,【问题现象】没有报错,现在的情况是openbindsheet(在ConfigPage里)和closebindsheet(在PipCustomDialog里)两个操作不是一个文件里的,closebindsheet时必须要填和打开bindsheet时一样的contentNode,我现在没搞通怎么把openbindsheet时的contentNode给到closebindsheet这个操作

更多关于HarmonyOS鸿蒙Next中在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者你好,可以通过AppStorage保存contentNode。
【背景知识】 AppStorage:提供状态变量在应用级全局共享的能力,可以实现应用中不同页面数据共享,在V2版本下可以使用AppStorageV2。 【解决方案】 使用AppStorage可以实现数据在应用中共享,在构建半模态页面的组件内容时保存其数据,再通过唯一的键字符串值访问获取此数据即可。 示例代码如下:
在EntryAbility.ets中获取windowStage:
onWindowStageCreate(windowStage: window.WindowStage): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    windowStage.loadContent('pages/MapChartDemo', (err) => {
      AppStorage.setOrCreate('uiContext', windowStage.getMainWindowSync().getUIContext());
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      AppStorage.setOrCreate('windowStage', windowStage)
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
    });
 }
@Entry
@Component
struct Index {
  windowStage = AppStorage.get('windowStage') as window.WindowStage;
  @State message: string = 'BindSheet';
  contentNode: ComponentContent<Params> | null = null;
  dialogController: CustomDialogController = new CustomDialogController({
    alignment: DialogAlignment.Top,
    builder: Dialog(),
    cancel: () => {
      this.dialogController.close()
    },
    backgroundColor: Color.Blue,
    offset: { dx: 0, dy: 0 }
  })
  aboutToAppear(): void {
    this.contentNode = new ComponentContent(this.getUIContext(), wrapBuilder(buildText),
      new Params(this.message, this.dialogController));
    AppStorage.setOrCreate('contentNode', this.contentNode)
  }
  build() {
    Column() {
      Button('打开Bindsheet')
        .onClick(() => {
          let uiContext = this.windowStage.getMainWindowSync().getUIContext();
          let uniqueId = this.getUniqueId();
          let frameNode: FrameNode | null = uiContext.getFrameNodeByUniqueId(uniqueId);
          let targetId = frameNode?.getFirstChild()?.getUniqueId();
          uiContext.openBindSheet(this.contentNode, {
            height: SheetSize.MEDIUM,
            title: { title: 'Title', subtitle: 'subtitle' },
          }, targetId)
            .then(() => {
              console.info('openBindSheet success');
            })
            .catch((err: BusinessError) => {
              console.error(`openBindSheet error. Cause:${err.code}, message:${err.message}`);
            })
        })
    }
  }
}
弹窗页面:
import { window } from '@kit.ArkUI'
// 弹窗相关
@CustomDialog
@Component
export struct Dialog {
  @State showFlag: Visibility = Visibility.Visible
  controller: CustomDialogController
  build() {
    Column() {
      Button('关闭Bindsheet')
        .onClick(() => {
          let node: ComponentContent<Params> = AppStorage.get('contentNode') as ComponentContent<Params>;
          let windowStage = AppStorage.get('windowStage') as window.WindowStage
          windowStage.getMainWindowSync().getUIContext().closeBindSheet(node)
        })
        .margin({ top: 53 })
    }
    .width('100%')
    .padding({ bottom: 15 })
    .linearGradient(
      {
        direction: GradientDirection.Bottom,
        colors: [['#283790', 0.0], ['#B2B1AB', 1.0]]
      }
    )
    .borderRadius({ bottomLeft: 20, bottomRight: 20 })
  }
}
export class Params {
  text: string = '';
  dialogController: CustomDialogController | null = null
  constructor(text: string, dialogController: CustomDialogController | null) {
    this.text = text;
    this.dialogController = dialogController
  }
}
@Builder
export function buildText(params: Params) {
  Column() {
    Text(params.text)
    Button('打开弹窗')
      .onClick(() => {
        params.dialogController?.open()
      })
  }
}
更多关于HarmonyOS鸿蒙Next中在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
可以用AppStorage来保存contentNode。 AppStorage能实现应用内不同页面的数据共享,V2版本里可以用AppStorageV2。具体做法是,在构建半模态页面的组件内容时,把数据存到AppStorage里,之后用唯一的键字符串就能访问到这些数据。 以下是示例代码:
主页面
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct Index {
  @State message: string = 'BindSheet';
  contentNode: ComponentContent<Params> | null = null;
  private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  dialogController: CustomDialogController = new CustomDialogController({
    alignment: DialogAlignment.Top,
    builder: Dialog(),
    cancel: () => {
      this.dialogController.close()
    },
    backgroundColor: Color.Blue,
    offset: { dx: 0, dy: 0 }
  })
  aboutToAppear(): void {
    this.contentNode = new ComponentContent(this.getUIContext(), wrapBuilder(buildText),
      new Params(this.message, this.dialogController));
    AppStorage.setOrCreate('contentNode', this.contentNode)
  }
  build() {
    Column() {
      Button('打开Bindsheet')
        .onClick(() => {
          let uniqueId = this.getUniqueId();
          let frameNode: FrameNode | null = uiContext.getFrameNodeByUniqueId(uniqueId);
          let targetId = frameNode?.getFirstChild()?.getUniqueId();
          this.context.openBindSheet(this.contentNode, {
            height: SheetSize.MEDIUM,
            title: { title: 'Title', subtitle: 'subtitle' },
          }, targetId)
        })
    }
  }
}
弹窗组件
import { window } from '@kit.ArkUI'
import { common } from '@kit.AbilityKit';
@CustomDialog
@Component
export struct Dialog {
  @State showFlag: Visibility = Visibility.Visible
  controller: CustomDialogController
  private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  build() {
    Column() {
      Button('关闭Bindsheet')
        .onClick(() => {
          let node: ComponentContent<Params> = AppStorage.get('contentNode') as ComponentContent<Params>;
          this.context.closeBindSheet(node)
        })
        .margin({ top: 53 })
    }
    .width('100%')
    .padding({ bottom: 15 })
    .linearGradient(
      {
        direction: GradientDirection.Bottom,
        colors: [['#283790', 0.0], ['#B2B1AB', 1.0]]
      }
    )
    .borderRadius({ bottomLeft: 20, bottomRight: 20 })
  }
}
export class Params {
  text: string = '';
  dialogController: CustomDialogController | null = null
  constructor(text: string, dialogController: CustomDialogController | null) {
    this.text = text;
    this.dialogController = dialogController
  }
}
@Builder
export function buildText(params: Params) {
  Column() {
    Text(params.text)
    Button('打开弹窗')
      .onClick(() => {
        params.dialogController?.open()
      })
  }
}
在HarmonyOS Next中,可通过windowStage的hide方法关闭bindsheet弹窗。确保在保存按钮的点击事件回调中调用弹窗组件的hide()方法。检查事件绑定是否正确,避免异步操作导致hide未执行。若使用自定义弹窗,需通过@State控制弹窗状态,在保存时更新状态变量触发关闭。
在HarmonyOS Next中,跨组件控制弹窗状态可以通过状态管理或事件传递实现。根据你的描述,ConfigPage和PipCustomDialog之间的contentNode需要共享。以下是两种推荐方案:
- 
使用AppStorage或LocalStorage
在ConfigPage中打开弹窗时,将contentNode存入AppStorage:AppStorage.setOrCreate('bindsheetContentNode', contentNode);在
PipCustomDialog中关闭时读取:let node = AppStorage.get('bindsheetContentNode'); closeBindSheet(node); - 
通过自定义事件传递
在ConfigPage中定义事件并传递参数:import { emitter } from '[@ohos](/user/ohos)/commonEventManager'; // 打开时发布事件 emitter.emit('bindsheetOpen', { contentNode });在
PipCustomDialog中订阅事件:emitter.on('bindsheetOpen', (data) => { this.contentNode = data.contentNode; }); 
确保关闭操作前已正确获取contentNode,并检查弹窗组件的生命周期是否与节点绑定一致。若仍无法解决,建议检查弹窗组件的visibility属性控制逻辑。
        
      
                  
                  
                  
