2012-04-18 36 views
0

我有问题,我如何更新在同一页上的其他复合组件。如果我输入客户ID并点击“搜索”按钮,客户应在数据库中搜索,如果存在,则系统继续基于客户ID搜索案例。反之亦然。JSF复合组件的每个其他更新

对于这个例子,假定关系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

用面板abs包装元件盒给它一个ID。将该ID作为更新属性提供给搜索。在命令按钮中使用该属性。

+0

好的,我打包组件的情况下: ...。但是,您的意思是“将该ID作为搜索并更新属性”和“在命令按钮中使用该属性”? – Ziletka 2012-04-19 16:46:55

+0

对于迟到的回复感到抱歉。我在休假。首先面板需要在一个表格内。接下来,为您的组件创建一个新参数,该参数用于获取表示要更新的项目的字符串。将该字符串馈送到命令按钮的更新属性中。 – mosgjig 2012-04-19 23:49:09

+0

我还在战斗。但另一个问题:standart 是否具有属性“update”?或者我必须使用例如PrimeFaces commandButton? – Ziletka 2012-04-20 16:13:35

0

我只可能通过实现观察者设计模式(具有不同之处在于除负责注册其观察员)来实现更新复合组件:

主题

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连接。