プログラムでAjaxクライアントの動作をカスタムコンポーネントに追加しようとしていますが、.xhtmlに動作を追加すると、null.pointer.exception(ブラウザーのアラートとしてログにエラーが表示されない)が発生します。正常に動作しますが、プログラムで追加する必要があります(実際には、コンポーネントは最上位のコンポーネントから動的にレンダリングされます(ダッシュボード->N列->列ごとにN個のウィジェットがすべてデータベースから)
簡単なDataListコンポーネントを作成してこれをテストしました
関連するコードは次のとおりです...
DataListRenderer
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException{
DataList datalist = (DataList)component;
ResponseWriter writer = context.getResponseWriter();
.. bunch of rendering options....
// If sortable then we add the sortable script.
// This basically ends up generating a call to jsf.ajax.request(source,event,params);
if (sortable != null && sortable.equalsIgnoreCase("true")) {
ScriptUtils.startScript(writer, clientId);
writer.write("$(function() {");
writer.write("$(EasyFaces.escapeId('" + clientId + "')).sortable({");
writer.write("update: function (event, ui) { ");
writer.write(new AjaxRequest().addEvent(StringUtils.addSingleQuotes("update"))
.addExecute(StringUtils.addSingleQuotes(datalist.getClientId()))
.addSource(StringUtils.addSingleQuotes(datalist.getClientId()))
.addOther("sourceId", "ui.item.attr('id')")
.addOther("dataValue", "ui.item.attr('data-value')")
.addOther("dropedPosition", "ui.item.index()")
.getAjaxCall());
writer.write(" } ");
encodeClientBehaviors(context, datalist);
writer.write("});");
writer.write("});");
ScriptUtils.endScript(writer);
}
// This is where I add the behavior
AjaxBehavior ajaxBehavior = (AjaxBehavior) FacesContext.getCurrentInstance().getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);
ajaxBehavior.setRender(Arrays.asList("@form"));
ajaxBehavior.setExecute(Arrays.asList("@form"));
MethodExpression listener = FacesContext.getCurrentInstance().getApplication()
.getExpressionFactory().createMethodExpression(context.getELContext(),"#{dataListManager.updateModel}", null,
new Class[] { AjaxBehaviorEvent.class });
ajaxBehavior.addAjaxBehaviorListener(new AjaxBehaviorListenerImpl(listener));
datalist.addClientBehavior(datalist.getDefaultEventName(), ajaxBehavior);
}
... rest of the code
これで、.xhtmlは次のようになります。
...
h:form>
<et:dataList id="dl" value="#{easyfacesBean.data}" itemValue="foo" var="xx" sortable="true">
<h:outputText id="txt" value="#{xx}" />
</et:dataList>
</h:form>
...
これにより、コードはOKになります。リストは実際に並べ替えることができますが、並べ替えるとnull.pointer.exceptionエラーが発生します。
これはサーバーから返されるものです:
<?xml version='1.0' encoding='UTF-8'?>
<partial-response><error><error-name>class java.lang.NullPointerException</error-name><error-message><![CDATA[]]></error-message></error></partial-response>
さて、この行にコメントすると
datalist.addClientBehavior(datalist.getDefaultEventName(), ajaxBehavior);
そして、次のようにタグを追加するだけです。
<h:form>
<et:dataList id="dl" value="#{easyfacesBean.data}" itemValue="foo" var="xx" sortable="true">
<f:ajax />
<h:outputText id="txt" value="#{xx}" />
</et:dataList>
</h:form>
すべてがうまくいきます..何かアイデアはありますか?null.point.exceptionがどこにあるかを実際に知る方法に落ち着きます。
ところで、実際に動作を追加する行にコメントを付けず、<f:ajax>タグを追加すると、エラーはjava.lang.IndexOutOfBoundsExceptionに変わります。
<?xml version='1.0' encoding='UTF-8'?>
<partial-response><error><error-name>class java.lang.IndexOutOfBoundsException</error-name><error-message><![CDATA[Index: 1, Size: 1]]></error-message>
よろしく!