可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have some problem's with a simple application in JSF 2.0.
I try to build a ToDo List with ajax support. I have some todo strings which I display using a datatable. Inside this datatable I have a commandLink to delete a task. The problem is now that the datatable don't get re-rendered.
<h:dataTable id="todoList" value="#{todoController.todos}" var="todo"> <h:column> <h:commandLink value="X" action="#{todoController.removeTodo(todo)}"> <f:ajax execute="@this" render="todoList" /> </h:commandLink> </h:column> <h:column> <h:outputText value="#{todo}"/> </h:column> </h:dataTable>
Thanks for your help.
Edit (TodoController):
@ManagedBean @SessionScoped public class TodoController { private String todoStr; private ArrayList<String> todos; public TodoController() { todoStr=""; todos = new ArrayList<String>(); } public void addTodo() { todos.add(todoStr); } public void removeTodo(String deleteTodo) { todos.remove(deleteTodo); } /* getter / setter */ }
回答1:
(Looks like I don't have enough reputation to comment on others' answers)
I think FRotthowe suggests wrapping the table with another element and referencing it using absolute reference (ie. naming all the parent containers from the root of the document) from the <f:ajax> tag.
Something like this:
<h:form id="form"> <h:panelGroup id ="wrapper"> <h:dataTable value="#{backingBean.data}" var="list"> <h:column> <h:commandButton value="-" action="#{backingBean.data}"> <f:ajax render=":form:wrapper"/> </h:commandButton> </h:column> </h:dataTable> </h:panelGroup> </h:form>
But, using absolute references is always a source of problems and increases exponentially the refactoring time as the view grows.
Isn't there a way to just render the table from a <f:ajax> tag (prevent jsf from adding those annoying ":number_of_row" in the ajax event)?
回答2:
I assume that the <h:dataTable> is enclosed by a form?
After struggling with this issue for a while, I googled an easy and clean solution: add @form to render attribute of <f:ajax> and voila!
Full example:
<h:form id="theForm"> <h:dataTable id="table" value="#{tasksMgr.allTasks}" var="task"> <h:column> #{task.name} </h:column> <h:column> <h:commandButton id="removeTaskButton" value="X" action="#{tasksMgr.removeTask(task)}"> <f:ajax render="@form" /> </h:commandButton> </h:column> </h:dataTable> </h:form>
The full article which helped me is here: http://blogs.steeplesoft.com/2009/10/jsf-2-hdatatable-and-ajax-updates/
回答3:
I ran into the same problem and figured that if you put an element (e.g. ) around the table and rerender that, it will work. I am however not quite sure why it is that way. Anyone?
回答4:
For some reason JSF is modifying the id in the <f:ajax> tag in the button. If I write this xhtml:
<h:form id="form"> <h:commandButton value="Button"> <f:ajax render="table"/> </h:commandButton> <h:dataTable id="table" value="#{tableData.data}"> <h:column> <h:commandButton value="Button"> <f:ajax render="tocoto"/> </h:commandButton> </h:column> </h:dataTable> </h:form>
I get this html:
<form id="j_idt7" name="j_idt7" method="post" action="/WebApplication1/faces/index.xhtml" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="j_idt7" value="j_idt7" /> <input id="j_idt7:j_idt8" type="submit" name="j_idt7:j_idt8" value="Button" onclick="mojarra.ab(this,event,'action',0,'j_idt7:table');return false" /> <table id="j_idt7:table"><tbody> <tr> <td><input id="j_idt7:table:0:j_idt10" type="submit" name="j_idt7:table:0:j_idt10" value="Button" onclick="mojarra.ab(this,event,'action',0,'j_idt7:table:0');return false" /></td> </tr> </tbody></table> <input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="-7634557012794378167:1020265910811114103" autocomplete="off" /> </form>
Notice that the id in the second button is 'j_idt7:table:0' while I'm expecting to get 'j_idt7:table' as I do in the first one.
That doesn't solve the problem but may help to find a workaround.
回答5:
use this code:
<h:form id="form"> <h:panelGroup id="panel"> <h:dataTable id="todoList" value="#{todoController.todos}" var="todo"> <h:column> <h:commandLink value="X" action="#{todoController.removeTodo(todo)}"> <f:ajax render=":form:panel" /> </h:commandLink> </h:column> <h:column> <h:outputText value="#{todo}"/> </h:column> </h:dataTable> </h:panelGroup> </h:form>
回答6:
You need to add prependId="false" to your h:form
回答7:
I ran into the same problem.
One thing that "works" is adding richfaces to your project, and replacing the
h:datatable
by a
rich:datatable.
Which will generate the correct id's.