首页 > 解决方案 > 在 Apostrophe CMS 中使用模式创建动态表单

问题描述

我的任务是创建一个动态表单系统。我们正在使用另一个 CRM 类型的平台,它有一个 API,可以通过 API 获取带有字段的表单。

我已经按照撇号-件-提交-小部件教程来做到这一点,但我遇到了一些砖墙。

我正在将其他平台的字段转换为正确的模式字段,没有问题。应用重启后的第一次加载是好的。我将来自其他平台的字段保存在 aposCache 集合中,以便更快地加载它们。这工作正常。

问题 1)

当字段(表单)在另一个平台中更新时,该平台会发送一个 web 挂钩调用,我已在小部件内部的路由中配置了该调用,然后对片段模块进行内部撇号调用,该模块重新缓存并重新生成通过清空字段options.addFields

通过调试,我似乎一切正常,但我正在努力让这个新模式完全应用于下一次加载,而无需重新加载应用程序。正如我所提到的,我的初始加载工作正常(包括将数据发回 CRM),但也在beforeConstructconstruct. 我来自小部件的内部调用发生在construct. 我在想它是关于self.load等等,但我真的坚持做这项工作。

问题2)

功能列表的一部分是,一旦填写了表格,然后我想向网站所有者和填写表格的人发​​送一封电子邮件,使用apostrophe-email它可以很好地与afterInsert片段模块中的模板一起使用。

但我希望这更加动态,并且可以由站点经理(非开发人员)控制。为此,我在小部件中添加了各种字段,站点管理员可以填写这些字段,然后根据自己的喜好修改邮件。问题是,邮件是在afterInsert片段模块的一部分中发送的,并且该模块似乎不知道我在提交它的小部件的字段内有什么内容。有什么办法可以从里面加载afterInsert吗?

问题 3)

CRM 平台有“应用程序”。这是带有字段的表单,可以是 Web 表单,这些表单可以通过 API 加载。这个想法是,在一个站点上,您可以拥有 2-3 或 10 个具有不同字段的表单,连接到 CRM 平台中的不同应用程序。

这个想法是,站点管理员可以将两个凭据从 CRM 平台复制/粘贴到小部件中,使用这两个凭据,Apostrophe 将获取字段并生成表单,并在用户提交数据时发回该应用程序。这意味着我需要能够拥有多个动态模式,而不需要超过我的两个(或者如果需要更多)模块来运行它,即片段模块和片段小部件模块。现在在我看来,我目前的方法是一个站点,一个表单。添加多个小部件,将覆盖所有其余部分。由于我被困在其他部分,我已经推迟了对此的担忧,但如果没有开发人员在网站上创建另一个片段和/或小部件模块,扩展基本模块,这可能是不可能的,

感谢有关我面临的上述任一或所有挑战的任何提示,并再次感谢您提供的出色平台!

标签: apostrophe-cms

解决方案


我对您的问题思考得越多,我就越认为用撇号支持它是一种“强制配合”。撇号的设计是为了“启动”一个特定的模式,该模式保持在原位,或者如果你通过修改 self.schema 变得聪明并设法将其推送到所有进程,则可能偶尔会发生变化,但无论如何,一个片段都有一个模式一次。

而且,从它的声音来看,您甚至不需要存储 Apostrophe 中的提交内容。因此,这里的作品并没有为它们的重量买单。

更合适的是apostrophe-schemas直接使用该模块并在需要时在您选择的集合中实施您的存储,或者在提交时直接将数据发送回其他应用程序。这将您从撇号模块的生命周期中解放出来,并且它与模式的关系保持不变。然后一个模块可以实现许多“应用程序”。

在服务器端,您可以完全自己生成一个模式数组,或者使用apos.schemas.composeaddFields 和arrangeFields 选项等处理对象并随时返回一个模式数组。您可以根据apos.schemas.newInstance给定的架构使用默认值来获取一个新对象。

然后,您可以使用apos.schemas.convert接受提交,并将数据类型参数设置为form. 然后,您有一个干净的对象可以插入到您自己的集合中或发送到您认为合适的 API。

在浏览器端,您可以使用apos.schemas.populate当前(包括默认值)值填充表单,并以服务器端期望apos.schemas.convert的格式准备传出提交。apos.schemas.convert

您仍然可以使用apostrophe-widgets. 它只是不会成为小部件本身架构的一部分 - 只会包含您提到的管理字段。(如您所知,您肯定需要使用该playerData模块的选项来避免那些被推送到浏览器领域,编辑器除外。)

要实际生成表单的标记,这是关键位:

{% import "apostrophe-schemas:macros.html" as schemas %}

<div class="my-form">
  {{ schemas.fields(data.widget._schema) }}
</div>

那么“data.widget._schema”是怎么回事?我在这里设想的是,在您的小部件模块的加载方法中,您将通过与其他应用程序的 API 交谈来确定架构。此时,您可以将它作为 _schema 附加到小部件对象,并带有前导下划线,这样它就不会在任何时候无意中在数据库中结束。


推荐阅读