adf - 如何修改树中的组件?

时间:2009-07-14 12:31:08

标签: jsf oracle-adf

来自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();
  }
  ...
}

3 个答案:

答案 0 :(得分:2)

你真的需要在演示方面这样做。不要使用phaselistener,它不适用。明智地使用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'}" />

答案 1 :(得分:0)

根据我(有限)搜索文档,UIViewRoot对象是视图树的根节点。您可以使用它的getChildren方法来查找相应的UIComponent并进行修改。但是,我建议采用不同的方式。

如果将Authorization服务公开为bean,则可以直接将方法添加到标记中。例如......

public class User {
...
Map<String, Boolean> allowedRoles;
...
public Map<String, Boolean> getAllowedRoles { return allowedRoles; }
}

<h:inputText value="#{SomethingImportant}" disabled="!#{User.allowedRoles['importantRole']}/>

更好的是使用安全框架,这将进一步简化这一过程。

答案 2 :(得分:0)

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