嗯,在这里我们主要讨论一下在使用Struts 2.5时最常遇到的一个问题:页面局部刷新。Struts是一个MVC模型,因此常见的返回结果类型为一个页面,它可以是jsp、freemarker或者velocity这样的模板引擎。在这里只说我们所使用的freemarker。你可以把freemarker看作是一个servlet,对于每一个servlet,它可以接收来自客户端的输入然后执行相应的操作后,将结果输出到客户端。实际上,你可以这么理解:freemarker将我们要写的servlet大大简化。比如说当你要写一个servlet输出如下:

    out.println("<body>");out.println(weibo.getContent());out.println("</body>");

在freemarker中你只需要写:

<body>${weibo.getContent()}
</body>

或者:

<body>${weibo.content}</body>

用freemarker的话说,这叫

Template + data-model = output

然而很多时候,我们希望页面能够局部刷新,而不需要执行从点击链接,调用对应的action,action将结果(model)传到对应的freemarker模板,然后刷新整个页面让结果在我们的浏览器中呈现,在这里我使用了两种不同的方式

用JSON作为客户端与服务器间消息传递的标准

在我们的系统中,几乎每一页都会用到一个数据来解释,使用这个系统的,发微博的,关注的,查看微博的这个用户主体“我”是谁。如果在每一个页面所对应的action当中都调用一次获取当前登陆用户数据的操作,会大幅增加开支,也增加了开发时间。实际上每一个页面调用当前用户信息的操作是大致相同的,于是我写了一个返回类型为JSON的接口api/user。当用get方法请求该接口的时候,会返回一个值如下

{"avatar":"http:\/\/o8m79d0cw.bkt.clouddn.com\/my-java.jpg","createTime":"2016-07-06T19:25:35","email":null,"emailConfirm":null,"fansAmount":0,"followAmount":0,"gender":null,"id":1,"isPublic":null,"lastLogin":null,"nickname":"陈家俊","phoneNumber":null,"phoneNumberConfirm":null,"signature":null,"username":"cjj","weiboAmount":0
}

这个接口对应的struts action在这里
在前端,我使用jQuery.ajax方法来调用这个接口以获取数据,实际上是用jQuery.get方法也行,.get是.ajax的一个简单版本。相关的文档可以看jQuery中文文档或者jQuery官网。代码如下

  $.ajax({type: 'GET',url: "<@s.url namespace="/api" action="user" />",}).done(function (data) {// handle received data;});

在获取到数据后,我们可以用一种非常类似于MVC模型的模型叫MVVM模型的实现从返回数据模型到呈现的过程。MVVM既Model-view-viewModel,基于这个理念的前端框架非常多,包括非常有名的AngularJS,最近很火的VueJS。我用的是KnouckoutJS。
废话少说,先看代码

function ViewModel(){var self = this;self.avatar = ko.observable();self.nickname = ko.observable();self.upload = ko.observable();$.ajax({type: 'GET',url: "<@s.url namespace="/api" action="user" />",}).done(function (data) {self.avatar(data.avatar);self.nickname(data.nickname);});self.signOut = function(){$("#sign-out").submit();};
}
$(function() {// Handler for .ready() called.var app = new ViewModel();ko.applyBindings(app);
});

ViewModel在这里的角色是binder,顾名思义,它的作用是将我们通过ajax方法获取的model绑定(bind)到不同的field中,以便于我们在html当中获取。KnockoutJS允许我们绑定很多东西,包括方法、值、列表等等。在完成绑定之后,在html中获取模型中对应的内容和freemarker其实相差无几。

<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><img data-bind="attr: { src: avatar, height: '20', width: '20' }, text: nickname "><span class="caret"></span></a><ul class="dropdown-menu"><li><a href="#">Action</a></li><li><a href="#">Another action</a></li><li><a href="#">Something else here</a></li><li role="separator" class="divider"></li><li><a href="#" data-bind="click: signOut">Sign out</a></li></ul>
</li>

很显然,在img元素和最后一个a元素我分别使用了属性绑定和函数绑定,关于KnockoutJS的更多内容请见KnockoutJS
如果你不喜欢MVVM,也可以直接使用jQuery或者javascript本身的一些方法(并不推荐后者)。

Javascript获取相应元素

很显然,Struts并不是一个为Web Service而生的框架,从在Struts使用JSON还需要另外使用插件就可见一斑。此外前一种方法也有不少缺陷,比方说绑定很罗嗦,几乎可以说是相当于把在编写Struts Action的工作直接搬到了前端。再比如说我们不太熟悉Javascript语言,而且我们还需要学习另一个框架等等,会大幅增加我们现在所需要的开发时间。再比如说我们已经在freemarker中自定义了一些很方便简洁的宏(macro),在后端调用它们并完成数据的绑定要比前端操作HTML DOM要更“爽”等等。因此我想到的另一种方法是用Javascript获取我们想要局部刷新的那个“局部”的html元素。
一个典型的例子是,我要在我的个人主页里获取我的微博的列表。我们可以写一个这样的action

@Results({ @Result(name="success" location="weibo.ftl") })
public WeiboAction extends ActionSupport{private List<Weibo> weibos;//getter and setter//execute method
}

对应的weibo.ftl

<#list weibos as weibo><li>$(weibo.getContent()}</li>
</#list>

那么根据ftl所生成的servlet大概会是这样

for(int i=0;i<weibos.size();i++){out.println("<li>");out.println(weibos.get(i).getContent());out.println("</li>");
}

这个ftl并没有html元素,但当你直接在浏览器中输入action所对应的url的时候,最终呈现的内容的源代码如下

<html>
<body><li>微博1</li><li>微博2</li>
</body>
</html>

这里的html元素和body元素是浏览器帮我们补全的。
然而这个并不是“局部”刷新。假设我们在我们需要局部刷新的页面有这么一个按钮,我们希望点击它后,页面能够获取微博,并在一个列表,即

  • 元素当中呈现,我们可以这样实现
<button id="fresh">刷</button>
<ul id="weibo-list">
</ul>
<script>$("#fresh").click(function(){$.ajax({type: 'GET',url: "<@s.url action="weibo" />",}).done(function (data) {$("#weibo-list").append(data);//data中的内容为//<li>微博1</li>//<li>微博2</li>});});
</script>

这个方法的核心思想就在于获取要刷新的局部的html元素,并在这个部分将元素“放”上去。

转自:https://github.com/Up618/TheNewUp/wiki/%E4%B8%A4%E7%A7%8D%E6%96%B9%E5%BC%8F%E5%AE%9E%E7%8E%B0%E5%B1%80%E9%83%A8%E5%88%B7%E6%96%B0

两种方式实现局部刷新相关推荐

  1. 【转】系统缓存全解析二:动态缓存(2)-页面局部缓存的两种方式

    有时缓存整个页面是不现实的,因为页的某些部分可能在每次请求时都需要变化.在这些情况下,只能缓存页的一部分.顾名思义,页面部分缓存是将页面部分内容保存在内存中以便响应用户请求,而页面其他部分内容则为动态 ...

  2. java如何做全局缓存_传智播客JNI第七讲 – JNI中的全局引用/局部引用/弱全局引用、缓存jfieldID和jmethodID的两种方式...

    讲解JNI中的全局引用/局部引用/弱全局引用.缓存jfieldID和jmethodID的两种方式,并编写两种缓存方式的示例代码. 1.从Java虚拟机创建的对象传到本地C/C++代码时会产生引用,根据 ...

  3. 网页刷新代码(html)两种方式

    网页刷新代码(html)两种方式: window.location.href = window.location.href; window.location.reload();

  4. android asynctask源码分析,Android通过Handler与AsyncTask两种方式动态更新ListView(附源码)...

    本文实例讲述了Android通过Handler与AsyncTask两种方式动态更新ListView的方法.分享给大家供大家参考,具体如下: 有时候我们需要修改已经生成的列表,添加或者修改数据,noti ...

  5. python模块的导入的两种方式区别详解

    Python 有两种导入模块的方法.两种都有用,你应该知道什么时候使用哪一种方法.一种方法,import module,另一种是from module import,下面是 from module i ...

  6. ajax的data传参的两种方式

    ajax的data传参的两种方式 本文为转载. 1.[javascript] view plaincopy   /** * 订单取消 * @return {Boolean} 处理是否成功 */ fun ...

  7. bootstraptable控制分页_bootstrap table分页(前后端两种方式实现)

    bootstrap table分页的两种方式: 前端分页:一次性从数据库查询所有的数据,在前端进行分页(数据量小的时候或者逻辑处理不复杂的话可以使用前端分页) 服务器分页:每次只查询当前页面加载所需要 ...

  8. php怎么跳转别的手机浏览器,JavaScript_JS脚本根据手机浏览器类型跳转WAP手机网站(两种方式),随着移动互联网的不断普及, - phpStudy...

    JS脚本根据手机浏览器类型跳转WAP手机网站(两种方式) 随着移动互联网的不断普及,企业的网络宣传不仅只局限在PC端,还要在移动端发展.我们在自己的网站做了WAP手机完整之后,如果有用户通过手机访问我 ...

  9. vue路由传参的三种方式/含页面刷新参数丢失解决方案(详细)

    vue路由传参的三种方式以及页面刷新参数丢失问题 一.路由传参的三种方式 1.传参方式一:params传参 2.传参方式二:路由属性配置传参 3.传参方式三:query传参 二.三种传递方式的区别 一 ...

最新文章

  1. Android中WIFI开发总结(一)
  2. HTML5中的CSS Shader技术
  3. python arp_用Python构造ARP请求、扫描、欺骗
  4. state.php,状态模式(State)
  5. 学习VIM之2014
  6. linux/mac下一键删除下载失败的maven jar包
  7. Java多线程编程那些事:volatile解惑
  8. java ssm旅游网站系统源码jsp maven项目推荐
  9. 在职攻读教育硕士专业学位有计算机专业吗,在职攻读教育硕士专业怎样?
  10. JQuery实现表单验证并使错误数据其无法提交到数据库
  11. 声明式导航编程式导航
  12. mysql score表_Mysql数据库练习题student,score表
  13. 使用Dockerfile创建包含nginx-fair和nginx-check模块的nginx镜像
  14. 基于人脸面部检测的口罩识别系统
  15. 深入剖析 grep 命令
  16. latex--图片并排和插入pdf格式图片
  17. 一、八位行波进位加法器(含电路图)
  18. 无人机航测作业流程,你会几个?
  19. 20230119英语学习
  20. 揭秘 媳妇第一次见婆婆的六个禁忌

热门文章

  1. 百度点石大数据开放平台,赋能营销场景,打造行业生态
  2. 部署Docker容器虚拟化平台
  3. Python 介绍及相关资料
  4. linux 时间戳几字节,时间戳汇总-jennyljd-ChinaUnix博客
  5. Kooboo CMS技术文档之三:切换数据存储方式
  6. CSU1129 送货到家 状压dp
  7. 中国电子携手IBM发力环保大数据
  8. 前端面试题(三)(CSS篇)建议收藏,持续更新中...
  9. 深度解读 | 饮食、肠道菌群与健康
  10. 《数据分析变革:大数据时代精准决策之道》一2.2 为大数据做好准备