如何在Xpages事件中实现“continue = false”

时间:2014-01-29 20:09:21

标签: xpages lotus-domino lotusscript xpages-ssjs

这是一个相当普遍的问题,但我会尽量保持精确:

我经常被客户要求正确实现LotusScript的

continue = false

在Notes'查询 *事件中。一个很常见的情况是表单的 QueryOpen 事件,我们实际上可以根据某些条件停止打开相关文档的过程,例如基于用户对话框的响应。

对于某些Xpages事件,例如 querySaveDocument ,有非常明显的解决方案,而对于其他人,我只建议重新思考整个逻辑,例如在更早的阶段阻止代码执行。但当然大多数人都更喜欢像“使用......重写这些代码”这样的通用方法。并且 - 说实话 - 我想知道自己;)

我或多或少熟悉Xpages / JSF生命周期,但不得不承认我没有正确的想法如何在任何给定阶段停止执行。 一如既往,任何提示都是受欢迎的。

编辑(澄清我的问题,但也回应蒂姆在下面的回答):

不仅仅是QuerySave,而且还有QueryModeChange和QueryRecalc以某种方式需要与存在的应用程序的逻辑一起转换,但在Xpages逻辑中没有它们的等价物。这两个概念(基于表单和基于xpages)在这一点上是否过于不同?

作为一个例子,我们需要在允许在潜在作者的编辑模式中打开现有文档之前检查某些条件。在我的Notes客户端应用程序中,我向2个事件添加了一些代码,即 QueryOpen ,其中我检查了“ mode ”arg和第二个 QueryModeChange ,在哪里检查当前的doc模式。在这两种情况下,如果需要,我可以通过添加continue = false来阻止编辑文档。根据事件,文档将不会更改其模式,或者根本不会打开。

使用Xpage我可以使用按钮来更改文档的编辑模式,我可以“隐藏”这些按钮,或者只是添加一些检查代码或其他任何内容。 但17年的Domino咨询至少给我上了一课:总会有用户找到隐藏的方法来实现他们的目标。在我们的案例中,他们可能会发现对页面URL的简单修改最终将允许他们编辑文档。为了防止这种情况,我可以使用“ beforeRenderResponse ”事件,我假设。但是,在其他情况下也会调用 beforeRenderResponse ,因此我们必须首先调查当前的情况。或者我可以确保用户没有作者权限,除非情况允许。

同样,这不是一个大问题,但是当从传统Notes应用程序进行转换时,这意味着重新思考其整个逻辑。这使得这项工作更加明显,而且更加昂贵。

真?或者我错过了这个概念的一些关键部分?

1 个答案:

答案 0 :(得分:8)

将您的活动结构化为操作组,并在适用时返回false。这将导致跳过组中的所有剩余操作。

例如,您可以拆分"保存"按钮分为两个单独的动作:

1

// by default, execute additional actions:
var result = true;
/* execute some logic here */
if (somethingFailed) {
    result = false;
}
return result;

somethingFailed替换为基于您使用的任何逻辑代替块注释的评估,以确定它是否适合现在保存文档。

2

return currentDocument.save();

如果第一个动作返回save(),上述模式不仅会导致调用false,而且因为save()反过来又返回一个布尔值,理论上你可以还将第三个操作添加为postSave事件:如果保存成功,第三个操作将自动运行;如果保存失败,将自动跳过第三个操作。

应将所有queryModeChange逻辑移至包含所有其他可编辑内容的面板(或XPage或自定义控件的readonly根)的view属性...您将基本上只是翻转布尔值:传统上,queryModeChange会将false(对于Continue)视为不应编辑文档的指示(尽管这也会强制您检查用户是否正试图从阅读更改为编辑,因为如果您放弃此检查,您可能还会阻止用户在已编辑时将模式更改回读取,而readonly如果内容不可编辑,当然应该返回true

由于queryModeChange方法几乎总是另外一层"无花果叶"安全性,在XPages中,通过实际的安全机制来处理这个问题要好得多; readonly属性明确用于强制执行安全性。此外,代替使用readonly,您可以使用acl复杂属性,该属性也可用于面板,XPage和自定义控件,以便为不同的用户子集提供不同的权限;例如,具有特定角色的任何人都将自动进行编辑,而默认条目的级别可以根据指示当前"状态"的项目值来计算。和/或"受让人"。使用这些机制中的任何一个(或两者),用户对URL的作用并不重要......如果容器是只读的,则相关组件不能可编辑。他们甚至可以尝试通过在Chrome开发者工具中运行JavaScript来尝试入侵,尝试模拟将在 编辑内容时发送的POST请求...他们发送的数据仍然不会被推送回到模型,因为目标组件是凭借其容器的属性是只读的。

尝试将所有Notes客户端模式直接应用于XPage上下文几乎总是令人沮丧 - 而且最终是徒劳的。虽然我在这里没有透露细节,但我(和我认识的一些最聪明的人)以很高的成本学到了这一课。虽然用户可能会说(甚至相信)他们想要他们已经拥有的东西......如果他们这样做了,他们会保留他们已有的东西,而不是付钱给你把它变成别的东西。因此,任何从Notes客户端应用程序迁移到XPage"等效的"是你有机会重新审视原因用于完成它所做的事情的代码,并确定是否有意义保留在XPage中,不仅基于Notes客户端和XPage范例之间的差异,而且还有用户与用户之间的任何差异。业务流程是在开发Notes客户端应用程序时,以及他们的流程现在。 省略此评估可确保生成的应用程序将运行它不需要的代码,并且无法充分利用目标平台。

queryRecalc就是一个很好的例子:通常,当用户的桌面和网络资源负责执行复杂和/或网络密集的重新计算时,会阻止重新计算以优化性能。在XPages中,这一切都发生在服务器上,因此来自浏览器的网络请求返回一个页面,其中所有内容都已更改,对于最终用户来说通常不会比没有任何变化的页面更昂贵(除非有极端差异)在实际发送的标记量中)。除非构成组件绑定到服务器重新计算的昂贵数据,否则重新计算的逻辑阻止对用户提供很少或没有性能优势。此外,如果你试图在某个事件中阻止重新计算,那你就太晚了:XPages使用的是"生命周期"它由6个阶段组成,因此当您的事件代码运行时,您尝试阻止的任何重新计算都已经发生。因此,如果阻止重新计算的原因是为了优化性能,请实施范围缓存策略,以确保您只在有意义的情况下提取新数据,并且最终用户体验将足够高效而无需预防重新计算整个页面。另一方面,如果queryRecalc被用作另一个无花果叶(某些 已更改,但我们不希望 向用户显示尚未更新),应该重新审视逻辑肯定以确定它是否仍然适用,仍然(如果有的话)是一个好主意,以及平台的哪些部分现在最适合满足业务流程目标。

总之,使用XPages独有的安全机制来锁定部分或全部页面,并使用我们在Notes客户端中没有的内存范围来确保应用程序运行良好。将用于包含此逻辑的事件移植到继续包含此逻辑的XPage事件可能无法产生所需的结果并浪费迁移到XPage的一些好处。