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名称即可使用一行标签显示一个列表了。只是刚刚开始尝试,也许想法不够成熟,希望多提意见:)

  • 相关阅读:
    DataGridView中绑定List泛型的问题 [轉]
    .NET 導入EXCEL後數值型toString會變成空問題
    Linq連接List時多值時使用方法
    SQL2008报表三种实现Reporting Service2008匿名访问的方法(转)
    IIS7 WCF HTTP 错误 404.3 Not Found
    sql2005取得TABLE主鍵及欄位名稱,說明
    MSSQL禁用/啟用TRIGGER
    IE6下a:hover span失效问题(转载)
    asp.ner上传文件限制(转载)
    css优先级(转载)
  • 原文地址:https://www.cnblogs.com/chenzhao/p/2761076.html
Copyright © 2011-2022 走看看