【问题标题】:p:datatable not refreshed correctly after data modification in p:dialog在 p:dialog 中修改数据后 p:datatable 未正确刷新
【发布时间】:2017-10-09 14:17:52
【问题描述】:

好的,尝试缩短一点并将代码放在帖子的末尾。谢谢你的回答。

在阅读了很多关于该主题的问题/答案并没有找到任何解决方案之后,这是我的问题。 我试图尽可能简洁,所以我可能会截断一些代码,请随时询问详细信息。 我对 JSF,primefaces 世界也很陌生。

我在基于 Spring/Hibernate/Primefaces 的现有 Web 应用程序上开发改进/修复。 用户界面包含一个带有一些 p:datatable 的 tabview :公司,在我的例子中是用户。

这是我的用例:

  • 在“formCompany”中,一个按钮会显示“createCompany”对话框。

  • 我创建了一家公司 'aaaa/aaaa'(名称和代码对于 societeEntity 是必需的) -> 公司被添加到'CompaniesTable'中

  • 我创建了一个与该公司 'john'/'aaaa' 关联的用户(名称和公司是 utilisateurEntity 的必填字段) -> 用户被创建并显示在 'userTable' 中,公司名称为 'aaaa'

  • 我修改名称为公司的'bbbb'并保存 -> 'userTable' 中的公司名称未更新

我怀疑 userTable 没有使用 commandButton 的“更新”属性从数据库中刷新。 我猜“:panelBas:formUser:userTable”上的“更新”属性可以正常工作,但只能在客户端。

我希望包含用户的数据表将使用新的公司名称“bbbb”进行刷新。

我尝试过的技巧:

  • 更新 p:commandButton 上的属性 => 失败
  • 从 p:commanbButton.oncomplete 访问 userTable 并使用其 widgetVar id 并调用假设的“刷新/重新加载/更新”方法,使用 PF('userTable') => 失败(primefaces 文档并没有真正帮助...)

这是保存公司的按钮代码:

<p:commandButton value="Save" update="companyNameMsg companyCodeMsg :panelBas:formCompany:CompaniesTable **:panelBas:formUser:userTable**" ajax="true"
    actionListener="#{companyDialog.save}" icon="ui-icon-disk"
    **oncomplete="if(args &amp;&amp; !args.validationFailed) { PF('createCompany').hide(); }"** />

组件 p:datatable 似乎没有从服务器重新加载数据的方法。 所以问题是如何在将公司保存在支持 bean 中后更新我的用户数据表?

下面的代码显示了 xhtml 页面,其中包含 tabview、对话框、数据表……

main.xhtml

<p:tabView id="panelBas" widgetVar="wvPanelBas" activeIndex="#{searchDialog.activeIndex}">
    <p:tab title="Companies">
        <h:form id="**formCompany**">
            <p:dataTable id="CompaniesTable" value="#{companyDialog.companyList}" var="item3" lazy="false"
                tableStyle="text-align: center;width:auto" paginator="true" rowsPerPageTemplate="5,10,15,20,30,50,100" rows="15"
                sortBy="#{item3.nom}" sortOrder="ascending" filteredValue="#{companyDialog.companyFilteredList}">
                ...
            </p:dataTable>
        </h:form>
    </p:tab>

    <p:tab title="Users">
        <h:form id="formUser">
            <p:dataTable id="userTable" widgetVar="wvUserTable" **value="#{userDialog.utilisateurList}"** var="item2" lazy="false" 
                tableStyle="text-align: center;width:auto" paginator="true" rowsPerPageTemplate="5,10,15" rows="10"
                sortBy="#{item2.nom}" sortOrder="ascending" filteredValue="#{userDialog.utilisateurFilteredList}">

                **<!-- This value is not updated when associated company's name is modified-->
                <p:column filterBy="#{item2.societe.nom}" sortBy="#{item2.societe.nom}" headerText="Company">
                    <h:outputText value="#{item2.societe.nom}" />
                </p:column>**
                ...
                <p:column filterBy="#{item2.nom}"  sortBy="#{item2.nom}" headerText="Nom" sortOrder="ascending">
                    <h:outputText value="#{item2.nom}" />
                </p:column>
            </p:dataTable>
        </h:form>
    </p:tab>
</p:tabView>

<!-- This dialog allows to modify company data -->
<p:dialog header="New Company" widgetVar="createCompany" id="createCompany" resizable="true" modal="true" width="500" showEffect="clip" hideEffect="clip">
    <h:form>
        ...
        <!-- Company modification form -->
        <p:commandButton value="Save" update="companyNameMsg companyCodeMsg :panelBas:formCompany:CompaniesTable **:panelBas:formUser:userTable**" ajax="true"
            actionListener="#{companyDialog.save}" icon="ui-icon-disk"
            **oncomplete="if(args &amp;&amp; !args.validationFailed) { PF('createCompany').hide(); }"** />
    </h:form>
</p:dialog>

这是bean的代码:

CompanyDialog.java

@Component("companyDialog")
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class CompanyDialog {
    // Managed property used by datatable attribute 'value'
    @ManagedProperty("#{companyList}")
    private List<SocieteEntity> companyList;

    // Managed property used by datatable attribute 'filteredValue'
    @ManagedProperty("#{companyFilteredList}")
    private List<SocieteEntity> companyFilteredList;

    @ManagedProperty("#{societeEntity}")
    private SocieteEntity societeEntity;

    @Override
    public void save() {
        ...
    }
}

UserDialog.java

@Component("userDialog")
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserDialog {
    // Managed property used by datatable attribute 'value'
    @ManagedProperty("#{utilisateurList}")
    private List<UtilisateurEntity> utilisateurList;

    // Managed property used by datatable attribute 'filteredValue'
    @ManagedProperty("#{utilisateurFilteredList}")
    private List<UtilisateurEntity> utilisateurFilteredList;

    @ManagedProperty("#{utilisateurEntity}")
    private UtilisateurEntity utilisateurEntity;

    public void recherche() {
        // Fills the managed property utilisateurList (used by the datatable)
        ...
    }
}

提前感谢您,祝您有美好的一天。

【问题讨论】:

标签: java jsf primefaces


【解决方案1】:

您的问题是:“如何在保存公司后更新我的用户数据表?”

在 jsf 对话框中的按钮中试试这个:

<h:commandButton id="ok" value="OK">
    <p:ajax click="messagesDialog.hide()" 
    update="@all"/>
</h:commandButton>

首先在更新目标中,尝试使用@form,如果不起作用,使用@all

如果不起作用,请尝试使用 imediate="true",imatiate true,这将改变订单生命周期,如果之前的建议不起作用,也许可以解决您的问题。我认为你的问题很简单,你不应该写很多文字。

【讨论】:

  • @all 只应在极少数情况下使用。 immediate="true" 在现代基于 jsf/ajax 的应用程序中很少需要,因为有一个 process\execute 属性。
  • 是的。我的意思是,尝试扩大范围。他应该首先使用初始范围。如果不工作。在最终情况下使用“@all”或“@form”。谢谢回答
【解决方案2】:

所以我用注入的 bean 挖掘了解决方案并使它起作用。

这个想法在那个链接中:Can I call multiple methods from <p:ajax event=select listner=method1, metho2>?

我不确定这种方法在注释方面是否非常干净......

我像这样在 CompanyDialog bean 中注入了 UserDialog bean:

@Component("companyDialog")
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class CompanyDialog {
    @Inject
    private UserDialog userDialog;

    // When I update a company, the list userDialog.utilisateurList of users is reloaded in userDialog
    public void save() {
        // ...
        userDialog.recherche();
    }
}

@Component("userDialog")
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserDialog {
    @ManagedProperty("#{utilisateurList}")
    private List<UtilisateurEntity> utilisateurList;

    // Fills the list utilisateurList
    public void recherche() {
        // ...
    }
}

如果有任何改进,请随时提出任何建议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    相关资源
    最近更新 更多