日期:2014-05-16  浏览次数:20414 次

回顾一下我早期写的javascript代码

今天和几个人聊javascript开发的代码风格和设计,深感时代在变迁,新人的起点总是比老人要高,无需走我们曾经走过的弯路。我这一代人是从jdbc、jsp/servlet、Prototype.js开始编程的,现在的人直接就用Spring、hibernate、jQuery,手快的开始用python\ruby\nodejs。

?

这个类对我的前端开发生涯具有一定标志性意义,是我在前端开发中第一次用OOP思考,放到今天毫不稀奇,甚至有些笨拙,但还是挺宝贵的一次实践。

?

?

//DeductMoney.js
//依赖类库:prototype,buffalo,prototype-window
//服务端需要实现接口:DeductMoneyService
//开发时间:2007-09-04
//作者:tedeyang

/**
 * 通用扣款类;
 * 扣款流程:
 * 1.扣款前首先计算各种扣款明细信息:发送机内码、所属时期和计税金额(或含税金额)给服务端扣款服务接口的DeductMoneyService.calculate()方法.
 * 2.返回明细信息,并用回调函数处理。默认的回调函数弹出一个confirm窗口询问是否真正扣款。
 * 3.如果上一步的回调函数返回true则进行实际扣款:DeductMoneyService.declare:。
 * 4.扣款过程中将出现一个弹出的div层屏蔽用户操作,并每隔一定时间查询扣款状态:DeductMoneyService.queryDeclareState。
 * 5.扣款可能有三种结果:失败,成功,超时.分别对应不同的回调函数(可以覆盖默认实现)
 * 6.如果离开页面或超时,会调用DeductMoneyService.cancel进行取消操作
*/
var DeductMoney = Class.create();
DeductMoney.version = '1.0';

DeductMoney.Default={
	//在得到服务端返回的实际扣款金额后会执行此回调函数.
	//参数reply:即buffalo回调的reply
	//如果该函数返回false则不会进行申报
	afterCalculate : function(reply){
		var success = false;
		if(!reply.isFault()){
			var message = "请确认:\n" +reply.getResult().join("\n");
			message += "\n确定要申报吗?";
			success = window.confirm(message);
		}
		return success;
	},
	//在刷新等待扣款时,如果用户触发了onbeforeunload事件,将执行此函数进行警告.
	unload:function(){return "正在扣款中,现在离开本页面将取消扣款";},
	//扣款失败后会执行此函数,
	//参数result:即buffalo回调的reply.getResult()
	declareFailure:function(result){
		window.alert("扣款失败!失败原因:"+result.description);
	},
	//扣款成功后会执行此函数,
	//参数result:即buffalo回调的reply.getResult()
	declareSuccess:function(result){
		window.alert("扣款成功!");
	},
	//该函数会在超时或用户关闭窗口时执行
	cancel:function(){
		window.alert("本次扣款操作将被取消!");
		Dialog.setInfoMessage("正在取消...");
		this.buffalo.async = false;
		this.buffalo.remoteCall(
			this.serviceName+".cancel",
	 		[this.request_id],
			function(reply){
				DeductMoney.reply = reply;
			}
		);
		if(!DeductMoney.reply.isFault()){
			Dialog.setInfoMessage("已经成功取消了扣款!");
		}else{
			Dialog.setInfoMessage("取消扣款失败!");
		}
	}
};
DeductMoney.reply={isFault:function(){return false;}};//临时存放buffalo返回值.
DeductMoney.prototype = {
	//构造函数
	//buffalo : 将调用的buffalo对象
	//serviceName : 要调用的buffalo服务.该服务必须实现一个接口
	//paramList : buffalo调用的参数列表.应该有三个参数:[机内码,所属时期,金额]
	//optionList :可选,JSON对象,可以覆盖默认的几个参数和回调函数.
	initialize: function(buffalo,serviceName,paramList,optionList){
		this.startTime = 0;     //unit:ms
		this.buffalo = buffalo;
		this.serviceName = serviceName;
		this.paramList = paramList;
		this.replyCallback = {};
		this.optionList = {
			timeout:15,//,超时,秒
			refresh:5,//刷新,秒
			afterCalculate:DeductMoney.Default.afterCalculate,
			whenExitPage:DeductMoney.Default.unload,
			declareFailure:DeductMoney.Default.declareFailure,
			declareSuccess:DeductMoney.Default.declareSuccess,
			cancel:DeductMoney.Default.cancel
		};
		Object.extend(this.optionList, optionList || {});
	},
	_calculate:function(){//预处理。 回调可以为空,这样会调用默认的回调函数
		this.buffalo.async = false;
		this.buffalo.remoteCall(
			this.serviceName+".calculate",
	 		this.paramList,
	 		function(reply){
	 			DeductMoney.reply = reply;
			}
		);
		var success = this.optionList.afterCalculate(DeductMoney.reply);
		if(success){
			this._declare();
		}
	},
	_declare:function(){//申报
		this.buffalo.async = false;
		this.buffalo.remoteCall(
			this.serviceName+".declare",
	 		this.paramList,
			function(reply){
				DeductMoney.reply = reply;
			}
		);
		if(!DeductMoney.reply.isFault()){
			this._wait(DeductMoney.reply.getResult());//查询id指定的扣款请求
		}
	},
	_wait :function (id){
		window.onbeforeunload = this.optionList.whenExitPage;
		window.onunload = this.optionList.cancel.createDelegate(this);
		this.startTime = new Date().getTime();
		Dialog.info("正在扣款中...<br>如果超过"+this.optionList.timeout+"秒还没有成功扣款,该笔扣款将被取消。" ,{className:"alphacube",width: 300, height:120,showProgress:true});
		this.request_id = id;
		this._checkBankKoukuan();
	},
	//循环查询扣款状态
	_checkBankKoukuan :function () {
	  	//查询是否已经扣款,使用ajax同步模式.
	  	//根据
	  	this.bu