1

我正在尝试以编程方式将 Ajax 客户端行为添加到自定义组件,但是当我这样做时,如果我在 .xhtml它工作正常,但我真的需要以编程方式添加它们(实际上组件将从顶部组件动态呈现(仪表板 - > N列 - >每列N个小部件都来自数据库)

我已经测试了这个创建一个简单的 DataList 组件

这是相关的代码...

数据列表渲染器

@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>
...

这会呈现代码 好的,列表实际上可以排序,但是当重新排序时,它会给我 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