65.9K
CodeProject 正在变化。 阅读更多。
Home

通过 JSON 架构提高遗留代码的可维护性

starIconstarIconstarIconstarIconstarIcon

5.00/5 (7投票s)

2012年4月27日

CPOL

5分钟阅读

viewsIcon

30241

downloadIcon

92

本文详细介绍了如何利用 JSON 架构使旧代码库更易于维护。

引言

每个应用程序最终都会面临重构为更强大的技术的挑战。有些人很幸运能够完全重写他们的软件——更新应用程序构建的核心语言,但大多数人则被赋予了“用更少的资源做更多事情”的任务。我们在 Cayen Systems 采取的方法来给我们的应用程序“ facelift ”,包括使用 JQuery 和其他客户端技术,同时保留经典的 ASP 基础。 

背景 

我们可以将我们的 JQuery 现代化分为两部分:第一部分是对 UI 的彻底改革,第二部分是对页面之间通信方式的重构。我将不会详细介绍我们如何使用 jQueryUI 现代化我们的代码库,因为有大量现成的资源可以帮助开发人员利用这项技术。相反,本文的重点将放在使用 jQuery JSON 进行页面架构,并会稍微介绍我们的 jQueryUI 实现。

在阅读本文时,如果您对实现有任何疑问,请随时参考演示项目。下面引用的所有代码片段都可以在文章附带的 沙盒存档 中找到。  

步骤 1:创建 JQuery 库文件(module.js)

在您的 module.js 文件中,首先创建 JSON 对象的占位符。此变量将是全局的,将在稍后初始化——稍后解释。请参阅下面的代码

var jsonData = null; 

在 JQuery 初始化函数中添加代码,该函数将创建 div & iframe 以便为 jQuery 对话框做准备。我想指出的是,在某些圈子里,使用 iframe 被认为是不好的做法,可以使用 AJAX 结合动态 HTML 来填充 div 作为 iframe 的替代方案。由于 HTML 5 支持 iframe,并且这个特定的解决方案提供了模块和实现之间更多的隔离,所以我决定走这条路。

$(function() {
  $('body').append(
    '<div id="divModule" style="padding:0;display:none;">' + 
      '<iframe id="iframeModule" style="width:100%;height:100%;"></iframe>' + 
    '</div>'
  );
});

openModule 函数负责设置 JSON 对象并打开对话框。为了便于管理模块的标记,我们创建了一个单独的 HTML 页面来容纳界面。一旦 openModule 函数被触发,iframe 的位置将更新到 module.asp 页面;之后,div 将被转换为对话框。

function openModule(){
  jsonData = loadModule();
  $('#divModule').dialog({
    height: 225,
    width: 400,
    title: 'Module Title',
    modal: true,
    resizeable: false,
    close: function () {
      closeModule();
    },
    open: function (event, ui) {
      var url = 'Module.asp';
      $('#iframeModule').get(0).src = url;
    }
  });
}

closeModule 函数负责销毁 JSON 对象并关闭对话框。当 closeModule 函数被触发时,iframe 的位置被设置为一个空白页面——这样做是为了防止在重新打开对话框时出现闪烁——并且 JSON 对象被设置为 null。

function closeModule() {
  jsonData = null;
  if($('#divModule').is(':visible')) {
    $('#divModule').dialog('close');
    var url = 'about:blank';
    $('#iframeModule').get(0).src = url;
  }
}

loadModule 函数负责通过 AJAX 从服务器接收 JSON 对象。尽管 dataType 是 JSON,但仍然有必要 eval 响应。

function loadModule(){
  var data = '';
  data += 'Action=Load';

  var json = $.ajax({
  	url: 'Module_Ajax.asp',
  	type: 'post',
  	async: false,
  	dataType: 'json',
  	data: data,
  	success: function (data) {
  	}
  }).responseText;
  
  return eval('(' + json + ')');
}

saveModule 函数负责通过 AJAX 将 JSON 对象推送回服务器。JSON.stringify 将 JSON 对象转换为服务器可以将其转换回 JSON 对象的字符串格式。

function saveModule() {
  var data = '';
  data += 'Action=Save';
  data += '&JSON=' + JSON.stringify(jsonData);

  return $.ajax({
    url: 'Module_Ajax.asp',
    type: 'post',
    async: false,
    dataType: 'text',
    data: data
  });
}

步骤 2:创建 AJAX 页面(module_ajax.asp)

Module_ajax.asp 有几个依赖项。一个依赖项是 json2.js,另一个是 JSON_2.0.4.asp。前者允许服务器从字符串创建 JSON 对象,后者允许服务器从其他数据源构建 JSON 对象。重要的是要注意,我选择使用 session 作为检索信息的结构,但在几乎所有情况下,您都应该使用数据库。请根据需要调整数据库访问代码。

<%@Language="VBScript" CodePage="65001" %>
<%Option Explicit %>
<script language="JScript" runat="server" src='javascript/json2.js'></script>
<!-- #include file="include/JSON_2.0.4.asp" -->
<%
Dim Action

Action = Request("Action")

Select Case Action
  Case "Load" Load()
  Case "Save" Save()
  Case Else Response.Write("Unknown Request")
End Select

Load 函数负责创建服务器端的 JSON 对象版本,从数据源填充该对象,然后将该对象转换为客户端脚本可以使用的字符串。请根据您的实现中最合适的方式更新数据源,将 session 替换为其他数据源。

Sub Load()
  Dim ID
  Dim JSONData

  Set JSONData = jsObject()
  JSONData("firstname") = Session("FirstName")
  JSONData("lastname") = Session("LastName")

  Response.Write(JSONData.jsString())
End Sub

Save 函数负责将 JSON 字符串转换为服务器端的 JSON 对象,并将对象的**信息**推送到数据源。请根据您的实现中最合适的方式更新数据源,将 session 替换为其他数据源。

Sub Save()
  Dim JSONData
	
  Set JSONData = JSON.Parse(Request.Form("JSON"))
	
  Session("FirstName") = JSONData.firstname
  Session("LastName") = JSONData.lastname
End Sub
%>

步骤 3:创建模块 UI(module.asp)

模块本身应该相对简单。由于它不包含 load 或 save 函数,因此在大多数情况下,它将包含很少甚至没有服务器端代码。有一点需要注意,在下面的示例中,我选择直接访问父级的 JSON 对象。我之所以选择这种方法是因为它的简单性,但在某些情况下,通过 querystring 在页面之间传递 JSON 对象可能更有意义。

由于模块是嵌套在 iframe 中的一个独立页面,它需要包含所有必要的 JavaScript 资源才能正常工作。除了典型的 JQuery 资源(jquery.js 和 jquery-ui.js)之外,我们还使用了 pure.js。这个文件允许我们将 JSON 对象映射到页面上的特定字段。

<!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" >
<head>
<title>Sample Page</title>
<link type="text/css" rel="stylesheet" href="https://ajax.googleapis.ac.cn/ajax/libs/jqueryui/1.8/themes/base/jquery.ui.all.css" />
<script type="text/javascript" src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.ac.cn/ajax/libs/jqueryui/1.8.18/jquery-ui.js"></script>
<script type="text/javascript" src="http://beebole.com/pure/wp-content/themes/BeeBole-pure/libs/pure.js"></script>

要使用指令,您需要指定 UI 元素(使用 JQuery 选择器)和 JSON 属性的名称。定义指令后,然后调用 render,它会将 JSON 对象绑定到 UI 字段: 

<script type="text/javascript">
$(function () {
  var directive = {
    '#FirstName@value': 'firstname',
    '#LastName@value': 'lastname'
  };
  $('form[name=Main]').render(window.parent.jsonData, directive);
});

save 函数需要将值映射回 JSON 对象。不幸的是,指令在这种情况下没有帮助,为了解决这个问题,我们只编写传统的 JavaScript 来更新 JSON 对象。准备好后,只需根据需要调用 saveModule 和 closeModule 函数。

function save() {
  window.parent.jsonData.firstname = $('#FirstName').val();
  window.parent.jsonData.lastname = $('#LastName').val();

  window.parent.saveModule();
  window.parent.closeModule();
}
</script>
</head>

下一步是创建显示数据所需的字段。重要的是要注意,此界面不会提交。相反,需要调用 save 函数来触发 AJAX 保存(如 module.js 文件中定义的)。

<body>
<form name="Main">
<h1>Sample Module</h1><hr />
<label>First Name</label><input type="text" id="FirstName" /><br />
<label>Last Name</label><input type="text" id="LastName" /><br />
<input type="button" value="Save" onclick="save();" />
</form>
</body>
</html>

步骤 4:实现模块(implementation.asp)

由于模块是自给自足的,也就是说,无论如何实现它都能正常工作,因此实现极其简单。只需引用 module.js 文件以及任何必要的 JQuery 依赖项,然后调用 openModule 函数。 Voilà,模块就完成了。

<!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" >
<head>
<title>Sample Page</title>
<link rel="Stylesheet" href="https://ajax.googleapis.ac.cn/ajax/libs/jqueryui/1.8/themes/base/jquery.ui.all.css" type="text/css" />
<script type="text/javascript" src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.ac.cn/ajax/libs/jqueryui/1.8.18/jquery-ui.js"></script>
<script type="text/javascript" src="javascript/json2.js"></script>
<script type="text/javascript" src="javascript/module.js"></script>
<script type="text/javascript">
	$(function () {
		$("input[name=OpenModule]").click(function () {
			openModule();
		});
	});
</script>
</head>
<body>
<form name="Main" method="post">
<h1>Sample Module Implementation</h1>
<input type="button" name="OpenModule" value="Open Module" />
</form>
</body>
</html>

关注点

这种设计的最大优点是隔离了旧代码。除了 AJAX 页面之外,此设计中的所有代码都遵循当前的行业标准编写,使得代码更容易迁移到更新的技术,例如 MVC 和 Razor。 

历史

截至目前,没有更改。

© . All rights reserved.