参数在使用 <p:commandButton> 时变为 null (Mojarra 2.3)

parameter goes null when using <p:commandButton> (Mojarra 2.3)

提问人:JakoBolt 提问时间:1/7/2023 最后编辑:JakoBolt 更新时间:1/8/2023 访问量:53

问:

xhtml 文件正在获取一个 Integer 参数,该参数另存为 deck_id。在该 xhtml 文件中,它被正常使用,并且与标头中一样工作,但是当我想将其与 <p:commandbutton> 结合使用时,参数变为 null。我不知道为什么,也不知道如何解决它。 由于我是编程新手,这是我的第一个项目,我现在迷路了,几个小时的谷歌也无济于事。

该deck_id在 #{deckListController.getDeckByDeckId(deck_id).name} 中工作正常,但在 <p:commandButton oncomplete=“PF('newCardDialog').show()” icon=“pi pi-plus” value=“新卡” title=“新”>

-->

通过按下“新建卡”按钮,我刚刚添加了一个函数,该函数在控制台中打印deck_id(如您在newCardDialog中看到的那样),它打印0,但它应该是给定卡组的ID。

XHTML 文件组 - 详细信息视图

    <ui:param name="deck_id" value="#{param['deck_id']}"/>
    <ui:define name="content">
        <h1>Cards of
            #{deckListController.getDeckByDeckId(deck_id).name}</h1>
        <div class="deck-detail">
            <!--  TODO: ADD NEW CARD -->
            <h:form id="newCardForm">
                <div class="txt-r">
                    <!--  TODO: only see for the creator of the deck -->
                    <!--  one Problem -> deckId somehow is null -> exception becaus of unboxing null is wrong -->
                    <p:commandButton oncomplete="PF('newCardDialog').show()"
                        icon="pi pi-plus" value="new card" title="New">
<!--                        rendered="#{deckListController.getDeckByDeckId(param['deck_id']).createUser == sessionInfoBean.currentUser}"> -->
                    </p:commandButton> 

                    
                    <p:commandButton oncomplete="PF('deckEditDialog').show()"
                        icon="pi pi-pencil" value="edit deck" title="Edit" styleClass="btn-light">
                        <f:setPropertyActionListener
                            value="#{deckListController.getDeckByDeckId(deck_id)}"
                            target="#{deckDetailController.deck}" />
                    </p:commandButton>
                </div>
                <br />
                
                
                <!-- new Card dialog -->
                <p:dialog header="Create new Card" id="newCardDialog"
                    widgetVar="newCardDialog" modal="true" showEffect="fade"
                    hideEffect="fade" resizable="false" width="400">
                    <p:outputPanel id="newCardData">
                        <p:messages id="messages" closable="true" autoUpdate="true" />
                        <h:panelGrid columns="2">
                            <p:outputLabel for="cardContentFront" value="Question: " />
                            <!-- TODO: required field check is not working yet -->
                            <p:inputTextarea id="cardContentFront"
                                value="#{newCardController.card.contentFront}" required="true"
                                requiredMessage="Question of card is required" />
                            <p:outputLabel for="cardContentBack" value="Answer: " />
                            <p:inputTextarea id="cardContentBack"
                                value="#{newCardController.card.contentBack}" required="true"
                                requiredMessage="Answer of card is required" />
                        </h:panelGrid>
                        <p:separator />
                        <h:panelGrid columns="2">
                            <p:outputLabel for="flipped" value="Flipped: " />
                            <p:selectBooleanCheckbox id="flipped"
                                value="#{newCardController.card.flipped}" />
                        </h:panelGrid>
                        <p:separator />
                        <h:panelGrid columns="3">
                            <p:commandButton value="Cancel"
                                onclick="PF('newCardDialog').hide()" styleClass="btn-light" />
                            <!-- TODO: after create refreshing of the table -->
                            <p:commandButton value="Create"
                                actionListener="#{cardListController.print(deck_id)}"
                                oncomplete="PF('newCardDialog').hide()" />
                            <!-- action="#{newCardController.doCreateCard(deck_id)}" -->
                            <!-- update="cardForm" /> -->
                        </h:panelGrid>
                    </p:outputPanel>
                </p:dialog>
                
                
                
                <!-- Edit deck dialog  -->
                <p:dialog header="Edit #{deckListController.getDeckByDeckId(param['deck_id']).name}" id="deckEditDialog"
                    widgetVar="deckEditDialog" modal="true" showEffect="fade"
                    hideEffect="fade" resizable="false" width="400">
                    <p:outputPanel id="deckData" rendered="#{ empty deckDetailController.deck}">
                        <h:panelGrid columns="2">
                            <p:outputLabel for="name" value="Deck Name: " />
                            <p:inputText id="name" disabled="false" />
                            <p:outputLabel for="description" value="Desription: " />
                            <p:inputTextarea id="description" disabled="false" />
                        </h:panelGrid>
                        <h:panelGrid columns="2">
                        <p:outputLabel for="public" value="Public: " />
                        <p:selectBooleanCheckbox id="public" />
                    </h:panelGrid>
                        <h:panelGrid columns="3">
                            <p:commandButton value="Cancel"
                                onclick="PF('deckEditDialog').hide()" styleClass="btn-light" />
                            <p:commandButton value="Reload"
                                            
                                            update=":cardForm:cardView"
                                            styleClass="btn-light" />
                        <p:commandButton value="Save"
                                        
                                        oncomplete="PF('deckEditDialog').hide()"
                                        update=":cardForm:cardView" />
                        </h:panelGrid>
                    </p:outputPanel>
                </p:dialog>
                
                
            </h:form>
            
            
            <h:form id="cardForm">
                <p:dataGrid id="cardView" var="card"
                    value="#{cardListController.getEnabledCardsOfOneDeckByDeckId(deck_id)}"
                    columns="4" paginator="false">
                    <p:dataViewGridItem>
                        <h3 class="card-name">Question:</h3>
                        <div class="card-grid-item-content">
                            <p class="card-contentFront">#{card.contentFront}</p>
                        </div>
                        <div class="open-btns txt-r">
                            <!--  TODO: edit and delete button in Progress -->
                            <p:commandButton update=":cardForm:cardEditDialog" 
                                            oncomplete="PF('cardEditDialog').show()"
                                            type="button" title="edit" value="edit" styleClass="btn-light"
                                            rendered="#{card.createUser == sessionInfoBean.currentUser}">
                                <f:setPropertyActionListener value="#{card}"
                                                            target="#{cardDetailController.card}" />
                            </p:commandButton>
                            <p:commandButton title="delete"
                                            action="#{cardDetailController.doDisableCard}"
                                            rendered="#{card.createUser == sessionInfoBean.currentUser}">
                                <f:setPropertyActionListener value="#{card}"
                                                            target="#{cardDetailController.card}" />

                                <p:confirm header="Confirmation"
                                    message="Are you sure you want do delete this card?"
                                    icon="pi pi-exclamation-triangle" />
                            </p:commandButton>
                        </div>
                    </p:dataViewGridItem>
                </p:dataGrid>


                <!-- Edit card dialog  -->
                <p:dialog header="Edit Card" id="cardEditDialog"
                    widgetVar="cardEditDialog" modal="true" showEffect="fade"
                    hideEffect="fade" resizable="false" width="400">
                    <p:outputPanel id="cardData"
                        rendered="#{not empty cardDetailController.card}">
                        <h:panelGrid columns="2">
                            <p:outputLabel for="contentFront" value="Question: " />
                            <p:inputText id="contentFront"
                                value="#{cardDetailController.card.contentFront}"
                                disabled="false" />
                            <p:outputLabel for="contentBack" value="Answer: " />
                            <p:inputTextarea id="contentBack"
                                value="#{cardDetailController.card.contentBack}"
                                disabled="false" />
                        </h:panelGrid>
                        <h:panelGrid columns="3">
                            <p:commandButton value="Cancel"
                                onclick="PF('cardEditDialog').hide()" styleClass="btn-light" />
                            <p:commandButton value="Reload"
                                action="#{cardDetailController.doReloadCard()}"
                                update=":cardsForm:cardView" styleClass="btn-light" />
                            <p:commandButton value="Save"
                                action="#{cardDetailController.doSaveCard()}"
                                oncomplete="PF('cardEditDialog').hide()"
                                update=":cardForm:cardView" />
                        </h:panelGrid>
                    </p:outputPanel>
                </p:dialog>

                
                <!--  Deletion confirmation dialog -->
                <p:confirmDialog global="true" showEffect="fade" hideEffect="fade"
                    width="300">
                    <p:commandButton value="Yes" type="button"
                        styleClass="ui-confirmdialog-yes btn-light" />
                    <p:commandButton value="No" type="button"
                        styleClass="ui-confirmdialog-no" />
                </p:confirmDialog>

            </h:form>
        </div>
    </ui:define>
</ui:composition>

xhtml 文件,其中参数被赋予 deck-detail 视图

<ui:composition xmlns="http://www.w3c.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.org/ui">

    <div class="personal-decks">
        <h:form id="newDeckForm">
            <div class="txt-r">
                <p:commandButton oncomplete="PF('newDeckDialog').show()"
                    icon="pi pi-plus" value="new deck" title="New" />
            </div>
            <br />
            <!-- NEW deck dialog-->
            <p:dialog header="Create new Deck" id="newDeckDialog"
                widgetVar="newDeckDialog" modal="true" showEffect="fade"
                hideEffect="fade" resizable="false" width="400">
                <p:outputPanel id="newDeckData">
                    <p:messages id="messages" closable="true" autoUpdate="true" />
                    <h:panelGrid columns="2">
                        <p:outputLabel for="deckName" value="Deck Name: " />
                        <!-- TODO: required field check is not working yet -->
                        <p:inputText id="deckName" value="#{newDeckController.deck.name}"
                            required="true" requiredMessage="Name of deck is required" />
                        <p:outputLabel for="deckDescription" value="Description: " />
                        <p:inputTextarea id="deckDescription"
                            value="#{newDeckController.deck.description}" disabled="false" />
                    </h:panelGrid>
                    <h:panelGrid columns="3">
                        <p:commandButton value="Cancel"
                            onclick="PF('newDeckDialog').hide()" styleClass="btn-light" />
                        <p:commandButton value="Create"
                            action="#{newDeckController.doCreateDeck()}">
                        </p:commandButton>
                    </h:panelGrid>
                </p:outputPanel>
            </p:dialog>
        </h:form>

        <!-- PRIVATE decks view-->
        <h:form id="privateDecksForm">
            <p:dataGrid id="decksView"
                        var="deck"
                        value="#{deckListController.userDecks}" columns="4"
                        paginator="false">

                <p:dataViewGridItem>
                    <div class="edit-btns">
                        <p:commandButton update=":deckTabs:privateDecksForm:deckEditDialog"
                                         oncomplete="PF('deckEditDialog').show()" icon="pi pi-pencil"
                                         title="Edit">
                            <f:setPropertyActionListener value="#{deck}"
                                                         target="#{deckDetailController.deck}" />
                        </p:commandButton>
                        <p:commandButton action="#{deckDetailController.doDisableDeck}"
                                         icon="pi pi-trash" title="Delete"
                                         update=":deckTabs:privateDecksForm:decksView">
                            <f:setPropertyActionListener value="#{deck}"
                                                         target="#{deckDetailController.deck}" />
                            <p:confirm header="Confirmation"
                                       message="Are you sure that you want to delete this deck? You cannot undo this operation."
                                       icon="pi pi-exclamation-triangle" />
                        </p:commandButton>
                    </div>
                    <h3 class="deck-name">#{deck.name}</h3>
                    <div class="deck-grid-item-content">
                        <p class="deck-description">#{deck.description}</p>
                        <p class="deck-no-cards">
                            New cards: #{deckDetailController.getNewCardsCount(deck)}
                            <br />
                            Repeatable cards: #{deckDetailController.getRepeatableCardsCount(deck)}
                        </p>
                    </div>
                    <div class="open-btns txt-r">
                        <p:linkButton outcome="deck-detail" value="view"
                            styleClass="btn-light">
                            <f:param name="deck_id" value="#{deck.deckID}" />
                        </p:linkButton>
                        <p:linkButton outcome="learning-view" value="learn">
                            <f:param name="deck_id" value="#{deck.deckID}" />
                        </p:linkButton>
                    </div>
                </p:dataViewGridItem>
            </p:dataGrid>

            <!-- Edit deck dialog-->
            <p:dialog header="Edit Deck" id="deckEditDialog"
                widgetVar="deckEditDialog" modal="true" showEffect="fade"
                hideEffect="fade" resizable="false" width="400">
                <p:outputPanel id="deckData"
                    rendered="#{not empty deckDetailController.deck}">
                    <h:panelGrid columns="2">
                        <p:outputLabel for="name" value="Deck Name: " />
                        <p:inputText id="name" value="#{deckDetailController.deck.name}"
                            disabled="false" />
                        <p:outputLabel for="description" value="Description: " />
                        <p:inputTextarea id="description"
                            value="#{deckDetailController.deck.description}" disabled="false" />
                    </h:panelGrid>
                    <h:panelGrid columns="2">
                        <p:outputLabel for="public" value="Public: " />
                        <p:selectBooleanCheckbox id="public"
                            value="#{deckDetailController.deck.publiclyShared}" />
                    </h:panelGrid>
                    <h:panelGrid columns="3">
                        <p:commandButton value="Cancel"
                            onclick="PF('deckEditDialog').hide()"
                            styleClass="btn-light" />
                        <p:commandButton value="Reload"
                            action="#{deckDetailController.doReloadDeck()}"
                            update=":deckTabs:privateDecksForm:decksView"
                            styleClass="btn-light" />
                        <p:commandButton value="Save"
                            action="#{deckDetailController.doSaveDeck()}"
                            oncomplete="PF('deckEditDialog').hide()"
                            update=":deckTabs:privateDecksForm:decksView" />
                    </h:panelGrid>
                </p:outputPanel>
            </p:dialog>

            <!-- Deletion confirmation dialog -->
            <p:confirmDialog global="true" showEffect="fade" hideEffect="fade"
                width="300">
                <p:commandButton value="Yes" type="button"
                    styleClass="ui-confirmdialog-yes btn-light" />
                <p:commandButton value="No" type="button"
                    styleClass="ui-confirmdialog-no" />
            </p:confirmDialog>

        </h:form>

    </div>
</ui:composition>

cardList控制器

package at.qe.skeleton.ui.controllers;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;

import at.qe.skeleton.model.Deck;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import at.qe.skeleton.model.Card;
import at.qe.skeleton.services.CardService;

/**
 * Controller for the Card list view.
 *
 * This class is part of the skeleton project provided for students of the
 * course "Software Architecture" offered by Innsbruck University.
*/
@Component
@Scope("view")
public class CardListController implements Serializable {

    @Autowired
    private CardService cardService;

    /**
     * Returns a list of all Cards.
     *
     * @return Collection
     */
    public Collection<Card> getCards() {
        return cardService.getAll();
    }

    /**
     * Returns a list of all Cards.
     *
     * @return Collection
     */
    public Collection<Card> getEnabledCardsOfOneDeckByDeckId(Integer deckId) {
        if(deckId == null)
            return new ArrayList<>();
        
        return cardService.findAllEnabledCardsByDeckId(deckId);
    }
    
    public void print(int deckId) {
        System.out.println("deckId is " + deckId);
    }
    

    /**
     * Returns the current Deck.
     *
     * @return Deck
     */
    public Deck getDeck(Integer deckId) {

        return cardService.findDeck(deckId);
    }
}


我试图将 action 更改为 actionListener,正如有人在论坛上所说的那样。 我发现这可能与 Mojarra 有关,但并不真正理解为什么。

primefaces xhtml javabeans mojarra

评论

0赞 WoAiNii 1/8/2023
何时以及如何设置参数?我尝试使用上面的代码,它打印了我设置为deck_id参数的内容,你能发布所有重要的代码吗?
0赞 JakoBolt 1/8/2023
我添加了设置参数的甲板视图。请在视图中看到按钮真的很奇怪,但是当我运行它时,它打印 0,但是当我设置 param =“1” 的值时,它打印 1,所以我不知道为什么当我设置 value=“#{param['deck_id']}” 时它会将参数重置为 0“ 有没有其他可能性将值保存在 xhtml 的变量中?
0赞 WoAiNii 1/8/2023
为什么不直接保存该参数服务器端呢?对不起,但我无法弄清楚你的所有情况。
0赞 JakoBolt 1/9/2023
如何保存参数服务器端?对不起,这些问题,但我是编程新手,这是我的第一个这样的项目。
0赞 WoAiNii 1/10/2023
只需在 bean 中创建一个 int 变量,根据需要选择其作用域(viewScope、flowScope、sessionScope);在正确的操作/操作侦听器中设置它,并在需要时重置它。在 xhtml 中使用它,并在需要时更新使用它的对话框/表单/等。

答: 暂无答案