【问题标题】:Adding a FileDownload Control by library control通过库控件添加 FileDownload 控件
【发布时间】:2012-07-16 11:29:59
【问题描述】:

我正在尝试根据 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();
    }
}

}

【问题讨论】:

  • buildContents // 什么都不做?
  • 这是我第一次创建这样的组件。我必须用这种方法写一些东西吗?
  • 我不得不问,你想在这里完成什么?我问是因为我看到您在上面的 ValueBinding 中有一个硬编码的字段名称。这违背了将组件放入插件库的目的。您将一个组件放入插件中,以使其可供服务器上的所有开发人员使用,而硬编码的 ValueBinding 会破坏该目的。此外,如果您正在从库构建应用程序,我建议您使用传统的 XPages 方式,并在库中包含任何 REST 服务、组件和关联类以及 nsf 中的业务逻辑。
  • 这只是我尝试做的一个例子。硬编码的值绑定、id 等将在我的应用程序中被替换。我的问题是我不知道为什么不呈现文件下载。我正在寻找我必须做什么的建议或简单的想法,我所做的事情有什么问题

标签: jsf xpages


【解决方案1】:

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

arg1.buildAll(arg0, this, true);

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

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

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

【讨论】:

  • 正如我在上面写的,这只是我想要做的一个例子,而不是我控制的 finla 代码。我将您的代码行添加到 buildcontents 方法中,但没有任何反应。我应该添加任何其他内容或更改/添加超出预期的内容吗?
  • 我无法从您迄今为止发布的内容中确定您为组件使用的渲染器。当您扩展现有组件时,它通常只使用基本组件的渲染器,除非您定义自己的。您是否为此组件创建并定义了自定义渲染器?
  • 我已将我的渲染器添加到我的问题文本中。我希望这能更好地解释我所做或尝试做的事情^^。我添加了自己的自定义渲染器并定义了一个配置文件。我也将它发布在 faces config 中
  • 你提到这只是一个想法的例子,而不是你打算实现的实际功能......但很难解决你的问题的一个关键原因是你的例子'已发布并没有真正添加核心控件中尚不可用的任何内容。事实上,它实际上减少了功能,因为您将硬编码的值分配给属性,否则这些属性可能会在每个页面上分配不同的值或值绑定。如果您发布一个更具代表性的示例来说明您要完成的工作,则问题的性质可能更容易识别。
  • 好的,整个想法是构建一个从 XML 配置创建一组控件的控件。从这个配置中应该有所有标准的 IBM 控件,如 Inputtext、richtext、fieldupload s.o。其中一个控件应该是文件下载。在“initBeforeContents”方法中,我最初构建了一些代码来读取配置,然后在 XSPTable 中构建控件。所以现在我唯一的问题是,没有文件下载,所有控制都可以正常工作。
猜你喜欢
  • 2010-09-21
  • 2013-09-08
  • 2013-07-05
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-25
相关资源
最近更新 更多