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

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

问题描述

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



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



所以,这里是:



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


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



    panel.hide()
    form.setReadOnly(true)


  2. GUI元素许可要求,例如:



    form.requires('READ','FORM_READ_ROLE' / p>

    adminPanel.requires('ADMIN_ROLE')


  3. 用户权限信息基本上是用户具有的角色;


  4. 授权逻辑:根据用户权限确定要隐藏/禁用的元素;


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




  • GUI元素(需要一定的访问权限)使用GPM注册他们的权限信息,像这样:



    GPM.register(这是'DEPARTMENT_DELETE_ROLE'); //按钮删除部门


  • GPM维护GUI许可注册列表


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


  • GPM通过GUI许可注册列表并根据用户权限确定哪个部分的GUI隐藏,并依次调用element.hide()




strong>:




  • GUI元素以树状层次结构组织,例如面板包含按钮栏和窗体,因此当面板被隐藏时,如果按钮栏和窗体需要隐藏,则无需进一步检查。 问题:如何在GPM中注册和维护此层次信息?

  • 目前,我只能想到GUI元素的两个用例:隐藏元素或集一个元素为只读(如表单)。还有其他用例吗?

  • 在ExtJS中,为了隐藏一个元素,我们称之为hide(),但是要设置一个只读的表单,我们必须提出自己的函数,这就是所谓的setReadOnly ),如何让GPM知道要调用哪个函数?作为注册的一部分传递函数

  • 设置表单的唯一方法是什么?如果我使用setReadOnly()函数来扩展表单组件,那么会有很多代码复制,我必须为需要权限控制的每个表单都这样做。是否可以在GPM中创建一个动态表单变换器,以便如果一个表单设置为只读,它会自动用只显示字段替换所有可编辑的字段?


解决方案

Q1:分层UI元素隐藏 - 优化您的GPM以避免隐藏已经通过父级隐藏的元素不会有太多的性能提升我的想法。我的理由:


  1. 您在用户登录时加载权限,而不是所有时间。

  2. 根据编码方式,需要额外的处理来确定层次结构。

  3. 有了足够的规划,您可以避免注册几十个组件并粘贴到总体容器。 li>

如果你真的想跟踪分层信息,你可以随时使用'contains'方法,所有的容器组件都提供了检查一个DisplayObject包含在其子列表中的任何位置(包括链条下)。这可以在每次注册组件时调用,以检查它是否已经具有已注册的父级。



然后可以在字典中设置一个标志,以忽略该组件的隐藏。该标志可以在迭代注册组件列表的同时首先进行检查,以确定应隐藏哪些内容。字典可以使用与注册组件的UID相对应的密钥。此外,当这个标志可以忽略其他GPM功能时,可以忽略该标志,例如表单禁用(因为表单永远不会被看到)。



Q2 。在我的头顶,您可以禁用/启用组件,实施状态更改或拦截事件以及所有警报。这真是太广泛的一个问题,因为任何事情都可以做 - 真的由设计师。



Q3。您可以:


  1. 在注册组件时提供参数,例如指示它们是什么类型(用于隐藏的容器,用于设置读取的表单只有等等)

  2. 检查每个组件的注册情况,以确定要使用的组件。

您将基本上与各种组件建立合同,GPM了解他们的界面,并相应地与他们进行互动。



Q4。您可以随时设置要禁用的表单(enabled = false)。这可以防止任何用户交互。一些皮肤将会更改,以表示组件被禁用,因此您可能需要修改其外观以防止某些显示行为。在这一行上,您还可以更改其外观以隐藏某些元素,例如TextInput框的边框,以使其看起来更像是一个视图而不是禁用输入。



可以创建一个使用RichText组件等改变TextInputs的变压器。这将需要大量的工作,并且应该被构建到扩展的Form类而不是GPM。我认为每个组件类型的不同外观状态可能是一个更好的解决方案,以避免创建和破坏组件,只是为了更改表单的显示方式。


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.

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.

So, here it goes:

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

  1. GUI element manipulation code, for example:

    panel.hide() form.setReadOnly(true)

  2. GUI element permission requirement, for example:

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

    adminPanel.requires('ADMIN_ROLE')

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

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

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 elements (that need certain permission to access) register their permission information with GPM, like this:

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

  • GPM maintains a list of GUI permission registration

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

  • 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

Questions:

  • 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: 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. You load permissions once when a user logs in, not all the time.
  2. Depending on how it is coded, additional processing will be needed to determine the hierarchy anyways.
  3. With adequate planning you could avoid registering dozens and dozens of components and stick to overarching containers.

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.

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).

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.

Q3. You could:

  1. Provide parameters when registering your components, such as to indicate what type they are (container for hiding, form for setting to read only, etc.)
  2. Check each component as it is registered to determine what is going to be done with it.

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

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.

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天全站免登陆