JSF setter调用多时间覆盖值
嗨,我正在使用PrimeFaces创建一个数据表,其中有一列,该数据表的每一行都有一个手风琴。 我想用与每行相关联的一些输入框中的值更新数据表中的特定行 当我每行提交表格时 首先,永远不会调用set属性操作侦听器,并且 其次,我正在更新的字段的setter被多次调用。事实上,它们被称为 数据表中的每行一次 问题是,在调试时,我可以看到无论编辑哪一行,都会为datatable中的所有行调用setter。因此,除非我编辑最后一行,否则我设置的值总是被覆盖。任何人都知道这是怎么发生的,因为我认为每行编辑只会调用setter一次 更新:最坏的情况是,我可以通过设置一个空签入来绕过调用的setter。但是,我不知道使用的是哪一行,因为没有调用set属性action listener JSF页面JSF setter调用多时间覆盖值,jsf,jsf-2,primefaces,Jsf,Jsf 2,Primefaces,嗨,我正在使用PrimeFaces创建一个数据表,其中有一列,该数据表的每一行都有一个手风琴。 我想用与每行相关联的一些输入框中的值更新数据表中的特定行 当我每行提交表格时 首先,永远不会调用set属性操作侦听器,并且 其次,我正在更新的字段的setter被多次调用。事实上,它们被称为 数据表中的每行一次 问题是,在调试时,我可以看到无论编辑哪一行,都会为datatable中的所有行调用setter。因此,除非我编辑最后一行,否则我设置的值总是被覆盖。任何人都知道这是怎么发生的,因为我认为每行编
<?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>
总结
含意
到期日
电子邮件操作
#{action.action}--{action.username}
我的背豆
@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;
}
}
}
@ManagedBean
@可配置
@视域
公共类EmailArticleBean实现了可序列化{
/**
*
*/
私有静态最终长serialVersionUID=1L;
@自动连线
EmailArticleService EmailArticleService;
私人物品清单;
私有字符串搜索文本;
私有字符串操作;
私人邮件文章选择电子邮件;
私人日期;
/**
*使用输入的搜索词将
*查询数据库并返回文章列表
*与该参数匹配
*@param-ae
*/
公共无效搜索(ActionEvent ae){
emailArticles=emailArticleService.findEmailArticles(searchText);
}
/**
*将输入的操作添加到现有操作列表中
*@param-ae
*/
公共无效更新操作(ActionEvent ae){
选择edemail.getActions().add(新的EmailActions(emailAction,“testUser”,actionDueDate));
选择edemail.merge();
emailAction=“”;
actionDueDate=null;
}
公共列表getEmailArticles(){
返回电子邮件文章;
}
public void setEmailArticles(列出emailArticles){
this.emailArticles=emailArticles;
}
公共字符串getSearchText(){
返回搜索文本;
}
public void setSearchText(字符串搜索文本){
this.searchText=searchText;
}
公共字符串getEmailAction(){
返回电子邮件操作;
}
public void setEmailAction(字符串emailAction){
//将此签入,因为它是jsf生命周期的一部分
//似乎每行调用一次setter,覆盖用户设置的新值
if(StringUtils.isEmpty(this.emailAction)){
this.emailAction=emailAction;
}
}
公共电子邮件文章getSelectedEmail(){
返回所选邮件;
}
公共作废设置selectedEmail(EmailArticle selectedEmail){
如果(selectedEmail==null){
this.selectedEmail=selectedEmail;
}
}
公共日期getActionDueDate(){
返回日期;
}
公共作废setActionDueDate(日期actionDueDate){
如果(this.actionDueDate==null){
this.actionDueDate=actionDueDate;
}
}
}
您确实将所有行的输入字段的值绑定到一个相同的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}" ... />
...
您确实将所有行的输入字段的值绑定到一个相同的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}" ... />
...
您确实将所有行的输入字段的值绑定到一个相同的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}" ... />
...
您确实将所有行的输入字段的值绑定到一个相同的bean属性
<p:dataTable var="email" value="#{emailArticleBean.emailArticles}" ...>
...
<h:inputTextarea value="#{emailArticleBean.emailAction}" ... />
...
从逻辑上讲,这毫无意义。你所描述的症状正是预期的结果