【问题标题】:JSF setter called multiple time overwriting valuesJSF setter 调用多次覆盖值
【发布时间】:2013-12-18 12:39:58
【问题描述】:

您好,我正在使用 PrimeFaces 创建一个数据表,其中包含 1 列,并且该数据表的每一行都包含一个手风琴。 我想用与每一行关联的一些输入框中的值更新数据表中的特定行。

当我每行提交表单时 首先,永远不会调用 set 属性操作侦听器,并且 其次,我正在更新的字段的设置器被多次调用。事实上他们被称为 对数据表中的每一行执行一次。

问题在于,在调试时我可以看到,无论我正在编辑哪一行,都会为数据表中的所有行调用 setter。因此,除非我正在编辑最后一行,否则我设置的值总是会被​​覆盖。任何人都知道这是怎么回事,因为我认为每行编辑只会调用一次设置器。

更新:在最坏的情况下,我可以通过签入 null 来绕过被调用的 setter。但是我不知道我正在使用哪一行,因为未调用 set 属性操作侦听器

JSF 页面

<?xml version="1.0" encoding="UTF-8"?>
<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"
    xmlns:ui="http://java.sun.com/jsf/facelets">
      <h:form id="userDetailsForm" style="padding:5px"> 
        <p:growl id="messages" showDetail="true" autoUpdate="true" life="2000"/>
        <p:spacer height="15"></p:spacer>

    <div class="row">     
      <div class="col-lg-4">
        <div class="input-group">
          <p:inputText type="text" styleClass="form-control" value="#{emailArticleBean.searchText}" />
          <span class="input-group-btn" style="margin:3px;">
            <p:commandButton actionListener="#{emailArticleBean.search}" value="Go!" update=":userDetailsForm:emailArticleTable" />
          </span>
        </div><!-- /input-group -->
      </div><!-- /.col-lg-6 -->
    </div><!-- /.row -->

    <p:spacer height="15"></p:spacer>

    <div class="row">
        <div class="col-lg-1">

        </div>
        <div class="col-lg-11">
        <p:dataTable var="email" value="#{emailArticleBean.emailArticles}" scrollRows="20"  
                    scrollable="true" liveScroll="true" scrollHeight="750" id="emailArticleTable" 
                    >
            <p:column>
                <p:accordionPanel multiple="true" activeIndex="-1" id="panel#{email.id}">  

                    <p:tab title="#{email.headline}" titleStyleClass="email-header">  
                           <div style="clear:both;margin-bottom:10px;">
                           <h6 style="font-weight:bold;">Summary</h6>
                            <h:outputText  
                                value="#{email.summary}" />     
                            </div>  
                            <div style="clear:both;margin-bottom:10px;">
                            <h6 style="font-weight:bold;">Implication</h6>
                            <h:outputText  
                                value="#{email.implication}" />     
                            </div>           
                            <div style="float:left;clear:both">
                                <p:commandButton  value="View Existing Actions" 
                                    oncomplete="PF('dlg2').show();" update=":userDetailsForm:emailActionDialog">
                                     <f:setPropertyActionListener value="#{email}" target="#{emailArticleBean.selectedEmail}" />  
                                </p:commandButton>                  
                             </div> 
                             <br/>
                             <br/>
                             <div style="margin-top:10px;">        
                                <h:inputTextarea id="accordian1" value="#{emailArticleBean.emailAction}" cols="90" rows="3" />                          
                            </div>
                            <h6 style="font-weight:bold;">Due Date</h6>  
                            <p:calendar value="#{emailArticleBean.actionDueDate}" id="popupCal" pattern="dd MMM, yyyy"/> 
                            <p:commandButton actionListener="#{emailArticleBean.updateAction}" value="Add Action" 
                                 style="margin-left:5px;">
                                <f:setPropertyActionListener value="#{email}" target="#{emailArticleBean.selectedEmail}" />
                            </p:commandButton> 

                    </p:tab>
                </p:accordionPanel>
            </p:column>
        </p:dataTable>
        </div>

    </div> 

    <p:dialog id="emailActionDialog" header="Email Actions" widgetVar="dlg2" modal="true" height="100">  
        <h3>Email Actions</h3>  
        <p:dataList value="#{emailArticleBean.selectedEmail.actions}" var="action" itemType="disc">  
            #{action.action} --- #{action.username}  
        </p:dataList>  
    </p:dialog> 



    </h:form>   



</html>

我的后盾

@ManagedBean
@Configurable
@ViewScoped
public class EmailArticleBean implements Serializable {

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

    @Autowired
    EmailArticleService emailArticleService;

    private List<EmailArticle> emailArticles;
    private String searchText;
    private String emailAction;
    private EmailArticle selectedEmail;
    private Date actionDueDate;

    /**
     * Using the search term entered will
     * query the database and return a list of articles 
     * that match that parameter
     * @param ae
     */
    public void search(ActionEvent ae) {
        emailArticles = emailArticleService.findEmailArticles(searchText);
    }   

    /**
     * add the inputted action to the list of existing actions
     * @param ae
     */
    public void updateAction(ActionEvent ae) {
        selectedEmail.getActions().add(new EmailActions(emailAction, "testUser", actionDueDate));
        selectedEmail.merge();
        emailAction = "";
        actionDueDate = null;
    }

    public List<EmailArticle> getEmailArticles() {
        return emailArticles;
    }

    public void setEmailArticles(List<EmailArticle> emailArticles) {
        this.emailArticles = emailArticles;
    }

    public String getSearchText() {
        return searchText;
    }

    public void setSearchText(String searchText) {
        this.searchText = searchText;
    }

    public String getEmailAction() {
        return emailAction;
    }

    public void setEmailAction(String emailAction) {
        //putting this check in because it the jsf lifecycle
        //seems to be calling the setter once for every row overwriting the new value set by the user
        if(StringUtils.isEmpty(this.emailAction)) {
            this.emailAction = emailAction;
        }       
    }   

    public EmailArticle getSelectedEmail() {
        return selectedEmail;
    }

    public void setSelectedEmail(EmailArticle selectedEmail) {
        if(selectedEmail == null) {
            this.selectedEmail = selectedEmail;
        }       
    }

    public Date getActionDueDate() {
        return actionDueDate;
    }

    public void setActionDueDate(Date actionDueDate) {
        if(this.actionDueDate == null) {
            this.actionDueDate = actionDueDate;
        }       
    }


}

【问题讨论】:

    标签: jsf jsf-2 primefaces


    【解决方案1】:

    您确实将 所有 行的输入字段的值绑定到一个相同的 bean 属性。

    <p:dataTable var="email" value="#{emailArticleBean.emailArticles}" ...>
        ...
        <h:inputTextarea value="#{emailArticleBean.emailAction}" ... /> 
    

    从逻辑上讲,这没有任何意义。您描述的症状正是预期的结果。您应该将输入字段的值绑定到当前迭代的行。

    <p:dataTable var="email" value="#{emailArticleBean.emailArticles}" ...>
        ...
        <h:inputTextarea value="#{email.emailAction}" ... /> 
    

    【讨论】:

    • 谢谢 BalusC 你能给我指点一下如何做到这一点吗?
    • 好的,太好了。但是我的 setpropertyactionlistener 仍然没有被调用来设置我的 bean 中的当前对象。有什么想法吗?
    • 每当您有与当前问题无关的新问题时,请按右上角的“”按钮。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 2012-07-15
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    相关资源
    最近更新 更多