在使用JSF / PrimeFaces执行CRUD操作时,通常需要一种重置托管bean字段/属性的常用方法,基本上在成功完成一个此类操作后调用,以便将支持bean中的字段重置为其初始(默认)值。
虚构代码:
@Named
@ViewScoped
public class Bean extends LazyDataModel<Entity> implements Serializable {
@Inject
private Service service; // EJB.
// Holds a list of selected rows in a <p:dataTable>.
private List<Entity> selectedValues; // Getter & setter.
private String someField; // Getter & setter.
// Other fields depending upon the business requirement.
public Bean() {}
@PostConstruct
private void init() {
// Do something.
}
@Override
public List<Entity> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
setRowCount(service.rowCount());
// Other complex logic as and when required.
return service.getList(first, pageSize, map, filters); // Returns a List<Entity>.
}
// Resets fields to their default value.
public void reset() {
someField = null;
selectedValues = null;
// Reset other fields to their default value.
}
// Add (insert submitted values to the database).
// This method is basically bound to an action(Listener) of <p:commandButton>.
public void submit() {
if (service.insert(someField)) {
// Add a FacesMessge to indicate a success.
reset(); // Calling reset.
} else {
// Add a FacesMessge to indicate a failure.
}
}
// Update the database using submitted values.
public void onRowEdit(RowEditEvent event) {
if (event.getObject() instanceof Entity) {
Entity entity = (Entity) event.getObject();
Entity newEntity = service.update(entity);
if (newEntity != null) {
// Update the model.
// Other things like adding a FacesMessage to indicate a success.
} else {
// Add a FacesMessage to warn against the null entity returned by the service layer.
}
} else {
// Add a FacesMessage to indicate a failure.
}
reset(); // Finally reset the fields to their initial/default value.
}
// Similarly, performing the delete operation also requires to call the reset() method.
}
执行“insert”的submit()
方法基本上与JSF / PrimeFaces命令组件相关联,如<p/h:commandButton>
或<p/h:commandLink>
。如。。
<p:inputText value="#{bean.someField}"/>
<p:commandButton value="Submit"
actionListener="#{bean.submit}"
oncomplete="if(args && !args.validationFailed) {updateTable();}"/>
<!-- Updating a p:dataTable in question after the above p:commandButton completes. -->
<p:remoteCommand name="updateTable" update="dataTable" process="@this"/>
以下与<p:dataTable>
相关联的AJAX事件也需要调用reset()
方法。
<p:ajax event="rowEdit"
onstart="..."
oncomplete="..."
update="..."
listener="#{bean.onRowEdit}"/>
<p:ajax event="rowEditCancel"
onstart="..."
oncomplete="..."
update="..."
listener="#{bean.reset}"/>
<p:ajax event="page"
onstart="..."
oncomplete="..."
update="..."
listener="#{bean.reset}"/>
<p:ajax event="sort"
onstart="..."
oncomplete="..."
update="..."
listener="#{bean.reset}"/>
<p:ajax event="filter"
onstart="..."
oncomplete="..."
update="..."
listener="#{bean.reset}"/>
可以看出,reset()
方法需要仔细记忆,因为它是从几个地方调用的。这种方式有点难以维护。
在每个POST请求执行其中一个CRUD操作成功完成其作业后,是否存在自动调用此类常用方法的方法?
答案 0 :(得分:8)
JSF没有任何标签。
理想情况下,您希望将<f:event type="postInvokeAction" listener="#{bean.reset}">
直接附加到<p:dataTable>
。但是JSF 2.2中不存在该事件。 OmniFaces有一个,但仅在UIViewRoot
,UIForm
,UIInput
和UICommand
支持。
<f:phaseListener>
接近,但它会直接附加到UIViewRoot
,即使您将其放在<p:dataTable>
内。并且,它需要整个PhaseListener
实现。
<f:view afterPhase>
似乎是您最好的选择。您只需要对相位ID和源组件进行一些额外的检查。
<p:dataTable binding="#{table}" ...>
<f:view afterPhase="#{bean.reset(table)}" />
<p:ajax ... />
<p:ajax ... />
<p:ajax ... />
<p:ajax ... />
...
</p:dataTable>
public void reset(UIData table) {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() != PhaseId.INVOKE_APPLICATION) {
return;
}
String source = context.getExternalContext().getRequestParameterMap().get("javax.faces.source");
if (!table.getClientId(context).equals(source)) {
return;
}
// Reset logic here.
// ...
}
(如果需要,可以用硬编码的表客户端ID替换binding
)
我明白这很尴尬。因此,对于即将到来的OmniFaces 2.2,我altered现有的InvokeActionEventListener
也支持此用例。它现在支持附加在任何UIComponent
上。
<p:dataTable ...>
<f:event type="postInvokeAction" listener="#{bean.reset}" />
<p:ajax ... />
<p:ajax ... />
<p:ajax ... />
<p:ajax ... />
...
</p:dataTable>
public void reset() {
// ...
}