1

プログラムで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>

よろしく!

4

0 に答える 0