2

EL 式を使用して値を取得/設定する、selectOneMenu タグについて明確にする必要があります。

        <h:selectOneMenu id="variantsMenu"
            value="#{missionHandler.selectedVariant}"
            converter="#{missionHandler.variantConverter}">
            <f:selectItem itemLabel="-- Select a Variant --" />
            <f:selectItems value="#{missionHandler.variants}" var="variant"
                itemValue="#{variant}" itemLabel="#{variant.commercialName}" />
        </h:selectOneMenu>

私はこのコードを持っています。それは ("-- Select a Variant--", Variant 1, Variant 2, ... Variant n) を含むリストを表示します。Variant をクリックすると、 managedBeanのselectedVariantプロパティがmissionHandler自動的に更新されます。しかし、そうではありません。コンバーターは、variantConverter文字列 "variant.commercialName" を実際のVariantオブジェクトに変換するためにも呼び出されません。バリアント オブジェクトはhashCode()equals()

  • EL式/タグのどの概念が欠けていますか?
  • 更新の問題の解決策は何ですか?

    編集: managedBean (簡略化)

    @ManagedBean
    @ViewScoped
    public class MissionHandler implements Serializable {
    
    private static final long serialVersionUID = 2462652101518266609L;
    
    private List<FlightFeasibilityException> exceptions;
    
    @EJB
    private VariantDao variantDao;
    
    private Variant selectedVariant;
    
    private List<Variant> variants;
    
    private VariantConverter variantConverter;
    
    public MissionHandler() {
        /** Create an empty list of exceptions */
        exceptions = new ArrayList<FlightFeasibilityException>();
    }
    
    @PostConstruct
    public void init() {
        System.out.println("init done");
    }
    
    public List<FlightFeasibilityException> getExceptions() {
        return exceptions;
    }
    
    public void setExceptions(List<FlightFeasibilityException> exceptions) {
        this.exceptions = exceptions;
    }
    
    public Variant getSelectedVariant() {
        return selectedVariant;
    }
    
    public void setSelectedVariant(Variant selectedVariant) {
        this.selectedVariant = selectedVariant;
    }
    
    public List<Variant> getVariants() {
        return variants;
    }
    
    public void setVariants(List<Variant> variants) {
        this.variants = variants;
    }
    
    public VariantConverter getVariantConverter() {
        return variantConverter;
    }
    
    public void setVariantConverter(VariantConverter variantConverter) {
        this.variantConverter = variantConverter;
    }
    

    }

コンバータ

@FacesConverter(forClass=Variant.class)
public class VariantConverter implements Converter, Serializable {

    private static final long serialVersionUID = 7053414108213420057L;

    private VariantDao variantDao=new VariantDaoImpl();

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        System.out.println("convert to Object " + value);
        Variant variant = variantDao.find(value);
        System.out.println("got variant " + variant.getCommercialName());
        return variant;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        System.out.println("convert to String " + value);
        return ((Variant) value).getCommercialName();
      }

    }

および xhtml ファイル

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
    <title>Mission Page</title>
    <link href="./css/styles.css" rel="stylesheet" type="text/css" />
</h:head>
<h:body>
    <rich:panel>
        <f:facet name="header">
            Mission Information
        </f:facet>
        <a4j:outputPanel layout="block">
            <h:form>
                <h:outputText style="font-weight: bold;" value="Mission Id: " />
                <h:inputText id="missionId" label="missionId"
                    value="#{missionHandler.mission.id}" disabled="true"
                    style=" width : 50px;">
                </h:inputText>
                <h:outputText style="font-weight: bold;" value="Mission Status: " />
                <h:inputText id="missionStatus" label="missionStatus"
                    value="#{missionHandler.mission.status}" disabled="true">
                </h:inputText>
            </h:form>
            <br />
            <h:form>
                <h:selectOneMenu value="#{missionHandler.selectedAircraftType}"
                    converter="#{missionHandler.acTypeConverter}">
                    <f:selectItem itemLabel="-- Select an A/C Type --" />
                    <f:selectItems value="#{missionHandler.aircraftTypes}" var="type"
                        itemValue="#{type}" itemLabel="#{type.typeOACI}" />
                    <f:ajax listener="#{missionHandler.changeSelectedAircraftType}"
                        render="@form" />
                </h:selectOneMenu>
                <h:selectOneMenu id="variantsMenu"
                    value="#{missionHandler.selectedVariant}"
                    converter="#{missionHandler.variantConverter}"
                    rendered="#{not empty missionHandler.selectedAircraftType}">
                    <f:selectItem itemLabel="-- Select a Variant --" />
                    <f:selectItems value="#{missionHandler.variants}" var="variant"
                        itemValue="#{variant}" itemLabel="#{variant.commercialName}" />
                </h:selectOneMenu>
            </h:form>
        </a4j:outputPanel>
    </rich:panel>
….. A LOT OF OTHER THINGS …..
</h:body>
</html>
4

3 に答える 3

2

コードに関するいくつかの注意事項:

  1. マネージド Bean のコンストラクターで何かを行う == 悪い設計、@PostConstructor代わりに使用します。

  2. コンバーターで DAO を手動でインスタンス化する == 悪い設計。理想的には、DAO は、コンバーターに注入できる管理対象オブジェクト (できれば EJB) である必要があります。管理対象オブジェクトであることは、(理論的には) おそらくシングルトンであり、コンテナーによって適切に管理されることを意味します。少なくともこの方法では、それについて気分が悪くなることはありません。

  3. コンバーターを手動で管理しようとしています。コンバーターをスタンドアロン コンポーネントとして宣言し、コンテナーに機能させて、不必要なデバッグを回避できるようにします。

  4. variantsMenuajax ハンドラーがアタッチされていないため、フォーム全体が送信されるまで、バッキング Bean で値が更新されません。

    <h:selectOneMenu id="variantsMenu"
                value="#{missionHandler.selectedVariant}"
                converter="#{variantConverter}"
                rendered="#{not empty missionHandler.selectedAircraftType}">
                <f:ajax listener="#{missionHandler.changeVariant}"       render="@form" />
                <f:selectItem itemLabel="-- Select a Variant --" />
                <f:selectItems value="#{missionHandler.variants}" var="variant"
                    itemValue="#{variant}" itemLabel="#{variant.commercialName}" />
            </h:selectOneMenu>
    
于 2013-02-26T15:51:11.730 に答える
2

フォームが送信されていないため、メニューから項目を選択してもマネージド Bean の値は直接更新されません。

経由で送信するか、メニュー内で<h:commandButton ...>ajax イベントを使用<f:ajax event="change" ...>します。

于 2013-02-26T02:56:27.397 に答える
1

何かが足りない場合を除いて、コンバーターをインスタンス化することはないと思います。Beanにバインドしてコンバーターを取得しますが、値はどこにありますか?

コンバーターでのデータベースアクセスが気に入らないことは理解できます。OmniFacesの選択アイテムコンバーターの1つを使用する場合、これを行う必要はほとんどありません。

于 2013-02-26T12:29:44.277 に答える