Primefaces数据表在删除时复制数据

时间:2014-09-17 17:10:55

标签: ajax jsf jsf-2 primefaces datatables

即时使用hibernate 4,spring 4,lucene 3,primefaces 5,java 7.

我有一个数据表,其中的数据填充在烘焙bean上,表中的想法是它向我显示了一些未分类的单词,并让我对它们进行分类。

初始表的示例看起来很正常,例如

1 2 3 4 5

这是我的页面

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<h:head>

</h:head>

<h:form id="form">
    <p:growl id="msgs" showDetail="true" life="2000" />

    <p:dataTable id="words" var="word"
        value="#{wordCatalogatorController.unknownWords}" editable="true"
        style="margin-bottom:20px">
        <f:facet name="header">Row Editing</f:facet>

        <p:ajax event="rowEdit"
            listener="#{wordCatalogatorController.onRowEdit}" update=":form:msgs" />
        <p:ajax event="rowEditCancel"
            listener="#{wordCatalogatorController.onRowCancel}" update=":form:msgs" />

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

        <p:column headerText="Tipo Palabra">
            <p:cellEditor>
                <f:facet name="output">
                    <h:outputText value="#{word.wordType}" />
                </f:facet>
                <f:facet name="input">
                    <h:selectOneMenu value="#{word.wordType}" style="width:100%"
                        converter="#{wordTypeConverter}">
                        <f:selectItems value="#{wordCatalogatorController.wordTypes}"
                            var="man" itemLabel="#{man.wordType}" itemValue="#{man}" />
                    </h:selectOneMenu>
                </f:facet>
            </p:cellEditor>
        </p:column>

        <p:column style="width:32px">
            <p:rowEditor />
        </p:column>
    </p:dataTable>
</h:form>
</html>

这个bean是:

@Controller
@Transactional
public class WordCatalogatorController {

    private List<Word> unknownWords = new ArrayList<Word>();

    private List<WordType> wordTypes = new ArrayList<WordType>();

    public WordCatalogatorController(){
        //inicializamos palabras desconocidas y tipos de palabras!
        for(int i = 0 ; i < 6 ; i++){
            unknownWords.add(new Word("" + i));
        }

        for(int i = 0 ; i < 4 ; i++){
            wordTypes.add(new WordType("" + i));
        }

    }

    public void onRowEdit(RowEditEvent event) {
        Word currentWord = (Word) event.getObject();

        unknownWords.remove(currentWord);
    }

    public void onRowCancel(RowEditEvent event) {
        FacesMessage msg = new FacesMessage("Edit Cancelled",
                ((Word) event.getObject()).getWord());
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onCellEdit(CellEditEvent event) {
        Object oldValue = event.getOldValue();
        Object newValue = event.getNewValue();

        if (newValue != null && !newValue.equals(oldValue)) {
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
                    "Cell Changed", "Old: " + oldValue + ", New:" + newValue);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

然后在编辑并保存第一行(1)后,数据表更新为1 2 2 3 4 5

任何想法都会非常令人沮丧!

这里有pojo clases的代码

@Entity
@Table(name="Word")
@Indexed
@AnalyzerDef(name = "searchtokenanalyzer",tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
  @TokenFilterDef(factory = StandardFilterFactory.class),
  @TokenFilterDef(factory = LowerCaseFilterFactory.class),
  @TokenFilterDef(factory = StopFilterFactory.class,params = { 
      @Parameter(name = "ignoreCase", value = "true") }) })
      @Analyzer(definition = "searchtokenanalyzer")
public class Word {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long wordId;

    @Column(name="word")
    @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
    @Analyzer(definition="searchtokenanalyzer")
    private String word;

    @ManyToMany(mappedBy="words")
    private Collection<Danger> dangers = new ArrayList<Danger>();

    @ManyToMany(mappedBy="words")
    private Collection<Risk> risks = new ArrayList<Risk>();

    @ManyToMany(mappedBy="words")
    private Collection<Control> controls = new ArrayList<Control>();

    @ManyToOne
    @JoinColumn(name = "wordTypeId")  
    private WordType wordType;

    public Word(String word, WordType wordType) {
        super();
        this.word = word;
        this.wordType = wordType;
    }

    public Word(String word) {
        super();
        this.word = word;
    }



    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Word){
            return ((Word)obj).getWord().equalsIgnoreCase(this.getWord());
        }else{
            return false;
        }
    }

    public Word() {
        super();

    }

    public long getWordId() {
        return wordId;
    }

    public void setWordId(long wordId) {
        this.wordId = wordId;
    }



@Entity
@Table(name = "WordType")
@Indexed
public class WordType {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long wordTypeId;

    @Column(name = "wordType")
    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
    @Analyzer(definition = "searchtokenanalyzer")
    private String wordType;

    @Column(name = "description")
    private String description;

    @OneToMany(mappedBy = "wordType")
    private Set<Word> words;

    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        if (!(obj instanceof WordType)) {
            return false;
        } else {
            WordType extenalWT = (WordType) obj;
            if (this.wordType.equalsIgnoreCase(extenalWT.getWordType())
                    && this.wordTypeId == extenalWT.getWordTypeId()) {
                return true;
            } else {
                return false;
            }
        }
    }

    public WordType() {

    }

    public WordType(String wordType) {
        this.wordType = wordType;
    }

    public long getWordTypeId() {
        return wordTypeId;
    }

    public void setWordTypeId(long wordTypeId) {
        this.wordTypeId = wordTypeId;
    }

    public String getWordType() {
        return wordType;
    }

    public void setWordType(String wordType) {
        this.wordType = wordType;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Set<Word> getWords() {
        return words;
    }

    public void setWords(Set<Word> words) {
        this.words = words;
    }

    @Override
    public String toString() {
        return wordType;
    }

}

2 个答案:

答案 0 :(得分:2)

对于遇到此问题的其他人:

这似乎是rowEditor和表排序之间的问题。在ajax标记上具有正确的更新目标不是问题,因为技术上删除了行但显示混乱了。只需一点点肮脏,你就可以解决这个问题。您可以在ajax标记的oncomplete期间强制使用过滤器。这将摆脱鬼重复记录。

<p:ajax event="rowEdit" 
        listener="#{beanName.onRowEdit}" 
        update=":growl :messages :formName:tableId"
        oncomplete="PF('tableWidgetVar').filter();" />

答案 1 :(得分:0)

最后最好的解决方案是为数据表实现select事件,并在事件中有一个对话框来选择选项,然后刷新表,这是最后的xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<h:head>

</h:head>

<h:body>


    <h:form id="myForm">
        <p:growl id="msgs" showDetail="true" life="2000" />


        <p:panel header="Sale Item" style="width: 400px;">

            <h:panelGrid columns="2" cellpadding="5">
                <p:outputLabel value="Texto" for="acSimple" />
                <p:autoComplete id="acSimple"
                    value="#{wordCatalogatorController.texto}"
                    completeMethod="#{wordCatalogatorController.completeText}"
                    binding="#{wordCatalogatorController.autoCompleteText}" />

                <p:commandButton value="Guardar actividad" id="save"
                    update=":myForm:msgs words"
                    binding="#{wordCatalogatorController.saveButton}"
                    actionListener="#{wordCatalogatorController.saveActivity}"
                    styleClass="ui-priority-primary" process="@this" />
            </h:panelGrid>

            <p:dataTable id="words" widgetVar="words" var="word"
                value="#{wordCatalogatorController.unknownWords}" editable="true"
                style="margin-bottom:20px" rowKey="#{word.word}"
                selection="#{wordCatalogatorController.selectedWord}"
                selectionMode="single" editMode="row">

                <p:ajax event="rowSelect"
                    listener="#{wordCatalogatorController.changeClient}"
                    oncomplete="PF('activityDialog').show()"
                    update=":myForm:activityDialog" />

                <f:facet name="header">Edicion de palabras</f:facet>

                <p:column headerText="Palabra">
                    <h:outputText value="#{word.word}" />
                </p:column>

                <p:column headerText="Edicion">
                    <h:outputText value="Presione para catalogar la palabra" />
                </p:column>
            </p:dataTable>

        </p:panel>



        <p:dialog id="activityDialog" width="500px" height="600px"
            header="Palabra a catalogar: #{wordCatalogatorController.selectedWord.word}"
            widgetVar="activityDialog" modal="true" closable="false">

            <h:panelGrid columns="2" cellpadding="5">

                <p:selectOneMenu id="wordTypes"
                    value="#{wordCatalogatorController.selectedWordType}"
                    style="width: 150px;" converter="#{wordTypeConverter}">
                    <p:ajax
                        listener="#{wordCatalogatorController.wordTypeChangeListener}"
                        update=":myForm:words" />
                    <f:selectItem itemLabel="" itemValue="" />
                    <f:selectItems value="#{wordCatalogatorController.wordTypes}" />
                </p:selectOneMenu>
            </h:panelGrid>

        </p:dialog>
    </h:form>
</h:body>
</html>