Можно ли вызвать параметризованный метод-подпись внутри составного компонента? - PullRequest
5 голосов
/ 07 июля 2011

В настоящее время я создаю композитный компонент JSF с сигнатурой метода, которая может принимать параметры.

Вот выдержка:

<composite:interface>
    ....
    <composite:attribute name="activateHeroMethod" method-signature="java.util.List action(id.co.sofcograha.core.Dto, id.co.sofcograha.core.Dto)" />
</composite:interface>

<composite:implementation>
    ....
    <p:commandLink value="#{hero.map['heroName']}"
        process="@this"
        update="#{cc.attrs.update}"
        oncomplete="infoRaceDialog.hide()"
        image="ui-icon ui-icon-search">
        <f:setPropertyActionListener value="#{hero}"
            target="#{cc.attrs.activateHeroMethod(infoRaceBean.race, hero)}" />
    </p:commandLink>
    ....
</composite:implementation>

target = "# {cc.attrs.activateHeroMethod (infoRaceBean.race, hero)}" "1007 * ужасно завершается со следующим сообщением об ошибке:

javax.faces.view.facelets.TagAttributeException: /resources/sofco/infoRace.xhtml @57,76 target="#{cc.attrs.activateHeroMethod(infoRaceBean.race, hero)}" /resources/sofco/infoRace.xhtml @57,76 target="#{cc.attrs.activateHeroMethod(infoRaceBean.race, hero)}" Illegal attempt to pass arguments to a composite component lookup expression (i.e. cc.attrs.[identifier]).
        at com.sun.faces.facelets.tag.TagAttributeImpl.getValueExpression(TagAttributeImpl.java:401)
        at com.sun.faces.facelets.tag.TagAttributeImpl.getValueExpression(TagAttributeImpl.java:351)
        at com.sun.faces.facelets.tag.jsf.core.SetPropertyActionListenerHandler.applyAttachedObject(SetPropertyActionListenerHandler.java:128)
        at com.sun.faces.facelets.tag.jsf.core.SetPropertyActionListenerHandler.apply(SetPropertyActionListenerHandler.java:101)

Можно ли вызвать параметризованный метод из атрибута составного компонента? Я думаю, что могу работать с множеством как обходной путь работы с несколькими параметрами в одном методе, но мне не нравится подход, так как он будет увеличиваться в размере вместе с параметрами.

Я мог бы обернуть каждый параметр в 1 объект-обертку, но мне все еще любопытно, есть ли способ решить проблему вызова метода с несколькими параметрами.

Пожалуйста, поделитесь своими мыслями!

Спасибо.

Ответы [ 3 ]

8 голосов
/ 02 апреля 2012

Да, возможно сделать это, сделайте это так:

<composite:interface displayName="Image uploader with preview list">
        <composite:attribute name="backingBean" required="true" />
        <composite:attribute name="imageType" required="true"  />
</composite:interface>
....
<p:commandButton  value="Save"  actionListener="#{cc.attrs.backingBean.imageUploaded(cc.attrs.imageType)}"/>

Надеюсь, это поможет какому-то телу.

0 голосов
/ 22 февраля 2018

чтобы любой человек, у которого была такая же проблема, мог попробовать что-то вроде этого

<composite:attribute name="methodName" method-signature="java.lang.String f(java.lang.String, java.lang.String)" required="false" />
0 голосов
/ 04 февраля 2017

Композитный компонент:

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

    <cc:interface>

        <cc:attribute name="header" type="java.lang.String" required="true"/>

        <cc:attribute name="value" required="true"/>
        <cc:attribute name="update" type="java.lang.String" required="false" default=""/>
        <cc:attribute name="controller" required="true"/>

        <cc:attribute name="addLine" required="true" method-signature="void addLine()"/>
        <cc:attribute name="deleteLine" type="java.lang.String" required="true"/>

    </cc:interface>

    <cc:implementation>

        <div id="#{cc.clientId}">

            <p:panel header="#{cc.attrs.header}">

                <p:dataTable id="table" value="#{cc.attrs.value}" var="line">

                    <p:column headerText="#{cc.attrs.header}">
                        <h:outputText value="#{line.entry}"/>
                    </p:column>

                    <p:column width="32">
                        <f:facet name="header">
                            <p:commandButton title="#{msgs.add}" icon="fa fa-plus"
                                             type="button">
                                <f:ajax listener="#{cc.attrs.addLine}" render="#{cc.attrs.update} table"/>
                            </p:commandButton>
                        </f:facet>
                        <p:commandButton title="#{msgs.delete}" icon="fa fa-minus"
                                         type="button">
                            <f:ajax listener="#{cc.attrs.controller[cc.attrs.deleteLine](line)}" render="#{cc.attrs.update} table"/>
                            <p:confirm message="#{msgs.deleteString}" icon="ui-icon-alert"/>
                        </p:commandButton>
                    </p:column>

                </p:dataTable>

            </p:panel>

        </div>

    </cc:implementation>

</ui:component>

Page:

<ui:composition
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
        xmlns:any="http://java.sun.com/jsf/composite/components"
>

    <!--@elvariable id="controller" type="org.controllers.AnyController"-->
    <any:row
            header="#{msgs.subjective}"
            value="#{controller.entity.things}"
            update="form:growl form:save"
            controller="#{anyController}"
            addLine="#{anyController.addTheLine}"
            deleteLine="deleteTheLine"/>

</ui:composition>

Controller:

@javax.inject.Named
@javax.enterprise.context.SessionScoped
public class AnyController
{
    ...

    public void addTheLine()
    {
        ...
    }

    public void deleteTheLine(final Line anyLine)
    {
        ...
    }

    ...
}
...