我使用的是PrimeFaces 5.1,当用户使用以下代码点击history.pushState
行时,我会调用p:dataTable
:
<p:dataTable value="#{associateBean.scenarios}"
selectionMode="single"
selection="#{associateBean.selectedScenarioViewBean}"
var="scenarioViewBean" rowKey="#{scenarioViewBean.id}">
<p:ajax event="rowSelect"
listener="#{associateBean.onScenarioRowSelect}"
oncomplete="history.pushState('','','test#{scenarioViewBean.id}')"
update="@form"/>
<p:column>
<h:outputText value="#{scenarioViewBean.name}"/>
</p:column>
</p:dataTable>
如您所见,我试图将scenarioViewBean.id
值传递给pushState
来电。
问题是#{scenarioViewBean.id}
没有返回任何内容,因此JavaScript会推送&#34; test&#34;而不是&#34; test123&#34;在网址中。
我该如何解决这个问题?
答案 0 :(得分:1)
无需复杂化,保留rowSelect ajax事件并将Id传递如下:
PF('dataTableWV').selection[0]
根据您的问题,最终结果应如下所示:
<p:ajax event="rowSelect"
listener="#{associateBean.onScenarioRowSelect}"
oncomplete="history.pushState('','','test'+PF('dataTableWV').selection[0]"
update="@form"/>
注意:dataTableWV
是dataTable widgetVar
答案 1 :(得分:0)
好的,它现在有效,但我不得不调整DataTable组件:
<script type="text/javascript">
jQuery(document).ready(function(jQuery) {
function updateHistory(selectedRowKey) {
history.pushState({
selectedRowKey: selectedRowKey
},
document.title,
selectedRowKey);
}
if (PF('widgetScenariosDataTable')) {
// initial callback
var f = PF('widgetScenariosDataTable').onRowClick;
PF('widgetScenariosDataTable').onRowClick = function(event, rowElement) {
// Call initial callback (we have to use apply because
// the method is using 'this')
f.apply(PF('widgetScenariosDataTable'), [event, rowElement]);
// selected row key
var selectedRowKey = PF('widgetScenariosDataTable').selection;
// Your callback
updateHistory(selectedRowKey);
};
jQuery(window).bind('popstate', function(event) {
// First we have to unselect all rows
PF('widgetScenariosDataTable').unselectAllRows();
if (event.originalEvent.state!=null) {
// We select the row by passing the tr object that
// has the correct rowKey value (this is safer than
// using the rowIndex if the user adds/deletes the
// datatable rows and then uses the browser's history)
PF('widgetScenariosDataTable').selectRow(
jQuery("tr[data-rk="+event.originalEvent.state.selectedScenarioId+"]"),
false
);
}
else {
// We use location.href if there is no state stored
var href = window.location.href;
PF('widgetScenariosDataTable').selectRow(
jQuery("tr[data-rk="+href.substr(href.lastIndexOf('/') + 1)+"]"),
false
);
}
});
}
});
</script>
此代码改编自http://www.takohi.com/javascript-callback-on-row-click-event-with-primefaces-datatable/
如果有人知道更简单的方法,请发布,我会将您的答案添加为最佳答案。
答案 2 :(得分:0)
我的解决方案没有使用onRowClick事件:
<h:outputScript library="js" target="head" name="pop.js"/>
<p:dataTable id="table" widgetVar="tableWdg" var="vv"
value="#{bean.list}"
rowKey="#{vv.id}" rowIndexVar="rowIndex"
selectionMode="single"
selection="#{bean.selected}">
<p:ajax event="rowSelect" process="@this" listener="#{bean.actionRowSelect}"/>
<p:column headerText="ID">
<h:outputText value="#{vv.id}" />
</p:column>
</p:dataTable>
'bean'中的监听器:
public void actionRowSelect(SelectEvent event) {
SelectedElement element = (SelectedElement) event.getObject();
HashMap<String, Object> jsonParams = new HashMap<String, Object>();
jsonParams.put("selectedRow", element.getId());
jsonParams.put("tableWdgName", table.getWidgetVar());
JSONObject json = new JSONObject(jsonParams);
String jsonString = json.toString();
String title = "generate yourself";
HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
String url = req.getRequestURL().toString();
if(req.getQueryString().length() > 0) {
url += "?" + req.getQueryString();
}
String jscriptString = "if (popstated != true) { window.history.pushState(" + jsonString + ", '" + title + "', '" + url + "'); popstated = false; } " ;
RequestContext.getCurrentInstance().execute(jscriptString);
}
JS脚本'pop.js':
var popstated = false;
window.addEventListener('popstate', function(event) {
console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
console.log("event state.selectedRow=" + event.state.selectedRow);
PF(tableWdgName).unselectAllRows();
if(event.state.selectedRow != null) {
popstated = true;
PF(tableWdgName).selectRow(
jQuery( "tr[data-rk=" + event.state.selectedRow + "]" ),
false
);
}
});
技巧是简单的布尔全局JS变量'popstated'并在服务器端生成JS。