0

Keith Strickland の例に基づいて、XPages 用の JSF ライブラリ コントロールを構築しようとしています。

http://xprentice.gbs.com/A55BAC/keithstric.nsf/default.xsp?documentId=82770C11FA7B9B21852579C100581766

FileDownloadControl の構築に少し問題があります。構築したコードは次のとおりです。

     public class Libcontrol extends UIComponentBase implements FacesComponent {

        private static final String RENDERER_TYPE = "de.chris.Libcontrol ";
        private static final String COMPONENT_FAMILY = "de.chris";

        public Libcontrol() {
                setRendererType(RENDERER_TYPE);
        }

        @Override
        public String getFamily() {
                return COMPONENT_FAMILY;
        }

        @SuppressWarnings("unchecked")
        public void initBeforeContents(FacesContext arg0) throws FacesException {


            FacesContext context;
            ExpressionEvaluatorImpl evaluator;

        
            context = FacesContext.getCurrentInstance();
            evaluator = new ExpressionEvaluatorImpl(context);

        
            XspFileDownload result = new XspFileDownload();
            String sourceId = "fileDownload1/@value";
            String valueExpr = "#{document1.FileField}";
            ValueBinding value = evaluator.createValueBinding(result, valueExpr, sourceId,Object.class);
            result.setValueBinding("value", value);
            result.setDisplayLastModified(true);
            result.setAllowDelete(true);
            result.setTitle("filedown");
            result.setRows(30);
            result.setId("fileDownload1");

            this.getChildren().add(result);


        }

        public void buildContents(FacesContext arg0, FacesComponentBuilder arg1) throws FacesException {
        // Do Nothing
        }

       
        public void initAfterContents(FacesContext arg0) throws FacesException {
        // Do nothing
        }
}

コントロールが完全にレンダリングされないのはなぜですか? HTML コードを見ると、コントロールからの開始タグが表示されますが、ダウンロードするファイルがなく、対応する NotesDocument にファイルをアップロードしました。

以下は、私が実装したレンダラーをそれぞれコピーしたものです。

public class MainLibcontrolRenderer extends Renderer {


@Override
public void encodeBegin(FacesContext context, UIComponent component) {
    try {
        super.encodeBegin(context, component);
        context =  FacesContext.getCurrentInstance();
        UIViewRootEx rootEx = (UIViewRootEx) context.getViewRoot();
        /*rootEx.setDojoParseOnLoad(true);
        rootEx.setDojoTheme(true);*/
        
        ResponseWriter writer = context.getResponseWriter();
        writer.startElement("fieldset", component);
        
        
    } catch (Exception e) {
        e.printStackTrace();
    }
}
 

@Override
public void encodeChildren(FacesContext context, UIComponent component) {
    try {
        
        super.encodeChildren(context, component);      
    } catch (Exception e) {
        e.printStackTrace();
    }
}
 

@Override
public void encodeEnd(FacesContext context, UIComponent component) {
    try {
        super.encodeEnd(context, component);
        ResponseWriter writer = context.getResponseWriter();
        writer.endElement("fieldset");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

4

1 に答える 1

0

Stephan の言うとおりです。コンテンツがレンダリングされないのは、作成していないからです。FacesComponent を実装する場合、buildContents メソッドは通常、FacesComponentBuilder にビルド プロセスを開始するよう指示する必要があります。例えば:

arg1.buildAll(arg0, this, true);

注:例の引数名を使用しています。理想的には、「context」や「builder」などの意味のある引数名を使用する必要があります。

上記の buildAll メソッドにより、init メソッド中に構造に加えられた変更がコンポーネント ツリーに適切に反映されます。このステップをスキップすると、後続の JSF フェーズ (RENDER_RESPONSE を含む) は、注入したコンポーネントを認識しません。

ちなみに、Keith も有効な点を指摘しています。値バインディングやその他のプロパティをハードコーディングすると、少なくとも提供した例では、再利用可能なコントロールを定義するという目的が損なわれる傾向があります。カスタム コンポーネントが本当に適切な実装であるかどうかを判断するために、何を達成しようとしているのかを詳しく調べてくださいという Keith のアドバイスに同意します。最後に 1 つ注意してください。挿入されたコンポーネントの id プロパティをプログラムで設定するときは、細心の注意を払ってください。コンパイル中に検出できない名前の衝突が発生する可能性があります。言い換えれば、デザイナーはあなたに警告することはできません...実行時に壊れるだけで、失敗の理由はおそらく明らかではありません。

于 2012-07-18T05:12:44.930 に答える