1

我必须为<h:commandLink/>标签编写一个自定义渲染器来支持data-*为了将 JSF 2.1 与 jQuery 移动框架一起使用,

我的 JSF 标记和此标记生成的输出如下:

          <h:commandLink value="Prev" data-theme="e" data-role="button" data-inline="true" data-mini="true" data-icon="arrow-l"/>
           <h:commandLink value="Page 1 of 3" data-theme="e" data-role="button" data-inline="true" data-mini="true"/>
           <h:commandLink value="Next" data-theme="e" data-role="button" data-inline="true" data-mini="true" data-icon="arrow-r" data-iconpos="right"/>

在此处输入图像描述

很明显,我的自定义渲染器正确渲染了第二个和第三个<h:commandLink/>标签,但不是第一个。似乎data-*属于第一个标签的属性是用直接父级呈现的<div/>标签呈现的。这似乎是 Mojarra 的一个奇怪(和错误)的行为(我使用V 2.1.11)。请告诉我如何克服这个问题?

我的自定义渲染器代码如下:

public class MyCommandLinkRenderer extends CommandLinkRenderer {

    @Override
    public void encodeBegin(FacesContext context, UIComponent component) {

        String[] attributes = {"data-theme", "data-role", "data-icon", "data-inline", "data-mini", "data-iconpos"};

        ResponseWriter writer = context.getResponseWriter();
        try {
            for (String attribute : attributes) {
                String value = (String) component.getAttributes().get(attribute);
                if (value != null) {
                    writer.writeAttribute(attribute, value, attribute);
                    System.out.println(attribute + " " + value);
                }
            }
            super.encodeBegin(context, component);
        } catch (Exception e) {
        }
    }
}
4

1 回答 1

4

You must call super.encodeBegin() before writing the attributes.

Otherwise you're writing the attributes to the previous HTML element, as confirmed by the generated HTML output. The super.encodeBegin() starts the new HTML element.

This is just a bug in your own code, not in Mojarra.


Update: also, overriding the encodeBegin() was not right in first place. You should rather be overriding the LinkRenderer#writeCommonLinkAttributes() method.

@Override
protected void writeCommonLinkAttributes(ResponseWriter writer, UIComponent component) throws IOException {
    super.writeCommonLinkAttributes(writer, component);

    // ...
}

It does by the way then not matter if you call super before or after your job.

于 2012-08-16T11:18:43.093 回答