位置: 编程技术 - 正文
推荐整理分享分离与继承的思想实现图片上传后的预览功能:ImageUploadView(分离与继承的思想是什么),希望有所帮助,仅作参考,欢迎阅读内容。
文章相关热门搜索词:如何理解分离,分离与继承的思想是什么,分离的概念,分离的概念,如何理解分离,分离是如何实现的,分离与继承的思维导图,分离的重要性,内容如对您有帮助,希望把文章链接给更多的朋友!
本文要介绍的是网页中常见的图片上传后直接在页面生成小图预览的实现思路,考虑到该功能有一定的适用性,于是把相关的逻辑封装成了一个ImageUploadView组件,实际使用效果可查看下一段的git效果图。在实现这个组件的过程中,有用到前面几篇博客介绍的相关内容,比如继承库class.js,任意组件的事件管理库eventBase.js,同时包含进了自己对职责分离,表现与行为分离这两方面的一些思考,欢迎阅读与交流。
演示效果:
注:由于演示的代码都是静态的,所以文件上传的组件是用setTimeout模拟的,不过它的调用方式跟我自己在实际工作中用上传组件完全相同,所以演示效果的代码实现完全符合真实的功能需求。
按照我以前博客的思路,先来介绍下这个上传预览功能的需求。
1. 需求分析
根据前面的演示效果图,分析需求如下:
1)初始时上传区域只显示一个可点击上传的按钮,当点击该按钮后,将上传成功的图片显示在后面的预览区域
2)上传的图片添加到预览区域以后,可以通过删除按钮来移除
3)当已上传的图片总数达到一定限制之后,比如演示中已上传的限制为4,就把上传按钮给移除掉;
4)当已上传的图片总数达到一定限制之时,如果通过删除操作移除了某张图片,还得再把上传按钮给显示出来。
以上需求是看的见的,根据经验,还可以分析得出的需求如下:
1)如果页面是编辑状态,也就是从数据库中查询出来的状态,只要图片列表不为空,初始时还得把图片显示出来;而且还要根据查出来的图片列表的长度跟上传限制去控制上传按钮是否显示;
2)如果当前页面是一种只能看不能改的状态,那么在初始时一定要把上传按钮和删除按钮移除掉。
需求分析完毕,接下来说明一下我的实现思路。
2. 实现思路
由于这是个表单页面,所以图片上传完以后如果要提交到后台,肯定得需要一个文本域,所以我在做静态页面的时候就把这个文本域考虑进去了,当上传完新的图片以及删除了图片之后都得去修改这个文本域的值。当时做静态页时这部分的结构如下:
从这个结构还可以看出,我把整个上传区域都放在一个ul里面,然后把ul的第一个li作为上传按钮来使用。为了完成这个功能,我们主要的任务是:上传及上传后的回调,新增或删除图片预览以及文本域值的管理。从这一点,结合职责分离的思想,这个功能至少需要三个组件,一个负责文件上传,一个负责图片预览的管理,一个负责文本域值的管理。千万不能把这三个功能,两两或者全部都封装在一起,那样的话功能耦合太强,写出来的组件可扩展性可重用性不高。如果这三个组件之间需要交互,我们只要借助回调函数或者发布-订阅模式定义它们给外部调用的接口即可。
不过文本域值的管理本身就很简单,写不写成组件都关系不大,但是至少函数级别的封装是得有的;文件上传组件虽然不是本文的重点,但是网上有很多现成的开源插件,比如webuploader,不管是直接用还是做二次封装都可以应用进来;图片预览的功能是本文的核心内容,ImageUploadView这个组件就是对它的封装,从需求来看,这个组件有语义的实例方法无非就是三个,分别是render, append, delItem,其中render用来在初始化完成之后显示初始的预览列表,append用来在上传成功后添加新的图片预览,delItem用来删除已有的图片预览,按照这个基本思路,我们只需要再结合需求和组件开发的经验为它设计好options和事件即可。
从前面的需求我们发现,这个ImageUploadView组件的render会受到页面状态的影响,当页面为查看模式时,这个组件不能做上传和删除的操作,所以可以考虑给它加一个readonly的option。同时它的上传和删除操作还会影响到上传按钮的UI逻辑,这个跟上传限制有关系,为了灵活性,也得把上传限制作为一个option。从前一段提到的三个实例方法来说,按照自己以前定义事件的经验,一般一个实例方法会定义一对事件,就像bootstrap的插件的做法一样,比如render方法,可以定义一个render.before,这个事件在render的主要逻辑执行前触发,如果外部监听器调用了这个事件的preventDefault()方法,那么render的主要逻辑都不会执行;还有一个render.after事件,这个事件在render的主要逻辑执行后触发。这种成对定义事件的好处是,既给外部提供扩展组件功能的方法,又能增加组件默认行为的管理。
最后从我之前的工作经验来说,除了有上传图片进行预览这样的功能,我曾经还做过上传视频,上传音频,上传普通文档等类似的,所以这一次碰到这个功能的时候我就觉得应该把这些功能里面相似的东西抽取出来,作为一个基类,图片上传,视频上传等分别继承这个基类去实现各自的逻辑。这个基类还有一个好处,就是能够让那些通用的逻辑完全与HTML结构分离,在这个基类里面只做一些通用的事情,比如options与组件行为(render, append, delItem)的定义,以及通用事件的监听和触发,它只要留有固定的接口留给子类来实现即可。在后面的实现中,我定义了一个FileUploadBaseView组件来完成这个基类的功能,这个基类不包含任何html或css处理的逻辑,它只是抽象了我们要完成的功能,不处理任何业务逻辑。根据业务逻辑实现的子类会受html结构的限制,所以子类的适用范围小;而基类因为做到了与html结构完全分离,所以有更大的适用范围。
3. 实现细节
从第2部分的实现思路,要实现的类有:FileUploadBaseView和ImageUploadView,前者是后者的基类。同时考虑到要给组件提供事件管理的功能,所以要用到上一篇博客的eventBase.js,FileUploadBaseView得继承该库的EventBase组件;考虑到要有类的定义和继承,还要用到之前写的继承库class.js来定义组件以及组件的继承关系。相关组件的继承关系为:ImageUploadView extend FileUploadBaseView extend EventBase。
(注:以下相关代码中模块化用的是seajs。)
FileUploadBaseView所做的事情有:
1)定义通用的option以及通用的事件管理
在该组件的DEFAULTS配置中可以看到所有的通用option和通用事件的定义:
在该组件的init方法中可以看到对通用option和事件管理的初始化逻辑:
2)定义组件的行为,预留可供子类实现的接口:
为了统一处理行为前后的事件派发逻辑,将render, append ,delItem的主要逻辑抽出来成为需被子类实现的方法_render, _append和_delItem。当调用子类的render方法时,调用的实际上父类的方法,但是当父类执行到_render方法时,执行的就是子类的方法,另外两个方法也是类似的处理。需要注意的是子类不能去覆盖render, append ,delItem三个方法,否则就得自己去处理相关事件的触发逻辑。
FileUploadBaseView整体实现如下:
ImageUploadView 的实现就比较简单了,跟填空差不多,有几个点需要说明一下:
1)这个类的DEFAULTS需要扩展父类的DEFAULTS,以便添加这个子类的默认options,同时还保留父类默认options的定义;根据静态页面结构,新增了一个onAppendClick事件,外部可在这个事件中调用文件上传组件的相关方法:
2)在init方法中,需要调用父类的init方法,才能完成那些通用的逻辑处理;同时在init的最后还得手动调用一下render方法,以便在组件实例化之后就能看到效果:
其它实现纯粹是业务逻辑实现,跟第2部分的需求密切相关。
ImageUploadView的整体实现如下:
4. 演示说明
演示的项目结构为:
框起来的就是演示的核心代码。其中fileUploadBaserView.js和imageUploadView.js是前面实现的两个核心组件。fileUploader.js是用来模拟上传组件的,它的实例有一个onSuccess的回调,表示上传成功;还有一个openChooseFileWin用来模拟真实的打开选择文件窗口并上传的这个过程:
app/regist.js是演示页面的逻辑代码,关键的部分已用注释进行说明:
5. 本文总结
ImageUploadView这个组件最终实现起来并不难,但是我也花了不少时间去琢磨它及其它父类的实现方法,大部分时间都花在对职责分离和行为分离的抽象过程中。我在本文表达的关于这两方面编程思想的观点也只是自己个人的实际体会,因为抽象层面的东西,每个人的思考方式不同最终理解的成果也就不会相同,所以我也不能直接说我的对还是不对,写出来的目的就是为了分享和交流,看看有没有其他有经验的朋友也愿意把自己在这方面的想法拿出来跟大家说一说,相信每个人看多了别人的思路之后,也会对自己的编程思想方面的锻炼带来帮助。
javascript原型继承工作原理和实例详解 先为大家分享JS原型继承实例,供大家参考,具体内容如下一、JS原型继承!DOCTYPEhtmlhtmlheadmetacharset="UTF-8"titleJS原型继承/title/headbody!--原型继承--scripttype="t
js类式继承与原型式继承详解 本文实例为大家分享了js类式继承与原型式继承相关代码,供大家参考,具体内容如下1.js类式继承/*--类式继承--*///先声明一个超类functionPerson(name){this.na
js实现商品抛物线加入购物车特效 本文实例为大家分享了js实现商品抛物线加入购物车动画代码,供大家参考,具体内容如下parapola.js/*!*byzhangxinxu(.com)--*
标签: 分离与继承的思想是什么
本文链接地址:https://www.jiuchutong.com/biancheng/373410.html 转载请保留说明!友情链接: 武汉网站建设