0

同じページにある他の複合コンポーネントを更新する方法について質問があります。顧客 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)または、どうにかして設計パターンObserverをJavaコードで実装してみるべきですか? しかし、多数のオブザーバー (Customer、Case など) に対して多数のサブジェクト (MainPageController、SecondPageController など) が存在するという問題があります。

4

2 に答える 2

0

パネル abs でコンポーネント ケースをラップし、ID を指定します。その ID を更新属性として検索にフィードします。コマンドボタンでその属性を使用します。

于 2012-04-18T10:45:36.813 に答える
0

Observer 設計パターンを実装することによってのみ、複合コンポーネントの更新を実装することができました (Subject が Observer の登録を担当するという違いがあります)。

主題

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 (JSF フレームワークが MainPageController のインスタンスを作成するように強制するために、ここで id が設定されます)

<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-21T19:59:17.883 に答える