Telegraf.js中进入Scene时如何传递Calendar实例?
在Telegraf.js中传递Calendar实例到场景的实现方法
方法一:通过场景初始化参数传递(推荐单场景使用)
ctx.scene.enter方法支持传入第二个参数作为场景的初始状态数据,可直接将Calendar实例放入该参数,场景内部通过ctx.scene.state获取。
修改触发动作的代码:
bot.action("launchListingBtn", async (ctx) => { // 将calendar实例传入场景的state ctx.scene.enter("collectLaunchData", { calendar }); });
在collectLaunchData场景中使用实例:
const collectLaunchDataScene = new Scene("collectLaunchData"); collectLaunchDataScene.enter(async (ctx) => { // 从场景state中取出calendar实例 const { calendar } = ctx.scene.state; // 调用calendar的方法,比如发送日历选择器 await calendar.sendCalendar(ctx); }); // 注册场景到Stage const stage = new Stage([collectLaunchDataScene]); bot.use(stage.middleware());
方法二:挂载到上下文原型(推荐多场景共用)
如果Calendar实例需要在多个场景或处理器中使用,可将其挂载到Telegraf的上下文原型上,所有ctx实例都能直接访问。
初始化时挂载实例:
const calendar = new Calendar(bot, { date_format: "MMM D, YYYY HH:mm", language: "en", start_week_day: 1, bot_api: "telegraf", time_selector_mod: true, time_range: "00:00-23:59", time_step: "60m", }); // 将calendar挂载到上下文原型 bot.context.calendar = calendar;
触发场景时无需额外传参:
bot.action("launchListingBtn", async (ctx) => { ctx.scene.enter("collectLaunchData"); });
场景中直接使用:
collectLaunchDataScene.enter(async (ctx) => { const calendar = ctx.calendar; await calendar.sendCalendar(ctx); });
方法三:使用全局变量(不推荐)
将Calendar实例声明为全局变量,场景中直接引用,但这种方式不利于代码模块化,多实例机器人场景下会出现冲突,仅适合简单单实例场景。
// 全局作用域声明calendar let calendar; // 初始化实例 calendar = new Calendar(bot, { date_format: "MMM D, YYYY HH:mm", language: "en", start_week_day: 1, bot_api: "telegraf", time_selector_mod: true, time_range: "00:00-23:59", time_step: "60m", }); bot.action("launchListingBtn", async (ctx) => { ctx.scene.enter("collectLaunchData"); }); // 场景中直接使用全局calendar collectLaunchDataScene.enter(async (ctx) => { await calendar.sendCalendar(ctx); });
内容的提问来源于stack exchange,提问作者Bilal Zahid Shah
相关产品推荐
相关产品推荐

