代码之家  ›  专栏  ›  技术社区  ›  andersonbd1

如何修改树中的组件?

  •  0
  • andersonbd1  · 技术社区  · 15 年前

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

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

    那么在adf 11g中如何做到这一点呢?我正在尝试实现一个应用程序范围的授权系统,其中的组件根据用户的角色可见/可编辑。但是,我找不到一种方法在响应被写出之前挂接到adf来修改组件(例如RichInputText.setDisabled(true))。我试过相位传感器和视图处理器。这些似乎都不允许我执行上述功能。那又有什么好处呢?我运气不好吗?我遗漏了什么吗?

    谢谢, 本

    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();
      }
      ...
    }
    
    3 回复  |  直到 13 年前
        1
  •  2
  •   BalusC    15 年前

    你真的需要在演讲的时候这样做。不要用鉴相器,因为它不适合。利用 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
  •  0
  •   Drew    15 年前

    根据我对文档的(有限的)搜索,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']}/>
    

    更好的方法是使用一个安全框架,它可以更简化这一点。

        3
  •  0
  •   Kedar    15 年前

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