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

Jsf 通过库控件添加文件下载控件,jsf,xpages,Jsf,Xpages,我试图基于Keith Strickland的示例为XPages构建一个JSF库控件 我在构建FileDownloadControl时遇到了一点麻烦 以下是我构建的代码: public class Libcontrol extends UIComponentBase implements FacesComponent { private static final String RENDERER_TYPE = "de.chris.Libcontrol &quo

我试图基于Keith Strickland的示例为XPages构建一个JSF库控件

我在构建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();
    }
}

}斯蒂芬是对的:内容不呈现的原因是您没有构建它们。在实现FacesComponent时,buildContents方法通常应指示FacesComponentBuilder启动构建过程;e、 g:

arg1.buildAll(arg0, this, true);
注意:我使用的是您示例中的参数名称;理想情况下,应该使用有意义的参数名称,如“context”和“builder”

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


顺便说一句,Keith也提出了一个有效的观点:硬编码值绑定和其他属性——至少在您提供的示例中是这样——往往会破坏定义可重用控件的目的。我赞同Keith的建议,仔细看看您试图完成的工作,以确定定制组件是否真的是合适的实现。还有最后一个警告:在以编程方式设置注入组件的id属性时,请格外小心。。。最终可能会导致编译期间无法检测到的名称冲突。换句话说,设计师不能警告你。。。它将在运行时中断,失败的原因可能并不明显。

buildContents//Do Nothing?这是我第一次创建这样的组件。我必须用这种方法写些东西吗?我必须问,你在这里想要完成什么?我这样问是因为我看到上面的ValueBinding中有一个硬编码字段名。这违背了将组件放入插件库的目的。您将一个组件放在插件中,使其可供服务器上的所有开发人员使用,而硬编码的ValueBinding则无法达到这一目的。另外,如果您要从库中构建应用程序,我建议您使用传统的XPages方法,并在库中包含任何REST服务、组件和关联类,以及nsf中的业务逻辑。这只是我尝试做的一个示例。在我的应用程序中,硬编码的绑定、id等将被替换。我的问题是,我不知道为什么不呈现文件下载。我在寻找一个我必须做的建议,或者一个简单的想法,我所做的有什么错,因为我在上面写的这只是我试图做的一个例子,而不是我控制的finla代码。我将您的代码行添加到buildcontents方法中,但什么也没有发生。我是否应该添加任何其他内容或更改/添加超出预期的内容?我无法根据您发布的内容确定您正在为组件使用的渲染器。扩展现有组件时,除非定义自己的渲染器,否则它通常只使用基本组件的渲染器。您是否为此组件创建并定义了自定义渲染器?我已将渲染器添加到问题文本中。我希望这能更好地解释我所做或试图做的事情。我添加了自己的自定义渲染器并定义了一个配置文件。此外,我已经在Facebook上发布了它。您提到,这只是一个想法的示例,而不是您打算实现的实际功能。。。但很难解决问题的一个关键原因是,您发布的示例并没有真正添加核心控件中尚未提供的任何内容。事实上,它实际上减少了功能,因为您将硬编码的值分配给属性,否则这些属性可以在每个页面上分配不同的值或值绑定。如果您发布了一个更具代表性的示例,说明您试图实现的目标,那么问题的本质可能更容易识别。好的,整个想法是构建一个控件,从XML配置创建一组控件。在此配置中,应该有所有标准IBM控件,如Inputtext、richtext、fieldupload s.o。其中一个控件应该是文件下载。我使用“initBeforeContents”方法,我最初构建了一些代码来读取配置,然后在XSPTable中构建控件。所以现在我唯一的问题是,没有文件下载,所有控件都可以正常工作。