提前感谢您的关注 .

我已经创建了一个JSF 2.0自定义组件来呈现Google GeoCharts . 因此,渲染器只是在最后写了一些javascript和div .

该组件可以正常工作 . 但我的要求是GeoChart应该使用ajax请求更改其值 . 为此,我使用primefaces命令按钮将其属性“更新”geoChart的id .

问题是单击comand按钮时GeoChart没有更新 .

我正在使用maven原型(myfaces-archetype-jsfcomponents20),允许自动生成一些配置文件 . 所以,我只需要写入类和注释 . 这些类是UIComponent和Renderer .

我在GlassFish 3.1和Mojarra 2.1.6中运行此代码

这些类的代码:

UIComponent:

@JSFComponent(
    name = "processum:geochart",
    clazz = "org.processum.component.gchart.GoogleChart",
    tagClass = "org.processum.component.gchart.GoogleChartTag")

abstract class AbstractGoogleChart extends UIComponentBase {

        public static final String COMPONENT_TYPE = "org.processum.GoogleChart";
        public static final String DEFAULT_RENDERER_TYPE = "org.processum.GoogleChartRenderer";
        public static final String COMPONENT_FAMILY = "javax.faces.Output";

    /**
    *
    * GoogleChartModel
    */
    @JSFProperty
    public abstract GoogleGeoChartModel getModel();        
}

渲染:

@JSFRenderer(
    renderKitId = "HTML_BASIC",
    family = "javax.faces.Output",
    type = "org.processum.GoogleChartRenderer")
public class GoogleChartRenderer extends Renderer {

@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
    GoogleChart chart = (GoogleChart) component;
    String divId = (String) component.getClientId() + "chartDiv";
    GoogleGeoChartModel model = chart.getModel();
    ResponseWriter writer = context.getResponseWriter();
    writer.write("<script type='text/javascript'>"
            + "google.load('visualization', '1', {'packages': ['geochart']});"
            + "google.setOnLoadCallback(initGeoMap);"
            + "function initGeoMap() {"
            + "var data = google.visualization.arrayToDataTable(["
            + "[");
    StringBuilder data = new StringBuilder();
    for (String header : model.getHeaders()) {
        data.append("\'").append(header).append("\'").append(",");
    }
    data.deleteCharAt(data.length() - 1).append("],");

    for (String[] value : model.getValues()) {
        data.append("[");
        for (int i = 0; i < value.length; i++) {
            if (i == 0) {
                data.append("\'").append(value[i]).append("\'");
            } else {
                data.append(value[i]);
            }
            data.append(",");
        }
        data.deleteCharAt(data.length() - 1).append("],");
    }
    data.deleteCharAt(data.length() - 1);
    writer.write(data.toString());
    writer.write("]);");
    writer.write("var options = {"
            + "region: 'CO',"
            + "displayMode: 'markers'"
            + "};"
            + "var chart = new google.visualization.GeoChart(document.getElementById(\'" + divId + "\'));"
            + "chart.draw(data, options);"
            + "};"
            + "</script>"
            + "<div id=\"" + divId + "\"/>");
}
}

XHTML:

<h:form>            
        <div id="anotherContent" style="width: 900px; height: 500px;">
            <h:panelGroup id="chartCont" layout="block">
                <processum:geochart id="chart" model="#{chartBackBean.model}"/>                   
            </h:panelGroup>
        </div>  
        <p:commandButton id="change" value="Cambio" actionListener="#{chartBackBean.change}" update="chart"/>            
    </h:form>

Some debugging:

ajax请求被充分触发 . 托管bean使用新值更新GoogleGeoChartModel . 接下来,控制流进入Renderer,它对图表的新值进行“编码”(这意味着再次调用encondeEnd) . 但是,这个新的“enconding”并没有在浏览器中绘制 .

html有两个JSF组件 . 我的自定义组件和h:panelGroup . 如果在primefaces按钮的“update”属性中我输入了图表div的id,然后我触发了ajax请求,则图表不会改变 . 但相反,我把h:panelGroup的id,图表的div消失了 .