我有一个XHTML页面,它描述了以下用户复合组件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui_component="http://java.sun.com/jsf/composite/ui_component" >
    <h:body>
         <h:form id="mergeform">          
                    <p:separator/>
                    <p:panelGrid styleClass="tableEdit" style="width: 100%">
                        <f:facet name="header">
                            <p:row>    
                                <p:column colspan="2">  
                                    <h:outputLabel style="font-size: 20px;" value="1-ое застрахованное лицо" />    
                                </p:column>
                                <p:column style="text-align: right; width: 20em;">
                                    <p:commandButton style="font-size: 14px;" value="Общий поиск" immediate="true" 
                                                     onclick="dialogPersonList.show();document.getElementById('mergeform:personNumber').value = '1';dlg22Search.show();" 
                                                     action="#{mergeBean.updateListPerson}"
                                                     oncomplete="dlg22Search.hide();"
                                                     update=":mergeform:enpsearchtable mergeform:checkSearch"/>
                                </p:column> 
                            </p:row> 
                        </f:facet>                  
                        <p:row>    
                            <p:column colspan="3">
                                <ui_component:personTable id="First" form="mergeform" id_link="Second" bean="#{mergeBean}" val="#{mergeBean.merge}" smoChanger="true" >
                                    <f:validator validatorId="FIOValidator" for="FIOValid" />                               
                                </ui_component:personTable>                            
                          </p:column> 
                        </p:row> 
                    </p:panelGrid>
                    <p:panelGrid styleClass="tableEdit" style="width: 100%">
                        <f:facet name="header">
                            <p:row>    
                                <p:column colspan="2">  
                                    <h:outputLabel style="font-size: 20px;" value="2-ое застрахованное лицо" />  
                                </p:column>
                                <p:column style="text-align: right; width: 20em;">
                                    <p:commandButton style="font-size: 14px;" value="Общий поиск" immediate="true" 
                                                     onclick="dialogPersonList.show();document.getElementById('mergeform:personNumber').value = '2';dlg22Search.show();"
                                                     action="#{mergeBean.updateListPerson}" 
                                                     oncomplete="dlg22Search.hide();"
                                                     update=":mergeform:enpsearchtable mergeform:checkSearch" />
                                </p:column> 
                            </p:row> 
                        </f:facet>
                        <p:row>    
                            <p:column colspan="3">  
                                <ui_component:personTable id="Second" bean="#{mergeBean}" val="#{mergeBean.merge.inputData}" smoChanger="true" >
                                    <f:validator validatorId="FIOValidator" for="FIOValid" />  
                                </ui_component:personTable>
                            </p:column> 
                        </p:row> 
                    </p:panelGrid>
         </h:form>        
    </h:body>
</html>

组件本身是一个具有多行的panelGrid . 例如,我领导了问题发生的地方 . 说明验证员我也降低了 .

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"  
      xmlns:ui="http://java.sun.com/jsf/facelets">

    <cc:interface>
        <cc:attribute name="id" />
        <cc:attribute name="bean" />
        <cc:attribute name="val" />
        <cc:attribute name="id_link" />
        <cc:attribute name="form" />
        <cc:attribute name="readonly" default="false" />
        <cc:attribute name="smoChanger" default="false" />
        <cc:editableValueHolder name="FIOValid" targets="Secondname#{cc.attrs.id}" />
        <cc:editableValueHolder name="DocValid" targets="DocNum#{cc.attrs.id}" />
        <cc:editableValueHolder name="PolValid" targets="PolNum#{cc.attrs.id}" />
        <cc:editableValueHolder name="PlaceBirthValid" targets="PlaceBirth#{cc.attrs.id}" />
        <cc:editableValueHolder name="EnpValid" targets="Enp#{cc.attrs.id}" />  
        <cc:editableValueHolder name="OgrnValid" targets="Ogrn#{cc.attrs.id}" />  
    </cc:interface>

    <cc:implementation>
        <p:panelGrid id="#{cc.attrs.id}Person" style="font-size: 14px; width: 100%" styleClass="tableEdit" >                                                  
            <p:row>    
                <p:column style="width: 180px">  
                    <h:outputLabel for="Secondname#{cc.attrs.id}" value="Фамилия: " />
                </p:column>
                <p:column>
                    <p:inputText id="Secondname#{cc.attrs.id}" value="#{cc.attrs.val.secondname}" 
                                 readonly="#{cc.attrs.readonly}" >    
                        <p:ajax event="blur" process="@this" update="Secondname#{cc.attrs.id} ErrorsSecondname#{cc.attrs.id}" /> 
                        <p:ajax event="blur" listener="#{cc.attrs.bean.changeField}"
                                update="Secondname#{cc.attrs.id} ErrorsSecondname#{cc.attrs.id} 
                                :#{cc.attrs.form}:#{cc.attrs.id_link}:Secondname#{cc.attrs.id_link} 
                                :#{cc.attrs.form}:#{cc.attrs.id_link}:ErrorsSecondname#{cc.attrs.id_link}"
                                disabled="#{empty cc.attrs.id_link}" />
                    </p:inputText>
                </p:column>
                <p:column>
                    <h:message showSummary="false" showDetail="true"
                               style="color: red; font-size: 15px; 
                               text-decoration: underline;"
                               id="ErrorsSecondname#{cc.attrs.id}"
                               for="Secondname#{cc.attrs.id}"/> 
                </p:column>
            </p:row>       
        </p:panelGrid>  
    </cc:implementation>
</html>

在bean MergeBean中,我描述了监听器,这只是一个错误发生 .

@ManagedBean
@SessionScoped
public class MergeBean implements Serializable {

    private Person selectedPerson;

    public MergeBean() {
    }

    public Message getMerge() {
        if (this.merge == null) {
            this.merge = new Message();
            this.merge.setInputData(new Message());
        }
        return this.merge;
    }

    public void setMerge(Message merge) {
        this.merge = merge;
    }

    public void changeField(AjaxBehaviorEvent event) {
        String id = event.getComponent().getId();
        String valStr = ((HtmlInputText) event.getComponent()).getValue().toString();
        if (valStr != null && !valStr.isEmpty()) {
            String idChange = id.substring(0, id.length() - 5);
            UIInput input = (UIInput) UtilsUIXhtml.findComponent(idChange + "Second");
            //TODO
            Object objTemp = input.getSubmittedValue();
            //String tempStr = objTemp.toString();
            String cngStr = input.getValue().toString();
            if (cngStr == null || cngStr.isEmpty()) {
                input.setValue(valStr);
            }
        }
    }
}

我正在尝试绑定到第一个自定义组件中的第一个文本输入和方法,以在第二个自定义组件中查找关联的文本输入,并检查其值为空和null . 但是当我在pery输入中插入一行时,第二个输入到调试器input.getValue() . ToString()等于用户输入的值,而不是它确实存在的事实 . 为什么会发生这种情况?如何才能在听众中获得真正的 Value ?

PS所以我正在寻找DOM树中的组件:

public static UIComponent findComponent(final String id) {
    FacesContext context = FacesContext.getCurrentInstance();
    UIViewRoot root = context.getViewRoot();
    final UIComponent[] found = new UIComponent[1];

    root.visitTree(new FullVisitContext(context), new VisitCallback() {
        @Override
        public VisitResult visit(VisitContext context, UIComponent component) {
            if (component.getId().equals(id)) {
                found[0] = component;
                return VisitResult.COMPLETE;
            }
            return VisitResult.ACCEPT;
        }
    });

    return found[0];
}