在公共函数中区分上层调用者的模型
2016-03-02 22:43
281 查看
一、背景及问题详述:
在编码时常常会将多次用到的公共函数封装之后,供其他函数调用。而在调用时,免不了需要根据上层调用函数的不同有不同的结果。举几个最近遇到的具体的场景:
1.UI界面的刷新按钮
UI界面的刷新按钮,其功能定义不同于F5的刷新整个页面。而是通过给定的url再次获取页面中指定的表格数据、图片等。以表格为例,为方便用户操作和减轻前端压力,表格常常会有分页、搜索功能。当存在分页功能时,搜索就必须后台处理(除非你想实现这样的效果————只告诉用户当前页有几项匹配,即使在后台保存的数据中存在其他的匹配项,也忽略),此时每一次搜索、翻页都是通过url请求数据来实现的。那刷新按钮需要实现的功能就是,记录最近一次的请求,点击刷新时重新获取一次数据。按理说实现起来简单啊,用个变量保存最近使用的url就好了,刷新就取这个变量再请求一次。的确,如果自己从头写请求,写表格的展现方式,这不失为一种解决方式。但我想现在很少有人在工作中会从头写,都是使用第三方的js库。比如,笔者在项目中使用的就是基于SlickGrid(https://github.com/mleibman/SlickGrid)再次封装的框架,该框架不支持动态传入url,取代的是在创建时指定一个baseUrl,在load数据时调用此url,之后若需要实现过滤效果,则需传入一个filter对象(JSON形式),由其内部拼装成baseUrl?key=value&name=tom的形式,再调用此url,可气的是封装好的对象不返回当前使用的url。
当时为了解决此问题,考虑过修改框架,增加一个方法,将当前使用的url暴露出来。当然这是最后的方法,因为太蠢太暴力。之后详细分析代码,发现两条流程有差异,也有联系。正常获取时,走load方法;过滤时需要先自行拼装json并传入对象,最后还是会调用load方法。
最后采用设置一个变量flag并初始化为false,当走过滤时,将flag置为true,并保存filter对象,在load执行时的回调函数中,先根据flag的值判断是过滤流程还是直接获取,在处理完相应业务后,再将flag置false。
整个流程中flag最终都会被置为false,唯一flag为true的时候就是经过过滤,业务处理完之前。
之前的刷新实现就是根据flag值判断是过滤还是直接获取后,用同一个函数封装处理如过滤则
func = function(){ obj.setFilter(filter); obj.load(); } func = function (){ obj.load(); }
最后点击刷新时直接调用函数func();
2.DOM元素事件委派
同样是使用封装过的控件(公司内部使用,样式统一,因信息安全问题无法贴代码),因原生select丑爆了且不可编辑,在封装select控件时,隐藏了select,以input显示,同时在功能上即支持用户下拉选择(通过css样式和事件委派,使用隐藏的select实现),也可支持用户输入(input实现),即界面显示的是一个有着select功能和视觉效果的input框!感觉屌屌的,马上问题就来了——参数检查。禁用input的输入还好,选什么就显示什么,怎么检查都好。但同时支持选择和输入时,检查就有问题。监听select的select事件,此事件触发时只是选中了,但值还没有填到input中,只能通过检查select的值来检查。而input的input方法(为了能感知到用户用鼠标复制黏贴而监听的input事件)因为用户输入的,肯定是取input的值检查合理,input事件处理完后会再执行select的select事件(因为有一个小功能,根据输入的input值会匹配下拉框现有的值,类似于百度搜索输入)。此时select用自己的逻辑检测并覆盖之前input的结果。然后悲剧。
最后同例一一样使用一个flag用以在公共的函数select中判断是哪个流程调用了该方法。区分执行各自的逻辑。
二、模型说明
抽取公共部分分析:全局定义flag=false,在每次公共函数结束时将flag置为false,flag只有在经过特性函数,且未退出公共函数时才为true,以此判断这一次流程是否走过特性函数。流程可反复循环的调用。
将flag换为整数,可以区分多个特性分支到底走了哪条。
三、扩展和遗留问题
1.input的input事件
该事件在标准浏览器中良好支持,IE9以下不支持。需使用IE专用属性onpropertychange oninput事件在value改变且失去焦点时实时触发,但是通过js改变value时不会触发; onpropertychange事件是任何属性改变都会触发,每增加或删除一个字符就会触发,通过js改变也会触发该事件
2.keyup事件
keyup事件未参数检测常用的事件。但经测试,该事件在select之前和之后各触发一次。不适用该模型
3.相似模型讨论
先调用公共函数,在调用下层函数(也可能没有下层函数)。目前有两条思路:
公共函数处理一遍,若有下层函数,推翻公共函数的结论,以下层函数结果为准(无脑覆盖流)。缺陷,过渡过程有时让人难以接受。还是以参数检测为例,先显示错误提示,再检测一次,发现合法,再隐藏,表现就是用户输入一个字符,错误提示闪一下又没了,坑。
为了解决上面的问题。考虑过再公共函数中使用一个定时器,我得到结果,但我傲娇,我要等一段时间(比如20ms)在将结果反馈展现。如果后续的下层调用者赞同我,以我的结果为准,定时器超时后显示结果,如果下层调用者结果与我不同,取消定时器,由下层调用者显示结果。(公共函数:意见一致时,我说了算,不一致时,别人说了算~)。
4.缺陷与待思考、优化点
只适用于单线程,目前在前端使用足够。但该模型在多线程时需注意同步互斥,具体可参考操作系统关于信号量的表述。 公共函数本身的立意是处理相同的逻辑,现在需在其中根据特性实现不同的功能,实际以违背了最初的用意,若代码全为自己实现,应考虑将对特性的区分处理抽取出来,独立处理。
相关文章推荐
- more、less 和 most 的区别
- Mootools 1.2教程 函数
- autoit InputBox 函数
- 文件遍历排序函数
- Oracle 函数大全[字符串函数,数学函数,日期函数]第1/4页
- 十万条Access数据表分页的两个解决方法
- ASP下经常用的字符串等函数参考资料
- PostgreSQL教程(五):函数和操作符详解(1)
- DOS批处理 函数定义与用法
- asp Chr 函数 数字转字母的方法
- Lua中的函数精讲笔记
- Lua中的闭合函数、非全局函数与函数的尾调用详解
- Lua中调用C++函数示例
- Lua实现split函数
- Lua常用时间函数使用实例
- Lua函数与字符串处理简明总结
- Lua学习笔记之表和函数
- Lua中实现sleep函数功能的4种方法
- Lua函数用法研究
- Lua基础教程之赋值语句、表达式、流程控制、函数学习笔记