我在页面上显示了数据表的层次结构。
顶部有一个可以选择的 CashValueCalculation
实体列表。如果您选择其中一个,则其下方会显示另一个可选 Paymentstream
实体的数据表。然后第三次,如果您选择这种实体,则会显示 Payment
实体的最后一个数据表。
为此有 3 个 CDI bean:CashValueCalculationManager
、PaymentStreamManager
和 PaymentManager
,形成层次结构:
`CashValueCalculationManager`
|
+- `PaymentstreamManager`
|
+- `PaymentstreamManager`
这些 bean 应该在选择/取消选择事件时对其父 bean 作出 react (UI 实际上是通过 PrimeFaces p:dataTable
使用 JSF 完成的)。
每个 bean 都继承自具有实体 PK 的框架类,并且实体类本身是通用的。这是一些相关代码:
public abstract class BaseManager<K, T extends Entity<K>> extends BaseCdiViewBean implements Manager<K, T>
{
private static final long serialVersionUID = 1L;
private List<T> entities;
private T selectedEntity;
private EMode mode; // VIEW, ADD, EDIT, REMOVE
// CDI event producers
@Inject
@SingleSelect
private Event<T> selectEvent;
@Inject
@SingleUnselect
private Event<T> unselectEvent;
...
@Override
public void setSelectedEntity(T selectedEntity)
{
if (selectedEntity == null)
{
// null entity not really selectable, interpret as clear selection command
this.setSelectedEntity(null);
// fire CDI event to 0-n observers
this.unselectEvent.fire(this.newEntity()); // cannot pass null to CDI events, use a new entity created from a concrete bean
return;
}
// here we have a non-null selected entity
this.selectedEntity = selectedEntity;
// fire CDI event to 0-n observers
this.selectEvent.fire(selectedEntity);
}
...
}
Entity
接口(interface)只是:
public interface Entity<K>
{
public K getPk();
public void setPk(K pk);
}
两个子管理器 PaymentStreamManager
和 PaymentManager
继承自 BaseSubManager
并充当其父管理器 CashValueCalculationManager
的观察者和 PaymentStreamManager
分别(这就是他们应该做的):
public abstract class BaseSubManager<K, T extends Entity<K>, P extends Entity<?>> extends BaseManager<K, T> implements SubManager<K, T, P>
{
private static final long serialVersionUID = 1L;
private P parentEntity;
@Override
public P getParentEntity()
{
return this.parentEntity;
}
@Override
public void setParentEntity(P parentEntity)
{
this.parentEntity = parentEntity;
}
public void onSelect(@Observes @SingleSelect P selectedParentEntity)
{
System.out.println(this.getClass().getSimpleName() + ": selected parent entity: " + selectedParentEntity);
this.setParentEntity(selectedParentEntity);
}
public void onUnselect(@Observes @SingleUnselect P unselectedParentEntity)
{
System.out.println(this.getClass().getSimpleName() + ": unselected parent entity: " + unselectedParentEntity);
this.setParentEntity(null);
}
}
@SingleSelect
注释:
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, PARAMETER})
public @interface SingleSelect
{
// no additional interface
}
@SingleUnselect
注释:
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, PARAMETER})
public @interface SingleUnselect
{
// no additional interface
}
我现在想要的是 PaymentstreamManager
接收来自 CashValueCalculationManager
的事件,并且 PaymentManager
接收来自 PaymentstreamManager
的事件 仅。
但是,每次我选择顶级管理器 CashValueCalculationManager
的实体时,两个子管理器的 @Observer
方法都会接收事件(当然还有方法调用,这不是我需要的):
在选择测试时:
21:17:34,310 INFO [stdout] PaymentManager: selected parent entity: CashValueCalculation[pk=2]
21:17:34,312 INFO [stdout] PaymentStreamManager: selected parent entity: CashValueCalculation[pk=2]
取消选择测试时:
21:19:20,176 INFO [stdout] PaymentStreamManager: unselected parent entity: CashValueCalculation[pk=null]
21:19:20,177 INFO [stdout] PaymentManager: unselected parent entity: CashValueCalculation[pk=null]
问:
为什么这不能立即起作用?我需要在代码中更改哪些内容才能使其正常工作?
谢谢
最佳答案
有根据的猜测:
由于泛型是通过类型删除实现的,因此运行时在 BaseManager 中基本上会发生以下事件:
@Inject
@SingleSelect
private Event<Object> selectEvent;
@Inject
@SingleUnselect
private Event<Object> unselectEvent;
另一方面,您观察到以下情况:
public void onSelect(@Observes @SingleSelect Object selectedParentEntity)
public void onUnselect(@Observes @SingleUnselect Object unselectedParentEntity)
...这显然与每个事件匹配。
我尝试的是,向限定符注释添加一个类值,例如:
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, PARAMETER})
public @interface SingleSelect
{
public Class<?> value();
}
@Inject
@SingleSelect(SomeConcreteType.class)
private Event<Object> selectEvent;
public void onSelect(@Observes @SingleSelect(SomeConcreteType.class) P selectedParentEntity)
这样,您的容器应该能够在运行时区分各种事件。
关于java - CDI:观察特定类型实体的选择/取消选择(数据表层次结构),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44912981/