我有疑问如何更新同一页面上的其他复合组件。如果我输入客户ID并单击“搜索”按钮,则应在数据库中搜索客户,如果存在,则系统继续搜索基于客户ID的案例。反之亦然。
对于此示例,假设关系Customer:Case为1:1。
main_page.xhtml
<h:body>
<ui:composition template="/WEB-INF/template/layout.xhtml">
<ui:define name="content">
<custom:component_customer
customerId="#{mainPageController.customer.id}"
searchCustomer="#{mainPageController.searchCustomer}"
/>
<custom:component_case
caseaseId="#{mainPageController.case.caseId}"
searchCase="#{mainPageController.searchCase}"
/>
</ui:define>
</ui:composition>
</h:body>
component_customer.xhtml
<composite:interface>
<composite:attribute name="customerId" type="java.lang.Long"/>
<composite:attribute name="searchCustomer" method-signature="void searchCustomer()"/>
</composite:interface>
<composite:implementation>
<h:form>
<h:inputText id="id" value="#{cc.attrs.customerId}"/>
<h:commandButton value="Search" action="#{cc.attrs.searchCustomer}"/>
</h:form>
</composite:implementation>
component_case.xhtml
<composite:interface>
<composite:attribute name="caseId" type="java.lang.Long"/>
<composite:attribute name="searchCase" method-signature="void searchCase()"/>
</composite:interface>
<composite:implementation>
<h:form>
<h:inputText id="id" value="#{cc.attrs.caseId}"/>
<h:commandButton value="Search" action="#{cc.attrs.searchCase}"/>
</h:form>
</composite:implementation>
MainPageController.java
@ManagedBean
@ViewScoped
public class MainPageController {
@EJB
private CaseLogic caseLogic;
@EJB
private CustomerLogic customerLogic;
private Customer customer = new Customer();
private Case case = new Case();
// getter & setters
public void searchCustomer() {
}
public void searchCase() {
}
1)是否有一些通用的“JSF”解决方案?
2)或者我应该尝试以某种方式在java代码中实现设计模式Observer?但是存在许多观察者(Customer,Case,...)存在许多主题(MainPageController,SecondPageController,...)的问题。
答案 0 :(得分:0)
用面板abs包装组件盒为它提供一个ID。将该ID作为更新属性提供给搜索。在命令按钮中使用该属性。
答案 1 :(得分:0)
我只能通过实现Observer设计模式来实现更新复合组件(不同主题负责注册其Observers):
主题
public abstract class Subject {
private final List<Observer> observerList = new ArrayList<>();
public void registerObserver(final Observer observer) {
observer.setSubject(this);
observerList.add(observer);
}
public List<Observer> getObserverList() {
return observerList;
}
public abstract void notifyObservers(final Observer observer);
}
具体主题
@ManagedBean
@ViewScoped
public class MainPageController extends Subject {
@ManagedProperty(value = "#{caseComponent}")
private CaseComponent caseComponent;
@ManagedProperty(value = "#{customerComponent}")
private CustomerComponent customerComponent;
private final String customerComponentId = "MainPageCustomer";
private final String caseComponentId = "MainPageCase";
@Override
public void notifyObservers(final Observer changed) {
for (Observer observer : getObserverList()) {
observer.update(changed);
}
}
// is invoked by JSF framework thanks to @ManagedProperty injection
public void setCaseComponent(CaseComponent caseComponent) {
this.caseComponent = caseComponent;
registerObserver(this.caseComponent);
}
// is invoked by JSF framework thanks to @ManagedProperty injection
public void setCustomerComponent(CustomerComponent customerComponent) {
this.customerComponent = customerComponent;
registerObserver(this.customerComponent);
}
public String getCustomerComponentId() {
return customerComponentId;
}
public String getCustomerComponentId() {
return customerComponentId;
}
}
观察
public interface Observer {
public abstract void setSubject(Subject subject);
public abstract void update(Observer changed);
}
具体观察者(CustomerComponent)
@ManagedBean
@ViewScoped
public class CustomerComponent implements Observer {
@EJB
private CustomerLogic logic;
private Subject subject;
// backing bean property
private Customer customer = new Customer();
@Override
public void setSubject(final Subject subject) {
this.subject = subject;
}
@Override
public void update(final Observer changed) {
if (changed instanceof CustomerComponent) {
// do nothing, in this case the customer was updated yet
// in public void searchCustomer() method
} else if (changed instanceof DeliverySiteComponent) {
DeliverySiteComponent deliverySiteComponent = (DeliverySiteComponent) changed;
searchCustomer(deliverySiteComponent.getDeliverySite());
}
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(final Customer customer) {
this.customer = customer;
}
public void searchCustomer() {
customer = logic.find(customer);
if(customer != null && customer.getId() != null) {
subject.notifyObservers(this);
}
}
private void searchCustomer(final DeliverySite deliverySite) {
customer = logic.find(deliverySite);
}
}
具体观察者(CaseComponent)
@ManagedBean
@ViewScoped
public class CaseComponent implements Observer {
...
}
main_page.xhtml(此处设置id以强制JSF框架创建MainPageController的实例)
<h:body>
<ui:composition template="/WEB-INF/template/layout.xhtml">
<ui:define name="content">
<custom:component_customer
id="#{mainPageController.customerComponentId}"
customerId="#{customerComponent.customer.id}"
searchCustomer="#{customerComponent.searchCustomer}"
/>
<custom:component_case
id="#{mainPageController.caseComponentId}"
caseaseId="#{caseComponent.case.caseId}"
searchCase="#{customerComponent.searchCase}"
/>
</ui:define>
</ui:composition>
</h:body>
所以,现在我将每个复合组件仅与其托管bean连接。