我正在尝试以编程方式将 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>
问候!