我正在启动一个 Web 应用程序,其客户端在纯 ExtJS 中实现,中间层在 Grails 中实现。该应用程序具有基于角色的授权,其中用户可以拥有许多细粒度的角色,例如 SOME_FORM_READ、SOME_FORM_UPDATE、SOME_DATA_DELETE、SOME_DATA_READ 等。根据用户的角色,某些 GUI 元素需要禁用或隐藏,而其他元素则需要禁用或隐藏。处于只读模式。
我在网上做了一些搜索,但没有找到任何专门解决这个问题的设计模式,所以我想出了自己的设计。我确信很多 Web 应用程序都会有类似的要求,所以我想在这里发布我的设计并听听人们对此的意见。我的设计绝不是完美的,但我希望它能在大家的意见下得到改进。虽然我正在使用 ExtJS,但总体设计也应该适用于类似的框架,如 GWT、Flex、Swing 等。
所以,事情是这样的:
我们需要在客户端层处理有关授权的四种类型的代码(或信息):
-
GUI元素操作代码,例如:
面板.隐藏()
form.setReadOnly(true)
-
GUI元素权限要求,例如:
form.requires('READ', 'FORM_READ_ROLE')
adminPanel.requires('ADMIN_ROLE')
用户权限信息,基本上是用户拥有的角色列表;
授权逻辑:根据用户权限决定隐藏/禁用哪些元素;
设计的核心是一个单例,名为GUIPermissionManager,简称GPM。这是一种集中式设计,大部分代码都在 GPM 中,因此 GUI 元素不会受到授权代码的污染。这就是 GPM 的工作原理:
-
GUI 元素(需要一定的权限才能访问)向 GPM 注册其权限信息,如下所示:
GPM.register(this, 'DEPARTMENT_DELETE_ROLE'); // 删除部门按钮
GPM维护GUI权限注册列表
用户登录时,GPM 会收到分配给该用户的角色列表
GPM 遍历 GUI 权限注册列表,并根据用户权限,确定要隐藏 GUI 的哪一部分,然后相应地调用 element.hide()
问题:
- GUI 元素以树形层次结构组织,例如面板包含按钮栏和窗体,因此隐藏面板时,无需进一步检查是否需要隐藏按钮栏和窗体。Problem:如何在GPM中注册和维护这个层次信息?
- 目前,我只能想到 GUI 元素的两种用例:隐藏元素或将元素设置为只读(例如表单)。还有其他用例吗?
- 在ExtJS中,要隐藏一个元素,我们调用hide(),但是要设置表单只读,我们必须想出自己的函数,假设它称为setReadOnly(),如何让GPM知道调用哪个函数?将函数作为注册的一部分传递?
- 将表单设置为只读的最佳方法是什么?如果我使用 setReadOnly() 功能扩展表单组件,将会出现大量代码重复,并且我必须对每个需要权限控制的表单执行此操作。是否可以在 GPM 中创建动态表单转换器,以便如果表单设置为只读,它会自动将所有可编辑字段替换为仅显示字段?
Q1:分层 UI 元素隐藏 - 在我看来,优化 GPM 以避免隐藏已经通过父级隐藏的元素不会有太大的性能提升。我的理由:
- 您在用户登录时加载一次权限,而不是一直加载权限。
- 根据编码方式,无论如何都需要额外的处理来确定层次结构。
- 通过充分的规划,您可以避免注册数十个组件并坚持使用总体容器。
如果您确实想跟踪层次结构信息,则始终可以使用所有容器组件提供的“contains”方法来检查 DisplayObject 是否包含在其子列表中的任何位置(包括下游链)。每次注册组件时都可以调用它来检查它是否已经有注册的父组件。
然后可以在字典中设置一个标志来忽略该组件上的隐藏。在迭代注册组件列表以确定应隐藏哪些内容时,可以首先检查此标志。字典可以使用与注册组件的 UID 相对应的键。此外,当需要忽略其他 GPM 功能时,例如表单禁用(因为表单永远不会被看到),此标志可用于忽略该组件。
Q2。在我的脑海中,您可以禁用/启用组件、实现状态更改或拦截事件和所有警报。这确实是一个太宽泛的问题,因为任何事情都可以做——这完全取决于设计师。
Q3。你可以:
- 注册组件时提供参数,例如指示它们的类型(用于隐藏的容器、用于设置为只读的表单等)
- 检查注册的每个组件以确定将如何处理它。
您本质上是与各种组件建立契约,其中 GPM 知道它们的接口并相应地与它们交互。
Q4。您始终可以将表单设置为禁用(enabled = false)。这会阻止任何用户交互。某些外观将发生更改以指示组件已禁用,因此您可能需要修改其外观以防止某些此类显示行为。在该行中,您还可以更改它们的外观以隐藏某些元素,例如 TextInput 框的边框,以便使其看起来更像是“视图”而不是禁用的输入。
可以创建一个“转换器”来使用 RichText 组件等更改 TextInputs。这将需要大量的工作,并且可能应该构建到扩展的 Form 类而不是 GPM 中。我认为每个组件类型的不同皮肤状态可能是更好的解决方案,以避免仅仅为了改变表单的显示方式而创建和销毁组件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)