大家在开发过程中, 经常会遇到半成品需求,比如有这样一个表单:
form.jpg项目经理开会说,要在联系人表单上,增加验证提示(红字)和搜索提示(蓝字)功能,但目前究竟在哪些input框上加还不能确定,需要再进一步请示上级领导。
当面对这样一个半拉子需求,一般人会认为:既然无法确定在哪些input加功能,后台接口也没有,那最好的办法还是等需求确定了再做,否则做了后面还得改,太麻烦。
真是这样吗?这时职责链模式就派上了用场。
职责链模式,就是通过对任务进行细粒度的划分,分解成一部分一部分的相互独立的模块,各个模块明确各自的职责,只负责职责内的事情,无关的事情传到下一个模块去做,直到需求完成。
从上面的需求来看,我们可以划分为这么几块:
1、请求后台数据模块。
2、解析数据模块。
3、创建组件模块。
4、模块单元测试。
5、完成。
下面一个一个来说。
请求后台数据模块。
它的职责就是做ajax后台请求。
var sendData = function(url,dealType,dom){
var xhr = new XMLHttpRequest();
xhr.onload = function(event){
if(xhr.status ===200){
dealData(xhr.responseText,dealType,dom)//解析数据交给下一个模块去做
}
}
xhr.open('get',url,true)
xhr.send(null)
}
解析数据模块
这个模块负责根据处理类型,将后台数据进行标准化,然后把工作往下移交。
var dealData = function(data,dealType,dom){
var dataType = Object.prototype.toString.call(data)//后台返回的数据类型
switch (dealType){
case 'list'://搜索下拉框,数据统一处理成数组
if(dataType === '[object Array]'){
return createList(data,dom)
}
if(dataType === '[object Object]'){
var newData = []
for(var key in data){
newData.push(data[key])
}
return createList(newData,dom)
}
return createList([data],dom) //普通字符串就丢进数组里面
break;
case 'validate'://验证提示
return createValidateRes(data,dom)
break;
}
}
创建组件模块
这个模块就是负责创建dom节点做显示处理了。
//创建提示框动作
var createList = function(data,dom){
var html = ''
for(var i=0;i<data.length;i++){
html+='<li>'+data[i]+'</li>'
}
dom.parentNode.getElementsByTagName('ul')[0].innerHTML = html;
}
var createValidateRes = function(data,dom){
//验证结果是唯一的
dom.parentNode.getElementsByTagName('span')[0].innerHTML = data;
}
单元测试
因为后台接口尚未完成,我们可以根据mock数据先进行单元测试了:
dealData('查无此人','validate',input[0])
dealData(['济南市','潍坊市','青岛市'],'list',input[3])
dealData({'jn':'济南市','wf':'潍坊市','qd':'青岛市'},'list',input[3])
完成
过了三天,后台接口完成,而项目经理终于确定了方案:
姓名做验证提示;家庭邮编做搜索下拉框提示。
于是我们很轻松的就完成了这个功能:
var input = document.getElementsByTagName('input')
input[0].onchange = function(e){
sendData('checkName.php?value='+this.value,'validate',this)
}
input[11].onkeydown = function(e){
sendData('searchCode.php?value='+this.value,'list',this)
}
网友评论