PrimeFaces CommandButton Действие не вызывается внутри Composite - PullRequest
8 голосов
/ 21 октября 2011

В приведенном ниже коде jsf html action commandButton вызывается идеально. Но простое действие commandButton не вызывается.

<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>
                    <!-- ACTION IS CALLED -->                                 
                    <h:commandButton 
                                action = "#{cc.attrs.managedBean.toogleEditing}" 
                                 value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
                                update = "componentes"/>

                                    <!-- ACTION IS NOT CALLED -->           
                    <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>

Если поместить один и тот же код за пределы композита (обычная страница HTML), оба работают нормально:

<!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">

    <h:head id="head">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Item de Texto</title>
    </h:head>
    <h:body id="body">          
        <f:view contentType="text/html"> 
            <h:form id="componentes">  
                <h:panelGrid columns="3">
                    <h:panelGroup>              
                        <h:outputText 
                              escape = "false" 
                               value = "#{editableHTMLText.value}" 
                            rendered = "#{!editableHTMLText.editing}"/>
                        <p:editor 
                            widgetVar = "editor" 
                                value = "#{editableHTMLText.value}" 
                             rendered = "#{editableHTMLText.editing}"/>
                    </h:panelGroup>

                                    <!-- ACTION IS CALLED -->                         
                    <h:commandButton 
                                action = "#{editableHTMLText.toogleEditing}" 
                                 value = "#{editableHTMLText.editing?'Back':'Edit'}" 
                                update = "componentes"/>

                                    <!-- ACTION IS CALLED -->
                    <p:commandButton 
                                action = "#{editableHTMLText.toogleEditing}" 
                                 value = "#{editableHTMLText.editing?'Back':'Edit'}" 
                                update = "componentes"/>
                </h:panelGrid>
            </h:form>                    
        </f:view>
    </h:body>
</html>

Это код компонента:

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

}

Есть предложения?

Ответы [ 7 ]

18 голосов
/ 15 декабря 2014

Сегодня я столкнулся с точно такой же проблемой с PrimeFaces 5.1. В моем случае у меня не было вложенных форм, и я уже устанавливал атрибут process для p:commandButton с элементами формы, которые я хотел обработать. Однако это еще не сработало.

«Решением» было добавить @this в список компонентов для обработки, например:

<p:commandButton process="myFormField1 myFormField2 @this">

Без @this (что обычно не требуется, поскольку сама кнопка не должна обрабатываться / проверяться). Я не нашел способа заставить что-либо из этого работать внутри композита:

  • <p:commandButton action="#{bean.myAction}"...>
  • <p:commandButton type="button"> с вложенным <p:ajax event="click" action="#{bean.myAction}"...>
  • <p:commandButton type="button" onclick="myAction()"> со связанными <p:remoteCommand name="myAction" action="#{bean.myAction}">

После отладки приложения я увидел, что этапы проверки и обновления модели были выполнены правильно, но затем на этапе вызова приложения событие в очереди отсутствовало и, следовательно, не было выполнено никаких действий. На самом деле, я могу указать все, что мне нравится, в значениях атрибутов action и actionListener, равных <p:commandButton>, без каких-либо жалоб PrimeFaces или JSF.

Вместо этого они работают так, как должны, но у вас нет частичной обработки, поэтому они не могут быть жизнеспособным решением:

  • <p:commandButton action="#{bean.myAction}" ajax="false"...>
  • <p:commandButton type="button"...> с вложенным <f:ajax event="click" action="#{bean.myAction}"...>

Это должна быть ошибка PrimeFaces.

5 голосов
/ 28 октября 2011

Когда вы использовали составной компонент, он уже был помещен в тег h: form? Когда у вас есть вложенные формы, действие командной кнопки не запускается.

Другой проблемой могут быть части Ajax, которые вы пытаетесь. Кнопка Primefaces имеет атрибут update, но в стандартном JSF его нет. Он всегда будет полностью обновлять страницу (за исключением случаев, когда внутри нее используется тег или f: ajax)

1 голос
/ 30 июля 2013

У меня также были проблемы с не запускающими кнопками команды. В моем случае запросы ajax и non-ajax не работали. 1. как описано выше - обязательно удалите все формы в форме. легко сделать с использованием композитов. 2. если у вас несколько кнопок, попробуйте использовать флаг «процесс». Помогло в моем случае.

<p:commandButton id="submitButton" value="Submit" type="submit" 
    actionListener="#{bean.save}"
    update="message"
    process="txtComment, @this"
    icon="ui-icon-disk"/>

process="txtComment, @this" выполняет метод установки для inputText с идентификатором txtComment и методом commandButton.

0 голосов
/ 19 апреля 2018

Я нашел решение этой проблемы

<composite:implementation>
 <p:commandButton onclick="JS_call_to<p:remoteCommand>" />
</composite:implementation>

Внутри вашей главной страницы определите с помощью
<p:remoteCommand action="managedBean.call_function()" update="..." />

Я сделал вызов Gmap с этим из Composite-Component на мою главную страницу

0 голосов
/ 10 февраля 2016

Добавить к вышеприведенным ответам, для полноты.

Одной из проблем, не охваченных в вышеприведенных ответах, является отсутствующий атрибут Targets в composite:interface

Из документов JSF

атрибут target: Если этот элемент имеет метод-подпись атрибута, значение атрибута target должно интерпретироваться как разделенный пробелами (не табуляция) список идентификаторов клиентов (относительно верхней части компонент уровня) компонентов внутри <составной: реализация> раздел. Пространство используется как разделитель для совместимости с типами данных IDREFS и NMTOKENS из схемы XML. Каждая запись в списке должна интерпретироваться как Идентификатор внутреннего компонента, которому передается MethodExpression из составной тег компонента на странице использования должен быть применен. Если это элемент имеет атрибут метода-подписи, но не имеет атрибута целей, значение атрибута name используется в качестве отдельной записи в список. Если значение атрибута name не является одним из специальных значения, перечисленные в описании атрибута имени, цели (или его производное значение) не должны соответствовать идентификатору внутреннего компонент.

<cc:interface>
    <cc:attribute name="value" />
    <cc:attribute name="action" targets="buttonId" />
    <cc:attribute name="actionListener" targets="buttonId" />
</cc:interface>
<cc:implementation>
    <p:commandButton id="buttonId" value="#{cc.attrs.value}" />
</cc:implementation>

@ source: https://stackoverflow.com/a/19680483/1850844

0 голосов
/ 13 ноября 2011

Я также столкнулся с этой проблемой и проверил ваши коды. Кажется, что primefaces не может предупредить вас об ошибках проверки в том же «xhtml», но в других PanelGrids вам может понадобиться родительский panelGrid, чтобы правильно инкапсулировать все сетки вашей формы.

Если вы полностью заполните всю свою форму, вы увидите, что вызывается ваше действие commandButton primefaces, в противном случае оно будет молча "переваривать" ошибки проверки, которые могут у вас возникнуть.

0 голосов
/ 31 октября 2011

Вы можете попытаться вставить атрибут ajax = "false" в p: commandButton.

...