zoukankan      html  css  js  c++  java
  • J2EE 关于Web前端与服务端实现开发分离的实践 .

    框架后台已经实现了基本的增删改查公共操作类,Action调用Service,再由Service调用公共数据库操作类。正在琢磨如何把数据传输到前台并以何种方式进行展示,而且目标是能很好的实现前端开发人员与后端开发人员工作的分离,实现通过既定好的接口进行交互。先做了一个小小的实践,是这样的。。。
    大致思路是前后台传输使用具有固定结构的JSON字符串,JSON字符串中可以存在多个数据集,每个数据集有一个名字。前端与后端开发人员通过这个名字进行衔接。
    并且前台使用JQuery封装了一个common.js文件用来初始化以及处理服务端传来的JSON字符串。

    服务端:
    通过查询返回 List list = (·····数据库中查询到的数据·····);
    服务端 将list 放如Map中,键值为前端开发人员进行读取的名称。
    然后将Map通过fastJson等类似工具库序列化为JSON字符串,存入request.setAttribute(······)

    前端:
    通过JSP中使用request.getAttribute(······)读取JSON,其实这里可以考虑固定这个getAttribute的参数值,作为框架的既定协议,然后将它放到类似COMMON.JSP中或者写入自定义标签。每个前端开发人员创建JSP的时候都要包含这个JSP或添加写好的自定义标签,由COMMON.JSP或者自定义标签将取得的JSON字符串格式化输出为一个JS对象,一个全局的JS对象。
    我们取得的JSON中是一个由map("list",list)序列化成的固定结构的字符串。
    这样我们可以在前端封装一些列固定的JS方法来将JSON中的数据渲染到我们想要的DOM元素中,以下JS代码将渲染数据到标签
    <div id="list" spname="list" datalist="resultList" column="listTitleDic" loadingImg="true" ></div>     中。
    以上标签中,spname:标签类型 datalist:对应map中的list的键值 :column:为读取数据字段键值对应的表头名称字典 loadingImg为是否显示滚动条图标选项。
    使用这样的标签,前端开发人员就不需要写任何代码,连渲染数据的工作都是由框架集成的(下边代码)来完成的。

    前端代码片段:
    [javascript] view plaincopyprint?

    • $(document).ready(function(){  
    •     // 加载页面列表内容,因为我们标签的spname是list,之后我们可能还有select标签,checkbox标签等等,   
    •     loadList();  
    •     // loadSelect();   
    • });  
    •   
    • function loadList()  
    • {  
    •     if($('div[spname]="list"').length !== 0 ) // 判断如果存在属性名spname值为list的div元素则显示加载图标并查找全局的JSON数据集Map或进行异步读取   
    •     {    // 遍历spname为list的Div标签   
    •         $('div[spname]="list"').each(function(i){  
    •             var dsName = $.trim($(this).attr("ds"));  
    •             var currentDs = eval("dataJson.map." + dsName);// dataJson假定为我们的全局JSON数据变量   
    •             var jTemplateId = $.trim($(this).attr("jtemplate")); //我使用了JTemplate来渲染数据,模板文件通过这个属性值来进行设置,但是上边的标签没有包含jtemplate属性,在这里不包含jtemplate属性的标签默认是按照list的结构自动生成对应模板,免去前端人员操作模板的工作。   
    •             var ifShowLoadingImg = $.trim($(this).attr("loadingImg"));// 是否显示loading滚动条图片   
    •             if(currentDs == undefined)  
    •                 return true; // 如果JSON数据集中不存在当前dalist值则跳出此次循环继续判断下一个   
    •             if(ifShowLoadingImg == "true")  
    •           {  
    •                showLoadingImg(this); // 显示loading图片   
    •             }     
    •           if(jTemplateId == "")  
    •           {  
    •                jTemplateId = "defaultListTemplate";  
    •                $(this).attr("jtemplate",jTemplateId);  
    •           }  
    •               
    •           processJTemplate(this,currentDs); //通过jTemplate模板渲染数据   
    •         });  
    •     }  
    • }  
    •   
    •   
    • /**
    • *通过jTemplate模板渲染数据,参数:输入元素,datalist
    • **/  
    • function processJTemplate(elementToBeRender, datalistData)  
    • {  
    •     var jDefaultListTemplate;  
    •     elementToBeRender = $(elementToBeRender);  
    •     var columnDic = $.trim($(elementToBeRender).attr("column"));  
    •     // 若jtemplate值为defaultListTemplate则自动生成默认列表模板   
    •     if($.trim(elementToBeRender.attr("jtemplate")) == "defaultListTemplate")   
    •     {  
    •         var ifShowLoadingImg = $.trim($(elementToBeRender).attr("loadingImg"));  
    •         jDefaultListTemplate = generateDefaultListTemplate(columnDic, datalistData);  
    •         elementToBeRender.setTemplate(jDefaultListTemplate);  
    •         if(ifShowLoadingImg == "true")  
    •             setTimeout(function(){elementToBeRender.processTemplate(datalistData)},500);  
    •         else  
    •             elementToBeRender.processTemplate(datalistData);  
    •     }  
    •     else  
    •     {  
    •        // jDefaultListTemplate   
    •     }  
    • }  
    •   
    • /**
    • * 在传入的Dom元素中添加显示加载中GIF图片
    • **/  
    • function showLoadingImg(element)  
    • {  
    •     if(element == undefined)  
    •         return false;  
    •     var loadingImgUrl = basePath + "/apps/common/image/loading.gif"; // loading图片路径   
    •     var loadingImg = $("<img>"); // 加载滚动条图片   
    •     loadingImg.hide(); // 隐藏loading图片   
    •     loadingImg.attr('src',loadingImgUrl);  
    •     $(element).addClass("loadingImgAlignCenter"); // 设置容器为剧中显示   
    •     $(element).append(loadingImg);  
    •     loadingImg.show(); // 显示图片   
    •     return loadingImg;  
    • }  
    •   
    • /**
    • * 隐藏并删除loading图片
    • **/  
    • function hideLoadingImg(imgElement)  
    • {  
    •     $(imgElement).parent().removeClass("loadingImgAlignCenter");  
    •     $(imgElement).remove();  
    • }  
    •   
    • /**
    • * 根据传入datalistData生成默认的列表Template
    • **/  
    • function generateDefaultListTemplate(columnDic, datalistData)  
    • {  
    •     if(datalistData== undefined)  
    •         return false; // datalistData为空不做任何操作返回false   
    •     var templateString = new Array(); // 用于模板字符串拼接,头部   
    •     var templateTdsString = new Array(); // 用于模板字符串拼接,内容部分   
    •     templateString.push('<table class="gridTable" align="center" width="90%">');  
    •     templateString.push('<thead><tr>');  
    •     templateTdsString.push('<tbody>{#foreach $T.dataRows as record}<tr>');  
    •       
    •     $.each(datalistData[0], function(i,n){ // 取得数据集中第一行数据   
    •         if(columnDic != undefined)  
    •         {  
    •             var columnName = $.trim(eval(columnDic+"."+i));  
    •             if(columnName != "")  
    •             {  
    •                 templateString.push('<th>');  
    •                 templateString.push(columnName);  
    •                 templateString.push('</th>');  
    •             }         
    •             else  
    •             {  
    •                 templateString.push('<th>');  
    •                 templateString.push(i);  
    •                 templateString.push('</th>');  
    •             }  
    •             templateTdsString.push('<td>');  
    •             templateTdsString.push('{$T.record.');  
    •             templateTdsString.push(i);  
    •             templateTdsString.push('}');  
    •             templateTdsString.push('</td>');  
    •         }         
    •     });  
    •     templateString.push('</tr></thead>');  
    •     templateTdsString.push('</tr>{#/for}</tbody>')  
    •     return templateString.join('')+templateTdsString.join('') + '</table>';  
    • }//这里之所以只用字符串数组进行拼接是因为这样性能比较好,参考<a href="http://www.quirksmode.org/dom/innerhtml.html">http://www.quirksmode.org/dom/innerhtml.html</a>  


    $(document).ready(function(){    // 加载页面列表内容,因为我们标签的spname是list,之后我们可能还有select标签,checkbox标签等等,    loadList();    // loadSelect();});function loadList(){    if($('div[spname]="list"').length !== 0 ) // 判断如果存在属性名spname值为list的div元素则显示加载图标并查找全局的JSON数据集Map或进行异步读取    {    // 遍历spname为list的Div标签        $('div[spname]="list"').each(function(i){            var dsName = $.trim($(this).attr("ds"));            var currentDs = eval("dataJson.map." + dsName);// dataJson假定为我们的全局JSON数据变量            var jTemplateId = $.trim($(this).attr("jtemplate")); //我使用了JTemplate来渲染数据,模板文件通过这个属性值来进行设置,但是上边的标签没有包含jtemplate属性,在这里不包含jtemplate属性的标签默认是按照list的结构自动生成对应模板,免去前端人员操作模板的工作。            var ifShowLoadingImg = $.trim($(this).attr("loadingImg"));// 是否显示loading滚动条图片            if(currentDs == undefined)                return true; // 如果JSON数据集中不存在当前dalist值则跳出此次循环继续判断下一个            if(ifShowLoadingImg == "true")          {               showLoadingImg(this); // 显示loading图片            }             if(jTemplateId == "")          {               jTemplateId = "defaultListTemplate";               $(this).attr("jtemplate",jTemplateId);          }                      processJTemplate(this,currentDs); //通过jTemplate模板渲染数据        });    }}/***通过jTemplate模板渲染数据,参数:输入元素,datalist**/function processJTemplate(elementToBeRender, datalistData){    var jDefaultListTemplate;    elementToBeRender = $(elementToBeRender);    var columnDic = $.trim($(elementToBeRender).attr("column"));    // 若jtemplate值为defaultListTemplate则自动生成默认列表模板    if($.trim(elementToBeRender.attr("jtemplate")) == "defaultListTemplate")      {        var ifShowLoadingImg = $.trim($(elementToBeRender).attr("loadingImg"));        jDefaultListTemplate = generateDefaultListTemplate(columnDic, datalistData);        elementToBeRender.setTemplate(jDefaultListTemplate);        if(ifShowLoadingImg == "true")            setTimeout(function(){elementToBeRender.processTemplate(datalistData)},500);        else            elementToBeRender.processTemplate(datalistData);    }    else    {       // jDefaultListTemplate    }}/*** 在传入的Dom元素中添加显示加载中GIF图片**/function showLoadingImg(element){    if(element == undefined)        return false;    var loadingImgUrl = basePath + "/apps/common/image/loading.gif"; // loading图片路径    var loadingImg = $("<img>"); // 加载滚动条图片    loadingImg.hide(); // 隐藏loading图片    loadingImg.attr('src',loadingImgUrl);    $(element).addClass("loadingImgAlignCenter"); // 设置容器为剧中显示    $(element).append(loadingImg);    loadingImg.show(); // 显示图片    return loadingImg;}/*** 隐藏并删除loading图片**/function hideLoadingImg(imgElement){    $(imgElement).parent().removeClass("loadingImgAlignCenter");    $(imgElement).remove();}/*** 根据传入datalistData生成默认的列表Template**/function generateDefaultListTemplate(columnDic, datalistData){    if(datalistData== undefined)        return false; // datalistData为空不做任何操作返回false    var templateString = new Array(); // 用于模板字符串拼接,头部    var templateTdsString = new Array(); // 用于模板字符串拼接,内容部分    templateString.push('<table class="gridTable" align="center" width="90%">');    templateString.push('<thead><tr>');    templateTdsString.push('<tbody>{#foreach $T.dataRows as record}<tr>');        $.each(datalistData[0], function(i,n){ // 取得数据集中第一行数据        if(columnDic != undefined)        {            var columnName = $.trim(eval(columnDic+"."+i));            if(columnName != "")            {                templateString.push('<th>');                templateString.push(columnName);                templateString.push('</th>');            }                   else            {                templateString.push('<th>');                templateString.push(i);                templateString.push('</th>');            }            templateTdsString.push('<td>');            templateTdsString.push('{$T.record.');            templateTdsString.push(i);            templateTdsString.push('}');            templateTdsString.push('</td>');        }           });    templateString.push('</tr></thead>');    templateTdsString.push('</tr>{#/for}</tbody>')    return templateString.join('')+templateTdsString.join('') + '</table>';}//这里之所以只用字符串数组进行拼接是因为这样性能比较好,参考<a href="http://www.quirksmode.org/dom/innerhtml.html">http://www.quirksmode.org/dom/innerhtml.html</a>
    这样前端开发人员只要知道服务端传来的dataList名称即可使用一行标签显示一个列表了。只是刚刚开始尝试,也许想法不够成熟,希望多提意见:)

  • 相关阅读:
    hdu 4002 Find the maximum
    hdu 2837 坑题。
    hdu 3123
    zoj Treasure Hunt IV
    hdu 2053 Switch Game 水题一枚,鉴定完毕
    poj 1430 Binary Stirling Numbers
    hdu 3037 Saving Beans
    hdu 3944 dp?
    南阳oj 求N!的二进制表示最低位的1的位置(从右向左数)。
    fzu 2171 防守阵地 II
  • 原文地址:https://www.cnblogs.com/chenzhao/p/2761076.html
Copyright © 2011-2022 走看看