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