无法调用 JSF 2.0 复合组件内的方法

发布于 2024-12-12 04:36:06 字数 8091 浏览 0 评论 0原文

我正在学习在 JSF 2.0 中使用复合组件。

首先我创建了这个组件如下。 它声明一个托管Bean并直接调用托管Bean的方法。

<h:commandButton 
                                action = "#{cc.attrs.managedBean.toogleEditing}"
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>

这是该组件的完整代码:

<ui:component          
              xmlns="http://www.w3.org/1999/xhtml" 
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:h="http://java.sun.com/jsf/html"
           xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:p="http://primefaces.prime.com.tr/ui"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface>
        <composite:attribute 
                name ="managedBean"         
                type = "java.lang.Object"
            required ="true">                   
        </composite:attribute>
    </composite:interface>

    <composite:implementation>
        <f:view contentType="text/html"> 
            <h:form id="componentes">  
                <h:panelGrid columns="3">
                    <h:panelGroup>              
                        <h:outputText 
                              escape = "false" 
                               value = "#{cc.attrs.managedBean['value']}"       
                            rendered = "#{!cc.attrs.managedBean['editing']}"/> 
                        <p:editor 
                            widgetVar = "editor" 
                                value = "#{cc.attrs.managedBean.value}" 
                             rendered = "#{cc.attrs.managedBean.editing}"/>
                    </h:panelGroup>

                    <h:commandButton 
                                action = "#{cc.attrs.managedBean.toogleEditing}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>

                    <p:commandButton 
                                action = "#{cc.attrs.managedBean.toogleEditing}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>
                </h:panelGrid>
            </h:form>                    
        </f:view>
    </composite:implementation>
</ui:component>

在第二个测试中,我创建了一个作为方法的属性。

<composite:attribute 
                        name = "action" 
            method-signature = "void action()"
                    required = "true"/>  

我使用该属性来调用该方法,而不是上面从托管Bean 调用该方法的其他版本。

<h:commandButton 
                                action = "#{cc.attrs.action}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>


This is the code of the second component:   

<ui:component          
              xmlns = "http://www.w3.org/1999/xhtml" 
            xmlns:f = "http://java.sun.com/jsf/core"
            xmlns:h = "http://java.sun.com/jsf/html"
           xmlns:ui = "http://java.sun.com/jsf/facelets"
            xmlns:p = "http://primefaces.prime.com.tr/ui"
    xmlns:composite = "http://java.sun.com/jsf/composite">

    <composite:interface>
        <composite:attribute 
                name = "managedBean"            
                type = "java.lang.Object"
            required = "true">                  
        </composite:attribute>
        <composite:attribute 
                        name = "action" 
            method-signature = "void action()"
                    required = "true"/>  
    </composite:interface>

    <composite:implementation>
        <f:view contentType="text/html"> 
            <h:form id="componentes">  
                <h:panelGrid columns="3">
                    <h:panelGroup>              
                        <h:outputText 
                              escape = "false" 
                               value = "#{cc.attrs.managedBean['value']}"       
                            rendered = "#{!cc.attrs.managedBean['editing']}"/> 
                        <p:editor 
                            widgetVar = "editor" 
                                value = "#{cc.attrs.managedBean.value}" 
                             rendered = "#{cc.attrs.managedBean.editing}"/>
                    </h:panelGroup>

                    <h:commandButton 
                                action = "#{cc.attrs.action}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>

                    <p:commandButton 
                                action = "#{cc.attrs.action}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>
                </h:panelGrid>
            </h:form>                    
        </f:view>
    </composite:implementation>
</ui:component>

这是我调用这两个组件的 xhtml 页面:

<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html 
             xml:lang="pt" 
                 lang="pt"
                xmlns="http://www.w3.org/1999/xhtml" 
              xmlns:f="http://java.sun.com/jsf/core"
              xmlns:h="http://java.sun.com/jsf/html"
             xmlns:ui="http://java.sun.com/jsf/facelets"
              xmlns:p="http://primefaces.prime.com.tr/ui"
    xmlns:components="http://java.sun.com/jsf/composite/components">

    <h:head id="head">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Editable HTML Text Sample</title>
    </h:head>

    <h:body id="body">
        <f:view contentType="text/html"> 
            <h:form>       
                <p:panel header="Editable HTML Text Sample">

                    <components:EditableHTMLText 
                        managedBean = "#{editableHTMLText}"/>

                </p:panel>       

                <p:panel header="Editable HTML Text Sample Direct Action">

                    <components:EditableHTMLTextPrimeFaces 
                        managedBean = "#{editableHTMLText}" 
                             action = "#{editableHTMLText.toogleEditing}"/>

                </p:panel>                                                                  
            </h:form>                    
        </f:view>
    </h:body>
</html>

问题是,在此 index.xhtml 中,如果我调用这两个组件,则第二个组件(具有在属性标记中声明的方法的组件)将不起作用。 如果在index.xhtml中,我评论第一个组件。比第二个工作得好。 一定是某种冲突,但我不明白为什么。 有什么提示吗?

这就是豆子:

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;


@ManagedBean
@SessionScoped
public class EditableHTMLText implements Serializable{

    /**
     * 
     */
    private static final long   serialVersionUID    = 8439126615761864409L;

    private String              value               = "Test<br>of<br>HTML<br>text<br><b>ITEM</b><br>";
    private boolean             editing             = false;


    public void toogleEditing(){

        this.setEditing(!this.isEditing());
        System.out.println("Editing State: " + this.editing);
    }


    public String getValue(){

        return value;
    }


    public void setValue(String value){

        this.value = value;
    }


    public boolean isEditing(){

        return editing;
    }


    public void setEditing(boolean editing){

        this.editing = editing;
    }

}

I am learning to use Composite Componentes in JSF 2.0.

First I created this component bellow.
It declares a managedBean and call a method of the managedBean directly.

<h:commandButton 
                                action = "#{cc.attrs.managedBean.toogleEditing}"
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>

This is the full code of the component:

<ui:component          
              xmlns="http://www.w3.org/1999/xhtml" 
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:h="http://java.sun.com/jsf/html"
           xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:p="http://primefaces.prime.com.tr/ui"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface>
        <composite:attribute 
                name ="managedBean"         
                type = "java.lang.Object"
            required ="true">                   
        </composite:attribute>
    </composite:interface>

    <composite:implementation>
        <f:view contentType="text/html"> 
            <h:form id="componentes">  
                <h:panelGrid columns="3">
                    <h:panelGroup>              
                        <h:outputText 
                              escape = "false" 
                               value = "#{cc.attrs.managedBean['value']}"       
                            rendered = "#{!cc.attrs.managedBean['editing']}"/> 
                        <p:editor 
                            widgetVar = "editor" 
                                value = "#{cc.attrs.managedBean.value}" 
                             rendered = "#{cc.attrs.managedBean.editing}"/>
                    </h:panelGroup>

                    <h:commandButton 
                                action = "#{cc.attrs.managedBean.toogleEditing}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>

                    <p:commandButton 
                                action = "#{cc.attrs.managedBean.toogleEditing}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>
                </h:panelGrid>
            </h:form>                    
        </f:view>
    </composite:implementation>
</ui:component>

In this second test I created a attribute that is a method.

<composite:attribute 
                        name = "action" 
            method-signature = "void action()"
                    required = "true"/>  

I call the method using the attribute instead of the other version above that calls the method from the managedBean.

<h:commandButton 
                                action = "#{cc.attrs.action}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>


This is the code of the second component:   

<ui:component          
              xmlns = "http://www.w3.org/1999/xhtml" 
            xmlns:f = "http://java.sun.com/jsf/core"
            xmlns:h = "http://java.sun.com/jsf/html"
           xmlns:ui = "http://java.sun.com/jsf/facelets"
            xmlns:p = "http://primefaces.prime.com.tr/ui"
    xmlns:composite = "http://java.sun.com/jsf/composite">

    <composite:interface>
        <composite:attribute 
                name = "managedBean"            
                type = "java.lang.Object"
            required = "true">                  
        </composite:attribute>
        <composite:attribute 
                        name = "action" 
            method-signature = "void action()"
                    required = "true"/>  
    </composite:interface>

    <composite:implementation>
        <f:view contentType="text/html"> 
            <h:form id="componentes">  
                <h:panelGrid columns="3">
                    <h:panelGroup>              
                        <h:outputText 
                              escape = "false" 
                               value = "#{cc.attrs.managedBean['value']}"       
                            rendered = "#{!cc.attrs.managedBean['editing']}"/> 
                        <p:editor 
                            widgetVar = "editor" 
                                value = "#{cc.attrs.managedBean.value}" 
                             rendered = "#{cc.attrs.managedBean.editing}"/>
                    </h:panelGroup>

                    <h:commandButton 
                                action = "#{cc.attrs.action}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>

                    <p:commandButton 
                                action = "#{cc.attrs.action}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>
                </h:panelGrid>
            </h:form>                    
        </f:view>
    </composite:implementation>
</ui:component>

This is the xhtml page that I call both components:

<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html 
             xml:lang="pt" 
                 lang="pt"
                xmlns="http://www.w3.org/1999/xhtml" 
              xmlns:f="http://java.sun.com/jsf/core"
              xmlns:h="http://java.sun.com/jsf/html"
             xmlns:ui="http://java.sun.com/jsf/facelets"
              xmlns:p="http://primefaces.prime.com.tr/ui"
    xmlns:components="http://java.sun.com/jsf/composite/components">

    <h:head id="head">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Editable HTML Text Sample</title>
    </h:head>

    <h:body id="body">
        <f:view contentType="text/html"> 
            <h:form>       
                <p:panel header="Editable HTML Text Sample">

                    <components:EditableHTMLText 
                        managedBean = "#{editableHTMLText}"/>

                </p:panel>       

                <p:panel header="Editable HTML Text Sample Direct Action">

                    <components:EditableHTMLTextPrimeFaces 
                        managedBean = "#{editableHTMLText}" 
                             action = "#{editableHTMLText.toogleEditing}"/>

                </p:panel>                                                                  
            </h:form>                    
        </f:view>
    </h:body>
</html>

The problem is that in this index.xhtml if I call both components the second component (the one with the method declared in the attribute tag) doesn't work.
If in index.xhtml I comment the first component. Than the second works fine.
Must be some kind of conflict but I don't understand why.
Any hints?

And this is the bean:

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;


@ManagedBean
@SessionScoped
public class EditableHTMLText implements Serializable{

    /**
     * 
     */
    private static final long   serialVersionUID    = 8439126615761864409L;

    private String              value               = "Test<br>of<br>HTML<br>text<br><b>ITEM</b><br>";
    private boolean             editing             = false;


    public void toogleEditing(){

        this.setEditing(!this.isEditing());
        System.out.println("Editing State: " + this.editing);
    }


    public String getValue(){

        return value;
    }


    public void setValue(String value){

        this.value = value;
    }


    public boolean isEditing(){

        return editing;
    }


    public void setEditing(boolean editing){

        this.editing = editing;
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仙女山的月亮 2024-12-19 04:36:06

快速思考一下:我看到您将 f:view 放在两个组件中。我的理解是只需要/允许一个。我什至整个项目都没有。

Just a quick thought: I see that you put the f:view in both components.My understanding is that only one is needed/allowed. I even don't have any in the whole project.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文