有没有一种简单的方法可以将当前处于活动状态的对话框显示在堆栈上?

时间:2019-12-19 17:34:15

标签: node.js botframework

我的机器人基于核心机器人示例,并具有中断功能,可以在对话期间通过某些意图调用该功能。如果我在对话框中,然后中断启动对话框,则它们都通过dc.beginDialog调用,并且在对话框堆栈中处于单个级别。例如,它看起来像这样

[ { id: 'viewOrderDialog', state: { dialogs: [Object] } }, { id: 'interruptDialog', state: { dialogs: [Object] } } ]

因此,我可以通过获取数组中最后一个元素的ID来轻松地获得活动对话框。但是,在此过程中,我可以从interruptDialog启动其他对话框。这些是通过step.beginDialog从瀑布内部开始的。在这种情况下,它们不再与其他对话框处于同一级别(从dc而不是step开始)。我必须进入state.dialogs.dialogStack来找到ID,如果该对话框调用另一个ID,则ID可以再次嵌套。这是dc.activeDialog最终看起来像的一个示例:

{"id":"interruptDialog","state":{"dialogs":{"dialogStack":[{"id":"waterfallDialog","state":{"options":"expediteOrder","values":{"instanceId":"d61d748e-af45-cea0-9188-63904de21dfc"},"stepIndex":0}},{"id":"escalationDialog","state":{"dialogs":{"dialogStack":[{"id":"waterfallDialog","state":{"options":{},"values":{"instanceId":"6e755278-d636-dd76-3b47-eb43e3eda1c7"},"stepIndex":2}},{"id":"emailDialog","state":{"dialogs":{"dialogStack":[{"id":"waterfallDialog","state":{"options":{},"values":{"instanceId":"87f08019-ff59-ce03-ccab-7914fb0b553b"},"stepIndex":1}},{"id":"emailPrompt","state":{"options":{"prompt":"Which email address do you want us to reply to?"},"state":{}}}]}}}]}}}]}}}

我可以降到最低级别,在这种情况下为emailPrompt,但检查和查看每个级别的对话框/ dialogStack是否为数组似乎要花费过多的开销。 (是的,我可能应该给我的瀑布对话框命名而不是WaterfallDialog)。我希望有一种简单的方法可以使最新的对话脱离堆栈,但是我找不到任何能给我这些信息的东西。

从一个不太一般的意义上讲,我正在专门尝试向该中断添加一个条件,以防止在某些对话框中调用该条件。我有一个步骤,用户可以编写电子邮件正文,并且如果他们写一些有关加快订单的内容,则表示正在激活中断。在这种特定情况下,我决定通过将dc.activeDialog转换为字符串然后检查其是否包含'emailDialog'来解决该问题。然后,我为!activeDialog.includes('emailDialog')添加一个条件。在这种情况下可以正常工作,但是我问了一个更笼统的问题,因为在其他情况下(我需要知道我在哪个对话框中),这可能不是一个好的解决方案。

如果需要,我可以提供代码片段,但是代码本身并不是很重要。我只是想确定从对话框上下文中获取当前活动对话框ID的最佳方法。

1 个答案:

答案 0 :(得分:1)

看到嵌套对话框堆栈的原因是因为您使用的是component dialogs

如果中断总是在根对话框上下文中执行的,并且这是添加中断对话框的位置,那么就不必挖掘嵌套的对话框堆栈了。由于中断对话框将始终位于根对话框堆栈中,因此您只需检查根对话框上下文即可查看活动对话框是否为中断对话框。

我不知道确定最内层活动对话框的任何内置方法,但是如果这确实是您要执行的操作,那么创建递归函数来做到这一点应该不难:

getInnermostActiveDialog(dc) {
    var child = dc.child;

    return child ? this.getInnermostActiveDialog(child) : dc.activeDialog;
}

应该注意的是,Core Bot示例通过使特定对话框扩展common base dialog class并随后从对话框内部而不是从bot类处理中断来使特定对话框可中断。您可能想通过使对话框“选择加入”以具有可中断性而不是使中断对话框“选择退出”来遵循该示例。