【问题标题】:adf - howto modify components in tree?adf - 如何修改树中的组件?
【发布时间】:2010-11-10 15:17:40
【问题描述】:

来自 jsf 1.2 revB mrel2 规范:第 65 页底部

■ 应用程序必须能够在请求处理生命周期中的任何时候以编程方式修改组件树(视图呈现期间除外),并使系统按预期运行。例如,必须允许以下内容。在渲染期间修改视图可能会导致未定义的结果。必须能够允许模板系统(例如 JSP)添加的组件在渲染之前从树中移除。必须能够以编程方式将组件添加到树中,并让它们呈现在层次结构中的适当位置。必须可以在渲染之前对树中的组件进行重新排序。这些操作确实要求添加到树中的任何组件都具有在最近的父 NamingContainer 组件范围内唯一的 ID。 rendersChildren 属性的值按预期处理,可能为 true 或 false。

那么如何在 adf 11g 中做到这一点?我正在尝试实现一个应用程序范围的授权系统,其中组件根据用户的角色可见/可编辑。但是,在写出响应之前,我无法找到一种方法来挂钩 adf 以修改组件(例如 RichInputText.setDisabled(true))。我已经尝试过 PhaseListeners 和 ViewHandlers。这些似乎都不允许我执行上述功能。那么给了什么?我运气不好?我错过了什么吗?

谢谢, 本

public class AuthorizationPhaseListener implements PhaseListener {
  ...
  public PhaseId getPhaseId() {
    return PhaseId.RENDER_RESPONSE; // I've also tried in the other phases including ALL_PHASES
  }
  public void beforePhase(PhaseEvent p1) {
    // relevant ui components don't yet exist
    ...
  }
  public void afterPhase(PhaseEvent p1) {
    // relevant ui components exist, but have already been written to the stream, thus it's too late to modify them
    ...
  }
  ...
}

public class MyCustomViewHandler extends ViewHandlerWrapper {
  ...
  @Override
  public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException {
    AuthorizationService as = (AuthorizationService)RiscsContext.getCurrentInstance().getBean("AuthorizationService");
    // relevant ui components don't yet exist
    as.applyAuthorization();
    super.renderView(context, viewToRender);
    // relevant ui components exist, but have already been written to the stream, thus it's too late to modify them
    as.applyAuthorization();
  }
  ...
}

【问题讨论】:

    标签: jsf oracle-adf


    【解决方案1】:

    您确实需要在演示端执行此操作。不要使用相位侦听器来执行此操作,它不适合。明智地使用rendered 属性。以下是一些如何使用它的基本示例:

    <h:someComponent rendered="#{bean.booleanValue}" />
    <h:someComponent rendered="#{bean.intValue > 10}" />
    <h:someComponent rendered="#{bean.objectValue == null}" />
    <h:someComponent rendered="#{bean.stringValue != 'someValue'}" />
    <h:someComponent rendered="#{!empty bean.collectionValue}" />
    <h:someComponent rendered="#{!bean.booleanValue && bean.intValue != 0}" />
    <h:someComponent rendered="#{bean.stringValue == 'oneValue' || bean.stringValue == 'anotherValue'}" />
    

    【讨论】:

      【解决方案2】:

      如果它是可定位的,它确实允许访问/修改树中的 UI 组件。使用 findComponent() 时需要提供客户端组件 ID。唯一的问题仍然是它不能让您访问/​​控制初始页面加载( restore_view )。 :-( 到目前为止,我只能找到一种方法是在 jspx/jsp/jsff 中指定 EL。

      【讨论】:

        【解决方案3】:

        根据我(有限)搜索文档, UIViewRoot 对象是视图树的根节点。您可以使用它的 getChildren 方法来查找适当的 UIComponents 并进行修改。不过,我会建议另一种方式。

        如果您将授权服务公开为 bean,则可以直接将方法添加到标记中。比如……

        public class User {
        ...
        Map<String, Boolean> allowedRoles;
        ...
        public Map<String, Boolean> getAllowedRoles { return allowedRoles; }
        }
        
        <h:inputText value="#{SomethingImportant}" disabled="!#{User.allowedRoles['importantRole']}/>
        

        更好的是使用可以进一步简化此操作的安全框架。

        【讨论】:

        • Drew,获取 UIViewRoot 并没有帮助,因为正如我在 cmets 中记录的那样,以下情况之一是正确的: // 相关的 ui 组件尚不存在 // 相关的 ui 组件存在,但已经被写入流我宁愿不必手动将 disabled 属性添加到我的所有 jsfs 中。一方面,这很乏味。另一方面,我们让用户设置角色。因此,我们的要求比该解决方案所允许的要细得多。
        • 我们正在使用安全框架 (acegi) 来帮助我们入门,但我们的要求更深入。我几乎正在编写我们自己的安全框架。我用 aop 做了必要的事情。这是一个 hack,但它有效。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-26
        • 1970-01-01
        • 2020-08-22
        • 1970-01-01
        • 1970-01-01
        • 2018-12-28
        • 1970-01-01
        相关资源
        最近更新 更多