我的项目是一个类似于JasperReport的动态报表应用程序,使用的是JSF 2.2.7(Mojara)和primefaces 5.0。当用户登录时,他/她只看到分配给他/她的报告,该报告是从数据库动态加载的。除了当他们选择报告时,其他所有内容都正常工作,页面不会加载整个报告,直到第二次点击。
我的问题是报告在第二次点击之前无法正确加载。这是我的代码。
@Named(value = "userController")
@SessionScoped
public class ReportUserController implements Serializable {
private HtmlPanelGroup panelGroup; // with getter and setter
@PostConstruct
public void init() {
values = new ArrayList<>();
// Retrieve user's details and reports here
MenuModel model = new DefaultMenuModel();
Application application = FacesContext.getCurrentInstance().getApplication();
panelGroup = (HtmlPanelGroup) application.createComponent(HtmlPanelGroup.COMPONENT_TYPE);
PanelGrid panelGrid = (PanelGrid) application.createComponent(PanelGrid.COMPONENT_TYPE);
panelGrid.setColumns(2);
// Retrieve reports for d group the logged-in user belong
List<Report> repts = setupController.getExistingReports();
DefaultSubMenu reports = new DefaultSubMenu("Reports");
for (Report rep : repts) {
DefaultMenuItem menuItem = new DefaultMenuItem(rep.getReportName());
menuItem.setId(rep.getReportName().replaceAll("\\s+", ""));
menuItem.setAjax(true);
menuItem.setUpdate(":reportForm");
menuItem.setProcess("@form");
menuItem.setCommand("#{userController.loadReport(" + rep.getId() + ")}");
reports.addElement(menuItem);
reports.addElement(new DefaultSeparator());
}
model.addElement(reports);
Menubar menubar = (Menubar) application.createComponent(Menubar.COMPONENT_TYPE);
menubar.setModel(model);
panelGroup.getChildren().add(menubar);
}
public void loadReport(Long id) {
selectedReport = reportFacade.find(id);
if (parameters != null) {
parameters.clear();
}
if (values != null) {
values.clear();
}
queryColumns = selectedReport.getColumns();
queryParams = selectedReport.getReportParameters();
query = selectedReport.getReportQuery();
// This method is called to build the components of the page to be rendered dynamically.
// And it's every time a new report is selected
buildPage();
}
}
这是同一个类中的buildPage()
方法。 (请告诉我一个愚蠢的长码)
public void buildPage() {
Application application = FacesContext.getCurrentInstance().getApplication();
reportPanelGroup = (HtmlPanelGroup) application.createComponent(HtmlPanelGroup.COMPONENT_TYPE);
PanelGrid panelGrid = (PanelGrid) application.createComponent(PanelGrid.COMPONENT_TYPE);
panelGrid.setColumns(2);
for (ReportParameter param : queryParams) {
String parameterLabel = param.getLabel();
String componentType = param.getComponentType();
String calendarPattern = param.getCalendarPattern();
boolean required = param.isRequired();
boolean userProperty = param.isUserProperty();
String queryPosition = param.getQueryPosition();
String sqlDatePattern = param.getSqlDatePattern();
String dataType = param.getDataType();
String userPropertyName = param.getUserPropertyName();
List<DropDown> dropDowns = param.getDropDowns();
if ((userProperty)) {
// Retrieve some info from the logged-in user
} else {
OutputLabel label = (OutputLabel) application.createComponent(OutputLabel.COMPONENT_TYPE);
label.setId(parameterLabel.replaceAll("\\s+", "") + "label");
label.setValue(parameterLabel + ":");
if (componentType.equalsIgnoreCase("Calendar")) {
Calendar cal = (Calendar) application.createComponent(Calendar.COMPONENT_TYPE);
cal.setId(parameterLabel.replaceAll("\\s+", ""));
cal.setShowButtonPanel(true);
cal.setPattern(calendarPattern);
cal.setRequired(required);
cal.setValueExpression("value",
getExpressionFactory()
.createValueExpression(getELContext(), "#{userController.parameters['"
+ queryPosition.trim() + "']}", Date.class));
label.setFor(parameterLabel.replaceAll("\\s+", ""));
panelGrid.getChildren().add(label);
panelGrid.getChildren().add(cal);
} else if (componentType.equalsIgnoreCase("TextField")) {
InputText input = (InputText) application.createComponent(InputText.COMPONENT_TYPE);
input.setRequired(required);
input.setId(parameterLabel.replaceAll("\\s+", ""));
input.setValueExpression("value",
getExpressionFactory()
.createValueExpression(getELContext(), "#{userController.parameters['"
+ queryPosition.trim() + "']}", String.class));
label.setFor(parameterLabel.replaceAll("\\s+", ""));
panelGrid.getChildren().add(label);
panelGrid.getChildren().add(input);
} else if (componentType.equalsIgnoreCase("DropDown")) {
SelectOneMenu selectOneMenu = (SelectOneMenu) application.createComponent(SelectOneMenu.COMPONENT_TYPE);
UISelectItems selectItems = (UISelectItems) application.createComponent(UISelectItems.COMPONENT_TYPE);
selectOneMenu.setRequired(required);
selectOneMenu.setId(parameterLabel.replaceAll("\\s+", ""));
selectItems.setId(parameterLabel.replaceAll("\\s+", "") + "selectItems");
List<SelectItem> items = new ArrayList<>();
items.add(new SelectItem("", "Select..."));
if (dropDowns != null && !dropDowns.isEmpty()) {
for (DropDown d : dropDowns) {
items.add(new SelectItem(d.getValue(), d.getLabel()));
}
}
selectItems.setValue(items);
selectOneMenu.getChildren().add(selectItems);
selectOneMenu.setValueExpression("value",
getExpressionFactory()
.createValueExpression(getELContext(), "#{userController.parameters['"
+ queryPosition.trim() + "']}", String.class));
label.setFor(parameterLabel.replaceAll("\\s+", ""));
panelGrid.getChildren().add(label);
panelGrid.getChildren().add(selectOneMenu);
}
}
}
reportPanelGroup.getChildren().add(panelGrid);
HtmlCommandButton searchBtn = (HtmlCommandButton) application.createComponent(HtmlCommandButton.COMPONENT_TYPE);
searchBtn.setId("searchBtnID");
searchBtn.setValue("Search");
//searchBtn.setIcon("icon ui-icon-search");
//searchBtn.setAjax(false);
ExpressionFactory ef = getApplication().getExpressionFactory();
MethodExpression performSearch = ef.createMethodExpression(getELContext(),
"#{userController.performSearch}", null, new Class[]{ActionEvent.class});
MethodExpressionActionListener meal = new MethodExpressionActionListener(performSearch);
searchBtn.addActionListener(meal);
searchBtn.setType("submit");
//searchForm.getChildren().add(searchBtn);
reportPanelGroup.getChildren().add(searchBtn);
Spacer spacer = (Spacer) application.createComponent(Spacer.COMPONENT_TYPE);
spacer.setHeight("30");
reportPanelGroup.getChildren().add(spacer);
HtmlForm downloadForm = (HtmlForm) application.createComponent(HtmlForm.COMPONENT_TYPE);
downloadForm.setId("downloadForm");
CommandLink downloadBtn = (CommandLink) application.createComponent(CommandLink.COMPONENT_TYPE);
downloadBtn.setId("downloadBtnID");
downloadBtn.setValue("Test Download");
//downloadBtn.setIcon("icon ui-icon-search");
downloadBtn.setAjax(false);
String reportName = this.selectedReport.getReportName().trim().replaceAll("\\s+", "").trim();
MethodExpression downloadAnyReport = ef.createMethodExpression(getELContext(),
"#{userController.downloadAnyReport(userController.values, "
+ "userController.headings, '" + reportName + "')}", null, // Replace report name
new Class[]{List.class, Collection.class, String.class});
downloadBtn.setType("submit");
downloadBtn.setActionExpression(downloadAnyReport);
downloadForm.getChildren().add(downloadBtn);
reportPanelGroup.getChildren().add(downloadForm);
DataTable dynamicTable = (DataTable) application.createComponent(DataTable.COMPONENT_TYPE);
dynamicTable.setValueExpression("value", getExpressionFactory()
.createValueExpression(getELContext(), "#{userController.values}", List.class));
dynamicTable.setVar("val");
dynamicTable.setRows(20);
List cols = new ArrayList<>();
for (int i = 0; i < queryColumns.size(); i++) {
Column col = (Column) application.createComponent(Column.COMPONENT_TYPE);
col.setHeaderText(queryColumns.get(i).getPrefferedName());
if (queryColumns.get(i).isLink()) {
HtmlForm linkForm = (HtmlForm) application.createComponent(HtmlForm.COMPONENT_TYPE);
linkForm.setId("linkForm");
CommandLink link = (CommandLink) application.createComponent(CommandLink.COMPONENT_TYPE);
if (queryColumns.get(i).isDataMasked()) {
link.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(),
"#{userController.maskStringValue(val[" + i + "]," + queryColumns.get(i).getLeftDigit() + "," + queryColumns.get(i).getRightDigit() + ")}", String.class));
} else {
link.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(),
"#{val[" + i + "]}", String.class));
}
link.setStyle("text-decoration: underline; color: blue;");
MethodExpression action = ef.createMethodExpression(getELContext(),
"customizeColumns?faces-redirect=true", null, new Class[]{String.class});
link.setAjax(false);
link.setActionExpression(action);
linkForm.getChildren().add(link);
col.getChildren().add(linkForm);
} else {
HtmlOutputText out = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
if (queryColumns.get(i).getFormatAs() != null && queryColumns.get(i).getFormatAs().equals("Amount")) {
out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(),
"#{userController.formatAsAmount(val[" + i + "])}", String.class));
} else if (queryColumns.get(i).getFormatAs() != null && queryColumns.get(i).getFormatAs().equals("Number")) {
out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(),
"#{userController.formatAsNumber(val[" + i + "])}", String.class));
} else if (queryColumns.get(i).isDataMasked()) {
out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(),
"#{userController.maskStringValue(val[" + i + "]," + queryColumns.get(i).getLeftDigit() + "," + queryColumns.get(i).getRightDigit() + ")}", String.class));
} else {
out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(),
"#{val[" + i + "]}", String.class));
}
col.getChildren().add(out);
}
cols.add(col);
}
dynamicTable.setColumns(cols); //renderReport
dynamicTable.setValueExpression("rendered", getExpressionFactory()
.createValueExpression(getELContext(), "#{userController.values.size() > 0}", Boolean.class));
dynamicTable.setPaginator(true);
dynamicTable.setRowsPerPageTemplate("20,50,100");
reportPanelGroup.getChildren().add(dynamicTable);
}
这是我的页面:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
template="./usersTemplate.xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns="http://www.w3.org/1999/xhtml">
<ui:define name="usersTitle">
usersTitle
</ui:define>
<ui:define name="usersContent">
<div class="container-fluid">
<p:growl id="growl" life="3000" sticky="true"/>
<h:form id="menuForm">
<!-- This panelGroup is for the menubar of reports -->
<h:panelGroup binding="#{userController.panelGroup}"/>
</h:form>
<h:form id="reportForm">
<!-- This panelGroup is to show the components and datatable of the selected report -->
<h:panelGroup id="reportPanel" binding="#{userController.reportPanelGroup}"/>
</h:form>
</div>
</ui:define>
请让我再说一遍,其他一切正常,但是当我从菜单栏中的报告列表中选择一个报告时,页面在第二次点击之前不会更新,我尝试了整页提交以及阿贾克斯。我将非常感谢任何人可以提供的帮助。提前谢谢。
答案 0 :(得分:0)
对于将来可能会遇到类似问题的其他人,可以找到最终解决的解决方案。我在<p:commandButton/>
属性页面中添加了rendered
,其中包含所选报告的组件。然后,我添加了一个javascript方法,通过commandButton
中ajax
oncomplete
的{{1}}属性,在menuItems
之后点击menubar
。以下是代码snipets:
// JavaScript:
function clickAgain(){
document.getElementById('reportForm:refreshBtn').click();
}
// I added the button to my page:
...
<h:form id="reportForm">
<p:commandButton value=" Load #{userController.selectedReport.reportName}"
icon="ui-icon-refresh" rendered="#{!userController.renderReport}"
id="refreshBtn">
<p:ajax update="@form" listener="#{userController.changeRender()}"/>
</p:commandButton>
<h:panelGroup id="reportPanel" binding="#{userController.reportPanelGroup}"
rendered="#{userController.renderReport}"/>
</h:form>
魔术是用户永远不会看到按钮,每次选择菜单项后都会调用javascript函数,这会重新加载页面,使按钮消失,我的报告正确加载。谢谢