【问题标题】:How do I efficiently update a property contained in several classes?如何有效地更新包含在多个类中的属性?
【发布时间】:2013-11-01 14:29:45
【问题描述】:

我有一个简单的模式,控制器/支持 bean 在 @ViewScoped 上下文中管理单个实体实例。该视图采用几个支持 bean 并显示信息。 Andy Gibson 在blog post 中描述了我正在使用的方法。

现在我需要显示关于两个实体的信息,一个人及其联系人:

@Entity
public class Person {
    @Id @Generated 
    private Long id;

    @OneToMany(mappedBy = "owner") 
    private Set<Contact> contacts = new LinkedHashSet<>();
}

@Entity
public class Contact {
    @Id @Generated 
    private Long id;

    private String content;

    @ManyToOne
    private Person owner;

    @OneToMany
    private Set<File> attachments;
}

有一个 ContactMgr 和一个 PersonMgr,我首先通过 f:viewAction 完全加载 Person。然后我会显示一个人的联系人列表,并让用户在rich:popupPanel 中编辑它们:

<h:dataTable value="#{personMgr.instance.contacts}" var="c">
    <h:column><a4j:commandLink value="#{c.content}"
        actionListener="#{contactMgr.setId(c.id)}"
        action="#{contactMgr.fullInit()}"
        render=":contactInnards"
        oncomplete="#{rich:component('contactPanel')}.show();" />
    </h:column>
 </h:dataTable>

单击链接会加载选定的联系人并让用户根据自己的喜好进行编辑。用户然后单击“保存”,更改将被保留。到这里为止,一切都很好。

但现在我想重新渲染联系人列表。如何让PersonMgr 知道已更改的联系人?联系人列表是前段时间填充的,在 ContactMgr 中没有更改。

我已经看过三个解决方案:

  • 直接在ContactMgr 上设置联系人,但我确实需要在显示弹出窗口之前再初始化一些字段,因为我不想为每个联系人承担成本。
  • 完全重新加载网站是可能的,但成本也很高。
  • 有了@Observe,恐怕我需要十几种方法,我附在Person的每个列表一个

那么,我如何有效地将更改信息从一个 bean 分发到包含已编辑实体的(现在陈旧的)副本的其他 bean?

【问题讨论】:

    标签: jsf-2 cdi weld2


    【解决方案1】:

    我开始认为这个问题实际上就像缓存失效 - 一个已知的难题。我可能会做一些东西来扩展@Observe(notifyOberserver = IF_EXISTS) 的想法,让它在不被新方法淹没的情况下发挥作用。

    但是我发现,只需将支持 dataTable 的任务移动到 ContactMgr 并将填充、选择和更新列表的所有逻辑都驻留在单个类中即可创造奇迹完全避免了这个问题。

    【讨论】:

      猜你喜欢
      • 2017-09-02
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 2012-12-27
      • 2018-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多