JSF 2.0简介:Ajax对页面的增加与删除操作例子(系列之六)

上一篇我们初步接触了一下JSF2.0的Ajax模型,为了适应Ajax的应用场景,JSF2.0中还引入了f:ajax标签,我们这一篇就用来初步使用一下,并采用managed  bean处理页面的元素,看看整个处理过程是否更简介可控。

还是从上一篇中的例子开始,首先看看我们改写后的echo.xhtml页面:

echo.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:h="http://java.sun.com/jsf/html"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:echo="http://java.sun.com/jsf/composite/echo"
            xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <title>测试简单的复合组件</title>
        <meta  http-equiv="keywords"  content="jsf2.0,组件,ajax"  />
        <meta  http-equiv="description"  content="测试简单的复合组件."  />
        <meta  http-equiv="content-type"  content="text/html;  charset=UTF-8"  />
    </h:head>
    <body>
        <div  id="header"  style="padding:100px  0  20px  100px;font-size:22px;font-weight:bold;border-bottom:solid  1px  red">
            这个应声器的作者是:#{echo.encoder.author}。
        </div>
        <div>
        <h:form  id="form"  style="padding:20px  0  20px  100px">
                <h:outputScript  library="javax.faces"  name="jsf.js"  target="head"/>
            <echo:echoInputText  echo="#{echo}"></echo:echoInputText>
            <div  style="padding-left:50px">
                            <h:commandButton  id="post"  style="padding:3px;width:100px;"  value="提交响应"  
                                    onclick="jsf.ajax.request(this,  event,  {execute:'form',  render:  'after'});  return  false;"
                                                actionListener="#{count.countIt}"/>
                            <h:commandButton  id="add"  style="padding:3px;width:100px;"  value="增加计数"  action="#{count.addCount}">
                                <f:ajax  execute="@this"  render="@none"  />
                            </h:commandButton>
                            <h:commandButton  id="delete"  style="padding:3px;width:100px;"  value="删除计数"  action="#{count.deleteCount}">
                                <f:ajax  execute="@this"  render="@none"  />
                            </h:commandButton>
            </div>
        </h:form>
        </div>
        <h:panelGroup  id="after">
        <div  style="padding:20px  0  0  100px">
        <div  style="padding:0  0  10px  0">应声器更新次数:#{count.count}</div>
        <h:outputText  id="echo"  value="响应:#{echo.outText}"  escape="false"></h:outputText>
        </div>
        </h:panelGroup>
    </body>
</html>

仔细观察一下,唯一的变化就是加入了两个button,并且分别加入了ajax的支持。
                            <h:commandButton  id="add"  style="padding:3px;width:100px;"  value="增加计数"  action="#{count.addCount}">
                                <f:ajax  execute="@this"  render="@none"  />
                            </h:commandButton>
此button解释一下就是执行managed  bean的addCount方法,并只做局部刷新。

再来看看managed  bean的变化,在count.java中加入了两个方法,如下:

count.java

        public  void  addCount()  {
                FacesContext  ctx  =  FacesContext.getCurrentInstance();
                ExternalContext  extContext  =  ctx.getExternalContext();
                if  (ctx.getPartialViewContext().isAjaxRequest())  {
                        try  {
                                extContext.setResponseContentType("text/xml");
                                extContext.addResponseHeader("Cache-Control",  "no-cache");
                                PartialResponseWriter  writer  =
                                            ctx.getPartialViewContext().getPartialResponseWriter();
                                writer.startDocument();
                                writer.startInsertBefore("echo");
                                writer.writeAttribute("id",  "before",  "id");
                                writer.writeAttribute("style",  "padding:0  0  10px  0",  "style");
                                writer.startElement("div",  null);
                                writer.writeText("应声器更新次数:"+this.count,  null,  null);
                                writer.endElement("div");
                                writer.endInsert();
                                writer.endDocument();
                                writer.flush();
                                ctx.responseComplete();
                        }  catch  (Exception  e)  {
                                throw  new  FacesException(e);
                        }
                }
        }
        
        public  void  deleteCount()  {
                FacesContext  ctx  =  FacesContext.getCurrentInstance();
                ExternalContext  extContext  =  ctx.getExternalContext();
                if  (ctx.getPartialViewContext().isAjaxRequest())  {
                        try  {
                                PartialResponseWriter  writer  =
                                            ctx.getPartialViewContext().getPartialResponseWriter();
                                extContext.setResponseContentType("text/xml");
                                extContext.addResponseHeader("Cache-Control",  "no-cache");
                                writer.startDocument();
                                writer.delete("before");
                                writer.endDocument();
                                writer.flush();
                                ctx.responseComplete();
                        }  catch  (Exception  e)  {
                                throw  new  FacesException(e);
                        }
                }
        }

此两个方法从字面上理解来,一个是来给页面加入元素,一个是删除页面上的一个元素。可以在浏览器中输入http://localhost:8088/TestJsf2.0/echo.xhtml看看运行效果。这儿很容易就改变了页面的元素,不需要你写任何Ajax代码。所有的代码都采用java编写,调试等工作都会变得容易。

再来解释一下bean中的Partial  Response,这是在JSF2.0中新引入的生命周期模型,字面意思就是局部请求返回,也就是局部更新,正好与Ajax提倡的理念配合的天衣无缝。

具体的f:ajax标签的解释可以参考https://javaserverfaces.dev.java.net/nonav/docs/2.0/pdldocs/facelets/,另外针对Partial  Response的解释限于篇幅和本文的性质就暂时告一段落,想了解更多我们可以再开篇幅讨论。

至此,关于JSF2.0中引入的最大的两个改变就介绍完了,我们也初步了解了JSF2.0开发的便捷与优雅之处。以后针对更多的特性以及更深入的话题,我们可以多多探讨,当然,在应用中肯定还会碰到JSF2.0的不足之处,我们也可以一起讨论。
欢迎大家一起探讨开发中的问题,以及各类思想。也可以将问题反应在JSF组中,以促进共同进步!

你可能感兴趣的:(Ajax,bean,XHTML,cache,JSF)