我正在开始一个新的应用程序,我正在尝试构建主菜单的结构,以使用AJAX更新内容部分。我正在使用JSF 2.2和Primefaces 6.1。我的项目结构如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>...</h:head>
<h:body>
<div id="header">
<ui:insert name="header">...</ui:insert>
</div>
<div id="menu">
<ui:insert name="menu"></ui:insert>
</div>
<h:panelGroup layout="block" id="content" styleClass="container">
<ui:insert name="content">Default content</ui:insert>
</h:panelGroup>
<div id="footer">...</div>
</h:body>
</html>
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
template="./resources/templates/template.xhtml">
<ui:define name="menu">
<h:form id="form-menu">
<p:menubar id="menubar">
<p:menuitem id="menuitem-home" value="Home" actionListener="#{navigation.navigate}" update="@(content)" process="@(form-menu)"/>
<p:submenu id="submenu" label="Submenu">
<p:menuitem id="menuitem-option1" value="Option 1" actionListener="#{navigation.navigate}" update="@(content)" process="@(form-menu)"/>
<p:menuitem id="menuitem-option2" value="Option 2" actionListener="#{navigation.navigate}" update="@(content)" process="@(form-menu)"/>
<p:menuitem id="menuitem-option3" value="Option 3" actionListener="#{navigation.navigate}" update="@(content)" process="@(form-menu)"/>
</p:submenu>
</p:menubar>
</h:form>
</ui:define>
<ui:define name="content">
<ui:include src="#{navigation.targetPartial}" />
</ui:define>
</ui:composition>
这是为了填充<ui:include>
。它们具有相同的结构,所以我在同一个地方恢复它:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html">
<h:body>
<h1 class="h1">My application</h1>
<h3 class="h3">Welcome/Option1/Option2/Option3</h3>
</h:body>
</html>
home.xhtml
位于src/main/webapp/
,template.xhtml
位于src/main/webapp/resources/templates/
,部分位于src/main/webapp/resources/partials/
。我的bean是一个简单的导航处理程序,如下所示:
@Named("navigation")
@SessionScoped
public class Navigation implements Serializable {
private static final long serialVersionUID = 6657512604418974978L;
private static final String PARTIALS_ROOT_FOLDER = "/resources/partials/";
private static final String XHTML_EXTENSION = ".xhtml";
private String targetPartial = "welcome";
private Map<String, String> idToPartialMap;
@PostConstruct
public void init() {
idToPartialMap = new HashMap<>();
idToPartialMap.put("menuitem-home", "welcome");
idToPartialMap.put("menuitem-option1", "option1");
idToPartialMap.put("menuitem-option2", "option2");
idToPartialMap.put("menuitem-option3", "option3");
}
public String getTargetPartial() {
return PARTIALS_ROOT_FOLDER + targetPartial + XHTML_EXTENSION;
}
public void setTargetPartial(final String targetPartial) {
this.targetPartial = targetPartial;
}
public void navigate(final ActionEvent event) {
setTargetPartial(idToPartialMap.get(event.getComponent().getId()));
}
}
因此,我们的想法是:在欢迎时初始化导航,以便首先在<ui:include src="#{navigation.targetPartial}"/>
中呈现主页(这样可以正常工作)。 idToPartialMap
<p:menuitem>
地图(请原谅冗余)从<ui:define name="content">
id到相应的部分名称。
之后,当您单击菜单中的任何选项时,应使用AJAX请求更新Navigation#targetPartial
部分。目标是通过保留页面的固定部分并仅更新内容部分来优化网络流量。
阅读文档我看到Primefaces 6.1现在支持jQuery选择器来使用id或类来定位任何组件。
使用项目,因为页面呈现正确但当我单击任何选项时页面闪烁但不会更改。如果我重新加载页面,则会呈现optionX页面,证明navigate()
已通过home.xhtml
方法进行了更改。检查网络流量,您可以看到Document
首先加载了类型为XML HTTP Request
的HTTP GET。在菜单中的后续单击中,将加载相同的文件,但类型为“XHR”(update
)。 AFAIK,这是<p:menuitem>
中update="@(content)"
属性触发的AJAX请求,我是否正确?
我在这里缺少什么?我怎样才能让它发挥作用?将update="@all"
更改为func tableView(_ tableView: UITableView,
editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
var patternImg:UIImage?
let upBtn = UITableViewRowAction(style: .normal, title: "") {
action, index in
print("upBtn button tapped")
}
patternImg = self.swipeCellImage(named: "UpIcn", side: 46.0)
upBtn.backgroundColor = UIColor(patternImage: patternImg!)
let downBtn = UITableViewRowAction(style: .normal, title: "") {
action, index in
print("downBtn button tapped")
}
patternImg = swipeCellImage(named: "DownIcn", side: 46.0)
downBtn.backgroundColor = UIColor(patternImage: patternImg!)
let rmvBtn = UITableViewRowAction(style: .destructive, title: "") {
action, index in
print("rmvBtn button tapped")
}
patternImg = swipeCellImage(named: "TrashIcn", side: 46.0)
rmvBtn.backgroundColor = UIColor(patternImage: patternImg!)
return [downBtn,upBtn,rmvBtn]
}
func swipeCellImage(named name: String, side: CGFloat) -> UIImage? {
let theImage = UIImage(named: name)
UIGraphicsBeginImageContextWithOptions(CGSize(width: side*2, height: side), false, UIScreen.main.scale)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(UIColor.clear.cgColor)
theImage?.draw(in: CGRect(x: 0, y: 0, width: side, height: side))
let resultImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resultImage
}
可以解决问题,但整个页面已加载,这不是主意。
欢迎任何想法,建议和指南。提前感谢您的回答。