首页 文章

在向JSF组件树动态添加新组件时重复id

提问于
浏览
3

使用JSF 2.1,Mojarra 2.1.3,Glassfish 3.1.1和PrimeFaces 3.3.1

我正在尝试在preRenderView事件中处理JSF中的处理字段级安全性,并且在需要向JSF组件树添加动态组件时遇到问题 . 在第一次渲染时,一切都很好,并且处理了场级安全性 . 然而,在任何类型的更新之后,Mojarra抱怨重复的id,即使通过打印到控制台,我的添加代码每次更新只运行一次 .

看起来Mojarra似乎没有清除回发的组件树,因此每次后续渲染的更新都会向树中添加组件的其他版本 .

感谢任何人都能提供的帮助 . 这是一些愚蠢的示例代码 . 在commandButton上单击引发的错误 .

的index.xhtml:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"
        >
    <f:event listener="#{lifeCycle.event}" type="preRenderView" />
    <h:body>
        <h:form id="form" prependId="false">
            <h:panelGroup id="testPanel">
                <h:inputText id="viewSec" value="viewSec node"/>
</h:panelGroup> <p:commandButton update="testPanel"/> </h:form> </h:body> </html>

LifeCycle.java:

package com.dynamic.test;

import java.io.Serializable;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.visit.VisitContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;

@ManagedBean
@RequestScoped
public class LifeCycle implements Serializable {
    public void event(ComponentSystemEvent event){
        FacesContext facesContext = FacesContext.getCurrentInstance();
        UIViewRoot root = facesContext.getViewRoot();
        NodeInspector visitCallback = new NodeInspector();

        root.visitTree(VisitContext.createVisitContext(FacesContext.getCurrentInstance()), visitCallback);

        List<UIComponent> securityEnabledComponents = visitCallback.getSecurityEnabledComponents();
        for (UIComponent securityEnabledComponent : securityEnabledComponents) {

            if(securityEnabledComponent.getClientId().equals("viewSec")){
                List<UIComponent> childList = securityEnabledComponent.getParent().getChildren();
                int targetPosition = securityEnabledComponent.getParent().getChildren().indexOf(securityEnabledComponent);

                HtmlOutputText outputTextComponent = new HtmlOutputText();
                outputTextComponent.setId(securityEnabledComponent.getId());
                outputTextComponent.setValue(securityEnabledComponent.getAttributes().get("value"));

                childList.set(targetPosition, outputTextComponent);
            }
        }
    }
}

NodeInspector.java

package com.dynamic.test;

import java.util.ArrayList;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;

public class NodeInspector implements VisitCallback {
    private List<UIComponent> securityEnabledComponents = new ArrayList<UIComponent>();
    FacesContext facesContext = FacesContext.getCurrentInstance();

    @Override
    public VisitResult visit(final VisitContext context, final UIComponent target) {
        if(target.getClientId().equals("viewSec")){
            securityEnabledComponents.add(target);
        }
        return VisitResult.ACCEPT;
    }

    public List<UIComponent> getSecurityEnabledComponents() {
        return securityEnabledComponents;
    }
}

错误:

SEVERE: JSF1007: Duplicate component ID viewSec found in view.
    ...  +id: j_idt2
       type: <html xmlns="http://www.w3.org/1999/xhtml">

      +id: j_idt3
       type: javax.faces.component.UIOutput@17098e7
        +id: form
         type: javax.faces.component.html.HtmlForm@14677de
          +id: testPanel
           type: javax.faces.component.html.HtmlPanelGroup@167ab25
            +id: viewSec  <===============
             type: javax.faces.component.html.HtmlOutputText@14a3d2e
            +id: viewSec  <===============
             type: javax.faces.component.html.HtmlOutputText@f6a607
            +id: j_idt4
             type: 
+id: j_idt5 type: org.primefaces.component.commandbutton.CommandButton@1380fc5 +id: j_idt6 type: </html>... SEVERE: Error Rendering View[/index.xhtml] java.lang.IllegalStateException: Component ID viewSec has already been found in the view. at com.sun.faces.util.Util.checkIdUniqueness(Util.java:821)...

1 回答

  • -1

    检查您使用的Mojarra版本是否与Primefaces 3.3.1兼容 .
    使用最新版本的Primefaces 3.6 .

相关问题