在JSF中按类型查找组件 [英] Find component by type in JSF

查看:96
本文介绍了在JSF中按类型查找组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与此中的所有隐藏输入字段有关动态地使用JSF ,但是它与我想使用JSF而不是纯HTML并希望在.xhtml文件中包含以下内容的方式不同:

My question is related to this one Get all hidden input fields in JSF dynamically but it's not the same as I want to work with JSF and not plain HTML, and assuming that I have the following in my .xhtml file:

<h:inputHidden id="name1" value="SomeValue1"/>
<h:inputHidden id="name2" value="SomeValue2"/>

我开发了一个小代码,试图在其中动态获取所有h:inputHidden标记并将其值打印到控制台,但是问题是我无法找到一种使所有内容动态化的方法.在我的代码中,如果要遍历uicomponents,我应该知道id的形式,如何遍历组件树中的所有UIComponent? (我尝试过UIViewRoot#getChildren(),但我只有第一个孩子).

I developed a small code where I tried to get all the h:inputHidden tags dynamically and print their values to the console, but the problem is that I can't figure out a way how to make everythning dynamic. In my code I should know the form id if I want to Iterate over the uicomponents, how can I iterate over all the UIComponent in the component tree ? (I tried UIViewRoot#getChildren() but i get only the first childrens).

这是代码段:

// 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());

}

推荐答案

您还需要遍历孩子的孩子以及他们的孩子等.您会看到,它是的组成部分.

You also need to iterate over children of children, and their children, etcetera. You see, it's a component tree.

以下是实用程序方法的启动代码段,该方法使用尾递归来实现:

Here's a kickoff snippet of an utility method which does exactly that using 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);
    }
}

这是您可以使用它的方式:

Here's how you could use it:

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

或者更好地,使用访问者模式.主要区别在于,它还迭代了诸如<ui:repeat><h:dataTable>之类的迭代组件,并为每次迭代恢复了子状态.否则,当在组件中包含<h:inputHidden>时,最终将毫无价值.

Or, better, use UIComponent#visitTree() which uses the visitor pattern. The major difference is that it also iterates over iterating components such as <ui:repeat> and <h:dataTable> and restores the child state for every iteration. Otherwise you would end up getting no value when you have an <h:inputHidden> enclosed in such component.

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);
}

另请参见:

  • 如何在bean的action方法中的UIData组件内收集UIInput组件的值?
  • 在JSF托管Bean中访问动态UIComponent
  • JSF 2-保存所有有效的组件值
  • See also:

    • 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>中:

      After all, it's probably easiest to just bind them to a bean property the usual way, if necessary inside an <ui:repeat>:

      <h:inputHidden id="name1" value="#{bean.name1}"/>
      <h:inputHidden id="name2" value="#{bean.name2}"/>
      

      这篇关于在JSF中按类型查找组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆