你的位置:首页 > ASP.net教程

[ASP.net教程]web前端架构


  每天上班,看着被无数码哥擦过一遍又一遍的代码,整个人都不好了。"爸,妈,请原谅我的不辞而别,地球有灾难了,我必须站出来了!"

      在前端开发过程中,怎样才能写出耦合度低,好维护的代码呢?我认为一个好的架构是必不可少的。当然,这也需要开发人员严格遵守该架构进行开发,不能钻架构的空子,如果实在担心某些屌丝不着调,非得跟你玩李埂楞,那架构中的异常抛出机制是必不可少的,不照规矩走,就给你抛各种异常,让你走歪路,完不成任务,无限加班,不能早点回家抱老婆......

      如今的前端,玲琅满目。新技术层出不穷,我们要在万恶的深渊中另辟新径。

      我们不妨回到现实生活中,因为我们除了是一名码农,还是一个玩手机的宅男。说起手机,硬菜来了,每个人都有一部手机,可以将其当做我们的前端模块,在这个模块的内部,我可以干各种事,玩游戏,看视频,听音乐等等,不会跟你的手机有任何关联,也就是解耦了。那么问题来了,是模块总是要通信的呀,该怎么通信呢?上图:

 

  A手机想要和其他手机通信,是必须经过运营商的,所以我们的前端模块之间需要进行通信,也需要一个类似于运营商的东西,而该东西就是整个架构的核心,那就是事件管理者(EventManager)。通过事件管理者,当A模块需要调用B模块里面的render方法时,A模块将会通过事件管理者通知B模块执行它的render方法。反之,当B模块需要调用A模块的get方法时,也通过事件管理者,通知A模块执行它的get方法。这样A模块中不会存在B模块的字样,B模块中也不存在A模块的字样,它们中只会存在EventManager,一个为二者建立通信的通道。

      这其实就是设计模式中的观察者模式,也称之为发布订阅模式。上面提到的事件已经不单是浏览器自带的那些事件(click,move等),它是有一定含义的自定义事件,可以起任何名称,比如:'dataChange'(数据改变事件),'render'(数据渲染事件),'clear'(页面清空事件)。模块内部,我们分层进行开发,采用mvc或者mvvm的开发方式。mvc只是一种设计思想,可以将model,view,controller分三个js文件开发,也可以在一个js文件中实现3种层次,另外controller过于臃肿的情况下,我们对其可以进行二次乃至三次分层,例如可以分成业务层,服务层等。我想说的是,mvc只是一种思想,它没有规定你必须几个文件,怎么书写,怎么具体分层,我们完全可以在符合思想的情况下为所欲为。结构如图:

  

      

上例子:

1、模块A:

 1 T.ModuleA = { 2   init:function(){ 3  4     // 事件监听,监听清空事件 5     T.EventManager.addEvent('clear', this.clear, this); 6   }, 7  8   clear:function(id){ 9     document.getElementById(id).innerHTML = '';10   }11 }

2、模块B:

 1 T.ModuleB = { 2   init:function(){ 3  4     // 事件监听,监听清空事件 5     T.EventManager.addEvent('clear', this.clear, this); 6   }, 7  8   clear:function(id){ 9     document.getElementById(id).innerHTML = '';10   }11 }

3、事件管理类:

 1 T.EventManager = { 2  3   // 事件容器 4   eventContianer:{}, 5  6   /** 7    * 事件监听函数 8    * @param {string}  evtName  事件名称 9    * @param {function} fn     函数引用10    * @param {obj}   ctx    上下文环境11   */12   addEvent:function(evtName, fn, ctx){13 14     var obj = {'fn':fn, 'ctx':ctx};15 16     if(!this.eventContianer[evtName]){17       this.eventContianer[evtName] = [];18     }19 20     this.eventContianer[evtName].push(obj);21   },22 23   /**24    * 派发事件25    * @param {string} evtName 需要触发的事件名称26    * @param {array} args  需要传递给事件回调函数的参数27   */28   dispatchEvent:function(evtName, args){29     var item, evts = this.eventContianer[evtName];30 31     // 事件没有注册,不派发32     if(!evts){33       return;34     }35 36     for (var i = 0; i < evts.length; i++) {37       var obj = evts[i];38 39       if (Array.isArray(args)) {40         if(args[i]){41           item = args[i];42         } else {43           item = null;44         }45       } else {46         item = args;47       }48 49       obj.fn.call(obj.ctx, item);50     }51   }52 }

4、页面展示

 1 <!DOCTYPE html>  2 <html>  3 <head>  4 <meta http-equiv="content-type" content="text/html; charset=utf-8"/>  5 <script type="text/javascript"> 6   window.T = window.T || {}; 7 </script> 8 <script type="text/javascript" src="EventManager.js"></script> 9 <script type="text/javascript" src="ModuleA.js"></script>10 <script type="text/javascript" src="ModuleB.js"></script>11 <style type="text/css">12   div{13     border: 1px solid black;14   }15 16   #moduleA{17     background-color: yellow;18   }19 20   #moduleB{21     background-color: green;22   }23 </style>24 </head> 25 <body>26   <div id="moduleA">我是模块A</div>27   <div id="moduleB">我是模块B</div>28   <input id="clear" type="button" value="清空"/>29   <script type="text/javascript">30     T.ModuleA.init();31     T.ModuleB.init();32     document.getElementById('clear').onclick=function(){33       T.EventManager.dispatchEvent('clear', ['moduleA','moduleB']);34     }35   </script>36 </body> 37 </html>

上面的例子,展示了事件广播的特性,模块A监听clear事件,模块B监听clear事件,事件管理器,触发clear事件,同时清空模块A的内容和模块B的内容。有点类似于运营商向每台手机发送消息。

这个demo只是一个简单的例子,旨在抛砖引玉,但核心思想就是这样的。具体的代码实现还是需要大家不断的完善,扩展,知识在于分享以及博众取长。

 

 

---恢复内容结束---