Java JSF - 使用 Primefaces RowEditEvent 时如何获取新旧值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19391155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 16:45:18  来源:igfitidea点击:

JSF - How to get old and new value when using Primefaces RowEditEvent?

javajsfjsf-2primefaces

提问by Catfish

I have a datatable with 2 columns(name and description) and I want to update my database when a person updates a row and clicks the checkmark which triggers the execBacking.updatemethod.

我有一个包含 2 列(名称和描述)的数据表,我想在一个人更新一行并单击触发该execBacking.update方法的复选标记时更新我的​​数据库。

In this method, I get the new values by casting event.getObject(), but how can i also get the old values? The name is my primary key so i need the old value to know which row to update in the db.

在这种方法中,我通过强制转换获得了新值event.getObject(),但我怎样才能获得旧值呢?名称是我的主键,所以我需要旧值才能知道要在数据库中更新哪一行。

xhtml page

xhtml页面

  <p:ajax event="rowEdit" listener="#{execBacking.update}" update=":execForm:execMessages" /> 

  <p:column headerText="Name">
    <p:cellEditor>
        <f:facet name="output">
            <h:outputText value="#{exec.name}" />
        </f:facet>
        <f:facet name="input">
            <h:inputText value="#{exec.name}" />
        </f:facet>
    </p:cellEditor>
  </p:column>

  <p:column headerText="Description">
    <p:cellEditor>
        <f:facet name="output">
            <h:outputText value="#{exec.description}" />
        </f:facet>
        <f:facet name="input">
            <h:inputText value="#{exec.description}" />
        </f:facet>
    </p:cellEditor>
  </p:column>

  <p:column headerText="Actions">
    <p:rowEditor />
    <p:commandLink styleClass="ui-icon ui-icon-trash" type="submit" actionListener="#{execBacking.delete}" update=":execForm:execMessages" >
            <f:attribute name="execName" value="#{exec.name}" />
        </p:commandLink>
  </p:column>
</p:dataTable>

Backing bean

支撑豆

public void update(RowEditEvent event) {

        Dao dao = new Dao(ds);
        Exec exec = (Exec) event.getObject();
        System.out.println("name = "+exec.getName());  //New name
        System.out.println("desc = "+exec.getDescription());  //New desc
        try {
            // If the new exec was updated successfully
            if(dao.updateExec(accessBacking.getUsername(), null, exec.getName(), exec.getDescription())) {
                FacesContext.getCurrentInstance().addMessage("growl", new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", "Exec Updated Successfully!"));
            } else {
                FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Error Updating Exec!"));
            }
        } catch (Exception e) {
            FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", e.getMessage()));
        }
    }

采纳答案by StormeHawke

I would recommend nothaving namebe your primary key, but instead add an auto-incrementing idfield and make that your primary key, and don'tmake that field editable by the user. This guarantees you always have access to the record that you want to update.

我建议具有name作为您的主键,而是添加一个自动递增id场,让你的主键,并且使用户该字段编辑。这保证您始终可以访问要更新的记录。

Generally speaking it's bad practice to attempt to modify the primary key in a database the way you're trying to do it.

一般来说,尝试以您尝试的方式修改数据库中的主键是不好的做法。

回答by kolossus

You can register a ValueChangeListeneron the component you're interested in using:

您可以ValueChangeListener在您感兴趣的组件上注册一个:

<p:column headerText="Description">
   <p:cellEditor>
      <f:facet name="output">
          <h:outputText value="#{exec.name}" />
      </f:facet>
      <f:facet name="input">
        <h:inputText value="#{exec.name}">
           <f:valueChangeListener binding="#{keyChangedListener}"/>
           <f:ajax/>
        </h:inputText>
      </f:facet>
   </p:cellEditor>
</p:column>

keyChangeListenerwill correspond to an implementation of ValueChangeListenerand we're using <f:ajax/>here to ensure that the valueChangedevent is fired on the textbox. Otherwise the listener will not be notified. Your listener should look something like:

keyChangeListener将对应于的实现,ValueChangeListener我们在<f:ajax/>这里使用以确保valueChanged在文本框上触发事件。否则将不会通知侦听器。你的听众应该看起来像:

@ManagedBean(name="keyChangedListener")
@ViewScoped
public class KeyChangeListener implements ValueChangeListener{

     public void processValueChange(ValueChangeEvent event) throws AbortProcessingException{
          Object oldValue = event.getOldValue(); //get the old value
          Object newValue = event.getNewValue(); //get the new value

      }

I'm using the @ViewScopedhere as advised by the JSF Spec, to avoid unwanted side effects.

@ViewScoped按照 JSF 规范的建议使用here,以避免不必要的副作用。