Программно получение UIComponents представления JSF в конструкторе bean

Представьте себе страницу JSF с несколькими компонентами, такими как <h:selectOneMenu>, <h:dataTable>, <h:panelGrid> и т.д. Каждый компонент имеет идентификатор. Есть ли какой-либо метод или способ, с помощью которого я могу получить компоненты программным образом, когда вызывается конструктор bean?

Ответ 1

Вы можете получить дерево компонентов FacesContext#getViewRoot() и найти конкретный компонент по идентификатору UIComponentBase#findComponent():

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

Однако корень представления напрямую не доступен в конструкторе bean. Он может возвращать null в GET-запросы к представлению, в котором bean не ссылается на тег или атрибут времени построения представления. Тем не менее он гарантированно будет доступен во время предварительного просмотра.

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

с

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

Несвязанный к конкретной проблеме, неясно, зачем вам это нужно, но я могу сказать, что это больше, чем часто запах кода. Я предлагаю исследовать, действительно ли это правильное решение для конкретного функционального требования, которое вы имели в виду. Для подсказок и подсказок см. Также Как работает атрибут привязки в JSF? Когда и как его использовать? и Как правильно использовать привязку компонентов в JSF? (компонент с охватом запросов в области сеанса связи bean).

Ответ 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

Я хочу спросить, что я получил форму (HtmlForm) здесь, но panel1 и myTable null, почему? Хотя я получаю панель и таблицу, проверяя детей HtmlForm, но почему я не могу получить их напрямую.

Спасибо

Ответ 3

см. этот 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;
}

Ответ 4

Если панель и таблица находятся в форме, попробуйте выполнить следующее:

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