【问题标题】:Each other updating of JSF composite componentsJSF复合组件的相互更新
【发布时间】:2012-04-18 07:13:39
【问题描述】:

我有疑问如何更新同一页面上的其他复合组件。如果我输入客户 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 代码中实现设计模式观察者?但是存在很多观察者(Customer,Case,...)的许多主题(MainPageController,SecondPageController,...)的问题。

【问题讨论】:

    标签: java design-patterns jsf-2 composite-component


    【解决方案1】:

    用面板abs包裹组件箱给它一个ID。将该 ID 作为更新属性输入搜索。在命令按钮中使用该属性。

    【讨论】:

    • 好的,我包装了组件案例:
      ...
      。但是您的意思是“将该 ID 输入搜索并更新属性”和“在命令按钮中使用该属性”?
    • 抱歉回复晚了。我在休假。首先,面板需要在一个表格内。接下来,为您的组件创建一个新参数,该参数接收一个表示您要更新的项目的字符串。将该字符串输入命令按钮的更新属性。
    • 我还在战斗。但另一个问题:标准 是否具有属性“更新”?或者我必须使用 PrimeFaces commandButton?
    【解决方案2】:

    我只能通过实现观察者设计模式来实现更新复合组件(不同的是,主题负责注册其观察者):

    主题

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

    【讨论】:

      猜你喜欢
      • 2012-04-01
      • 2012-07-26
      • 2015-01-23
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 2013-03-23
      相关资源
      最近更新 更多