创建主从表和对话框,如何重用相同的对话框进行创建和编辑 [英] Creating master-detail table and dialog, how to reuse same dialog for create and edit

查看:26
本文介绍了创建主从表和对话框,如何重用相同的对话框进行创建和编辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个对话框,用于创建对象和更新对象.因此,如果我碰巧单击新建"按钮,我将看到一个包含要填充的空字段的对话框,或者如果我单击条目的编辑按钮,则该条目的数据将显示在对话框中以供更新.

I am attempting to create a dialog that will serve the purpose of both creating objects and updating them. So if I happen to click the 'new' button I will be presented a dialog containing empty fields to be filled or if I click on an edit button for an entry, that entry's data will presented in the dialog for update.

按照 5.2 版 primefaces 展示中的示例,我可以以只读的 outputText 形式呈现数据,但是当我将其更改为 inputText 时,该字段仍为空.以下代码是我所拥有的示例:

Following the example in the primefaces showcase for version 5.2, I can present the data in a read only outputText form, however when I change it to an inputText, the field remains empty. The following code is an example of what I have:

<h:form id="form">    
  <p:dataGrid id="guestList" var="guest" value="${guestList.guests}" columns="3" paginator="true" rows="20">
    <f:facet name="header">
      Guest List
    </f:facet>

    <p:panel>
      <h:outputText value="${guest.name}" />
      <br />
      <h:outputText value="${guest.street}" />
      <br />
      <h:outputText rendered="#{guest.street2.length() gt 0}"
        value="${guest.street2}" />
      <h:panelGroup rendered="#{guest.street2.length() gt 0}">
        <br />
      </h:panelGroup>
      <h:outputText value="${guest.city}, " />
      <h:outputText value="${guest.state} " />
      <h:outputText value="${guest.zipCode}" />
      <p:commandButton update="@form:newGuestDetail" oncomplete="PF('newGuestDialog').show()" icon="ui-icon-edit" styleClass="ui-btn-inline">
        <h:outputText styleClass="ui-icon ui-icon-edit" style="margin:0 auto;" />
        <f:setPropertyActionListener value="#{guest}" target="#{guestList.selectedGuest}" />
      </p:commandButton>
    </p:panel>
  </p:dataGrid>

  <p:dialog header="#{guestList.hasSelected() ? 'Edit Guest' : 'New Guest'}" widgetVar="newGuestDialog" modal="true" showEffect="fade" hideEffect="fade">
    <p:outputPanel id="newGuestDetail">
      <h:outputText value="'#{guestList.selectedGuest.name}'"/>
      <p:inputText id="guestName" value="#{guestList.hasSelected() ? '' : guestList.selectedGuest.name}" pt:placeholder="Name"/>
      <p:commandButton value="#{guestList.selectedGuest == null ? 'Create Guest' : 'Update Guest'}"/>
    </p:outputPanel>
  </p:dialog>
</h:form>

hasSelected() 方法评估选定的guest 是否为空,如果不为空则返回true.单击 commandButton 时应设置 selectedGuest,以便对话框可以检索对象,但是,对于 selectedGuest 的 get/set 中的跟踪器,我没有看到使用上述代码段调用的 setter.如果我删除 inputText,那么即使 hasSelected 仍然返回 false,因此新来宾"正在引导对话框,outputText 填充了一个值.

The hasSelected() method evaluates whether the selected guest is null or not, returning true if not null. The selectedGuest should be set when the commandButton is clicked so that an object is available for retrieval by the dialog, however, with tracers in the get/set for selectedGuest, I am not seeing the setter called with the above snippet. If I remove the inputText, then even though the hasSelected is still returning false, and thus the 'New Guest' is heading the dialog, the outputText is filled with a value.

我发现这篇很棒的帖子讨论了与动作、动作侦听器等相关的执行顺序,但不要认为这完全是我的问题:动作和动作监听器之间的区别.

I found this great post talking about the order of execution with respect to the action, action listener, etc., but don't think this quite my issue: Differences between action and actionListener.

所以最终的问题是,当我只有一个 outputText 时,为什么我的 setter 会被命令按钮调用,但是对于 inputText,我从未在日志中看到它被调用?

So the ultimate question is why will my setter get called with the command button when I only have an outputText, but with an inputText, I never see it called in the log?

我感谢任何人可以提供的时间和帮助.

I appreciate the time and help anyone can provide.

推荐答案

即使我们解决了你的问题,这个构造

Even if we fix your problem, this construct

<p:inputText value="#{guestList.hasSelected() ? '' : guestList.selectedGuest.name}">

永远不会工作.它需要引用模型属性,而不是空字符串.

is not ever going to work. It needs to reference a model property, not an empty string.

您最好只重复使用编辑表单并让创建按钮预先创建一个空实体.这将在视图方面简化很多.如果实体具有 @Id 属性,该属性仅在它持久存在于数据库中时才存在,则会更容易.

You'd best just reuse the edit form and let the create button precreate an empty entity. This would simplify a lot in the view side. It'd be more easy if the entity has an @Id property which is only present when it's persisted in the database.

这是一个启动示例:

<h:form id="entitiesForm">
    <p:dataTable id="entitiesTable" value="#{bean.entities}" var="entity">
        <p:column>#{entity.foo}</p:column>
        <p:column>#{entity.bar}</p:column>
        <p:column>
            <p:commandButton id="edit" value="Edit" 
                process="@this" action="#{bean.edit(entity)}"
                update=":entityDialog" oncomplete="PF('entityDialog').show()" />
            <p:commandButton id="delete" value="Delete" 
                process="@this" action="#{bean.delete(entity)}"
                update=":entitiesForm:entitiesTable" />
        </p:column>
    </p:dataTable>
    <p:commandButton id="add" value="Add" 
        process="@this" action="#{bean.add}" 
        update=":entityDialog" oncomplete="PF('entityDialog').show()" />
</h:form>

<p:dialog id="entityDialog" widgetVar="entityDialog" 
    header="#{empty bean.entity.id ? 'New' : 'Edit'} entity">
    <h:form id="entityForm">
        <p:inputText id="foo" value="#{bean.entity.foo}" />
        <p:inputText id="bar" value="#{bean.entity.bar}" />
        <p:commandButton id="save" value="#{empty bean.entity.id ? 'Create' : 'Update'} entity" 
            process="@form" action="#{bean.save}"
            update=":entitiesForm:entitiesTable" oncomplete="PF('entityDialog').hide()" />
    </h:form>
</p:dialog>

使用这个 @ViewScoped bean:

With this @ViewScoped bean:

private List<Entity> entities; // +getter
private Entity entity; // +getter

@EJB
private EntityService entityService;

@PostConstruct
public void load() {
    entities = entityService.list();
    entity = null;
}

public void add() {
    entity = new Entity();
}

public void edit(Entity entity) {
    this.entity = entity;
}

public void save() {
    entityService.save(entity); // if (id==null) em.persist() else em.merge()
    load();
}

public void delete(Entity entity) {
    entityService.delete(entity); // em.remove(em.find(type, id))
    load();
}

另见:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆