You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何点击按钮向Rex ScrollablePanel添加面板实现聊天对话框?

问题:基于Rex ScrollablePanel实现聊天消息动态展示

我需要实现一个迷你聊天对话框,要求输入内容点击发送按钮后,消息能显示在Rex ScrollablePanel(滚动面板)中。目前已编写了点击事件监听和滚动面板创建代码,但将滚动面板代码移入点击事件内无法正常工作,求可行的解决建议。

现有代码

点击事件监听

this.dialogChatInput.addListener("click");
this.dialogChatInput.on("click", (event) => {
  if (event.target.id === "sendButton") {
    var inputChat = this.dialogChatInput.getChildByName("nameFieldChat");

    if (inputChat.value !== "") {
      console.log(`Chat : ${inputChat.value}`);
      
    }
  }
});

滚动面板创建代码

var panel = this.rexUI.add
  .scrollablePanel({
    x: this.dialogKhungHienThi.x + 225,
    y: this.dialogKhungHienThi.y,
    height: 1200,

    scrollMode: 0,

    background: this.rexUI.add.roundRectangle({
      // strokeColor: transparent,
      strokeWidth: 2,
    }),
    panel: {
      child: CreatePanel(this),
    },

    slider: {
      track: this.rexUI.add.roundRectangle({
        width: 20,
        height: 20,
        radius: 40,
        color: COLOR_TRACK,
      }),
      thumb: this.rexUI.add.roundRectangle({
        radius: 50,
        color: COLOR_THUMB,
      }),
    },

    space: { panel: 4 },
  })
  .layout();

面板生成函数(定义在Create()外)

var CreatePanel = function (scene, data) {
  var panel = scene.rexUI.add.sizer({
    width: 100,
    orientation: "y",
    space: { item: 4 },
  });

  if (ngu) {
    var name = `item-${i}`;
    var label = scene.rexUI.add.label(
      {
        height: 350,
        width: 1000,
        background: scene.rexUI.add.roundRectangle({
          // color: COLOR_PRIMARY,
        }),
        icon: scene.add.image(0, 0, "avatarDemo").setScale(2),
        text: scene.add
          .text(10, 10, ` ${hour} :  ${minute}: ${second} `, {
            font: "70px Arial",
            fill: "#ffffff",
            stroke: "black",
            strokeThickness: 15,
          })
          .setFontSize("70px"),
        wrapText: true,
        name: name,
      },
      this
    );
    panel.add(label, { expand: true });
  }

  return panel;
};

解决方案

1. 提前初始化滚动面板,避免重复创建

滚动面板只需在场景初始化时创建一次,不要放在点击事件里重复生成。将面板实例作为场景全局变量保存:

// 在场景类中声明全局变量
this.scrollPanel;

// 在create()方法中初始化滚动面板
this.scrollPanel = this.rexUI.add
  .scrollablePanel({
    x: this.dialogKhungHienThi.x + 225,
    y: this.dialogKhungHienThi.y,
    height: 1200,
    scrollMode: 0,
    background: this.rexUI.add.roundRectangle({
      strokeWidth: 2,
    }),
    panel: {
      child: this.rexUI.add.sizer({
        width: 100,
        orientation: "y",
        space: { item: 4 },
      }),
    },
    slider: {
      track: this.rexUI.add.roundRectangle({
        width: 20,
        height: 20,
        radius: 40,
        color: COLOR_TRACK,
      }),
      thumb: this.rexUI.add.roundRectangle({
        radius: 50,
        color: COLOR_THUMB,
      }),
    },
    space: { panel: 4 },
  })
  .layout();

2. 修改点击事件,动态添加消息到滚动面板

点击发送按钮时,直接生成新消息元素并添加到滚动面板的内部sizer,然后更新布局并自动滚动到底部:

this.dialogChatInput.on("click", (event) => {
  if (event.target.id === "sendButton") {
    var inputChat = this.dialogChatInput.getChildByName("nameFieldChat");

    if (inputChat.value !== "") {
      // 获取当前时间
      const now = new Date();
      const timeStr = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;

      // 创建新消息标签
      const messageLabel = this.rexUI.add.label({
        height: 350,
        width: 1000,
        background: this.rexUI.add.roundRectangle(),
        icon: this.add.image(0, 0, "avatarDemo").setScale(2),
        text: this.add.text(10, 10, `${timeStr} - ${inputChat.value}`, {
          font: "70px Arial",
          fill: "#ffffff",
          stroke: "black",
          strokeThickness: 15,
        }).setFontSize(70),
        wrapText: true,
        name: `item-${Date.now()}`
      });

      // 获取滚动面板内部的sizer容器
      const innerSizer = this.scrollPanel.getElement("panel").child;
      // 添加新消息到容器
      innerSizer.add(messageLabel, { expand: true });
      // 重新布局滚动面板
      this.scrollPanel.layout();
      // 自动滚动到最新消息位置
      this.scrollPanel.scrollToBottom(100);

      // 清空输入框
      inputChat.value = "";
    }
  }
});

3. 修复CreatePanel函数的复用问题

原CreatePanel函数存在未定义变量(ngu、i等),如果需要复用消息创建逻辑,可拆分为初始化容器和创建单条消息的独立函数:

// 初始化滚动面板内部的sizer容器
function createMessageContainer(scene) {
  return scene.rexUI.add.sizer({
    width: 100,
    orientation: "y",
    space: { item: 4 },
  });
}

// 创建单条消息标签的函数
function createSingleMessage(scene, content, timeStr) {
  return scene.rexUI.add.label({
    height: 350,
    width: 1000,
    background: scene.rexUI.add.roundRectangle(),
    icon: scene.add.image(0, 0, "avatarDemo").setScale(2),
    text: scene.add.text(10, 10, `${timeStr} - ${content}`, {
      font: "70px Arial",
      fill: "#ffffff",
      stroke: "black",
      strokeThickness: 15,
    }).setFontSize(70),
    wrapText: true,
    name: `item-${Date.now()}`
  });
}

关键注意事项

  • 滚动面板仅需初始化一次,重复创建会导致DOM冗余和功能异常
  • 添加新消息后必须调用layout()方法更新面板布局,否则新元素不会显示
  • 使用scrollToBottom()实现自动滚动,优化用户查看最新消息的体验
  • 发送后清空输入框,避免重复发送相同内容

内容的提问来源于stack exchange,提问作者Nguyễn Hải Long

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 01:52:11