【问题标题】:Programmatically getting UIComponents of a JSF view in bean's constructor在 bean 的构造函数中以编程方式获取 JSF 视图的 UIComponents
【发布时间】:2012-01-20 12:14:45
【问题描述】:

想象一个 JSF 页面,其中包含多个组件,例如 <h:selectOneMenu><h:dataTable><h:panelGrid> 等。每个组件都有一个 ID。当调用 bean 的构造函数时,是否有任何方法或技术可以通过编程方式获取组件?

【问题讨论】:

  • “pragmatic”的含义与“programmatic”完全不同。如果您不确定拼写,请查阅字典:)

标签: jsf-2


【解决方案1】:

您可以通过FacesContext#getViewRoot() 获取组件树,并通过UIComponentBase#findComponent() 通过ID 查找特定组件:

UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
UIComponent component = viewRoot.findComponent("someId");
// ...

但是,视图根在 bean 的构造函数本身中并不直接可用。它可能会在 GET 请求上将 null 返回到视图,其中视图构建时间标记或属性中未引用 bean。但是,它保证在预渲染视图事件期间可用。

<f:event type="preRenderView" listener="#{bean.init}" />

public void init() {
    // ...
}

与具体问题无关,尚不清楚您为什么需要这样做,但我可以看出这通常是代码异味。我建议调查一下这是否真的是您想到的具体功能需求的正确解决方案。有关线索和提示,另请参阅 How does the 'binding' attribute work in JSF? When and how should it be used?How to use component binding in JSF right ? (request-scoped component in session scoped bean)

【讨论】:

  • 这段代码对我有用。但是您必须指定组件的完整路径,例如“form:component1:someId”
  • @Mindaugas:如果它们又在 NamingContainer 中,那是正确的。另请参阅我的回答中 findComponent() 的 javadoc 的链接。
  • @BalusC,你的“无关”在这里最有价值!
【解决方案2】:

我尝试了您的解决方案,它奏效了 :)。在这里,我只是发布我的答案,我是如何做到的。实际上有人刚刚问我这个问题,当我们的页面调用时,我们可以在构造函数中获取所有组件,即为什么我在这个论坛上问:)。这是我的代码

/** Creates a new instance of ExporterProfileUpdateRequestGrid */
public ExporterProfileUpdateRequestGrid() {

    session = ConnectionUtil.getCurrentSession();
    exporterProfileUpdateRequestList = new ArrayList<ExporterProfileUpdateRequest>();

    int test = selectedRadioButton;
    System.out.println();
    //getExporterProfileUpdateRequestGrid();

} //end of constructor

@PostConstruct
public void init() {

    UIViewRoot viewRoot =  FacesContext.getCurrentInstance().getViewRoot();
    UIComponent component1 = viewRoot.findComponent("exporterProfileUpdateRequestGrid");  //form id
    HtmlForm form = (HtmlForm)component1;

    List<UIComponent> componentList = form.getChildren();

    for(int i=0; i<componentList.size(); i++) {

        UIComponent component = componentList.get(i);

        if (component instanceof Panel) {

            Panel myPanel = (Panel)component;

            List<UIComponent> panelComponentList = myPanel.getChildren();

            for(int j=0; j<panelComponentList.size(); j++) {

                UIComponent panelComponent = panelComponentList.get(j);

                System.out.println();


            }

             System.out.println();

        }

        System.out.println();

    } //end of for()

    UIComponent component2 = viewRoot.findComponent("panel1");   //null
    UIComponent component3 = viewRoot.findComponent("myTable");  // null

} //end of init

我想问我这里有form(HtmlForm),但是panel1和myTable为空,为什么?虽然我通过检查 HtmlForm 子项获得面板和表格,但为什么我不能直接获得它们。

谢谢

【讨论】:

    【解决方案3】:

    如果面板和表格都在表格中,请尝试以下操作:

    UIComponent component2 = viewRoot.findComponent("exporterProfileUpdateRequestGrid").findComponent("panel1");
    

    【讨论】:

      【解决方案4】:

      看到这个http://horrikhalid.com/2011/01/27/how-to-find-uicomponent-in-jsf/

      public UIComponent findComponent(String id) {
      
      UIComponent result = null;
      UIComponent root = FacesContext.getCurrentInstance().getViewRoot();
      if (root != null) {
      result = findComponent(root, id);
      }
      return result;
      
      }
      
      private UIComponent findComponent(UIComponent root, String id) {
      
      UIComponent result = null;
      if (root.getId().equals(id))
      return root;
      
      for (UIComponent child : root.getChildren()) {
      if (child.getId().equals(id)) {
      result = child;
      break;
      }
      result = findComponent(child, id);
      if (result != null)
      break;
      }
      return result;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 2017-10-23
        • 1970-01-01
        • 2011-06-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多