如何正确使用Primefaces选择器使用AJAX更新内容

时间:2018-02-01 02:10:21

标签: jquery ajax primefaces jsf-2.2

我正在开始一个新的应用程序,我正在尝试构建主菜单的结构,以使用AJAX更新内容部分。我正在使用JSF 2.2和Primefaces 6.1。我的项目结构如下:

的template.xhtml

<!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>

home.xhtml

<?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>

welcome / option1 / option2 / option3.xhtml(partials)

这是为了填充<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是一个简单的导航处理程序,如下所示:

Navigation.java

@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 } 可以解决问题,但整个页面已加载,这不是主意。

欢迎任何想法,建议和指南。提前感谢您的回答。

0 个答案:

没有答案