本文把挑战书的具体内容显示在独立页面上,这里涉及如下四个步骤:

1、增加触发入口

2、增加业务配置

3、服务端获取数据后封装为Json对象返回

4、通过对DOM元素操作绘制页面


在讲解这四个步骤之前先修改一个Bug:

【问题描述】:

(1)用户首次点击“下战书”菜单,进入登录界面提示用户需要登录

(2)用户登录成功之后就进入下战书页面

(3)此时再次点击“下战书”菜单,界面又进入到登录页面

期望:下次再点击“下战书”菜单,此时的会话已存在,所以不应该再进入登录页面

【问题原因】:

点击“下战书”菜单时,数据直接从浏览器内存中读取,并没有调用到服务端,所以这里应该禁止直接从浏览器中直接读取

【问题解决]:

解决办法通过增加时间戳的办法来解决

(1)在common.js中增加两个方法,分别用于响应“下战书”和“首页”菜单动作

/**
 * 响应首页动作
 */
function doMainAction()
{
    top.location = "index.act?timestamp=" + new Date().getTime();
}

/**
 * 响应挑战动作
 */
function doChallengeAction()
{
    top.location = "challenge.act?timestamp=" + new Date().getTime();
}

(2)修改common.js中的generateSystemMenu()方法

systemMenu += '<li id="system_challenge_menu"><a href="javascript:doChallengeAction()">下战书</a></li>';
systemMenu += '<li id="system_home_menu"><a href="javascript:doMainAction()">首页</a></li>';

通过这样修改,点击“下战书”时浏览器地址栏中会出现时间戳参数,如下图:

wKioL1QB_YKg1fq2AACEoP6C1Mw398.jpg

接下来进入正题j_0010.gif


1、增加触发入口

入口就是《【斗医】【18】Web应用开发20天》讲解的首页上话题标题,所以需要修改main.js的操纵DOM把数据绘制到页面方法appendData()

/**
 * 操纵DOM把数据绘制到页面上
 */
function appendData(i, item)
{
    // 略去部分内容

    // >>>>>>设置挑战话题标题 
    var topWrapper = $("<div />").attr("class", "main_item_wrapper");
    var topicTitle = $("<div />").attr("class", "main_item_title");
    var titleLink = $("<a />").attr("href", "javascript:forwardTopic('" + item.topicId + "')").text(item.topicTitle);
    titleLink.appendTo(topicTitle);
    topicTitle.appendTo(topWrapper);

    // 略去部分内容
}

在main.js中增加forwardTopic()方法

/**
 * 跳转到话题内容
 */
function forwardTopic(topicId)
{
    top.location = "topic.act?topicId=" + topicId + "&timestamp=" + new Date().getTime();
}


2、增加业务配置

(1)为了能响应topic.act请求,需要在system-action.xml中增加业务配置

<business name="topic" mustlogin="false">
    <forward>
        <path name="success" path="/module/topic/topic.html" />
        <path name="failure" path="/module/topic/topic.html" />
    </forward>
</business>

(2)业务配置完后经过系统转发后跳转到topic.html页面,所以需要在D:\medical\war\module\topic下增加topic.html文件

<!DOCTYPE HTML>
<html>
    <head>
        <title>斗医</title>
        <!--利于搜索引擎查询-->
        <meta name="description" content="斗医是一个医学交流平台" />
        <meta name="keywords" content="医学,交流,讨论" />
        <!--设置字符集-->
        <meta http-equiv="content-type" content="text/html;charset=utf-8" />
        <!--页面不缓存-->
        <meta http-equiv="pragma" content="no-cache" />
        <meta http-equiv="cache-control" content="no-cache,must-revalidate" />
        <meta http-equiv="expires" content="Wed, 26 Feb 1997 08:21:57 GMT" />
        <!--引入外部文件-->
        <link rel="stylesheet" type="text/css" href="theme/navigation/navigation.css">
        <link rel="stylesheet" type="text/css" href="theme/topic/topic.css">
        <script src="js/common/jquery.js"></script>
        <script src="js/common/common.js"></script>
        <script src="js/topic/topic.js"></script>
    </head>
    <body>
        <!--系统导航菜单-->
        <div id="system_navigation_menu"></div>

        <!--系统内容部分-->
        <div class="system_content">
            <div class="system_content_left">
                <div class="topic_content_wrapper" id="topic_content_dynamic_id">                   
                </div>
            </div>

            <div class="system_content_right"></div>
        </div>        
    </body>
</html>

(3)由于topic.html文件中需要引用topic.js和topic.css,所以在系统中增加这两个文件。

(4)当topic.js加载时通过Ajax异步调用到服务端

(function( window){
    $(document).ready(function()
    {
        // 生成系统菜单
        generateSystemMenu();
        // 设置"首页"菜单选中
        selectSystemMenu("system_home_menu");
        // 获取话题内容
        getTopicContent();
    });

    /**
     * 获取话题内容
     */
    function getTopicContent()
    {
        var data = {"topicId": getTopicId()};
        asyncRequest("topicContent.data", data, function(result)
        {
            
        });
    }
})( window );


3、服务端获取数据后封装为Json对象返回

(1)由于使通过topicContent.data调用到服务端,所以需要配置如下内容

<!--获取话题内容信息-->
<business name="topicContent" business-class="com.medical.server.data.TopicDataAction" />

(2)定义TopicDataAction类,完成服务端数据读取和封装

/**
 * 斗医系统获取科室信息处理类
 * 
 * @author qingkechina 2014-08-31
 */
public class TopicDataAction extends FrameDefaultAction
{
    /**
     * 全局Gson对象
     */
    private final static Gson gson = new Gson();
    
    @Override
    public String execute()
        throws FrameException
    {
        // 获取当前记录索引值
        String topicId = getParameter("topicId");
        if (FrameUtil.isEmpty(topicId))
        {
            FrameResultBean result = new FrameResultBean();
            result.setErrorCode(FrameErrorCode.REQUEST_PARAM_ERROR);
            result.setErrorDesc(FrameUtil.getErrorDescByCode(result.getErrorCode()));
            return gson.toJson(result);
        }
        
        // 获取不到话题
        TopicDAO topic = TopicUtil.getTopicById(topicId);
        if (topic == null)
        {
            FrameResultBean result = new FrameResultBean();
            result.setErrorCode(FrameErrorCode.REQUEST_CONTENT_EMPTY);
            result.setErrorDesc(FrameUtil.getErrorDescByCode(result.getErrorCode()));
            return gson.toJson(result);
        }
        
        return gson.toJson(topic);
    }
}


4、通过对DOM元素操作绘制页面

完善topic.js文件中的getTopicContent()方法

/**
 * 获取话题内容
 */
function getTopicContent()
{
    var data = {"topicId": getTopicId()};
    asyncRequest("topicContent.data", data, function(result)
    {
        // 若有错误码返回表明获取数据异常
        var resultJson = eval(result);
        if(resultJson.errorCode)
        {
            showSystemGlobalInfo(resultJson.errorDesc);
            return;
        }

        // 操纵DOM在页面绘制数据
        appendTopic2Page(resultJson);
    });
}
/**
 * 操纵DOM在页面绘制数据
 */
function appendTopic2Page(result)
{
    // 添加标题
    var contentId = $("#topic_content_dynamic_id");
    var topicTitle = $("<h2 />").text(result.topicTitle);
    topicTitle.appendTo(contentId);

    // 添加内容
    var topicContent = $("<div />").attr("class", "topic_content").html(result.prescript);
    topicContent.appendTo(contentId);

    // 添加附属内容
    var topicAttach = $("<div />").attr("class", "topic_attach");
    var attachPanel = $("<div />").attr("class", "topic_attach_panel");
    attachPanel.appendTo(topicAttach);
    topicAttach.appendTo(contentId);

    // 添加话题评论
    var commentIcon = $("<i />").attr("class", "topic_comment_icon");
    var commentLink = $("<a />").attr("href", "#").attr("class", "topic_comment_link");
    commentIcon.appendTo(commentLink);
    commentLink.text("添加评论");
    commentLink.appendTo(attachPanel);

    // 添加话题分享
    var shareIcon = $("<i />").attr("class", "topic_share_icon");
    var shareLink = $("<a />").attr("href", "#").attr("class", "topic_share_link");
    shareIcon.appendTo(shareLink);
    shareLink.text("分享");
    shareLink.appendTo(attachPanel);

    // 添加话题邀请        
    var inviteLink = $("<a />").attr("href", "#").attr("class", "topic_invite_link");        
    inviteLink.text("邀请回答");
    inviteLink.appendTo(attachPanel);

    // 添加话题举报
    var reportIcon = $("<i />").attr("class", "topic_report_icon");
    var reportLink = $("<a />").attr("href", "#").attr("class", "topic_report_link");
    reportIcon.appendTo(reportLink);
    reportLink.text("举报");
    reportLink.appendTo(attachPanel);
}

在浏览器中输入http://localhost:8080/medical,回车后效果图如下:

wKiom1QDTm7gtBLsAAIb1L5g9tU056.jpg


【备注】:这里面还有很多功能待完善,如评论功能、分享功能、邀请回答功能以及右侧内容等,这些功能要留到JSP内容部分实现了t_0015.gif