通过库控件添加文件下载控件

时间:2012-07-16 11:29:59

标签: jsf xpages

我正在尝试根据Keith Strickland的例子为XPage构建一个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代码时,我看到控件中的starttag但没有要下载的文件 是的,我已将文件上传到相应的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();
    }
}

}

1 个答案:

答案 0 :(得分:0)

Stephan是对的:内容不呈现的原因是你没有构建它们。在实现FacesComponent时,buildContents方法通常应该指示FacesComponentBuilder启动构建过程; e.g:

arg1.buildAll(arg0, this, true);

注意:我正在使用您示例中的参数名称;理想情况下,您应该使用有意义的参数名称,如“context”和“builder”。

上面提到的buildAll方法使组件树正确反映了init方法期间对结构所做的任何更改。如果跳过此步骤,后续的JSF阶段(包括RENDER_RESPONSE)将不知道您注入的任何组件。

顺便说一句,Keith也提出了一个有用的观点:对值绑定和其他属性进行硬编码 - 至少在您提供的示例中 - 往往会破坏定义可重用控件的目的。我想回应Keith的建议,仔细研究一下你要完成的工作,以确定自定义组件是否真的是合适的实现。最后一个注意事项:在注入组件上以编程方式设置id属性时要特别小心......最终可能会出现在编译期间无法检测到的名称冲突。换句话说,Designer无法警告你......它只会在运行时断开,失败的原因可能并不明显。