根据用户权限隐藏/禁用 GUI 元素的最佳方法? [英] Best way to hide/disable GUI elements based on user's privilege?

查看:20
本文介绍了根据用户权限隐藏/禁用 GUI 元素的最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在启动一个 Web 应用程序,客户端在纯 ExtJS 中实现,中间层在 Grails 中实现.应用程序具有基于角色的授权,其中用户可以拥有许多细粒度的角色,如 SOME_FORM_READ、SOME_FORM_UPDATE、SOME_DATA_DELETE、SOME_DATA_READ 等.根据用户的角色,某些 GUI 元素需要禁用或隐藏,而其他则需要处于只读模式.

I am starting a web application with client side implemented in pure ExtJS and middle tier in Grails. The application has role-based authorization, where a user can have many fine grained roles like SOME_FORM_READ, SOME_FORM_UPDATE, SOME_DATA_DELETE, SOME_DATA_READ, etc. Based on the roles of the user, certain GUI elements need to be disabled or hidden, while others need to be in a read-only mode.

我在网上进行了一些搜索,但没有找到任何专门解决这个问题的设计模式,所以我想出了自己的设计.我相信很多 Web 应用程序都会有类似的要求,所以我想在这里发布我的设计并听取人们的意见.我的设计绝不是完美的,但我希望可以通过每个人的投入来改进它.虽然我使用的是 ExtJS,但总体设计也应该适用于类似的框架,如 GWT、Flex、Swing 等.

I did some search on the web, but didn't find any design pattern that specifically addresses this issue, so I came up with my own design. I am sure that a lot of the web applications out there will have a similar requirement, so I'd like to post my design here and hear people's opinion on it. By no means is my design a perfect one, but I hope it can be improved with everyone's input. Although I am working with ExtJS, the general design should also apply to similar frameworks like GWT, Flex, Swing, etc.

关于授权,我们需要在客户端层处理四种类型的代码(或信息):

There are four types of code (or information) we need to deal with in the client tier regarding authorization:

  1. GUI 元素操作代码,例如:

  1. GUI element manipulation code, for example:

panel.hide()form.setReadOnly(true)

panel.hide() form.setReadOnly(true)

GUI 元素权限要求,例如:

GUI element permission requirement, for example:

form.requires('READ', 'FORM_READ_ROLE')

form.requires('READ', 'FORM_READ_ROLE')

adminPanel.requires('ADMIN_ROLE')

adminPanel.requires('ADMIN_ROLE')

用户权限信息,基本上就是用户拥有的角色列表;

User privilege information, which is basically a list of roles that the user has;

授权逻辑:根据用户权限决定隐藏/禁用哪些元素;

Authorization logic: determines which elements to hide/disable based on user privilege;

设计的核心是一个单例,名为 GUIPermissionManager,简称 GPM.这是一种集中式设计,因为大部分代码都在GPM中,因此GUI元素不会被授权代码污染.这就是 GPM 的工作原理:

The core of the design is a singleton, named GUIPermissionManager, or GPM for short. This is a centralized design in that most of the code is in GPM, so that GUI elements are not polluted by the authorization code. This is how GPM works:

  • GUI 元素(需要特定权限才能访问)向 GPM 注册其权限信息,如下所示:

  • GUI elements (that need certain permission to access) register their permission information with GPM, like this:

GPM.register(this, 'DEPARTMENT_DELETE_ROLE');//删除部门的按钮

GPM.register(this, 'DEPARTMENT_DELETE_ROLE'); // button for deleting a department

GPM 维护一个 GUI 权限注册列表

GPM maintains a list of GUI permission registration

在用户登录时,GPM 会收到用户分配的角色列表

On user login, GPM receives the list of roles the use is assigned

GPM 遍历 GUI 权限注册列表,并根据用户权限确定要隐藏 GUI 的哪个部分,然后相应地调用 element.hide()

GPM walks through the GUI permission registration list and based on user privilege, determines which part of the GUI to hide, and in turn, calls element.hide() accordingly

问题:

  • GUI 元素以树状层次结构组织,例如一个面板包含一个按钮栏和一个表单,所以当面板隐藏时,不需要进一步检查按钮栏和表单是否需要隐藏.问题:如何在 GPM 中注册和维护这些分层信息?
  • 目前,我只能想到 GUI 元素的两个用例:隐藏元素或将元素设置为只读(例如表单).还有其他用例吗?
  • 在ExtJS中,要隐藏一个元素,我们调用hide(),但是要设置一个只读的表单,我们必须想出我们自己的函数,假设它叫做setReadOnly(),如何让GPM知道是哪个调用函数?将函数作为注册的一部分传递?
  • 将表单设置为只读的最佳方法是什么?如果我使用 setReadOnly() 功能扩展表单组件,将会有很多代码重复,我必须为每个需要权限控制的表单执行此操作.是否可以在 GPM 中创建动态表单转换器,以便如果表单设置为只读,它会自动将所有可编辑字段替换为仅显示字段?
  • GUI elements are organized in a tree hierarchy, e.g. a panel contains a button bar and a form, so when the panel is hidden, there is no need to check further if the button bar and the form need to be hidden. Problem: how to register and maintain this hierarchical information in GPM?
  • Currently, I can only think of two use cases for GUI element: hide an element or set an element as read-only (such as a form). Is there any other use cases?
  • In ExtJS, to hide an element, we call hide(), but to set a form read-only, we have to come up with our own function, let's say it's called setReadOnly(), how to let GPM know which function to call? Passing the function as part of the registration?
  • What is the best way to set a form read-only? If I extend the form component with the setReadOnly() functionality, there will be a lot of code duplication and I have to do this for every form that need permission control. Is it possible to create a dynamic form transformer in GPM so that if a form is set to read-only, it automatically replaces all editable fields with display-only fields?

推荐答案

Q1:分层 UI 元素隐藏 - 优化 GPM 以避免隐藏已经通过父级隐藏的元素不会对我的性能有很大提升观点.我的理由:

Q1: Hierarchical UI element hiding - Optimizing your GPM to avoid hiding elements that are already hidden via a parent is not going to have much of a performance boost in my opinion. My reasons:

  1. 您在用户登录时加载一次权限,而不是一直加载.
  2. 根据编码方式,无论如何都需要额外的处理来确定层次结构.
  3. 通过充分规划,您可以避免注册数十个组件并坚持使用总体容器.

如果您真的想跟踪层次信息,您可以始终使用所有容器组件提供的包含"方法来检查 DisplayObject 是否包含在其子列表中的任何位置(包括链下游).每次注册组件时都可以调用它来检查它是否已经有一个注册的父组件.

If you really want to keep track of hierarchical information you can always use the 'contains' method that all container components provide for checking if a DisplayObject is contained anywhere in its child list (including down the chain). This could be called up each time a component is registered to check if it already has a registered parent.

然后可以在字典中设置一个标志来忽略隐藏在该组件上.在迭代注册组件列表以确定应该隐藏什么时,可以首先检查此标志.字典可以使用与注册组件的 UID 对应的键.此外,当需要忽略其他 GPM 功能时,此标志可用于忽略组件,例如禁用表单(因为无论如何都不会看到该表单).

A flag could then be set in a dictionary to ignore hiding on that component. This flag could get checked first while iterating over the list of registered components to determine what should be hidden. The dictionary could use keys that correspond to the registered component's UID. Furthermore this flag could be used to ignore the component when it comes time to ignore other GPM functions, like form disabling (as the form would never be seen anyways).

第 2 季度.您可以禁用/启用组件、实现状态更改或拦截事件以及所有警报.这个问题实在是太宽泛了,因为任何事情都可以做——这完全取决于设计师.

Q2. Off the top of my head you could disable/enable components, implement state changes, or intercept events, and all alerts. This is really too broad of a question as anything could be done - really up to the designer.

第三季度.你可以:

  1. 在注册你的组件时提供参数,例如指明它们是什么类型(用于隐藏的容器、用于设置为只读的表单等)
  2. 在注册时检查每个组件,以确定将要对其执行的操作.

本质上,您将与各种组件签订合同,其中 GPM 知道它们的接口并相应地与它们交互.

You would essentially be establishing a contract with various components where the GPM is aware of their interfaces and interacts with them accordingly.

第四季度.您始终可以将表单设置为禁用(启用 = 假).这可以防止任何用户交互.某些外观会发生变化以指示组件已禁用,因此您可能需要修改它们的外观以防止某些此类显示行为.在该行中,您还可以更改它们的外观以隐藏某些元素,例如 TextInput 框的边框,使其看起来更像是视图"而不是禁用的输入.

Q4. You can always set a form to be disabled (enabled = false). This prevents any user interaction. Some skins will change to indicate that the components are disabled so you may want to modify their skins to prevent some of this display behavior. On that line, you could also change their skins to hide certain elements such as the TextInput box's border so as to make it look more like a 'view' than a disabled input.

可以创建一个转换器",使用 RichText 组件等更改 TextInputs.这将需要大量的工作,并且可能应该构建到扩展的 Form 类而不是 GPM 中.我认为每个组件类型的不同皮肤状态可能是一个更好的解决方案,以免只是为了改变表单的外观而创建和销毁组件.

It would be possible to create a 'transformer' that changes TextInputs with RichText components and such. This would take a decent amount of work and should probably be built into an extended Form class instead of the GPM. I think different skins states for each component type may be a better solution, so as to avoid creation and destruction of components just to change how the form appears.

这篇关于根据用户权限隐藏/禁用 GUI 元素的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆