客户端脚本最佳做法
虽然开发客户端脚本对于资深的 JavaScript 开发人员来说似乎很容易,但考虑使用这些脚本时,请务必注意最佳做法。 开发人员也会经常忽略用户可以使用其他方法访问数据, 例如,他们可以使用数据导入或导出、制作者工作室、画布应用、第三方桌面应用、shell 脚本等。您应使用客户端脚本来解决特定的客户端 UI 问题,并增强特定模型驱动应用中的用户体验。 它不是一项安全措施,也不能够解决所有问题。 在许多情况下,您需要结合运用客户端方法与服务器端方法(如 Dataverse 插件),以确保所有访问点都实现业务要求。
使用解决方案检查器
解决方案检查器可以根据一组最佳做法规则对您的解决方案执行静态分析检查,并快速识别这些有问题的模式。 该检查包括用于客户端脚本的 JavaScript。 一旦出现性能、稳定性和可靠性问题,检查器就会识别出来,这可能会对用户体验造成不利影响。 检查器还可以发现使用已弃用的方法的情况。 定期运行时,您可以主动识别并修正问题,避免用户遇到这些问题。 解决方案检查器可从 Maker Portal 按需运行,也可以作为自动生成流程的一部分运行。 这种自动化将使其定期运行,并成为您持续进行的应用程序生命周期管理流程的一部分。
有关使用解决方案检查器的详细信息,请参阅产品文档中的在 Power Apps 中使用解决方案检查器验证您的应用。
业务规则与客户端脚本
业务规则是模型驱动应用中提供的一项功能,使用户能够根据某些要求和条件对窗体执行经常需要执行的操作。 具体来说,业务规则可以执行以下任务:
设置字段值
清除字段值
设置字段要求级别
显示或隐藏窗体列控件
启用或禁用窗体列控件
验证数据并显示错误消息
基于商业智能创建业务建议。
业务规则的一个显著特征是,在适用时,表作用域的规则可以自动将逻辑应用于后端。 此范围可确保在应用中,无论是通过用户界面、数据导入还是 API 方法调用运行操作,都保持一致。 在这些场景中,客户端脚本本身不完全等效。
虽然现有的业务规则框架十分稳健,但可能在某些场景中,业务规则无法完全实现指定要求。 在这种情况下,客户端脚本可以缩小业务规则与更高要求之间的差异。 以下是用户在使用业务规则时遇到的一些常见限制,在这类情况下,客户端脚本可能是更恰当的解决方案。
引用相关数据
如果您需要引用相关表中包含的数据,例如客户主要联系人的地址,您将需要使用客户端脚本和 Web API。
需要对窗体保存事件运行逻辑
业务规则仅在窗体载入和字段更改时运行,除非将作用域设置为表。 如果您需要对“保存窗体”事件运行业务逻辑,则需要使用客户端脚本。
复杂条件
如果您的条件具有多个 and
语句或需要 or
语句,则在客户端脚本中写入这些类型的条件可能比使用业务规则更有效。
清除窗体数据的值
在业务规则中,无法轻松地清除窗体列中的数据。 虽然可以通过变通解决方法来实现本操作,即分配始终包含 NULL 值的“虚拟”列,但使用客户端脚本更轻松。
计算列与客户端脚本
计算列在检索时运行逻辑,因此在刷新窗体之前,任何客户端更改都不会反映在计算列的值中。 如果您希望在窗体上立即更新数据,客户端脚本将是您的首选方法。 客户端脚本通常补充使用计算列或汇总列、插件等执行的后端实现。本组合方法可在应用中提供一致的用户体验,同时确保后端的数据一致性和完整性。
编码标准和最佳做法
以下部分介绍编码的最佳做法和标准。
定义唯一脚本函数名称
您写入的函数很可能位于包含许多其他库的窗体中。 如果另一个库中有一个函数的名称与您提供的名称相同,则最后加载的函数将是窗体使用的函数。 为了避免产生冲突,请务必使用唯一的函数名称。 如果您或贵组织尚未建立以下策略,则您可以使用以下策略:
唯一函数前缀 - 使用标准语法和包含唯一命名约定的一致名称定义您的每个函数,如以下示例中所示。
function MyUniqueName_performMyAction() { // Code to perform your action. }
具有命名空间的库 - 将您的每个函数与脚本对象相关联,以创建命名空间在调用函数时使用,如以下示例中所示。
//If the MyUniqueName namespace object isn’t defined, create it. if (typeof (MyUniqueName) == "undefined") { MyUniqueName = {}; } // Create Namespace container for functions in this library; MyUniqueName.MyFunctions = { performMyAction: function(){ // Code to perform your action. //Call another function in your library this.anotherAction(); }, anotherAction: function(){ // Code in another function } };
使用函数时指定全名,如以下示例中所示。
MyUniqueName.MyFunctions.performMyAction();
提示
如果您调用的函数位于另一个函数中,且这两个函数位于同一个命名空间,您可以使用 this 关键字作为快捷方式,指向同时包含这两个函数的对象。 但是,如果您的函数作为事件处理程序使用,则 this 关键字将引用事件所发生的对象。
避免使用不支持的方法
虽然一些第三方在线资源可能会建议或提供示例,说明您可以使用不受支持的方法执行某些操作,但不支持也不建议这样做。 这些方法无法保证在后续的应用版本中能够发挥作用,并且可能会破坏实现的稳定性。 您还应当避免使用通过检查调试器中的 API 对象而发现的方法(如果您发现的方法没有出现在客户端 API 引用文档中的官方记录)。
查看已弃用方法的代码
人们正在持续开发和改进客户端 API。 请务必查看代码库,以了解已弃用方法的使用情况,并按照文档建议替换这些已弃用的方法。 如果您使用解决方案检查器,则检查器会将其标记为问题。
避免在窗体和功能区命令中使用 jQuery
窗体脚本或命令栏命令中不支持 jQuery 和其他直接 HTML DOM 操作库。 您应该将脚本限制为仅使用客户端 API 对象模型中的方法。 有关详细信息,请参阅了解客户端 API 对象模型。
写入非阻塞代码
执行查询或流程密集型活动时,请确保使用异步模式,以确保提供没有阻塞的用户体验。
尽量避免使用阻塞 UI 的方法,如确认对话框、阻止进度指示器等。与用户交互的首选方法是使用非侵入性通知机制,如应用或窗体中醒目的警报区域。
为多个浏览器写入代码
确保您写入的任何脚本已进行测试,可用于模型驱动应用的用户所支持的所有浏览器和设备规格。 有关详细信息,请参阅支持的 Web 浏览器和移动设备。