在 JSF 中按类型查找组件
Find component by type in JSF
我的问题与这个问题有关 但它与我想使用 JSF 而不是普通的 HTML 不同,并且假设我的 [=12] 中有以下内容=] 文件:
<h:inputHidden id="name1" value="SomeValue1"/>
<h:inputHidden id="name2" value="SomeValue2"/>
我开发了一个小代码,我试图动态获取所有 h:inputHidden
标签并将它们的值打印到控制台,但问题是我无法想出如何使一切动态化的方法.在我的代码中,如果我想遍历 uicomponents,我应该知道 id
的形式,我如何遍历组件树中的所有 UIComponent
? (我试过 UIViewRoot#getChildren()
但我只得到第一个孩子)。
这是代码片段:
// formId is the id of my form
List<UIComponent> components = FacesContext.getCurrentInstance().getViewRoot().findComponent("formId").getChildren();
// A List of UIComponent where I am adding my Hidden Inputs
List<UIComponent> hiddenComponents = new ArrayList<UIComponent>();
for (UIComponent component : components) {
// using the hidden inputs type in JSF: HtmlInputHidden
if (component instanceof HtmlInputHidden) {
hiddenComponents.add(component);
}
}
for (UIComponent component : hiddenComponents) {
// Printing the hidden inputs values for demonstration purposes
System.out.println(((HtmlInputHidden)component).getValue());
}
您还需要迭代 children of children,以及它们的 children,等等。你看,它是一个组件 tree.
这是一个实用方法的启动片段,它使用 tail recursion:
public static <C extends UIComponent> void findChildrenByType(UIComponent parent, List<C> found, Class<C> type) {
for (UIComponent child : parent.getChildren()) {
if (type.isAssignableFrom(child.getClass())) {
found.add(type.cast(child));
}
findChildrenByType(child, found, type);
}
}
以下是您的使用方法:
UIForm form = (UIForm) FacesContext.getCurrentInstance().getViewRoot().findComponent("formId");
List<HtmlInputHidden> hiddenComponents = new ArrayList<>();
findChildrenByType(form, hiddenComponents, HtmlInputHidden.class);
for (HtmlInputHidden hidden : hiddenComponents) {
System.out.println(hidden.getValue());
}
或者,更好的是,使用 UIComponent#visitTree()
which uses the visitor pattern。主要区别在于它还迭代 <ui:repeat>
和 <h:dataTable>
等迭代组件,并为每次迭代恢复 child 状态。否则,当您将 <h:inputHidden>
包含在此类组件中时,您最终将得不到任何价值。
FacesContext context = FacesContext.getCurrentInstance();
List<Object> hiddenComponentValues = new ArrayList<>();
context.getViewRoot().findComponent("formId").visitTree(VisitContext.createVisitContext(context), new VisitCallback() {
@Override
public VisitResult visit(VisitContext visitContext, UIComponent component) {
if (component instanceof HtmlInputHidden) {
hiddenComponentValues.add(((HtmlInputHidden) component).getValue());
return VisitResult.COMPLETE;
} else {
return VisitResult.ACCEPT;
}
}
});
for (Object hiddenComponentValue : hiddenComponentValues) {
System.out.println(hiddenComponentValue);
}
另请参阅:
- How to collect values of an UIInput component inside an UIData component in bean's action method?
- How do I attach a FacesMessage from the backing bean to a specific field in a ui:repeat?
- Accessing dynamic UIComponents in JSF Managed Bean
- JSF 2 -- Save All Valid Component Values
毕竟,最简单的方法可能是将它们以通常的方式绑定到 bean 属性,如有必要,可以在 <ui:repeat>
:
中
<h:inputHidden id="name1" value="#{bean.name1}"/>
<h:inputHidden id="name2" value="#{bean.name2}"/>
我的问题与这个问题有关
<h:inputHidden id="name1" value="SomeValue1"/>
<h:inputHidden id="name2" value="SomeValue2"/>
我开发了一个小代码,我试图动态获取所有 h:inputHidden
标签并将它们的值打印到控制台,但问题是我无法想出如何使一切动态化的方法.在我的代码中,如果我想遍历 uicomponents,我应该知道 id
的形式,我如何遍历组件树中的所有 UIComponent
? (我试过 UIViewRoot#getChildren()
但我只得到第一个孩子)。
这是代码片段:
// formId is the id of my form
List<UIComponent> components = FacesContext.getCurrentInstance().getViewRoot().findComponent("formId").getChildren();
// A List of UIComponent where I am adding my Hidden Inputs
List<UIComponent> hiddenComponents = new ArrayList<UIComponent>();
for (UIComponent component : components) {
// using the hidden inputs type in JSF: HtmlInputHidden
if (component instanceof HtmlInputHidden) {
hiddenComponents.add(component);
}
}
for (UIComponent component : hiddenComponents) {
// Printing the hidden inputs values for demonstration purposes
System.out.println(((HtmlInputHidden)component).getValue());
}
您还需要迭代 children of children,以及它们的 children,等等。你看,它是一个组件 tree.
这是一个实用方法的启动片段,它使用 tail recursion:
public static <C extends UIComponent> void findChildrenByType(UIComponent parent, List<C> found, Class<C> type) {
for (UIComponent child : parent.getChildren()) {
if (type.isAssignableFrom(child.getClass())) {
found.add(type.cast(child));
}
findChildrenByType(child, found, type);
}
}
以下是您的使用方法:
UIForm form = (UIForm) FacesContext.getCurrentInstance().getViewRoot().findComponent("formId");
List<HtmlInputHidden> hiddenComponents = new ArrayList<>();
findChildrenByType(form, hiddenComponents, HtmlInputHidden.class);
for (HtmlInputHidden hidden : hiddenComponents) {
System.out.println(hidden.getValue());
}
或者,更好的是,使用 UIComponent#visitTree()
which uses the visitor pattern。主要区别在于它还迭代 <ui:repeat>
和 <h:dataTable>
等迭代组件,并为每次迭代恢复 child 状态。否则,当您将 <h:inputHidden>
包含在此类组件中时,您最终将得不到任何价值。
FacesContext context = FacesContext.getCurrentInstance();
List<Object> hiddenComponentValues = new ArrayList<>();
context.getViewRoot().findComponent("formId").visitTree(VisitContext.createVisitContext(context), new VisitCallback() {
@Override
public VisitResult visit(VisitContext visitContext, UIComponent component) {
if (component instanceof HtmlInputHidden) {
hiddenComponentValues.add(((HtmlInputHidden) component).getValue());
return VisitResult.COMPLETE;
} else {
return VisitResult.ACCEPT;
}
}
});
for (Object hiddenComponentValue : hiddenComponentValues) {
System.out.println(hiddenComponentValue);
}
另请参阅:
- How to collect values of an UIInput component inside an UIData component in bean's action method?
- How do I attach a FacesMessage from the backing bean to a specific field in a ui:repeat?
- Accessing dynamic UIComponents in JSF Managed Bean
- JSF 2 -- Save All Valid Component Values
毕竟,最简单的方法可能是将它们以通常的方式绑定到 bean 属性,如有必要,可以在 <ui:repeat>
:
<h:inputHidden id="name1" value="#{bean.name1}"/>
<h:inputHidden id="name2" value="#{bean.name2}"/>