提前感谢您的关注。
我已经创建了一个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>
一些调试:
充分触发了ajax请求。托管bean使用新值更新GoogleGeoChartModel。 接下来,控制流进入Renderer,它对图表的新值进行“编码”(这意味着再次调用encondeEnd)。但是,这个新的“enconding”并没有在浏览器中绘制。
html有两个JSF组件。我的自定义组件和h:panelGroup。如果在primefaces按钮的“update”属性中我输入了图表div的id,然后我触发了ajax请求,则图表不会改变。但相反,我把h:panelGroup的id,图表的div消失了。